GrContext.cpp revision fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78b
127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc. 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com */ 827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 9ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 101fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com#include "GrContext.h" 111fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com 12278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com#include "GrBufferAllocPool.h" 13278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com#include "GrClipIterator.h" 1405ef510389950e1ae8dcba40e41e001db771b12dbsalomon@google.com#include "GrGpu.h" 1527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#include "GrIndexBuffer.h" 1627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#include "GrInOrderDrawBuffer.h" 1727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#include "GrPathRenderer.h" 18d22b6e4351e552a8379d7781096d9e79feeae263tomhudson@google.com#include "GrPathUtils.h" 1950398bf7f1953e640e5529616e710cf540799731bsalomon@google.com#include "GrResourceCache.h" 20558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com#include "GrStencilBuffer.h" 21278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com#include "GrTextStrike.h" 228c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com#include "SkTLazy.h" 230c8d93a94099dee2dff8da6000ded9ad59676488tomhudson@google.com#include "SkTrace.h" 2427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 2527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#define DEFER_TEXT_RENDERING 1 2627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 27fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.com#define DEFER_PATHS 1 28fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.com 2927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#define BATCH_RECT_TO_RECT (1 && !GR_STATIC_RECT_VB) 3027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 313b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org#define MAX_BLUR_SIGMA 4.0f 323b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org 33fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.com 34d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com// When we're using coverage AA but the blend is incompatible (given gpu 35d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com// limitations) should we disable AA or draw wrong? 36950d7a8d8def14efc98d12d6947347fde351b737bsalomon@google.com#define DISABLE_COVERAGE_AA_FOR_BLEND 1 37d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com 388ccadddfa78adbdbbdfa724247318436465a7378bsalomon@google.comstatic const size_t MAX_TEXTURE_CACHE_COUNT = 256; 398ccadddfa78adbdbbdfa724247318436465a7378bsalomon@google.comstatic const size_t MAX_TEXTURE_CACHE_BYTES = 16 * 1024 * 1024; 4027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 41fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.comstatic const size_t DRAW_BUFFER_VBPOOL_BUFFER_SIZE = 1 << 13; 4227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comstatic const int DRAW_BUFFER_VBPOOL_PREALLOC_BUFFERS = 4; 4327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 44fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.com// path rendering is the only thing we defer today that uses non-static indices 45fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.comstatic const size_t DRAW_BUFFER_IBPOOL_BUFFER_SIZE = DEFER_PATHS ? 1 << 11 : 0; 46fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.comstatic const int DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS = DEFER_PATHS ? 4 : 0; 4727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 48bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com#define ASSERT_OWNED_RESOURCE(R) GrAssert(!(R) || (R)->getContext() == this) 49bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com 5005ef510389950e1ae8dcba40e41e001db771b12dbsalomon@google.comGrContext* GrContext::Create(GrEngine engine, 5105ef510389950e1ae8dcba40e41e001db771b12dbsalomon@google.com GrPlatform3DContext context3D) { 5227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrContext* ctx = NULL; 5327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrGpu* fGpu = GrGpu::Create(engine, context3D); 5427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL != fGpu) { 5527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com ctx = new GrContext(fGpu); 5627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fGpu->unref(); 5727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 5827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return ctx; 5927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 6027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 6127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comGrContext::~GrContext() { 628fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com this->flush(); 6327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com delete fTextureCache; 6427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com delete fFontCache; 6527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com delete fDrawBuffer; 6627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com delete fDrawBufferVBAllocPool; 67de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com delete fDrawBufferIBAllocPool; 683008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com 69205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrSafeUnref(fAAFillRectIndexBuffer); 70205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrSafeUnref(fAAStrokeRectIndexBuffer); 71205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com fGpu->unref(); 723008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com GrSafeUnref(fPathRendererChain); 7327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 7427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 758fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.comvoid GrContext::contextLost() { 7653a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com contextDestroyed(); 7753a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com this->setupDrawBuffer(); 7853a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com} 7953a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com 8053a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.comvoid GrContext::contextDestroyed() { 81205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com // abandon first to so destructors 82205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com // don't try to free the resources in the API. 83205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com fGpu->abandonResources(); 84205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 853008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com // a path renderer may be holding onto resources that 863008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com // are now unusable 873008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com GrSafeSetNull(fPathRendererChain); 883008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com 898fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com delete fDrawBuffer; 908fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fDrawBuffer = NULL; 91205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 928fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com delete fDrawBufferVBAllocPool; 938fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fDrawBufferVBAllocPool = NULL; 94205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 958fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com delete fDrawBufferIBAllocPool; 968fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fDrawBufferIBAllocPool = NULL; 978fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 98205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrSafeSetNull(fAAFillRectIndexBuffer); 99205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrSafeSetNull(fAAStrokeRectIndexBuffer); 100205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1018fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fTextureCache->removeAll(); 1028fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fFontCache->freeAll(); 1038fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fGpu->markContextDirty(); 1048fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com} 1058fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 1068fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.comvoid GrContext::resetContext() { 1078fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fGpu->markContextDirty(); 1088fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com} 1098fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 1108fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.comvoid GrContext::freeGpuResources() { 1118fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com this->flush(); 1128fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fTextureCache->removeAll(); 1138fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fFontCache->freeAll(); 1143008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com // a path renderer may be holding onto resources 1153008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com GrSafeSetNull(fPathRendererChain); 11627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 11727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 11805e70247c31ae927074ef27ea9893634a8dda543twiz@google.comsize_t GrContext::getGpuTextureCacheBytes() const { 11905e70247c31ae927074ef27ea9893634a8dda543twiz@google.com return fTextureCache->getCachedResourceBytes(); 12005e70247c31ae927074ef27ea9893634a8dda543twiz@google.com} 12105e70247c31ae927074ef27ea9893634a8dda543twiz@google.com 122fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 123fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com 12426c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.comint GrContext::PaintStageVertexLayoutBits( 12526c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com const GrPaint& paint, 12626c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com const bool hasTexCoords[GrPaint::kTotalStages]) { 12726c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com int stageMask = paint.getActiveStageMask(); 12826c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com int layout = 0; 12926c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com for (int i = 0; i < GrPaint::kTotalStages; ++i) { 13026c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com if ((1 << i) & stageMask) { 13126c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com if (NULL != hasTexCoords && hasTexCoords[i]) { 13226c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com layout |= GrDrawTarget::StageTexCoordVertexLayoutBit(i, i); 13326c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com } else { 13426c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com layout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(i); 13526c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com } 13626c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com } 13726c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com } 13826c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com return layout; 13926c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com} 14026c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 14126c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 14226c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 14326c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 144fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.comenum { 145558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com // flags for textures 146558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com kNPOTBit = 0x1, 147558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com kFilterBit = 0x2, 148558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com kScratchBit = 0x4, 149558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com 150558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com // resource type 151558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com kTextureBit = 0x8, 152558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com kStencilBufferBit = 0x10 153fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com}; 154fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com 15550398bf7f1953e640e5529616e710cf540799731bsalomon@google.comGrTexture* GrContext::TextureCacheEntry::texture() const { 15650398bf7f1953e640e5529616e710cf540799731bsalomon@google.com if (NULL == fEntry) { 15750398bf7f1953e640e5529616e710cf540799731bsalomon@google.com return NULL; 15850398bf7f1953e640e5529616e710cf540799731bsalomon@google.com } else { 15950398bf7f1953e640e5529616e710cf540799731bsalomon@google.com return (GrTexture*) fEntry->resource(); 16050398bf7f1953e640e5529616e710cf540799731bsalomon@google.com } 16150398bf7f1953e640e5529616e710cf540799731bsalomon@google.com} 16250398bf7f1953e640e5529616e710cf540799731bsalomon@google.com 16350398bf7f1953e640e5529616e710cf540799731bsalomon@google.comnamespace { 16450398bf7f1953e640e5529616e710cf540799731bsalomon@google.com// returns true if this is a "special" texture because of gpu NPOT limitations 16550398bf7f1953e640e5529616e710cf540799731bsalomon@google.combool gen_texture_key_values(const GrGpu* gpu, 1661fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com const GrSamplerState* sampler, 16750398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrContext::TextureKey clientKey, 16850398bf7f1953e640e5529616e710cf540799731bsalomon@google.com int width, 16950398bf7f1953e640e5529616e710cf540799731bsalomon@google.com int height, 17078d6cf9f434d3351b19de14f1eab424c23f0ab6dbsalomon@google.com int sampleCnt, 17150398bf7f1953e640e5529616e710cf540799731bsalomon@google.com bool scratch, 17250398bf7f1953e640e5529616e710cf540799731bsalomon@google.com uint32_t v[4]) { 17350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GR_STATIC_ASSERT(sizeof(GrContext::TextureKey) == sizeof(uint64_t)); 17450398bf7f1953e640e5529616e710cf540799731bsalomon@google.com // we assume we only need 16 bits of width and height 17550398bf7f1953e640e5529616e710cf540799731bsalomon@google.com // assert that texture creation will fail anyway if this assumption 17650398bf7f1953e640e5529616e710cf540799731bsalomon@google.com // would cause key collisions. 17718c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com GrAssert(gpu->getCaps().fMaxTextureSize <= SK_MaxU16); 17850398bf7f1953e640e5529616e710cf540799731bsalomon@google.com v[0] = clientKey & 0xffffffffUL; 17950398bf7f1953e640e5529616e710cf540799731bsalomon@google.com v[1] = (clientKey >> 32) & 0xffffffffUL; 18050398bf7f1953e640e5529616e710cf540799731bsalomon@google.com v[2] = width | (height << 16); 18150398bf7f1953e640e5529616e710cf540799731bsalomon@google.com 18278d6cf9f434d3351b19de14f1eab424c23f0ab6dbsalomon@google.com v[3] = (sampleCnt << 24); 18378d6cf9f434d3351b19de14f1eab424c23f0ab6dbsalomon@google.com GrAssert(sampleCnt >= 0 && sampleCnt < 256); 18478d6cf9f434d3351b19de14f1eab424c23f0ab6dbsalomon@google.com 18518c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com if (!gpu->getCaps().fNPOTTextureTileSupport) { 186fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com bool isPow2 = GrIsPow2(width) && GrIsPow2(height); 187fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com 1881fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com bool tiled = NULL != sampler && 1891fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com ((sampler->getWrapX() != GrSamplerState::kClamp_WrapMode) || 1901fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com (sampler->getWrapY() != GrSamplerState::kClamp_WrapMode)); 191fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com 192fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com if (tiled && !isPow2) { 19350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com v[3] |= kNPOTBit; 1941fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com if (GrSamplerState::kNearest_Filter != sampler->getFilter()) { 19550398bf7f1953e640e5529616e710cf540799731bsalomon@google.com v[3] |= kFilterBit; 196fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com } 197fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com } 198fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com } 199fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com 20050398bf7f1953e640e5529616e710cf540799731bsalomon@google.com if (scratch) { 20150398bf7f1953e640e5529616e710cf540799731bsalomon@google.com v[3] |= kScratchBit; 202fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com } 20350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com 204558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com v[3] |= kTextureBit; 205558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com 20650398bf7f1953e640e5529616e710cf540799731bsalomon@google.com return v[3] & kNPOTBit; 20750398bf7f1953e640e5529616e710cf540799731bsalomon@google.com} 208558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com 209558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com// we should never have more than one stencil buffer with same combo of 210558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com// (width,height,samplecount) 211558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.comvoid gen_stencil_key_values(int width, int height, 212558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com int sampleCnt, uint32_t v[4]) { 213558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com v[0] = width; 214558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com v[1] = height; 215558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com v[2] = sampleCnt; 216558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com v[3] = kStencilBufferBit; 217558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com} 218558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com 219558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.comvoid gen_stencil_key_values(const GrStencilBuffer* sb, 220558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com uint32_t v[4]) { 221558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com gen_stencil_key_values(sb->width(), sb->height(), 222558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com sb->numSamples(), v); 223558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com} 22482c7bd8f25682fcacfeea12ed899976504a767ffbsalomon@google.com 2253b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.orgvoid build_kernel(float sigma, float* kernel, int kernelWidth) { 2263b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org int halfWidth = (kernelWidth - 1) / 2; 2273b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org float sum = 0.0f; 2283b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org float denom = 1.0f / (2.0f * sigma * sigma); 2293b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org for (int i = 0; i < kernelWidth; ++i) { 2303b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org float x = static_cast<float>(i - halfWidth); 2313b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org // Note that the constant term (1/(sqrt(2*pi*sigma^2)) of the Gaussian 2323b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org // is dropped here, since we renormalize the kernel below. 2333b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org kernel[i] = sk_float_exp(- x * x * denom); 2343b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org sum += kernel[i]; 2353b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org } 2363b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org // Normalize the kernel 2373b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org float scale = 1.0f / sum; 2383b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org for (int i = 0; i < kernelWidth; ++i) 2393b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org kernel[i] *= scale; 2403b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org} 2413b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org 2423b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.orgvoid scale_rect(SkRect* rect, float xScale, float yScale) { 2433b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org rect->fLeft *= xScale; 2443b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org rect->fTop *= yScale; 2453b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org rect->fRight *= xScale; 2463b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org rect->fBottom *= yScale; 2473b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org} 2483b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org 2493b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.orgfloat adjust_sigma(float sigma, int *scaleFactor, int *halfWidth, 2503b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org int *kernelWidth) { 2513b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org *scaleFactor = 1; 2523b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org while (sigma > MAX_BLUR_SIGMA) { 2533b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org *scaleFactor *= 2; 2543b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org sigma *= 0.5f; 2553b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org } 2563b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org *halfWidth = static_cast<int>(ceilf(sigma * 3.0f)); 2573b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org *kernelWidth = *halfWidth * 2 + 1; 2583b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org return sigma; 2593b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org} 2603b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org 2613b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.orgvoid apply_morphology(GrGpu* gpu, 2623b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrTexture* texture, 2633b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org const SkRect& rect, 2643b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org int radius, 2653b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrSamplerState::Filter filter, 2663b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrSamplerState::FilterDirection direction) { 2673b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrAssert(filter == GrSamplerState::kErode_Filter || 2683b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org filter == GrSamplerState::kDilate_Filter); 2693b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org 2703b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrDrawTarget::AutoStateRestore asr(gpu); 2713b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrDrawState* drawState = gpu->drawState(); 2723b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrRenderTarget* target = drawState->getRenderTarget(); 2733b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org drawState->reset(); 2743b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org drawState->setRenderTarget(target); 2753b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrMatrix sampleM; 2763b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org sampleM.setIDiv(texture->width(), texture->height()); 2773b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org drawState->sampler(0)->reset(GrSamplerState::kClamp_WrapMode, filter, 2783b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org sampleM); 2793b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org drawState->sampler(0)->setMorphologyRadius(radius); 2803b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org drawState->sampler(0)->setFilterDirection(direction); 2813b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org drawState->setTexture(0, texture); 2823b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org gpu->drawSimpleRect(rect, NULL, 1 << 0); 2833b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org} 2843b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org 2853b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.orgvoid convolve(GrGpu* gpu, 2863b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrTexture* texture, 2873b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org const SkRect& rect, 2883b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org const float* kernel, 2893b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org int kernelWidth, 2903b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrSamplerState::FilterDirection direction) { 2913b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrDrawTarget::AutoStateRestore asr(gpu); 2923b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrDrawState* drawState = gpu->drawState(); 2933b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrRenderTarget* target = drawState->getRenderTarget(); 2943b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org drawState->reset(); 2953b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org drawState->setRenderTarget(target); 2963b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrMatrix sampleM; 2973b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org sampleM.setIDiv(texture->width(), texture->height()); 2983b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org drawState->sampler(0)->reset(GrSamplerState::kClamp_WrapMode, 2993b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrSamplerState::kConvolution_Filter, 3003b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org sampleM); 3013b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org drawState->sampler(0)->setConvolutionParams(kernelWidth, kernel); 3023b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org drawState->sampler(0)->setFilterDirection(direction); 3033b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org drawState->setTexture(0, texture); 3043b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org gpu->drawSimpleRect(rect, NULL, 1 << 0); 3053b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org} 3063b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org 307fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com} 308fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com 3091fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.comGrContext::TextureCacheEntry GrContext::findAndLockTexture( 3101fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com TextureKey key, 3111fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com int width, 3121fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com int height, 3131fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com const GrSamplerState* sampler) { 31450398bf7f1953e640e5529616e710cf540799731bsalomon@google.com uint32_t v[4]; 31578d6cf9f434d3351b19de14f1eab424c23f0ab6dbsalomon@google.com gen_texture_key_values(fGpu, sampler, key, width, height, 0, false, v); 31650398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrResourceKey resourceKey(v); 317558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com return TextureCacheEntry(fTextureCache->findAndLock(resourceKey, 318558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com GrResourceCache::kNested_LockType)); 319558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com} 320558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com 321fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.combool GrContext::isTextureInCache(TextureKey key, 322fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com int width, 323fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com int height, 3241fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com const GrSamplerState* sampler) const { 325fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com uint32_t v[4]; 32678d6cf9f434d3351b19de14f1eab424c23f0ab6dbsalomon@google.com gen_texture_key_values(fGpu, sampler, key, width, height, 0, false, v); 327fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com GrResourceKey resourceKey(v); 328fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com return fTextureCache->hasKey(resourceKey); 329fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com} 330fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com 331558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.comGrResourceEntry* GrContext::addAndLockStencilBuffer(GrStencilBuffer* sb) { 332bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(sb); 333558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com uint32_t v[4]; 334558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com gen_stencil_key_values(sb, v); 335558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com GrResourceKey resourceKey(v); 336558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com return fTextureCache->createAndLock(resourceKey, sb); 337558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com} 338558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com 339558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.comGrStencilBuffer* GrContext::findStencilBuffer(int width, int height, 340558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com int sampleCnt) { 341558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com uint32_t v[4]; 342558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com gen_stencil_key_values(width, height, sampleCnt, v); 343558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com GrResourceKey resourceKey(v); 344558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com GrResourceEntry* entry = fTextureCache->findAndLock(resourceKey, 345558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com GrResourceCache::kSingle_LockType); 346558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com if (NULL != entry) { 347558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com GrStencilBuffer* sb = (GrStencilBuffer*) entry->resource(); 348558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com return sb; 349558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com } else { 350558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com return NULL; 351558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com } 352558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com} 353558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com 354558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.comvoid GrContext::unlockStencilBuffer(GrResourceEntry* sbEntry) { 355bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(sbEntry->resource()); 356558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com fTextureCache->unlock(sbEntry); 35727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 35827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 35927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comstatic void stretchImage(void* dst, 36027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int dstW, 36127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int dstH, 36227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com void* src, 36327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int srcW, 36427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int srcH, 36527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int bpp) { 36627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrFixed dx = (srcW << 16) / dstW; 36727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrFixed dy = (srcH << 16) / dstH; 36827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 36927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrFixed y = dy >> 1; 37027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 37127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int dstXLimit = dstW*bpp; 37227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com for (int j = 0; j < dstH; ++j) { 37327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrFixed x = dx >> 1; 37427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com void* srcRow = (uint8_t*)src + (y>>16)*srcW*bpp; 37527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com void* dstRow = (uint8_t*)dst + j*dstW*bpp; 37627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com for (int i = 0; i < dstXLimit; i += bpp) { 37727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com memcpy((uint8_t*) dstRow + i, 37827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com (uint8_t*) srcRow + (x>>16)*bpp, 37927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com bpp); 38027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com x += dx; 38127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 38227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com y += dy; 38327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 38427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 38527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 3861fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.comGrContext::TextureCacheEntry GrContext::createAndLockTexture( 3871fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com TextureKey key, 3881fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com const GrSamplerState* sampler, 3891fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com const GrTextureDesc& desc, 3901fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com void* srcData, 3911fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com size_t rowBytes) { 392278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com SK_TRACE_EVENT0("GrContext::createAndLockTexture"); 39327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 39427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#if GR_DUMP_TEXTURE_UPLOAD 39527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrPrintf("GrContext::createAndLockTexture [%d %d]\n", desc.fWidth, desc.fHeight); 39627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#endif 39727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 39850398bf7f1953e640e5529616e710cf540799731bsalomon@google.com TextureCacheEntry entry; 39950398bf7f1953e640e5529616e710cf540799731bsalomon@google.com uint32_t v[4]; 40050398bf7f1953e640e5529616e710cf540799731bsalomon@google.com bool special = gen_texture_key_values(fGpu, sampler, key, 40178d6cf9f434d3351b19de14f1eab424c23f0ab6dbsalomon@google.com desc.fWidth, desc.fHeight, 40278d6cf9f434d3351b19de14f1eab424c23f0ab6dbsalomon@google.com desc.fSampleCnt, false, v); 40350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrResourceKey resourceKey(v); 40450398bf7f1953e640e5529616e710cf540799731bsalomon@google.com 40527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (special) { 4061fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com GrAssert(NULL != sampler); 4071fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com TextureCacheEntry clampEntry = this->findAndLockTexture(key, 4081fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com desc.fWidth, 4091fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com desc.fHeight, 4101fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com NULL); 41127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 41250398bf7f1953e640e5529616e710cf540799731bsalomon@google.com if (NULL == clampEntry.texture()) { 4131fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com clampEntry = this->createAndLockTexture(key, NULL, desc, 4141fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com srcData, rowBytes); 41550398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrAssert(NULL != clampEntry.texture()); 41650398bf7f1953e640e5529616e710cf540799731bsalomon@google.com if (NULL == clampEntry.texture()) { 41750398bf7f1953e640e5529616e710cf540799731bsalomon@google.com return entry; 41827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 41927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 420fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com GrTextureDesc rtDesc = desc; 421fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com rtDesc.fFlags = rtDesc.fFlags | 422fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com kRenderTarget_GrTextureFlagBit | 423fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com kNoStencil_GrTextureFlagBit; 4249962108c400dadcae913614e8a5ab781780981d8bsalomon@google.com rtDesc.fWidth = GrNextPow2(GrMax(desc.fWidth, 64)); 4259962108c400dadcae913614e8a5ab781780981d8bsalomon@google.com rtDesc.fHeight = GrNextPow2(GrMax(desc.fHeight, 64)); 42627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 42727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrTexture* texture = fGpu->createTexture(rtDesc, NULL, 0); 42827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 42927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL != texture) { 43027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget::AutoStateRestore asr(fGpu); 4318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = fGpu->drawState(); 43252a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com drawState->reset(); 4338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setRenderTarget(texture->asRenderTarget()); 4348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setTexture(0, clampEntry.texture()); 43582c7bd8f25682fcacfeea12ed899976504a767ffbsalomon@google.com 4366aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com GrSamplerState::Filter filter; 4376aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com // if filtering is not desired then we want to ensure all 4386aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com // texels in the resampled image are copies of texels from 4396aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com // the original. 4401fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com if (GrSamplerState::kNearest_Filter == sampler->getFilter()) { 4416aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com filter = GrSamplerState::kNearest_Filter; 4426aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com } else { 4436aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com filter = GrSamplerState::kBilinear_Filter; 4446aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com } 4451e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com drawState->sampler(0)->reset(GrSamplerState::kClamp_WrapMode, 4461e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com filter); 44727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 44827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com static const GrVertexLayout layout = 44927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget::StageTexCoordVertexLayoutBit(0,0); 45027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget::AutoReleaseGeometry arg(fGpu, layout, 4, 0); 45127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 45227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (arg.succeeded()) { 45327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrPoint* verts = (GrPoint*) arg.vertices(); 45427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[0].setIRectFan(0, 0, 45527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com texture->width(), 45627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com texture->height(), 45727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 2*sizeof(GrPoint)); 45827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[1].setIRectFan(0, 0, 1, 1, 2*sizeof(GrPoint)); 45927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fGpu->drawNonIndexed(kTriangleFan_PrimitiveType, 46027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 0, 4); 46150398bf7f1953e640e5529616e710cf540799731bsalomon@google.com entry.set(fTextureCache->createAndLock(resourceKey, texture)); 46227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 4631da0746fa155cdca982ae8deb68cc64f540c92dfbsalomon@google.com texture->releaseRenderTarget(); 46427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 46527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // TODO: Our CPU stretch doesn't filter. But we create separate 46627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // stretched textures when the sampler state is either filtered or 46727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // not. Either implement filtered stretch blit on CPU or just create 46827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // one when FBO case fails. 46927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 470fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com rtDesc.fFlags = kNone_GrTextureFlags; 47127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // no longer need to clamp at min RT size. 47227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com rtDesc.fWidth = GrNextPow2(desc.fWidth); 47327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com rtDesc.fHeight = GrNextPow2(desc.fHeight); 47464c4fe4113424bcfab8b3e0c7049887fda5ab4ffbsalomon@google.com int bpp = GrBytesPerPixel(desc.fConfig); 4753582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com SkAutoSMalloc<128*128*4> stretchedPixels(bpp * 47627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com rtDesc.fWidth * 47727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com rtDesc.fHeight); 47827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com stretchImage(stretchedPixels.get(), rtDesc.fWidth, rtDesc.fHeight, 47927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com srcData, desc.fWidth, desc.fHeight, bpp); 48027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 48127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com size_t stretchedRowBytes = rtDesc.fWidth * bpp; 48227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 48327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrTexture* texture = fGpu->createTexture(rtDesc, 48427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com stretchedPixels.get(), 48527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com stretchedRowBytes); 48627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrAssert(NULL != texture); 48750398bf7f1953e640e5529616e710cf540799731bsalomon@google.com entry.set(fTextureCache->createAndLock(resourceKey, texture)); 48827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 48950398bf7f1953e640e5529616e710cf540799731bsalomon@google.com fTextureCache->unlock(clampEntry.cacheEntry()); 49027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 49127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 49227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrTexture* texture = fGpu->createTexture(desc, srcData, rowBytes); 49327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL != texture) { 49450398bf7f1953e640e5529616e710cf540799731bsalomon@google.com entry.set(fTextureCache->createAndLock(resourceKey, texture)); 49527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 49627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 49727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return entry; 49827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 49927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 50050398bf7f1953e640e5529616e710cf540799731bsalomon@google.comnamespace { 50150398bf7f1953e640e5529616e710cf540799731bsalomon@google.cominline void gen_scratch_tex_key_values(const GrGpu* gpu, 50250398bf7f1953e640e5529616e710cf540799731bsalomon@google.com const GrTextureDesc& desc, 50350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com uint32_t v[4]) { 50450398bf7f1953e640e5529616e710cf540799731bsalomon@google.com // Instead of a client-provided key of the texture contents 50550398bf7f1953e640e5529616e710cf540799731bsalomon@google.com // we create a key of from the descriptor. 50678d6cf9f434d3351b19de14f1eab424c23f0ab6dbsalomon@google.com GrContext::TextureKey descKey = (desc.fFlags << 8) | 50764c4fe4113424bcfab8b3e0c7049887fda5ab4ffbsalomon@google.com ((uint64_t) desc.fConfig << 32); 50850398bf7f1953e640e5529616e710cf540799731bsalomon@google.com // this code path isn't friendly to tiling with NPOT restricitons 50950398bf7f1953e640e5529616e710cf540799731bsalomon@google.com // We just pass ClampNoFilter() 5101fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com gen_texture_key_values(gpu, NULL, descKey, desc.fWidth, 51178d6cf9f434d3351b19de14f1eab424c23f0ab6dbsalomon@google.com desc.fHeight, desc.fSampleCnt, true, v); 51250398bf7f1953e640e5529616e710cf540799731bsalomon@google.com} 51327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 51427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 51550398bf7f1953e640e5529616e710cf540799731bsalomon@google.comGrContext::TextureCacheEntry GrContext::lockScratchTexture( 51650398bf7f1953e640e5529616e710cf540799731bsalomon@google.com const GrTextureDesc& inDesc, 51750398bf7f1953e640e5529616e710cf540799731bsalomon@google.com ScratchTexMatch match) { 51850398bf7f1953e640e5529616e710cf540799731bsalomon@google.com 519b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com GrTextureDesc desc = inDesc; 52050398bf7f1953e640e5529616e710cf540799731bsalomon@google.com if (kExact_ScratchTexMatch != match) { 52150398bf7f1953e640e5529616e710cf540799731bsalomon@google.com // bin by pow2 with a reasonable min 52250398bf7f1953e640e5529616e710cf540799731bsalomon@google.com static const int MIN_SIZE = 256; 52350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com desc.fWidth = GrMax(MIN_SIZE, GrNextPow2(desc.fWidth)); 52450398bf7f1953e640e5529616e710cf540799731bsalomon@google.com desc.fHeight = GrMax(MIN_SIZE, GrNextPow2(desc.fHeight)); 52550398bf7f1953e640e5529616e710cf540799731bsalomon@google.com } 526b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com 52750398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrResourceEntry* entry; 528b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com int origWidth = desc.fWidth; 529b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com int origHeight = desc.fHeight; 530b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com bool doubledW = false; 531b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com bool doubledH = false; 532b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com 533b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com do { 53450398bf7f1953e640e5529616e710cf540799731bsalomon@google.com uint32_t v[4]; 53550398bf7f1953e640e5529616e710cf540799731bsalomon@google.com gen_scratch_tex_key_values(fGpu, desc, v); 53650398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrResourceKey key(v); 537558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com entry = fTextureCache->findAndLock(key, 538558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com GrResourceCache::kNested_LockType); 539b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com // if we miss, relax the fit of the flags... 540b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com // then try doubling width... then height. 54150398bf7f1953e640e5529616e710cf540799731bsalomon@google.com if (NULL != entry || kExact_ScratchTexMatch == match) { 542b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com break; 543b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } 544b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com if (!(desc.fFlags & kRenderTarget_GrTextureFlagBit)) { 545b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fFlags = desc.fFlags | kRenderTarget_GrTextureFlagBit; 546b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } else if (desc.fFlags & kNoStencil_GrTextureFlagBit) { 547b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fFlags = desc.fFlags & ~kNoStencil_GrTextureFlagBit; 548b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } else if (!doubledW) { 549b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fFlags = inDesc.fFlags; 550b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fWidth *= 2; 551b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com doubledW = true; 552b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } else if (!doubledH) { 553b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fFlags = inDesc.fFlags; 554b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fWidth = origWidth; 555b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fHeight *= 2; 556b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com doubledH = true; 557b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } else { 558b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com break; 559b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } 560b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com 561b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } while (true); 562b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com 563b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com if (NULL == entry) { 564b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fFlags = inDesc.fFlags; 565b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fWidth = origWidth; 566b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fHeight = origHeight; 567b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com GrTexture* texture = fGpu->createTexture(desc, NULL, 0); 568b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com if (NULL != texture) { 56950398bf7f1953e640e5529616e710cf540799731bsalomon@google.com uint32_t v[4]; 57050398bf7f1953e640e5529616e710cf540799731bsalomon@google.com gen_scratch_tex_key_values(fGpu, desc, v); 57150398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrResourceKey key(v); 572b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com entry = fTextureCache->createAndLock(key, texture); 573b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } 574b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } 575b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com 576b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com // If the caller gives us the same desc/sampler twice we don't want 577b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com // to return the same texture the second time (unless it was previously 578b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com // released). So we detach the entry from the cache and reattach at release. 579b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com if (NULL != entry) { 580b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com fTextureCache->detach(entry); 581b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } 58250398bf7f1953e640e5529616e710cf540799731bsalomon@google.com return TextureCacheEntry(entry); 583b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com} 584b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com 58550398bf7f1953e640e5529616e710cf540799731bsalomon@google.comvoid GrContext::unlockTexture(TextureCacheEntry entry) { 586bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(entry.texture()); 58750398bf7f1953e640e5529616e710cf540799731bsalomon@google.com // If this is a scratch texture we detached it from the cache 58850398bf7f1953e640e5529616e710cf540799731bsalomon@google.com // while it was locked (to avoid two callers simultaneously getting 58950398bf7f1953e640e5529616e710cf540799731bsalomon@google.com // the same texture). 59050398bf7f1953e640e5529616e710cf540799731bsalomon@google.com if (kScratchBit & entry.cacheEntry()->key().getValue32(3)) { 59150398bf7f1953e640e5529616e710cf540799731bsalomon@google.com fTextureCache->reattachAndUnlock(entry.cacheEntry()); 592fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com } else { 59350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com fTextureCache->unlock(entry.cacheEntry()); 594fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com } 59527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 59627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 597fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.comGrTexture* GrContext::createUncachedTexture(const GrTextureDesc& desc, 59827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com void* srcData, 59927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com size_t rowBytes) { 60027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return fGpu->createTexture(desc, srcData, rowBytes); 60127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 60227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 60327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::getTextureCacheLimits(int* maxTextures, 60427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com size_t* maxTextureBytes) const { 60527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fTextureCache->getLimits(maxTextures, maxTextureBytes); 60627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 60727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 60827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::setTextureCacheLimits(int maxTextures, size_t maxTextureBytes) { 60927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fTextureCache->setLimits(maxTextures, maxTextureBytes); 61027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 61127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 612919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.comint GrContext::getMaxTextureSize() const { 61318c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com return fGpu->getCaps().fMaxTextureSize; 614919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com} 615919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com 616919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.comint GrContext::getMaxRenderTargetSize() const { 61718c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com return fGpu->getCaps().fMaxRenderTargetSize; 61827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 61927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 62027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com/////////////////////////////////////////////////////////////////////////////// 62127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 622e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.comGrTexture* GrContext::createPlatformTexture(const GrPlatformTextureDesc& desc) { 623e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com return fGpu->createPlatformTexture(desc); 624e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com} 625e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com 626e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.comGrRenderTarget* GrContext::createPlatformRenderTarget(const GrPlatformRenderTargetDesc& desc) { 627e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com return fGpu->createPlatformRenderTarget(desc); 628e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com} 629e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com 6305877ffd5ea71a3ea70096d5c11c843798defa690bsalomon@google.com/////////////////////////////////////////////////////////////////////////////// 6315877ffd5ea71a3ea70096d5c11c843798defa690bsalomon@google.com 6321fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.combool GrContext::supportsIndex8PixelConfig(const GrSamplerState* sampler, 6331f221a70214fa1ab87b8a32dd66facf485f318eebsalomon@google.com int width, int height) const { 63418c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com const GrDrawTarget::Caps& caps = fGpu->getCaps(); 63518c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com if (!caps.f8BitPaletteSupport) { 63627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return false; 63727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 63827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 63927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com bool isPow2 = GrIsPow2(width) && GrIsPow2(height); 64027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 64127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (!isPow2) { 6421fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com bool tiled = NULL != sampler && 6431fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com (sampler->getWrapX() != GrSamplerState::kClamp_WrapMode || 6441fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com sampler->getWrapY() != GrSamplerState::kClamp_WrapMode); 64518c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com if (tiled && !caps.fNPOTTextureTileSupport) { 64627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return false; 64727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 64827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 64927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return true; 65027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 65127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 65227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 65327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 65405ef510389950e1ae8dcba40e41e001db771b12dbsalomon@google.comconst GrClip& GrContext::getClip() const { return fGpu->getClip(); } 65505ef510389950e1ae8dcba40e41e001db771b12dbsalomon@google.com 65627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::setClip(const GrClip& clip) { 65727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fGpu->setClip(clip); 6588f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com fGpu->drawState()->enableState(GrDrawState::kClip_StateBit); 65927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 66027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 66127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::setClip(const GrIRect& rect) { 66227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrClip clip; 663d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com clip.setFromIRect(rect); 66427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fGpu->setClip(clip); 66527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 66627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 66727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 66827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 6696aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.comvoid GrContext::clear(const GrIRect* rect, const GrColor color) { 670398109cc3e56b8122ad21c4d43a74a83be5b42a8bsalomon@google.com this->flush(); 6716aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com fGpu->clear(rect, color); 67227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 67327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 67427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::drawPaint(const GrPaint& paint) { 67527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // set rect to be big enough to fill the space, but not super-huge, so we 67627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // don't overflow fixed-point implementations 677d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com GrRect r; 678d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com r.setLTRB(0, 0, 679d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com GrIntToScalar(getRenderTarget()->width()), 680d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com GrIntToScalar(getRenderTarget()->height())); 68127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrMatrix inverse; 6828c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com SkTLazy<GrPaint> tmpPaint; 6838c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com const GrPaint* p = &paint; 6848f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = fGpu->drawState(); 6858f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrAutoMatrix am; 6868f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 6874f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com // We attempt to map r by the inverse matrix and draw that. mapRect will 6884f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com // map the four corners and bound them with a new rect. This will not 6894f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com // produce a correct result for some perspective matrices. 6908c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com if (!this->getMatrix().hasPerspective()) { 6918f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com if (!drawState->getViewInverse(&inverse)) { 6928c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com GrPrintf("Could not invert matrix"); 6938c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com return; 6948c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com } 69527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com inverse.mapRect(&r); 69627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 6978c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com if (paint.getActiveMaskStageMask() || paint.getActiveStageMask()) { 6988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com if (!drawState->getViewInverse(&inverse)) { 6998c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com GrPrintf("Could not invert matrix"); 7008c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com return; 7018c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com } 7028c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com tmpPaint.set(paint); 7038c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com tmpPaint.get()->preConcatActiveSamplerMatrices(inverse); 7048c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com p = tmpPaint.get(); 7058c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com } 7064f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com am.set(this, GrMatrix::I()); 70727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 7084f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com // by definition this fills the entire clip, no need for AA 7094f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com if (paint.fAntiAlias) { 7108c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com if (!tmpPaint.isValid()) { 7118c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com tmpPaint.set(paint); 7128c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com p = tmpPaint.get(); 7138c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com } 7148c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com GrAssert(p == tmpPaint.get()); 7158c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com tmpPaint.get()->fAntiAlias = false; 7164f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com } 7174f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com this->drawRect(*p, r); 71827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 71927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 720205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 721205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 722d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.comnamespace { 723d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.cominline bool disable_coverage_aa_for_blend(GrDrawTarget* target) { 724d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com return DISABLE_COVERAGE_AA_FOR_BLEND && !target->canApplyCoverage(); 725d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com} 726d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com} 727d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com 72806afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 72906afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com 73027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com/* create a triangle strip that strokes the specified triangle. There are 8 73127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com unique vertices, but we repreat the last 2 to close up. Alternatively we 73227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com could use an indices array, and then only send 8 verts, but not sure that 73327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com would be faster. 73427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com */ 735205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comstatic void setStrokeRectStrip(GrPoint verts[10], GrRect rect, 73627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrScalar width) { 73727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrScalar rad = GrScalarHalf(width); 738205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com rect.sort(); 73927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 74027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[0].set(rect.fLeft + rad, rect.fTop + rad); 74127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[1].set(rect.fLeft - rad, rect.fTop - rad); 74227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[2].set(rect.fRight - rad, rect.fTop + rad); 74327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[3].set(rect.fRight + rad, rect.fTop - rad); 74427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[4].set(rect.fRight - rad, rect.fBottom - rad); 74527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[5].set(rect.fRight + rad, rect.fBottom + rad); 74627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[6].set(rect.fLeft + rad, rect.fBottom - rad); 74727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[7].set(rect.fLeft - rad, rect.fBottom + rad); 74827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[8] = verts[0]; 74927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[9] = verts[1]; 75027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 75127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 752205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comstatic void setInsetFan(GrPoint* pts, size_t stride, 753205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com const GrRect& r, GrScalar dx, GrScalar dy) { 754205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com pts->setRectFan(r.fLeft + dx, r.fTop + dy, r.fRight - dx, r.fBottom - dy, stride); 755205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com} 756205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 757205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comstatic const uint16_t gFillAARectIdx[] = { 758205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 0, 1, 5, 5, 4, 0, 759205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1, 2, 6, 6, 5, 1, 760205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 2, 3, 7, 7, 6, 2, 761205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 3, 0, 4, 4, 7, 3, 762205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 4, 5, 6, 6, 7, 4, 763205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com}; 764205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 765205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comint GrContext::aaFillRectIndexCount() const { 766205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return GR_ARRAY_COUNT(gFillAARectIdx); 767205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com} 768205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 769205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comGrIndexBuffer* GrContext::aaFillRectIndexBuffer() { 770205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (NULL == fAAFillRectIndexBuffer) { 771205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com fAAFillRectIndexBuffer = fGpu->createIndexBuffer(sizeof(gFillAARectIdx), 772205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com false); 7739b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com if (NULL != fAAFillRectIndexBuffer) { 7749b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com #if GR_DEBUG 7759b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com bool updated = 7769b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com #endif 7779b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com fAAFillRectIndexBuffer->updateData(gFillAARectIdx, 7789b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com sizeof(gFillAARectIdx)); 7799b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com GR_DEBUGASSERT(updated); 7809b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com } 781205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 782205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return fAAFillRectIndexBuffer; 783205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com} 784205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 785205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comstatic const uint16_t gStrokeAARectIdx[] = { 786205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 0 + 0, 1 + 0, 5 + 0, 5 + 0, 4 + 0, 0 + 0, 787205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1 + 0, 2 + 0, 6 + 0, 6 + 0, 5 + 0, 1 + 0, 788205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 2 + 0, 3 + 0, 7 + 0, 7 + 0, 6 + 0, 2 + 0, 789205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 3 + 0, 0 + 0, 4 + 0, 4 + 0, 7 + 0, 3 + 0, 790205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 791205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 0 + 4, 1 + 4, 5 + 4, 5 + 4, 4 + 4, 0 + 4, 792205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1 + 4, 2 + 4, 6 + 4, 6 + 4, 5 + 4, 1 + 4, 793205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 2 + 4, 3 + 4, 7 + 4, 7 + 4, 6 + 4, 2 + 4, 794205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 3 + 4, 0 + 4, 4 + 4, 4 + 4, 7 + 4, 3 + 4, 795205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 796205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 0 + 8, 1 + 8, 5 + 8, 5 + 8, 4 + 8, 0 + 8, 797205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1 + 8, 2 + 8, 6 + 8, 6 + 8, 5 + 8, 1 + 8, 798205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 2 + 8, 3 + 8, 7 + 8, 7 + 8, 6 + 8, 2 + 8, 799205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 3 + 8, 0 + 8, 4 + 8, 4 + 8, 7 + 8, 3 + 8, 800205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com}; 801205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 802205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comint GrContext::aaStrokeRectIndexCount() const { 803205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return GR_ARRAY_COUNT(gStrokeAARectIdx); 804205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com} 805205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 806205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comGrIndexBuffer* GrContext::aaStrokeRectIndexBuffer() { 807205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (NULL == fAAStrokeRectIndexBuffer) { 808205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com fAAStrokeRectIndexBuffer = fGpu->createIndexBuffer(sizeof(gStrokeAARectIdx), 809205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com false); 8109b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com if (NULL != fAAStrokeRectIndexBuffer) { 8119b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com #if GR_DEBUG 8129b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com bool updated = 8139b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com #endif 8149b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com fAAStrokeRectIndexBuffer->updateData(gStrokeAARectIdx, 8159b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com sizeof(gStrokeAARectIdx)); 8169b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com GR_DEBUGASSERT(updated); 8179b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com } 818205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 819205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return fAAStrokeRectIndexBuffer; 820205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com} 821205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 822a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.comstatic GrVertexLayout aa_rect_layout(const GrDrawTarget* target, 823a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com bool useCoverage) { 824a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com GrVertexLayout layout = 0; 8259381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com for (int s = 0; s < GrDrawState::kNumStages; ++s) { 8268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com if (NULL != target->getDrawState().getTexture(s)) { 827a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com layout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(s); 828a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com } 829a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com } 830a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com if (useCoverage) { 831a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com layout |= GrDrawTarget::kCoverage_VertexLayoutBit; 832a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com } else { 833a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com layout |= GrDrawTarget::kColor_VertexLayoutBit; 834a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com } 835a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com return layout; 836a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com} 837a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com 838205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comvoid GrContext::fillAARect(GrDrawTarget* target, 839a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com const GrRect& devRect, 840a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com bool useVertexCoverage) { 841a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com GrVertexLayout layout = aa_rect_layout(target, useVertexCoverage); 842205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 843205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com size_t vsize = GrDrawTarget::VertexSize(layout); 844205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 845205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrDrawTarget::AutoReleaseGeometry geo(target, layout, 8, 0); 8466513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com if (!geo.succeeded()) { 8476513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com GrPrintf("Failed to get space for vertices!\n"); 8486513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com return; 8496513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com } 8509b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com GrIndexBuffer* indexBuffer = this->aaFillRectIndexBuffer(); 8519b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com if (NULL == indexBuffer) { 8529b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com GrPrintf("Failed to create index buffer!\n"); 8539b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com return; 8549b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com } 855205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 856205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com intptr_t verts = reinterpret_cast<intptr_t>(geo.vertices()); 857205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 858205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrPoint* fan0Pos = reinterpret_cast<GrPoint*>(verts); 859205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrPoint* fan1Pos = reinterpret_cast<GrPoint*>(verts + 4 * vsize); 860205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 861205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com setInsetFan(fan0Pos, vsize, devRect, -GR_ScalarHalf, -GR_ScalarHalf); 862205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com setInsetFan(fan1Pos, vsize, devRect, GR_ScalarHalf, GR_ScalarHalf); 863205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 864205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com verts += sizeof(GrPoint); 865205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com for (int i = 0; i < 4; ++i) { 866205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com *reinterpret_cast<GrColor*>(verts + i * vsize) = 0; 867205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 868205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 869a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com GrColor innerColor; 870a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com if (useVertexCoverage) { 871e10f6fdf76fa9b627cbb8471b58b13c457af83e8bsalomon@google.com innerColor = 0xffffffff; 872a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com } else { 8738f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com innerColor = target->getDrawState().getColor(); 874a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com } 875a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com 876205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com verts += 4 * vsize; 877205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com for (int i = 0; i < 4; ++i) { 878205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com *reinterpret_cast<GrColor*>(verts + i * vsize) = innerColor; 879205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 880205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 8819b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com target->setIndexSourceToBuffer(indexBuffer); 882205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 883205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com target->drawIndexed(kTriangles_PrimitiveType, 0, 884205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 0, 8, this->aaFillRectIndexCount()); 885205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com} 886205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 887a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.comvoid GrContext::strokeAARect(GrDrawTarget* target, 888a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com const GrRect& devRect, 889a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com const GrVec& devStrokeSize, 890a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com bool useVertexCoverage) { 891205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com const GrScalar& dx = devStrokeSize.fX; 892205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com const GrScalar& dy = devStrokeSize.fY; 893205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com const GrScalar rx = GrMul(dx, GR_ScalarHalf); 894205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com const GrScalar ry = GrMul(dy, GR_ScalarHalf); 895205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 896205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrScalar spare; 897205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com { 898205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrScalar w = devRect.width() - dx; 899205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrScalar h = devRect.height() - dy; 900205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com spare = GrMin(w, h); 901205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 902205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 903205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (spare <= 0) { 904205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrRect r(devRect); 905205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com r.inset(-rx, -ry); 906a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com fillAARect(target, r, useVertexCoverage); 907205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return; 908205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 909a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com GrVertexLayout layout = aa_rect_layout(target, useVertexCoverage); 910205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com size_t vsize = GrDrawTarget::VertexSize(layout); 911205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 912205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrDrawTarget::AutoReleaseGeometry geo(target, layout, 16, 0); 9136513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com if (!geo.succeeded()) { 9146513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com GrPrintf("Failed to get space for vertices!\n"); 9156513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com return; 9166513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com } 9179b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com GrIndexBuffer* indexBuffer = this->aaStrokeRectIndexBuffer(); 9189b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com if (NULL == indexBuffer) { 9199b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com GrPrintf("Failed to create index buffer!\n"); 9209b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com return; 9219b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com } 922205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 923205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com intptr_t verts = reinterpret_cast<intptr_t>(geo.vertices()); 924205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 925205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrPoint* fan0Pos = reinterpret_cast<GrPoint*>(verts); 926205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrPoint* fan1Pos = reinterpret_cast<GrPoint*>(verts + 4 * vsize); 927205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrPoint* fan2Pos = reinterpret_cast<GrPoint*>(verts + 8 * vsize); 928205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrPoint* fan3Pos = reinterpret_cast<GrPoint*>(verts + 12 * vsize); 929205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 930205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com setInsetFan(fan0Pos, vsize, devRect, -rx - GR_ScalarHalf, -ry - GR_ScalarHalf); 931205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com setInsetFan(fan1Pos, vsize, devRect, -rx + GR_ScalarHalf, -ry + GR_ScalarHalf); 932205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com setInsetFan(fan2Pos, vsize, devRect, rx - GR_ScalarHalf, ry - GR_ScalarHalf); 933205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com setInsetFan(fan3Pos, vsize, devRect, rx + GR_ScalarHalf, ry + GR_ScalarHalf); 934205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 935205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com verts += sizeof(GrPoint); 936205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com for (int i = 0; i < 4; ++i) { 937205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com *reinterpret_cast<GrColor*>(verts + i * vsize) = 0; 938205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 939205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 940a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com GrColor innerColor; 941a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com if (useVertexCoverage) { 942e10f6fdf76fa9b627cbb8471b58b13c457af83e8bsalomon@google.com innerColor = 0xffffffff; 943a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com } else { 9448f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com innerColor = target->getDrawState().getColor(); 945a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com } 946205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com verts += 4 * vsize; 947205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com for (int i = 0; i < 8; ++i) { 948205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com *reinterpret_cast<GrColor*>(verts + i * vsize) = innerColor; 949205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 950205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 951205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com verts += 8 * vsize; 952205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com for (int i = 0; i < 8; ++i) { 953205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com *reinterpret_cast<GrColor*>(verts + i * vsize) = 0; 954205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 955205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 9569b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com target->setIndexSourceToBuffer(indexBuffer); 957205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com target->drawIndexed(kTriangles_PrimitiveType, 958205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 0, 0, 16, aaStrokeRectIndexCount()); 959205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com} 960205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 96120efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com/** 96220efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com * Returns true if the rects edges are integer-aligned. 96320efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com */ 96420efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.comstatic bool isIRect(const GrRect& r) { 96520efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com return GrScalarIsInt(r.fLeft) && GrScalarIsInt(r.fTop) && 96620efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com GrScalarIsInt(r.fRight) && GrScalarIsInt(r.fBottom); 96720efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com} 96820efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com 969205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comstatic bool apply_aa_to_rect(GrDrawTarget* target, 970205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com const GrRect& rect, 971205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrScalar width, 972205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com const GrMatrix* matrix, 973205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrMatrix* combinedMatrix, 974a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com GrRect* devRect, 975a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com bool* useVertexCoverage) { 9762eba795bcda66813fdc7a7c4388a99ae9cb2c864bsalomon@google.com // we use a simple coverage ramp to do aa on axis-aligned rects 9772eba795bcda66813fdc7a7c4388a99ae9cb2c864bsalomon@google.com // we check if the rect will be axis-aligned, and the rect won't land on 9782eba795bcda66813fdc7a7c4388a99ae9cb2c864bsalomon@google.com // integer coords. 979d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com 980a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com // we are keeping around the "tweak the alpha" trick because 981a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com // it is our only hope for the fixed-pipe implementation. 982a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com // In a shader implementation we can give a separate coverage input 983289533ada623f2238a83771eec977f204f75994fbsalomon@google.com // TODO: remove this ugliness when we drop the fixed-pipe impl 984a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com *useVertexCoverage = false; 985d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com if (!target->canTweakAlphaForCoverage()) { 9862eba795bcda66813fdc7a7c4388a99ae9cb2c864bsalomon@google.com if (disable_coverage_aa_for_blend(target)) { 9871983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#if GR_DEBUG 9882eba795bcda66813fdc7a7c4388a99ae9cb2c864bsalomon@google.com //GrPrintf("Turning off AA to correctly apply blend.\n"); 9891983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#endif 990a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com return false; 9912eba795bcda66813fdc7a7c4388a99ae9cb2c864bsalomon@google.com } else { 9922eba795bcda66813fdc7a7c4388a99ae9cb2c864bsalomon@google.com *useVertexCoverage = true; 993a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com } 994205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 9958f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com const GrDrawState& drawState = target->getDrawState(); 9968f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com if (drawState.getRenderTarget()->isMultisampled()) { 997205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return false; 998205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 999205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1000471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com if (0 == width && target->willUseHWAALines()) { 1001205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return false; 1002205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 1003205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 10048f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com if (!drawState.getViewMatrix().preservesAxisAlignment()) { 1005205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return false; 1006205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 1007205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1008205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (NULL != matrix && 1009205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com !matrix->preservesAxisAlignment()) { 1010205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return false; 1011205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 1012205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 10138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com *combinedMatrix = drawState.getViewMatrix(); 1014205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (NULL != matrix) { 1015205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com combinedMatrix->preConcat(*matrix); 1016205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrAssert(combinedMatrix->preservesAxisAlignment()); 1017205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 1018205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1019205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com combinedMatrix->mapRect(devRect, rect); 1020205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com devRect->sort(); 1021205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1022205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (width < 0) { 102320efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com return !isIRect(*devRect); 1024205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } else { 1025205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return true; 1026205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 1027205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com} 1028205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 102927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::drawRect(const GrPaint& paint, 103027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrRect& rect, 103127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrScalar width, 103227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrMatrix* matrix) { 1033278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com SK_TRACE_EVENT0("GrContext::drawRect"); 103427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 103527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory); 103626c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com int stageMask = paint.getActiveStageMask(); 103727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1038205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrRect devRect = rect; 1039205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrMatrix combinedMatrix; 1040a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com bool useVertexCoverage; 1041289533ada623f2238a83771eec977f204f75994fbsalomon@google.com bool needAA = paint.fAntiAlias && 1042289533ada623f2238a83771eec977f204f75994fbsalomon@google.com !this->getRenderTarget()->isMultisampled(); 1043289533ada623f2238a83771eec977f204f75994fbsalomon@google.com bool doAA = needAA && apply_aa_to_rect(target, rect, width, matrix, 1044289533ada623f2238a83771eec977f204f75994fbsalomon@google.com &combinedMatrix, &devRect, 1045289533ada623f2238a83771eec977f204f75994fbsalomon@google.com &useVertexCoverage); 1046205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1047205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (doAA) { 10488f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawTarget::AutoDeviceCoordDraw adcd(target, stageMask); 1049205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (width >= 0) { 1050205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrVec strokeSize;; 1051205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (width > 0) { 1052205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com strokeSize.set(width, width); 1053cc4dac3dac215dc0dd56f7b30d07cc304671b033bsalomon@google.com combinedMatrix.mapVectors(&strokeSize, 1); 1054205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com strokeSize.setAbs(strokeSize); 1055205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } else { 1056205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com strokeSize.set(GR_Scalar1, GR_Scalar1); 1057205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 1058a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com strokeAARect(target, devRect, strokeSize, useVertexCoverage); 1059205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } else { 1060a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com fillAARect(target, devRect, useVertexCoverage); 1061205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 1062205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return; 1063205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 1064205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 106527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (width >= 0) { 106627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // TODO: consider making static vertex buffers for these cases. 106727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // Hairline could be done by just adding closing vertex to 106827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // unitSquareVertexBuffer() 106926c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com GrVertexLayout layout = PaintStageVertexLayoutBits(paint, NULL); 107026c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 107127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com static const int worstCaseVertCount = 10; 107227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget::AutoReleaseGeometry geo(target, layout, worstCaseVertCount, 0); 107327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 107427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (!geo.succeeded()) { 10756513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com GrPrintf("Failed to get space for vertices!\n"); 107627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return; 107727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 107827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 107927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrPrimitiveType primType; 108027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int vertCount; 108127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrPoint* vertex = geo.positions(); 108227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 108327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (width > 0) { 108427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertCount = 10; 108527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com primType = kTriangleStrip_PrimitiveType; 108627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com setStrokeRectStrip(vertex, rect, width); 108727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 108827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // hairline 108927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertCount = 5; 109027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com primType = kLineStrip_PrimitiveType; 109127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertex[0].set(rect.fLeft, rect.fTop); 109227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertex[1].set(rect.fRight, rect.fTop); 109327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertex[2].set(rect.fRight, rect.fBottom); 109427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertex[3].set(rect.fLeft, rect.fBottom); 109527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertex[4].set(rect.fLeft, rect.fTop); 109627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 109727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 10988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState::AutoViewMatrixRestore avmr; 109927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL != matrix) { 11008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = target->drawState(); 11018f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com avmr.set(drawState); 11028f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->preConcatViewMatrix(*matrix); 11038f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->preConcatSamplerMatrices(stageMask, *matrix); 110427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 110527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 110627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target->drawNonIndexed(primType, 0, vertCount); 110727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 11088f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com#if GR_STATIC_RECT_VB 110926c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com GrVertexLayout layout = PaintStageVertexLayoutBits(paint, NULL); 11106513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com const GrVertexBuffer* sqVB = fGpu->getUnitSquareVertexBuffer(); 11116513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com if (NULL == sqVB) { 11126513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com GrPrintf("Failed to create static rect vb.\n"); 11136513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com return; 11146513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com } 11156513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com target->setVertexSourceToBuffer(layout, sqVB); 11168f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = target->drawState(); 11178f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState::AutoViewMatrixRestore avmr(drawState); 111827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrMatrix m; 11198295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com m.setAll(rect.width(), 0, rect.fLeft, 1120205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 0, rect.height(), rect.fTop, 1121205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 0, 0, GrMatrix::I()[8]); 112227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 112327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL != matrix) { 112427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com m.postConcat(*matrix); 112527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 11268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->preConcatViewMatrix(m); 11278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->preConcatSamplerMatrices(stageMask, m); 112826c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 112927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target->drawNonIndexed(kTriangleFan_PrimitiveType, 0, 4); 11308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com#else 113126c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com target->drawSimpleRect(rect, matrix, stageMask); 11328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com#endif 113327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 113427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 113527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 113627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::drawRectToRect(const GrPaint& paint, 113727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrRect& dstRect, 113827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrRect& srcRect, 113927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrMatrix* dstMatrix, 114027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrMatrix* srcMatrix) { 1141278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com SK_TRACE_EVENT0("GrContext::drawRectToRect"); 114227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 114326c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com // srcRect refers to paint's first texture 114426c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com if (NULL == paint.getTexture(0)) { 114527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com drawRect(paint, dstRect, -1, dstMatrix); 114627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return; 114727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 1148de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com 114927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GR_STATIC_ASSERT(!BATCH_RECT_TO_RECT || !GR_STATIC_RECT_VB); 115027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 115127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#if GR_STATIC_RECT_VB 115227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory); 11538f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = target->drawState(); 115426c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com GrVertexLayout layout = PaintStageVertexLayoutBits(paint, NULL); 11558f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState::AutoViewMatrixRestore avmr(drawState); 115627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 115727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrMatrix m; 115827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 115927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com m.setAll(dstRect.width(), 0, dstRect.fLeft, 116027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 0, dstRect.height(), dstRect.fTop, 116127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 0, 0, GrMatrix::I()[8]); 116227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL != dstMatrix) { 116327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com m.postConcat(*dstMatrix); 116427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 11658f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->preConcatViewMatrix(m); 116627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 116726c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com // srcRect refers to first stage 116826c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com int otherStageMask = paint.getActiveStageMask() & 116926c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com (~(1 << GrPaint::kFirstTextureStage)); 117026c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com if (otherStageMask) { 11718f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->preConcatSamplerMatrices(otherStageMask, m); 117226c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com } 117326c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 117427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com m.setAll(srcRect.width(), 0, srcRect.fLeft, 117527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 0, srcRect.height(), srcRect.fTop, 117627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 0, 0, GrMatrix::I()[8]); 117727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL != srcMatrix) { 117827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com m.postConcat(*srcMatrix); 117927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 11808f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->sampler(GrPaint::kFirstTextureStage)->preConcatMatrix(m); 118127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 11826513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com const GrVertexBuffer* sqVB = fGpu->getUnitSquareVertexBuffer(); 11836513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com if (NULL == sqVB) { 11846513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com GrPrintf("Failed to create static rect vb.\n"); 11856513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com return; 11866513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com } 11876513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com target->setVertexSourceToBuffer(layout, sqVB); 118827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target->drawNonIndexed(kTriangleFan_PrimitiveType, 0, 4); 118927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#else 119027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 119127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget* target; 1192de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com#if BATCH_RECT_TO_RECT 119327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target = this->prepareToDraw(paint, kBuffered_DrawCategory); 1194de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com#else 119527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target = this->prepareToDraw(paint, kUnbuffered_DrawCategory); 119627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#endif 119727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 11989381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com const GrRect* srcRects[GrDrawState::kNumStages] = {NULL}; 11999381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com const GrMatrix* srcMatrices[GrDrawState::kNumStages] = {NULL}; 120027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com srcRects[0] = &srcRect; 120127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com srcMatrices[0] = srcMatrix; 120227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 120327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target->drawRect(dstRect, dstMatrix, 1, srcRects, srcMatrices); 120427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#endif 120527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 120627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 120727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::drawVertices(const GrPaint& paint, 120827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrPrimitiveType primitiveType, 120927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int vertexCount, 121027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrPoint positions[], 121127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrPoint texCoords[], 121227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrColor colors[], 121327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const uint16_t indices[], 121427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int indexCount) { 1215278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com SK_TRACE_EVENT0("GrContext::drawVertices"); 121627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 121727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget::AutoReleaseGeometry geo; 121827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 121927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory); 122027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 122126c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com bool hasTexCoords[GrPaint::kTotalStages] = { 122226c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com NULL != texCoords, // texCoordSrc provides explicit stage 0 coords 122326c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 0 // remaining stages use positions 122426c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com }; 122526c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 122626c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com GrVertexLayout layout = PaintStageVertexLayoutBits(paint, hasTexCoords); 122727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 122827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL != colors) { 122927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com layout |= GrDrawTarget::kColor_VertexLayoutBit; 123027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 123126c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com int vertexSize = GrDrawTarget::VertexSize(layout); 123227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 123327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (sizeof(GrPoint) != vertexSize) { 123427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (!geo.set(target, layout, vertexCount, 0)) { 12356513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com GrPrintf("Failed to get space for vertices!\n"); 123627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return; 123727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 12389381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com int texOffsets[GrDrawState::kMaxTexCoords]; 123927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int colorOffset; 124026c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com GrDrawTarget::VertexSizeAndOffsetsByIdx(layout, 124126c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com texOffsets, 1242aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com &colorOffset, 1243a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com NULL, 1244a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com NULL); 124527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com void* curVertex = geo.vertices(); 124627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 124727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com for (int i = 0; i < vertexCount; ++i) { 124827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com *((GrPoint*)curVertex) = positions[i]; 124927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 125027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (texOffsets[0] > 0) { 125127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com *(GrPoint*)((intptr_t)curVertex + texOffsets[0]) = texCoords[i]; 125227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 125327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (colorOffset > 0) { 125427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com *(GrColor*)((intptr_t)curVertex + colorOffset) = colors[i]; 125527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 125626c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com curVertex = (void*)((intptr_t)curVertex + vertexSize); 125727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 125827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 125927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target->setVertexSourceToArray(layout, positions, vertexCount); 126027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 126127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1262919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com // we don't currently apply offscreen AA to this path. Need improved 1263919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com // management of GrDrawTarget's geometry to avoid copying points per-tile. 1264a47a48dca5045d71cbc5de343404045209a13e15bsalomon@google.com 12658295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com if (NULL != indices) { 1266919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com target->setIndexSourceToArray(indices, indexCount); 12678295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com target->drawIndexed(primitiveType, 0, 0, vertexCount, indexCount); 126827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 12698295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com target->drawNonIndexed(primitiveType, 0, vertexCount); 12708295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com } 127127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 127227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 127306afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com/////////////////////////////////////////////////////////////////////////////// 1274150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com#include "SkDraw.h" 1275150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com#include "SkRasterClip.h" 1276150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com 1277150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.comnamespace { 1278150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com 1279150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.comSkPath::FillType gr_fill_to_sk_fill(GrPathFill fill) { 1280150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com switch (fill) { 1281150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com case kWinding_PathFill: 1282150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com return SkPath::kWinding_FillType; 1283150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com case kEvenOdd_PathFill: 1284150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com return SkPath::kEvenOdd_FillType; 1285150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com case kInverseWinding_PathFill: 1286150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com return SkPath::kInverseWinding_FillType; 1287150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com case kInverseEvenOdd_PathFill: 1288150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com return SkPath::kInverseEvenOdd_FillType; 1289150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com default: 1290150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com GrCrash("Unexpected fill."); 1291150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com return SkPath::kWinding_FillType; 1292150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com } 1293150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com} 1294150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com 1295150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com// gets device coord bounds of path (not considering the fill) and clip. The 1296150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com// path bounds will be a subset of the clip bounds. returns false if path bounds 1297150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com// would be empty. 1298150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.combool get_path_and_clip_bounds(const GrDrawTarget* target, 1299150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com const GrPath& path, 1300150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com const GrVec* translate, 1301150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com GrIRect* pathBounds, 1302150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com GrIRect* clipBounds) { 1303150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com // compute bounds as intersection of rt size, clip, and path 1304150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com const GrRenderTarget* rt = target->getDrawState().getRenderTarget(); 1305150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com if (NULL == rt) { 1306150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com return false; 1307150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com } 1308150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com *pathBounds = GrIRect::MakeWH(rt->width(), rt->height()); 1309150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com const GrClip& clip = target->getClip(); 1310150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com if (clip.hasConservativeBounds()) { 1311150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com clip.getConservativeBounds().roundOut(clipBounds); 1312150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com if (!pathBounds->intersect(*clipBounds)) { 1313150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com return false; 1314150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com } 1315150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com } else { 1316150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com // pathBounds is currently the rt extent, set clip bounds to that rect. 1317150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com *clipBounds = *pathBounds; 1318150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com } 1319150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com GrRect pathSBounds = path.getBounds(); 1320150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com if (!pathSBounds.isEmpty()) { 1321150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com if (NULL != translate) { 1322150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com pathSBounds.offset(*translate); 1323150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com } 1324150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com target->getDrawState().getViewMatrix().mapRect(&pathSBounds, 1325150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com pathSBounds); 1326150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com GrIRect pathIBounds; 1327150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com pathSBounds.roundOut(&pathIBounds); 1328150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com if (!pathBounds->intersect(pathIBounds)) { 1329150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com return false; 1330150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com } 1331150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com } else { 1332150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com return false; 1333150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com } 1334150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com return true; 1335150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com} 1336150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com 1337150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com/** 1338150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com * sw rasterizes path to A8 mask using the context's matrix and uploads to a 1339150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com * scratch texture. 1340150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com */ 1341150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com 1342150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.combool sw_draw_path_to_mask_texture(const GrPath& clientPath, 1343150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com const GrIRect& pathDevBounds, 1344150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com GrPathFill fill, 1345150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com GrContext* context, 1346150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com const GrPoint* translate, 1347150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com GrAutoScratchTexture* tex) { 1348150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com SkPaint paint; 1349150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com SkPath tmpPath; 1350150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com const SkPath* pathToDraw = &clientPath; 1351150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com if (kHairLine_PathFill == fill) { 1352150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com paint.setStyle(SkPaint::kStroke_Style); 1353150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com paint.setStrokeWidth(SK_Scalar1); 1354150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com } else { 1355150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com paint.setStyle(SkPaint::kFill_Style); 1356150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com SkPath::FillType skfill = gr_fill_to_sk_fill(fill); 1357150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com if (skfill != pathToDraw->getFillType()) { 1358150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com tmpPath = *pathToDraw; 1359150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com tmpPath.setFillType(skfill); 1360150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com pathToDraw = &tmpPath; 1361150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com } 1362150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com } 1363150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com paint.setAntiAlias(true); 1364150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com paint.setColor(SK_ColorWHITE); 1365150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com 1366150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com GrMatrix matrix = context->getMatrix(); 1367150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com if (NULL != translate) { 1368150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com matrix.postTranslate(translate->fX, translate->fY); 1369150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com } 1370150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com 1371150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com matrix.postTranslate(-pathDevBounds.fLeft * SK_Scalar1, 1372150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com -pathDevBounds.fTop * SK_Scalar1); 1373150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com GrIRect bounds = GrIRect::MakeWH(pathDevBounds.width(), 1374150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com pathDevBounds.height()); 1375150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com 1376150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com SkBitmap bm; 1377150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com bm.setConfig(SkBitmap::kA8_Config, bounds.fRight, bounds.fBottom); 1378150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com if (!bm.allocPixels()) { 1379150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com return false; 1380150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com } 1381150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com sk_bzero(bm.getPixels(), bm.getSafeSize()); 1382150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com 1383150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com SkDraw draw; 1384150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com sk_bzero(&draw, sizeof(draw)); 1385150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com SkRasterClip rc(bounds); 1386150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com draw.fRC = &rc; 1387150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com draw.fClip = &rc.bwRgn(); 1388150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com draw.fMatrix = &matrix; 1389150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com draw.fBitmap = &bm; 1390150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com draw.drawPath(*pathToDraw, paint); 1391150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com 1392150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com const GrTextureDesc desc = { 1393150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com kNone_GrTextureFlags, 1394150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com bounds.fRight, 1395150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com bounds.fBottom, 139678d6cf9f434d3351b19de14f1eab424c23f0ab6dbsalomon@google.com kAlpha_8_GrPixelConfig, 139778d6cf9f434d3351b19de14f1eab424c23f0ab6dbsalomon@google.com {0} // samples 1398150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com }; 1399150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com 1400150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com tex->set(context, desc); 1401150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com GrTexture* texture = tex->texture(); 1402150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com 1403150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com if (NULL == texture) { 1404150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com return false; 1405150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com } 1406150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com SkAutoLockPixels alp(bm); 1407150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com texture->writePixels(0, 0, desc.fWidth, desc.fHeight, desc.fConfig, 1408150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com bm.getPixels(), bm.rowBytes()); 1409150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com return true; 1410150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com} 1411150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com 1412150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.comvoid draw_around_inv_path(GrDrawTarget* target, 1413150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com GrDrawState::StageMask stageMask, 1414150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com const GrIRect& clipBounds, 1415150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com const GrIRect& pathBounds) { 1416150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com GrDrawTarget::AutoDeviceCoordDraw adcd(target, stageMask); 1417150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com GrRect rect; 1418150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com if (clipBounds.fTop < pathBounds.fTop) { 1419150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com rect.iset(clipBounds.fLeft, clipBounds.fTop, 1420150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com clipBounds.fRight, pathBounds.fTop); 1421150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com target->drawSimpleRect(rect, NULL, stageMask); 1422150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com } 1423150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com if (clipBounds.fLeft < pathBounds.fLeft) { 1424150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com rect.iset(clipBounds.fLeft, pathBounds.fTop, 1425150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com pathBounds.fLeft, pathBounds.fBottom); 1426150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com target->drawSimpleRect(rect, NULL, stageMask); 1427150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com } 1428150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com if (clipBounds.fRight > pathBounds.fRight) { 1429150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com rect.iset(pathBounds.fRight, pathBounds.fTop, 1430150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com clipBounds.fRight, pathBounds.fBottom); 1431150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com target->drawSimpleRect(rect, NULL, stageMask); 1432150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com } 1433150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com if (clipBounds.fBottom > pathBounds.fBottom) { 1434150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com rect.iset(clipBounds.fLeft, pathBounds.fBottom, 1435150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com clipBounds.fRight, clipBounds.fBottom); 1436150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com target->drawSimpleRect(rect, NULL, stageMask); 1437150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com } 1438150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com} 1439150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com 1440150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com} 144127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 144207f3ee10d34f09342abb93d758b5e151ff78f7a5reed@google.comvoid GrContext::drawPath(const GrPaint& paint, const GrPath& path, 144307f3ee10d34f09342abb93d758b5e151ff78f7a5reed@google.com GrPathFill fill, const GrPoint* translate) { 144427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1445fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com if (path.isEmpty()) { 1446fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com if (GrIsFillInverted(fill)) { 1447fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com this->drawPaint(paint); 1448fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 1449fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com return; 1450fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 1451fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com 1452fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.com // Note that below we may sw-rasterize the path into a scratch texture. 1453fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.com // Scratch textures can be recycled after they are returned to the texture 1454fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.com // cache. This presents a potential hazard for buffered drawing. However, 1455fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.com // the writePixels that uploads to the scratch will perform a flush so we're 1456fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.com // OK. 1457fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.com DrawCategory category = (DEFER_PATHS) ? kBuffered_DrawCategory : 1458fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.com kUnbuffered_DrawCategory; 1459fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.com GrDrawTarget* target = this->prepareToDraw(paint, category); 1460150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com GrDrawState::StageMask stageMask = paint.getActiveStageMask(); 1461d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com 1462289533ada623f2238a83771eec977f204f75994fbsalomon@google.com bool prAA = paint.fAntiAlias && !this->getRenderTarget()->isMultisampled(); 1463289533ada623f2238a83771eec977f204f75994fbsalomon@google.com 1464d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com // An Assumption here is that path renderer would use some form of tweaking 1465d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com // the src color (either the input alpha or in the frag shader) to implement 1466d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com // aa. If we have some future driver-mojo path AA that can do the right 1467d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com // thing WRT to the blend then we'll need some query on the PR. 1468d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com if (disable_coverage_aa_for_blend(target)) { 14691983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#if GR_DEBUG 1470979432ba2621b617f5e85a9ff48c6b6cd1504a0dbsalomon@google.com //GrPrintf("Turning off AA to correctly apply blend.\n"); 14711983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#endif 1472289533ada623f2238a83771eec977f204f75994fbsalomon@google.com prAA = false; 1473d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com } 1474289533ada623f2238a83771eec977f204f75994fbsalomon@google.com 1475289533ada623f2238a83771eec977f204f75994fbsalomon@google.com GrPathRenderer* pr = NULL; 1476289533ada623f2238a83771eec977f204f75994fbsalomon@google.com if (prAA) { 1477c2099d2707abcc94e139627399aed4b8894b69bbbsalomon@google.com pr = this->getPathRenderer(path, fill, target, true); 1478289533ada623f2238a83771eec977f204f75994fbsalomon@google.com if (NULL == pr) { 1479150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com GrAutoScratchTexture ast; 1480150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com GrIRect pathBounds, clipBounds; 1481150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com if (!get_path_and_clip_bounds(target, path, translate, 1482150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com &pathBounds, &clipBounds)) { 1483150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com return; 1484150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com } 1485150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com if (NULL == pr && sw_draw_path_to_mask_texture(path, pathBounds, 1486150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com fill, this, 1487150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com translate, &ast)) { 1488150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com GrTexture* texture = ast.texture(); 1489150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com GrAssert(NULL != texture); 1490150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com GrDrawTarget::AutoDeviceCoordDraw adcd(target, stageMask); 1491150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com enum { 1492150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com kPathMaskStage = GrPaint::kTotalStages, 1493150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com }; 1494150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com target->drawState()->setTexture(kPathMaskStage, texture); 1495150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com target->drawState()->sampler(kPathMaskStage)->reset(); 1496150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com GrScalar w = GrIntToScalar(pathBounds.width()); 1497150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com GrScalar h = GrIntToScalar(pathBounds.height()); 1498150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com GrRect maskRect = GrRect::MakeWH(w / texture->width(), 1499150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com h / texture->height()); 1500150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com const GrRect* srcRects[GrDrawState::kNumStages] = {NULL}; 1501150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com srcRects[kPathMaskStage] = &maskRect; 1502150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com stageMask |= 1 << kPathMaskStage; 15035db3b6cce4e9e02415a0a31d95666c044c953ac2bsalomon@google.com GrRect dstRect = GrRect::MakeLTRB( 15045db3b6cce4e9e02415a0a31d95666c044c953ac2bsalomon@google.com SK_Scalar1* pathBounds.fLeft, 15055db3b6cce4e9e02415a0a31d95666c044c953ac2bsalomon@google.com SK_Scalar1* pathBounds.fTop, 15065db3b6cce4e9e02415a0a31d95666c044c953ac2bsalomon@google.com SK_Scalar1* pathBounds.fRight, 15075db3b6cce4e9e02415a0a31d95666c044c953ac2bsalomon@google.com SK_Scalar1* pathBounds.fBottom); 1508150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com target->drawRect(dstRect, NULL, stageMask, srcRects, NULL); 1509150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com target->drawState()->setTexture(kPathMaskStage, NULL); 1510150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com if (GrIsFillInverted(fill)) { 1511150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com draw_around_inv_path(target, stageMask, 1512150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com clipBounds, pathBounds); 1513150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com } 1514150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com return; 1515150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com } 1516289533ada623f2238a83771eec977f204f75994fbsalomon@google.com } 1517289533ada623f2238a83771eec977f204f75994fbsalomon@google.com } else { 1518c2099d2707abcc94e139627399aed4b8894b69bbbsalomon@google.com pr = this->getPathRenderer(path, fill, target, false); 1519289533ada623f2238a83771eec977f204f75994fbsalomon@google.com } 1520289533ada623f2238a83771eec977f204f75994fbsalomon@google.com 15213008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com if (NULL == pr) { 15221983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#if GR_DEBUG 15233008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com GrPrintf("Unable to find path renderer compatible with path.\n"); 15241983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#endif 15253008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com return; 15263008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com } 15273008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com 1528c2099d2707abcc94e139627399aed4b8894b69bbbsalomon@google.com pr->drawPath(path, fill, translate, target, stageMask, prAA); 152927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 15308295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com 153127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 153227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1533a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.comvoid GrContext::flush(int flagsBitfield) { 1534a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com if (kDiscard_FlushBit & flagsBitfield) { 1535a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com fDrawBuffer->reset(); 1536a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com } else { 1537c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com this->flushDrawBuffer(); 1538a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com } 1539a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com if (kForceCurrentRenderTarget_FlushBit & flagsBitfield) { 154027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fGpu->forceRenderTargetFlush(); 154127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 154227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 154327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 154427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::flushText() { 154527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (kText_DrawCategory == fLastDrawCategory) { 154627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com flushDrawBuffer(); 154727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 154827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 154927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 155027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::flushDrawBuffer() { 155127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#if BATCH_RECT_TO_RECT || DEFER_TEXT_RENDERING 155253a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com if (fDrawBuffer) { 155397805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com fDrawBuffer->flushTo(fGpu); 155453a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com } 155527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#endif 155627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 155727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 15586f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.comvoid GrContext::internalWriteTexturePixels(GrTexture* texture, 15596f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com int left, int top, 15606f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com int width, int height, 15616f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com GrPixelConfig config, 15626f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com const void* buffer, 15636f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com size_t rowBytes, 15646f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com uint32_t flags) { 15656f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com SK_TRACE_EVENT0("GrContext::writeTexturePixels"); 1566bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(texture); 1567bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com 15686f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com if (!(kDontFlush_PixelOpsFlag & flags)) { 15696f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com this->flush(); 15706f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com } 15716f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com // TODO: use scratch texture to perform conversion 15726f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com if (GrPixelConfigIsUnpremultiplied(texture->config()) != 15736f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com GrPixelConfigIsUnpremultiplied(config)) { 15746f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com return; 15756f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com } 15766f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com 15776f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com fGpu->writeTexturePixels(texture, left, top, width, height, 15786f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com config, buffer, rowBytes); 15796f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com} 15806f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com 15816f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.combool GrContext::internalReadTexturePixels(GrTexture* texture, 15826f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com int left, int top, 15836f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com int width, int height, 15846f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com GrPixelConfig config, 15856f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com void* buffer, 15866f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com size_t rowBytes, 15876f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com uint32_t flags) { 1588278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com SK_TRACE_EVENT0("GrContext::readTexturePixels"); 1589bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(texture); 1590669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com 1591a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com // TODO: code read pixels for textures that aren't also rendertargets 1592669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com GrRenderTarget* target = texture->asRenderTarget(); 1593669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com if (NULL != target) { 15946f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com return this->internalReadRenderTargetPixels(target, 15956f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com left, top, width, height, 15966f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com config, buffer, rowBytes, 15976f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com flags); 1598669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com } else { 1599669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com return false; 1600669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com } 1601669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com} 1602669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com 1603a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com#include "SkConfig8888.h" 1604a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com 1605a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.comnamespace { 1606a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com/** 1607a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com * Converts a GrPixelConfig to a SkCanvas::Config8888. Only byte-per-channel 1608a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com * formats are representable as Config8888 and so the function returns false 1609a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com * if the GrPixelConfig has no equivalent Config8888. 1610a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com */ 1611a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.combool grconfig_to_config8888(GrPixelConfig config, 1612a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com SkCanvas::Config8888* config8888) { 1613a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com switch (config) { 1614a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com case kRGBA_8888_PM_GrPixelConfig: 1615a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com *config8888 = SkCanvas::kRGBA_Premul_Config8888; 1616a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com return true; 1617a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com case kRGBA_8888_UPM_GrPixelConfig: 1618a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com *config8888 = SkCanvas::kRGBA_Unpremul_Config8888; 1619a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com return true; 1620a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com case kBGRA_8888_PM_GrPixelConfig: 1621a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com *config8888 = SkCanvas::kBGRA_Premul_Config8888; 1622a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com return true; 1623a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com case kBGRA_8888_UPM_GrPixelConfig: 1624a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com *config8888 = SkCanvas::kBGRA_Unpremul_Config8888; 1625a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com return true; 1626a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com default: 1627a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com return false; 1628a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com } 1629a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com} 1630a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com} 1631a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com 16326f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.combool GrContext::internalReadRenderTargetPixels(GrRenderTarget* target, 16336f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com int left, int top, 16346f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com int width, int height, 16356f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com GrPixelConfig config, 16366f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com void* buffer, 16376f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com size_t rowBytes, 16386f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com uint32_t flags) { 1639278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com SK_TRACE_EVENT0("GrContext::readRenderTargetPixels"); 1640bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(target); 1641bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com 1642669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com if (NULL == target) { 16438f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com target = fGpu->drawState()->getRenderTarget(); 1644c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com if (NULL == target) { 1645c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com return false; 1646c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } 1647c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } 1648669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com 16496f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com if (!(kDontFlush_PixelOpsFlag & flags)) { 16506f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com this->flush(); 16516f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com } 1652c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 1653a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com if (!GrPixelConfigIsUnpremultiplied(target->config()) && 1654a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com GrPixelConfigIsUnpremultiplied(config) && 1655a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com !fGpu->canPreserveReadWriteUnpremulPixels()) { 1656a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com SkCanvas::Config8888 srcConfig8888, dstConfig8888; 1657a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com if (!grconfig_to_config8888(target->config(), &srcConfig8888) || 1658a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com !grconfig_to_config8888(config, &dstConfig8888)) { 1659a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com return false; 1660a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com } 1661a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com // do read back using target's own config 1662a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com this->internalReadRenderTargetPixels(target, 1663a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com left, top, 1664a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com width, height, 1665a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com target->config(), 1666a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com buffer, rowBytes, 1667a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com kDontFlush_PixelOpsFlag); 1668a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com // sw convert the pixels to unpremul config 1669a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com uint32_t* pixels = reinterpret_cast<uint32_t*>(buffer); 1670a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com SkConvertConfig8888Pixels(pixels, rowBytes, dstConfig8888, 1671a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com pixels, rowBytes, srcConfig8888, 1672a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com width, height); 1673a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com return true; 1674a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com } 1675a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com 1676c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com GrTexture* src = target->asTexture(); 16770a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com bool swapRAndB = NULL != src && 16780a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com fGpu->preferredReadPixelsConfig(config) == 16790a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com GrPixelConfigSwapRAndB(config); 1680c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 1681c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com bool flipY = NULL != src && 1682c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com fGpu->readPixelsWillPayForYFlip(target, left, top, 1683c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com width, height, config, 1684c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com rowBytes); 16850a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com bool alphaConversion = (!GrPixelConfigIsUnpremultiplied(target->config()) && 16860a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com GrPixelConfigIsUnpremultiplied(config)); 1687c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 16880a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com if (NULL == src && alphaConversion) { 16890a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com // we should fallback to cpu conversion here. This could happen when 16900a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com // we were given an external render target by the client that is not 16910a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com // also a texture (e.g. FBO 0 in GL) 16920a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com return false; 16930a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com } 16940a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com // we draw to a scratch texture if any of these conversion are applied 1695c4ff22a2965616629765b8ffe0e58f6d05f92fa3bsalomon@google.com GrAutoScratchTexture ast; 16960a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com if (flipY || swapRAndB || alphaConversion) { 16970a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com GrAssert(NULL != src); 16980a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com if (swapRAndB) { 16990a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com config = GrPixelConfigSwapRAndB(config); 17000a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com GrAssert(kUnknown_GrPixelConfig != config); 1701c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } 1702c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com // Make the scratch a render target because we don't have a robust 1703c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com // readTexturePixels as of yet (it calls this function). 1704c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com const GrTextureDesc desc = { 1705c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com kRenderTarget_GrTextureFlagBit, 1706c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com width, height, 170778d6cf9f434d3351b19de14f1eab424c23f0ab6dbsalomon@google.com config, 170878d6cf9f434d3351b19de14f1eab424c23f0ab6dbsalomon@google.com {0}, // samples 1709c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com }; 1710c4ff22a2965616629765b8ffe0e58f6d05f92fa3bsalomon@google.com 171156d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com // When a full readback is faster than a partial we could always make 171256d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com // the scratch exactly match the passed rect. However, if we see many 171356d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com // different size rectangles we will trash our texture cache and pay the 171456d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com // cost of creating and destroying many textures. So, we only request 171556d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com // an exact match when the caller is reading an entire RT. 171656d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com ScratchTexMatch match = kApprox_ScratchTexMatch; 171756d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com if (0 == left && 171856d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com 0 == top && 171956d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com target->width() == width && 172056d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com target->height() == height && 172156d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com fGpu->fullReadPixelsIsFasterThanPartial()) { 172256d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com match = kExact_ScratchTexMatch; 172356d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com } 172456d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com ast.set(this, desc, match); 1725c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com GrTexture* texture = ast.texture(); 1726c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com if (!texture) { 1727c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com return false; 1728c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } 1729c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com target = texture->asRenderTarget(); 1730c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com GrAssert(NULL != target); 1731c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 1732c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com GrDrawTarget::AutoStateRestore asr(fGpu); 17338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = fGpu->drawState(); 173452a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com drawState->reset(); 17358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setRenderTarget(target); 1736c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 1737c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com GrMatrix matrix; 1738c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com if (flipY) { 1739c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com matrix.setTranslate(SK_Scalar1 * left, 1740c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com SK_Scalar1 * (top + height)); 1741c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com matrix.set(GrMatrix::kMScaleY, -GR_Scalar1); 1742c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } else { 1743c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com matrix.setTranslate(SK_Scalar1 *left, SK_Scalar1 *top); 1744c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } 1745c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com matrix.postIDiv(src->width(), src->height()); 17461e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com drawState->sampler(0)->reset(matrix); 17471e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com drawState->sampler(0)->setRAndBSwap(swapRAndB); 17488f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setTexture(0, src); 1749c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com GrRect rect; 1750c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com rect.setXYWH(0, 0, SK_Scalar1 * width, SK_Scalar1 * height); 1751c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com fGpu->drawSimpleRect(rect, NULL, 0x1); 1752c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com left = 0; 1753c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com top = 0; 1754c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } 1755669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com return fGpu->readPixels(target, 1756c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com left, top, width, height, 1757c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com config, buffer, rowBytes, flipY); 175827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 175927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 176075f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.comvoid GrContext::resolveRenderTarget(GrRenderTarget* target) { 176175f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com GrAssert(target); 176275f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com ASSERT_OWNED_RESOURCE(target); 176375f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com // In the future we may track whether there are any pending draws to this 176475f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com // target. We don't today so we always perform a flush. We don't promise 176575f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com // this to our clients, though. 176675f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com this->flush(); 176775f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com fGpu->resolveRenderTarget(target); 176875f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com} 176975f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com 1770ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.orgvoid GrContext::copyTexture(GrTexture* src, GrRenderTarget* dst) { 1771ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org if (NULL == src || NULL == dst) { 1772ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org return; 1773ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org } 1774ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org ASSERT_OWNED_RESOURCE(src); 1775ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org 1776ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org GrDrawTarget::AutoStateRestore asr(fGpu); 17778f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = fGpu->drawState(); 177852a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com drawState->reset(); 17798f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setRenderTarget(dst); 1780ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org GrMatrix sampleM; 1781ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org sampleM.setIDiv(src->width(), src->height()); 17828f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setTexture(0, src); 17831e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com drawState->sampler(0)->reset(sampleM); 17845db3b6cce4e9e02415a0a31d95666c044c953ac2bsalomon@google.com SkRect rect = SkRect::MakeXYWH(0, 0, 17855db3b6cce4e9e02415a0a31d95666c044c953ac2bsalomon@google.com SK_Scalar1 * src->width(), 17865db3b6cce4e9e02415a0a31d95666c044c953ac2bsalomon@google.com SK_Scalar1 * src->height()); 1787ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org fGpu->drawSimpleRect(rect, NULL, 1 << 0); 1788ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org} 1789ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org 17906f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.comvoid GrContext::internalWriteRenderTargetPixels(GrRenderTarget* target, 17916f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com int left, int top, 17926f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com int width, int height, 17936f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com GrPixelConfig config, 17946f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com const void* buffer, 17956f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com size_t rowBytes, 17966f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com uint32_t flags) { 17976f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com SK_TRACE_EVENT0("GrContext::writeRenderTargetPixels"); 1798bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(target); 17996f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com 18006f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com if (NULL == target) { 18018f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com target = fGpu->drawState()->getRenderTarget(); 18026f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com if (NULL == target) { 18036f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com return; 18046f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com } 18056f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com } 180627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 180727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // TODO: when underlying api has a direct way to do this we should use it 180827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // (e.g. glDrawPixels on desktop GL). 180927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1810a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com // If the RT is also a texture and we don't have to do PM/UPM conversion 1811a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com // then take the texture path, which we expect to be at least as fast or 1812a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com // faster since it doesn't use an intermediate texture as we do below. 1813a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com 1814a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com#if !GR_MAC_BUILD 1815a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com // At least some drivers on the Mac get confused when glTexImage2D is called 1816a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com // on a texture attached to an FBO. The FBO still sees the old image. TODO: 1817a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com // determine what OS versions and/or HW is affected. 1818a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com if (NULL != target->asTexture() && 1819a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com GrPixelConfigIsUnpremultiplied(target->config()) == 1820a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com GrPixelConfigIsUnpremultiplied(config)) { 1821a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com 1822a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com this->internalWriteTexturePixels(target->asTexture(), 1823a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com left, top, width, height, 1824a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com config, buffer, rowBytes, flags); 1825a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com return; 1826a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com } 1827a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com#endif 1828a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com if (!GrPixelConfigIsUnpremultiplied(target->config()) && 1829a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com GrPixelConfigIsUnpremultiplied(config) && 1830a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com !fGpu->canPreserveReadWriteUnpremulPixels()) { 1831a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com SkCanvas::Config8888 srcConfig8888, dstConfig8888; 1832a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com if (!grconfig_to_config8888(config, &srcConfig8888) || 1833a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com !grconfig_to_config8888(target->config(), &dstConfig8888)) { 1834a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com return; 1835a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com } 1836a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com // allocate a tmp buffer and sw convert the pixels to premul 1837a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com SkAutoSTMalloc<128 * 128, uint32_t> tmpPixels(width * height); 1838a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com const uint32_t* src = reinterpret_cast<const uint32_t*>(buffer); 1839a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com SkConvertConfig8888Pixels(tmpPixels.get(), 4 * width, dstConfig8888, 1840a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com src, rowBytes, srcConfig8888, 1841a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com width, height); 1842a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com // upload the already premul pixels 1843a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com this->internalWriteRenderTargetPixels(target, 1844a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com left, top, 1845a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com width, height, 1846a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com target->config(), 1847a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com tmpPixels, 4 * width, flags); 1848a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com return; 1849a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com } 1850a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com 1851a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com bool swapRAndB = fGpu->preferredReadPixelsConfig(config) == 1852a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com GrPixelConfigSwapRAndB(config); 1853a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com if (swapRAndB) { 1854a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com config = GrPixelConfigSwapRAndB(config); 1855a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com } 1856a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com 1857fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com const GrTextureDesc desc = { 185878d6cf9f434d3351b19de14f1eab424c23f0ab6dbsalomon@google.com kNone_GrTextureFlags, width, height, config, {0} 185927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com }; 186050398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrAutoScratchTexture ast(this, desc); 186150398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrTexture* texture = ast.texture(); 186227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL == texture) { 186327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return; 186427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 18656f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com this->internalWriteTexturePixels(texture, 0, 0, width, height, 18666f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com config, buffer, rowBytes, flags); 186727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 186827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget::AutoStateRestore asr(fGpu); 18698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = fGpu->drawState(); 187052a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com drawState->reset(); 187127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 187227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrMatrix matrix; 187327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com matrix.setTranslate(GrIntToScalar(left), GrIntToScalar(top)); 18748f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setViewMatrix(matrix); 18758f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setRenderTarget(target); 18768f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setTexture(0, texture); 187727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 18785c63865b529eb5714e41419dfa23c70d26ff6e4ebsalomon@google.com matrix.setIDiv(texture->width(), texture->height()); 18791e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com drawState->sampler(0)->reset(GrSamplerState::kClamp_WrapMode, 18801e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com GrSamplerState::kNearest_Filter, 18811e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com matrix); 18821e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com drawState->sampler(0)->setRAndBSwap(swapRAndB); 188327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 188427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrVertexLayout layout = GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0); 188527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com static const int VCOUNT = 4; 18866513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com // TODO: Use GrGpu::drawRect here 188727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget::AutoReleaseGeometry geo(fGpu, layout, VCOUNT, 0); 188827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (!geo.succeeded()) { 18896513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com GrPrintf("Failed to get space for vertices!\n"); 189027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return; 189127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 189227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com ((GrPoint*)geo.vertices())->setIRectFan(0, 0, width, height); 189327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fGpu->drawNonIndexed(kTriangleFan_PrimitiveType, 0, VCOUNT); 189427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 189527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 189627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1897bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.comvoid GrContext::setPaint(const GrPaint& paint, GrDrawTarget* target) { 18988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = target->drawState(); 189926c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 190026c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com for (int i = 0; i < GrPaint::kMaxTextures; ++i) { 190126c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com int s = i + GrPaint::kFirstTextureStage; 19028f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setTexture(s, paint.getTexture(i)); 1903bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(paint.getTexture(i)); 1904f864ec467dfd518e32f6e4d709fafe57f1b3dbc6bsalomon@google.com if (paint.getTexture(i)) { 1905f864ec467dfd518e32f6e4d709fafe57f1b3dbc6bsalomon@google.com *drawState->sampler(s) = paint.getTextureSampler(i); 1906f864ec467dfd518e32f6e4d709fafe57f1b3dbc6bsalomon@google.com } 190726c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com } 190826c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 19098f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setFirstCoverageStage(GrPaint::kFirstMaskStage); 191026c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 191126c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com for (int i = 0; i < GrPaint::kMaxMasks; ++i) { 191226c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com int s = i + GrPaint::kFirstMaskStage; 19138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setTexture(s, paint.getMask(i)); 1914bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(paint.getMask(i)); 1915f864ec467dfd518e32f6e4d709fafe57f1b3dbc6bsalomon@google.com if (paint.getMask(i)) { 1916f864ec467dfd518e32f6e4d709fafe57f1b3dbc6bsalomon@google.com *drawState->sampler(s) = paint.getMaskSampler(i); 1917f864ec467dfd518e32f6e4d709fafe57f1b3dbc6bsalomon@google.com } 191826c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com } 191926c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 19208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setColor(paint.fColor); 192127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 192227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (paint.fDither) { 19238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->enableState(GrDrawState::kDither_StateBit); 192427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 19258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->disableState(GrDrawState::kDither_StateBit); 192627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 192727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (paint.fAntiAlias) { 19288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->enableState(GrDrawState::kHWAntialias_StateBit); 192927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 19308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->disableState(GrDrawState::kHWAntialias_StateBit); 193127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 193250bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org if (paint.fColorMatrixEnabled) { 193350bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org drawState->enableState(GrDrawState::kColorMatrix_StateBit); 19349b1517edc7eb3e116902a3b3da447a73aaa56585bsalomon@google.com drawState->setColorMatrix(paint.fColorMatrix); 193550bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org } else { 193650bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org drawState->disableState(GrDrawState::kColorMatrix_StateBit); 193750bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org } 19386b67e21b6549598254c1ffa4243bf32615d90fb6bsalomon@google.com drawState->setBlendFunc(paint.fSrcBlendCoeff, paint.fDstBlendCoeff); 19398f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setColorFilter(paint.fColorFilterColor, paint.fColorFilterXfermode); 1940dd1be60702b3622f49d97651e31d13eaf2175cf8bsalomon@google.com drawState->setCoverage(paint.fCoverage); 1941d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com 1942d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com if (paint.getActiveMaskStageMask() && !target->canApplyCoverage()) { 1943d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com GrPrintf("Partial pixel coverage will be incorrectly blended.\n"); 1944d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com } 194527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 194627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1947de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.comGrDrawTarget* GrContext::prepareToDraw(const GrPaint& paint, 194827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com DrawCategory category) { 194927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (category != fLastDrawCategory) { 1950fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.com this->flushDrawBuffer(); 195127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fLastDrawCategory = category; 195227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 1953bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com this->setPaint(paint, fGpu); 195427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget* target = fGpu; 195527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com switch (category) { 195627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com case kText_DrawCategory: 195727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#if DEFER_TEXT_RENDERING 195827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target = fDrawBuffer; 195927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fDrawBuffer->initializeDrawStateAndClip(*fGpu); 196027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#else 196127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target = fGpu; 196227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#endif 196327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com break; 196427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com case kUnbuffered_DrawCategory: 196527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target = fGpu; 196627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com break; 196727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com case kBuffered_DrawCategory: 196827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target = fDrawBuffer; 196927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fDrawBuffer->initializeDrawStateAndClip(*fGpu); 197027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com break; 197127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 197227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return target; 197327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 197427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1975289533ada623f2238a83771eec977f204f75994fbsalomon@google.comGrPathRenderer* GrContext::getPathRenderer(const GrPath& path, 1976289533ada623f2238a83771eec977f204f75994fbsalomon@google.com GrPathFill fill, 1977c2099d2707abcc94e139627399aed4b8894b69bbbsalomon@google.com const GrDrawTarget* target, 1978289533ada623f2238a83771eec977f204f75994fbsalomon@google.com bool antiAlias) { 19793008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com if (NULL == fPathRendererChain) { 19803008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com fPathRendererChain = 19813008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com new GrPathRendererChain(this, GrPathRendererChain::kNone_UsageFlag); 19823008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com } 1983c2099d2707abcc94e139627399aed4b8894b69bbbsalomon@google.com return fPathRendererChain->getPathRenderer(path, fill, target, antiAlias); 19843008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com} 19853008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com 198627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 198727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 198827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::setRenderTarget(GrRenderTarget* target) { 1989bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(target); 1990fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.com if (fGpu->drawState()->getRenderTarget() != target) { 1991fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.com this->flush(false); 1992fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.com fGpu->drawState()->setRenderTarget(target); 1993fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.com } 199427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 199527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 199627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comGrRenderTarget* GrContext::getRenderTarget() { 19978f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com return fGpu->drawState()->getRenderTarget(); 199827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 199927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 200027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comconst GrRenderTarget* GrContext::getRenderTarget() const { 20018f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com return fGpu->getDrawState().getRenderTarget(); 200227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 200327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 200427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comconst GrMatrix& GrContext::getMatrix() const { 20058f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com return fGpu->getDrawState().getViewMatrix(); 200627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 200727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 200827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::setMatrix(const GrMatrix& m) { 20098f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com fGpu->drawState()->setViewMatrix(m); 201027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 201127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 201227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::concatMatrix(const GrMatrix& m) const { 20138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com fGpu->drawState()->preConcatViewMatrix(m); 201427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 201527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 201627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comstatic inline intptr_t setOrClear(intptr_t bits, int shift, intptr_t pred) { 201727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com intptr_t mask = 1 << shift; 201827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (pred) { 201927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com bits |= mask; 202027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 202127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com bits &= ~mask; 202227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 202327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return bits; 202427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 202527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 202627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::resetStats() { 202727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fGpu->resetStats(); 202827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 202927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 203005ef510389950e1ae8dcba40e41e001db771b12dbsalomon@google.comconst GrGpuStats& GrContext::getStats() const { 203127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return fGpu->getStats(); 203227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 203327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 203427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::printStats() const { 203527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fGpu->printStats(); 203627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 203727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 2038583a1e38503ebd57ba9bd39a3fabe89bead8e76cbsalomon@google.comGrContext::GrContext(GrGpu* gpu) { 203927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fGpu = gpu; 204027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fGpu->ref(); 2041669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com fGpu->setContext(this); 20428fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 20433008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com fPathRendererChain = NULL; 2044dfe75bcf98b0c04535efbf7fe36492a7fb53c90dbsalomon@google.com 204550398bf7f1953e640e5529616e710cf540799731bsalomon@google.com fTextureCache = new GrResourceCache(MAX_TEXTURE_CACHE_COUNT, 204650398bf7f1953e640e5529616e710cf540799731bsalomon@google.com MAX_TEXTURE_CACHE_BYTES); 204727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fFontCache = new GrFontCache(fGpu); 204827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 204927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fLastDrawCategory = kUnbuffered_DrawCategory; 205027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 20518fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fDrawBuffer = NULL; 20528fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fDrawBufferVBAllocPool = NULL; 20538fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fDrawBufferIBAllocPool = NULL; 20548fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 2055205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com fAAFillRectIndexBuffer = NULL; 2056205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com fAAStrokeRectIndexBuffer = NULL; 2057919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com 20588fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com this->setupDrawBuffer(); 20598fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com} 20608fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 20618fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.comvoid GrContext::setupDrawBuffer() { 20628fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 20638fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com GrAssert(NULL == fDrawBuffer); 20648fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com GrAssert(NULL == fDrawBufferVBAllocPool); 20658fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com GrAssert(NULL == fDrawBufferIBAllocPool); 20668fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 206727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#if DEFER_TEXT_RENDERING || BATCH_RECT_TO_RECT 2068de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com fDrawBufferVBAllocPool = 20698fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com new GrVertexBufferAllocPool(fGpu, false, 207027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com DRAW_BUFFER_VBPOOL_BUFFER_SIZE, 207127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com DRAW_BUFFER_VBPOOL_PREALLOC_BUFFERS); 2072de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com fDrawBufferIBAllocPool = 20738fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com new GrIndexBufferAllocPool(fGpu, false, 2074de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com DRAW_BUFFER_IBPOOL_BUFFER_SIZE, 207527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS); 207627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 2077471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com fDrawBuffer = new GrInOrderDrawBuffer(fGpu, 2078471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com fDrawBufferVBAllocPool, 207927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fDrawBufferIBAllocPool); 208027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#endif 208127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 208227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#if BATCH_RECT_TO_RECT 208327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fDrawBuffer->setQuadIndexBuffer(this->getQuadIndexBuffer()); 208427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#endif 2085fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.com fDrawBuffer->setAutoFlushTarget(fGpu); 208627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 208727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 208827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comGrDrawTarget* GrContext::getTextTarget(const GrPaint& paint) { 208927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget* target; 209027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#if DEFER_TEXT_RENDERING 209127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target = prepareToDraw(paint, kText_DrawCategory); 209227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#else 209327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target = prepareToDraw(paint, kUnbuffered_DrawCategory); 209427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#endif 2095bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com this->setPaint(paint, target); 209627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return target; 209727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 209827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 209927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comconst GrIndexBuffer* GrContext::getQuadIndexBuffer() const { 210027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return fGpu->getQuadIndexBuffer(); 210127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 2102dfe75bcf98b0c04535efbf7fe36492a7fb53c90dbsalomon@google.com 21033b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.orgGrTexture* GrContext::gaussianBlur(GrTexture* srcTexture, 21043b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrAutoScratchTexture* temp1, 21053b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrAutoScratchTexture* temp2, 21063b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org const SkRect& rect, 21073b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org float sigmaX, float sigmaY) { 2108ceb441476e1712861e87a9bb428f119349ef6bb5senorblanco@chromium.org ASSERT_OWNED_RESOURCE(srcTexture); 21093b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrRenderTarget* oldRenderTarget = this->getRenderTarget(); 21103b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrClip oldClip = this->getClip(); 21113b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrTexture* origTexture = srcTexture; 21123b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrAutoMatrix avm(this, GrMatrix::I()); 21133b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org SkIRect clearRect; 21143b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org int scaleFactorX, halfWidthX, kernelWidthX; 21153b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org int scaleFactorY, halfWidthY, kernelWidthY; 21163b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org sigmaX = adjust_sigma(sigmaX, &scaleFactorX, &halfWidthX, &kernelWidthX); 21173b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org sigmaY = adjust_sigma(sigmaY, &scaleFactorY, &halfWidthY, &kernelWidthY); 21183b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org 21193b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org SkRect srcRect(rect); 21203b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org scale_rect(&srcRect, 1.0f / scaleFactorX, 1.0f / scaleFactorY); 21213b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org srcRect.roundOut(); 21223b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org scale_rect(&srcRect, scaleFactorX, scaleFactorY); 21233b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->setClip(srcRect); 2124bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com 21253b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org const GrTextureDesc desc = { 21263b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit, 21273b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org srcRect.width(), 21283b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org srcRect.height(), 21293b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org kRGBA_8888_GrPixelConfig, 21303b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org {0} // samples 21313b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org }; 21321e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com 21333b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org temp1->set(this, desc); 21343b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org if (temp2) temp2->set(this, desc); 21353b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org 21363b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrTexture* dstTexture = temp1->texture(); 21373b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrPaint paint; 21383b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org paint.reset(); 21393b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org paint.textureSampler(0)->setFilter(GrSamplerState::kBilinear_Filter); 21403b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org 21413b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org for (int i = 1; i < scaleFactorX || i < scaleFactorY; i *= 2) { 21423b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org paint.textureSampler(0)->matrix()->setIDiv(srcTexture->width(), 21433b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org srcTexture->height()); 21443b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->setRenderTarget(dstTexture->asRenderTarget()); 21453b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org SkRect dstRect(srcRect); 21463b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org scale_rect(&dstRect, i < scaleFactorX ? 0.5f : 1.0f, 21473b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org i < scaleFactorY ? 0.5f : 1.0f); 21483b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org paint.setTexture(0, srcTexture); 21493b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->drawRectToRect(paint, dstRect, srcRect); 21503b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org srcRect = dstRect; 21513b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org SkTSwap(srcTexture, dstTexture); 21523b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org // If temp2 is non-NULL, don't render back to origTexture 21533b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org if (temp2 && dstTexture == origTexture) dstTexture = temp2->texture(); 21543b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org } 21553b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org 21563b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org if (sigmaX > 0.0f) { 21573b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org SkAutoTMalloc<float> kernelStorageX(kernelWidthX); 21583b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org float* kernelX = kernelStorageX.get(); 21593b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org build_kernel(sigmaX, kernelX, kernelWidthX); 21603b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org 21613b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org if (scaleFactorX > 1) { 21623b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org // Clear out a halfWidth to the right of the srcRect to prevent the 21633b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org // X convolution from reading garbage. 21643b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org clearRect = SkIRect::MakeXYWH( 21653b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org srcRect.fRight, srcRect.fTop, halfWidthX, srcRect.height()); 21663b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->clear(&clearRect, 0x0); 21673b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org } 216805054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org 21693b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->setRenderTarget(dstTexture->asRenderTarget()); 21703b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org convolve(fGpu, srcTexture, srcRect, kernelX, kernelWidthX, 21713b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrSamplerState::kX_FilterDirection); 21723b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org SkTSwap(srcTexture, dstTexture); 21733b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org if (temp2 && dstTexture == origTexture) dstTexture = temp2->texture(); 21743b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org } 21753b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org 21763b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org if (sigmaY > 0.0f) { 21773b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org SkAutoTMalloc<float> kernelStorageY(kernelWidthY); 21783b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org float* kernelY = kernelStorageY.get(); 21793b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org build_kernel(sigmaY, kernelY, kernelWidthY); 21803b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org 21813b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org if (scaleFactorY > 1 || sigmaX > 0.0f) { 21823b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org // Clear out a halfWidth below the srcRect to prevent the Y 21833b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org // convolution from reading garbage. 21843b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org clearRect = SkIRect::MakeXYWH( 21853b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org srcRect.fLeft, srcRect.fBottom, srcRect.width(), halfWidthY); 21863b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->clear(&clearRect, 0x0); 21873b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org } 21883b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org 21893b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->setRenderTarget(dstTexture->asRenderTarget()); 21903b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org convolve(fGpu, srcTexture, srcRect, kernelY, kernelWidthY, 21913b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrSamplerState::kY_FilterDirection); 21923b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org SkTSwap(srcTexture, dstTexture); 21933b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org if (temp2 && dstTexture == origTexture) dstTexture = temp2->texture(); 21943b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org } 21953b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org 21963b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org if (scaleFactorX > 1 || scaleFactorY > 1) { 21973b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org // Clear one pixel to the right and below, to accommodate bilinear 21983b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org // upsampling. 21993b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org clearRect = SkIRect::MakeXYWH( 22003b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org srcRect.fLeft, srcRect.fBottom, srcRect.width() + 1, 1); 22013b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->clear(&clearRect, 0x0); 22023b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org clearRect = SkIRect::MakeXYWH( 22033b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org srcRect.fRight, srcRect.fTop, 1, srcRect.height()); 22043b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->clear(&clearRect, 0x0); 22053b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org // FIXME: This should be mitchell, not bilinear. 22063b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org paint.textureSampler(0)->setFilter(GrSamplerState::kBilinear_Filter); 22073b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org paint.textureSampler(0)->matrix()->setIDiv(srcTexture->width(), 22083b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org srcTexture->height()); 22093b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->setRenderTarget(dstTexture->asRenderTarget()); 22103b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org paint.setTexture(0, srcTexture); 22113b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org SkRect dstRect(srcRect); 22123b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org scale_rect(&dstRect, scaleFactorX, scaleFactorY); 22133b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->drawRectToRect(paint, dstRect, srcRect); 22143b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org srcRect = dstRect; 22153b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org SkTSwap(srcTexture, dstTexture); 22163b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org } 22173b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->setRenderTarget(oldRenderTarget); 22183b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->setClip(oldClip); 22193b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org return srcTexture; 22203b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org} 22213b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org 22223b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.orgGrTexture* GrContext::applyMorphology(GrTexture* srcTexture, 22233b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org const GrRect& rect, 22243b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrTexture* temp1, GrTexture* temp2, 22253b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrSamplerState::Filter filter, 22263b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org SkISize radius) { 2227ceb441476e1712861e87a9bb428f119349ef6bb5senorblanco@chromium.org ASSERT_OWNED_RESOURCE(srcTexture); 22283b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrRenderTarget* oldRenderTarget = this->getRenderTarget(); 22293b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrAutoMatrix avm(this, GrMatrix::I()); 22303b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrClip oldClip = this->getClip(); 22313b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->setClip(GrRect::MakeWH(srcTexture->width(), srcTexture->height())); 22323b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org if (radius.fWidth > 0) { 22333b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->setRenderTarget(temp1->asRenderTarget()); 22343b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org apply_morphology(fGpu, srcTexture, rect, radius.fWidth, filter, 22353b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrSamplerState::kX_FilterDirection); 22363b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org SkIRect clearRect = SkIRect::MakeXYWH(rect.fLeft, rect.fBottom, 22373b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org rect.width(), radius.fHeight); 22383b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->clear(&clearRect, 0x0); 22393b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org srcTexture = temp1; 22403b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org } 22413b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org if (radius.fHeight > 0) { 22423b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->setRenderTarget(temp2->asRenderTarget()); 22433b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org apply_morphology(fGpu, srcTexture, rect, radius.fHeight, filter, 22443b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrSamplerState::kY_FilterDirection); 22453b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org srcTexture = temp2; 22463b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org } 22473b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->setRenderTarget(oldRenderTarget); 22483b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->setClip(oldClip); 22493b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org return srcTexture; 2250027de5f922e8ad1acc5402829f716b8c513fdd8dsenorblanco@chromium.org} 2251c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 2252c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com/////////////////////////////////////////////////////////////////////////////// 2253