GrContext.cpp revision 1e266f8ff2fb2f05f44e77e046a24410ff7b4c77
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 25919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com// Using MSAA seems to be slower for some yet unknown reason. 26919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com#define PREFER_MSAA_OFFSCREEN_AA 0 27919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com#define OFFSCREEN_SSAA_SCALE 4 // super sample at 4x4 2806afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com 2927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#define DEFER_TEXT_RENDERING 1 3027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 3127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#define BATCH_RECT_TO_RECT (1 && !GR_STATIC_RECT_VB) 3227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 33d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com// When we're using coverage AA but the blend is incompatible (given gpu 34d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com// limitations) should we disable AA or draw wrong? 35950d7a8d8def14efc98d12d6947347fde351b737bsalomon@google.com#define DISABLE_COVERAGE_AA_FOR_BLEND 1 36d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com 378ccadddfa78adbdbbdfa724247318436465a7378bsalomon@google.comstatic const size_t MAX_TEXTURE_CACHE_COUNT = 256; 388ccadddfa78adbdbbdfa724247318436465a7378bsalomon@google.comstatic const size_t MAX_TEXTURE_CACHE_BYTES = 16 * 1024 * 1024; 3927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 4027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comstatic const size_t DRAW_BUFFER_VBPOOL_BUFFER_SIZE = 1 << 18; 4127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comstatic const int DRAW_BUFFER_VBPOOL_PREALLOC_BUFFERS = 4; 4227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 4327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com// We are currently only batching Text and drawRectToRect, both 4427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com// of which use the quad index buffer. 4527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comstatic const size_t DRAW_BUFFER_IBPOOL_BUFFER_SIZE = 0; 4627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comstatic const int DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS = 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 118fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 119fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com 12026c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.comint GrContext::PaintStageVertexLayoutBits( 12126c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com const GrPaint& paint, 12226c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com const bool hasTexCoords[GrPaint::kTotalStages]) { 12326c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com int stageMask = paint.getActiveStageMask(); 12426c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com int layout = 0; 12526c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com for (int i = 0; i < GrPaint::kTotalStages; ++i) { 12626c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com if ((1 << i) & stageMask) { 12726c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com if (NULL != hasTexCoords && hasTexCoords[i]) { 12826c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com layout |= GrDrawTarget::StageTexCoordVertexLayoutBit(i, i); 12926c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com } else { 13026c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com layout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(i); 13126c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com } 13226c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com } 13326c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com } 13426c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com return layout; 13526c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com} 13626c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 13726c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 13826c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 13926c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 140fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.comenum { 141558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com // flags for textures 142558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com kNPOTBit = 0x1, 143558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com kFilterBit = 0x2, 144558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com kScratchBit = 0x4, 145558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com 146558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com // resource type 147558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com kTextureBit = 0x8, 148558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com kStencilBufferBit = 0x10 149fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com}; 150fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com 15150398bf7f1953e640e5529616e710cf540799731bsalomon@google.comGrTexture* GrContext::TextureCacheEntry::texture() const { 15250398bf7f1953e640e5529616e710cf540799731bsalomon@google.com if (NULL == fEntry) { 15350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com return NULL; 15450398bf7f1953e640e5529616e710cf540799731bsalomon@google.com } else { 15550398bf7f1953e640e5529616e710cf540799731bsalomon@google.com return (GrTexture*) fEntry->resource(); 15650398bf7f1953e640e5529616e710cf540799731bsalomon@google.com } 15750398bf7f1953e640e5529616e710cf540799731bsalomon@google.com} 15850398bf7f1953e640e5529616e710cf540799731bsalomon@google.com 15950398bf7f1953e640e5529616e710cf540799731bsalomon@google.comnamespace { 16050398bf7f1953e640e5529616e710cf540799731bsalomon@google.com// returns true if this is a "special" texture because of gpu NPOT limitations 16150398bf7f1953e640e5529616e710cf540799731bsalomon@google.combool gen_texture_key_values(const GrGpu* gpu, 1621fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com const GrSamplerState* sampler, 16350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrContext::TextureKey clientKey, 16450398bf7f1953e640e5529616e710cf540799731bsalomon@google.com int width, 16550398bf7f1953e640e5529616e710cf540799731bsalomon@google.com int height, 16650398bf7f1953e640e5529616e710cf540799731bsalomon@google.com bool scratch, 16750398bf7f1953e640e5529616e710cf540799731bsalomon@google.com uint32_t v[4]) { 16850398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GR_STATIC_ASSERT(sizeof(GrContext::TextureKey) == sizeof(uint64_t)); 16950398bf7f1953e640e5529616e710cf540799731bsalomon@google.com // we assume we only need 16 bits of width and height 17050398bf7f1953e640e5529616e710cf540799731bsalomon@google.com // assert that texture creation will fail anyway if this assumption 17150398bf7f1953e640e5529616e710cf540799731bsalomon@google.com // would cause key collisions. 17218c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com GrAssert(gpu->getCaps().fMaxTextureSize <= SK_MaxU16); 17350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com v[0] = clientKey & 0xffffffffUL; 17450398bf7f1953e640e5529616e710cf540799731bsalomon@google.com v[1] = (clientKey >> 32) & 0xffffffffUL; 17550398bf7f1953e640e5529616e710cf540799731bsalomon@google.com v[2] = width | (height << 16); 17650398bf7f1953e640e5529616e710cf540799731bsalomon@google.com 17750398bf7f1953e640e5529616e710cf540799731bsalomon@google.com v[3] = 0; 17818c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com if (!gpu->getCaps().fNPOTTextureTileSupport) { 179fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com bool isPow2 = GrIsPow2(width) && GrIsPow2(height); 180fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com 1811fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com bool tiled = NULL != sampler && 1821fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com ((sampler->getWrapX() != GrSamplerState::kClamp_WrapMode) || 1831fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com (sampler->getWrapY() != GrSamplerState::kClamp_WrapMode)); 184fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com 185fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com if (tiled && !isPow2) { 18650398bf7f1953e640e5529616e710cf540799731bsalomon@google.com v[3] |= kNPOTBit; 1871fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com if (GrSamplerState::kNearest_Filter != sampler->getFilter()) { 18850398bf7f1953e640e5529616e710cf540799731bsalomon@google.com v[3] |= kFilterBit; 189fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com } 190fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com } 191fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com } 192fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com 19350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com if (scratch) { 19450398bf7f1953e640e5529616e710cf540799731bsalomon@google.com v[3] |= kScratchBit; 195fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com } 19650398bf7f1953e640e5529616e710cf540799731bsalomon@google.com 197558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com v[3] |= kTextureBit; 198558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com 19950398bf7f1953e640e5529616e710cf540799731bsalomon@google.com return v[3] & kNPOTBit; 20050398bf7f1953e640e5529616e710cf540799731bsalomon@google.com} 201558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com 202558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com// we should never have more than one stencil buffer with same combo of 203558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com// (width,height,samplecount) 204558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.comvoid gen_stencil_key_values(int width, int height, 205558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com int sampleCnt, uint32_t v[4]) { 206558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com v[0] = width; 207558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com v[1] = height; 208558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com v[2] = sampleCnt; 209558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com v[3] = kStencilBufferBit; 210558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com} 211558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com 212558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.comvoid gen_stencil_key_values(const GrStencilBuffer* sb, 213558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com uint32_t v[4]) { 214558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com gen_stencil_key_values(sb->width(), sb->height(), 215558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com sb->numSamples(), v); 216558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com} 21782c7bd8f25682fcacfeea12ed899976504a767ffbsalomon@google.com 21882c7bd8f25682fcacfeea12ed899976504a767ffbsalomon@google.com// This should be subsumed by a future version of GrDrawState 21982c7bd8f25682fcacfeea12ed899976504a767ffbsalomon@google.com// It does not reset stage textures/samplers or per-vertex-edge-aa state since 22082c7bd8f25682fcacfeea12ed899976504a767ffbsalomon@google.com// they aren't used unless the vertex layout references them. 22182c7bd8f25682fcacfeea12ed899976504a767ffbsalomon@google.com// It also doesn't set the render target. 2226b67e21b6549598254c1ffa4243bf32615d90fb6bsalomon@google.comvoid reset_draw_state(GrDrawState* drawState){ 2238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 2248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setViewMatrix(GrMatrix::I()); 2258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setColorFilter(0, SkXfermode::kDst_Mode); 2266b67e21b6549598254c1ffa4243bf32615d90fb6bsalomon@google.com drawState->resetStateFlags(); 2278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setEdgeAAData(NULL, 0); 2288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->disableStencil(); 2298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setAlpha(0xFF); 2306b67e21b6549598254c1ffa4243bf32615d90fb6bsalomon@google.com drawState->setBlendFunc(kOne_BlendCoeff, 2313d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com kZero_BlendCoeff); 2328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setFirstCoverageStage(GrDrawState::kNumStages); 2338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setDrawFace(GrDrawState::kBoth_DrawFace); 23482c7bd8f25682fcacfeea12ed899976504a767ffbsalomon@google.com} 235fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com} 236fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com 2371fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.comGrContext::TextureCacheEntry GrContext::findAndLockTexture( 2381fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com TextureKey key, 2391fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com int width, 2401fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com int height, 2411fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com const GrSamplerState* sampler) { 24250398bf7f1953e640e5529616e710cf540799731bsalomon@google.com uint32_t v[4]; 24350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com gen_texture_key_values(fGpu, sampler, key, width, height, false, v); 24450398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrResourceKey resourceKey(v); 245558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com return TextureCacheEntry(fTextureCache->findAndLock(resourceKey, 246558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com GrResourceCache::kNested_LockType)); 247558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com} 248558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com 249fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.combool GrContext::isTextureInCache(TextureKey key, 250fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com int width, 251fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com int height, 2521fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com const GrSamplerState* sampler) const { 253fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com uint32_t v[4]; 254fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com gen_texture_key_values(fGpu, sampler, key, width, height, false, v); 255fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com GrResourceKey resourceKey(v); 256fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com return fTextureCache->hasKey(resourceKey); 257fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com} 258fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com 259558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.comGrResourceEntry* GrContext::addAndLockStencilBuffer(GrStencilBuffer* sb) { 260bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(sb); 261558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com uint32_t v[4]; 262558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com gen_stencil_key_values(sb, v); 263558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com GrResourceKey resourceKey(v); 264558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com return fTextureCache->createAndLock(resourceKey, sb); 265558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com} 266558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com 267558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.comGrStencilBuffer* GrContext::findStencilBuffer(int width, int height, 268558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com int sampleCnt) { 269558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com uint32_t v[4]; 270558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com gen_stencil_key_values(width, height, sampleCnt, v); 271558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com GrResourceKey resourceKey(v); 272558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com GrResourceEntry* entry = fTextureCache->findAndLock(resourceKey, 273558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com GrResourceCache::kSingle_LockType); 274558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com if (NULL != entry) { 275558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com GrStencilBuffer* sb = (GrStencilBuffer*) entry->resource(); 276558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com return sb; 277558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com } else { 278558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com return NULL; 279558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com } 280558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com} 281558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com 282558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.comvoid GrContext::unlockStencilBuffer(GrResourceEntry* sbEntry) { 283bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(sbEntry->resource()); 284558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com fTextureCache->unlock(sbEntry); 28527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 28627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 28727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comstatic void stretchImage(void* dst, 28827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int dstW, 28927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int dstH, 29027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com void* src, 29127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int srcW, 29227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int srcH, 29327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int bpp) { 29427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrFixed dx = (srcW << 16) / dstW; 29527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrFixed dy = (srcH << 16) / dstH; 29627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 29727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrFixed y = dy >> 1; 29827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 29927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int dstXLimit = dstW*bpp; 30027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com for (int j = 0; j < dstH; ++j) { 30127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrFixed x = dx >> 1; 30227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com void* srcRow = (uint8_t*)src + (y>>16)*srcW*bpp; 30327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com void* dstRow = (uint8_t*)dst + j*dstW*bpp; 30427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com for (int i = 0; i < dstXLimit; i += bpp) { 30527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com memcpy((uint8_t*) dstRow + i, 30627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com (uint8_t*) srcRow + (x>>16)*bpp, 30727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com bpp); 30827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com x += dx; 30927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 31027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com y += dy; 31127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 31227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 31327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 3141fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.comGrContext::TextureCacheEntry GrContext::createAndLockTexture( 3151fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com TextureKey key, 3161fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com const GrSamplerState* sampler, 3171fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com const GrTextureDesc& desc, 3181fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com void* srcData, 3191fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com size_t rowBytes) { 320278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com SK_TRACE_EVENT0("GrContext::createAndLockTexture"); 32127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 32227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#if GR_DUMP_TEXTURE_UPLOAD 32327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrPrintf("GrContext::createAndLockTexture [%d %d]\n", desc.fWidth, desc.fHeight); 32427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#endif 32527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 32650398bf7f1953e640e5529616e710cf540799731bsalomon@google.com TextureCacheEntry entry; 32750398bf7f1953e640e5529616e710cf540799731bsalomon@google.com uint32_t v[4]; 32850398bf7f1953e640e5529616e710cf540799731bsalomon@google.com bool special = gen_texture_key_values(fGpu, sampler, key, 32950398bf7f1953e640e5529616e710cf540799731bsalomon@google.com desc.fWidth, desc.fHeight, false, v); 33050398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrResourceKey resourceKey(v); 33150398bf7f1953e640e5529616e710cf540799731bsalomon@google.com 33227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (special) { 3331fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com GrAssert(NULL != sampler); 3341fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com TextureCacheEntry clampEntry = this->findAndLockTexture(key, 3351fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com desc.fWidth, 3361fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com desc.fHeight, 3371fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com NULL); 33827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 33950398bf7f1953e640e5529616e710cf540799731bsalomon@google.com if (NULL == clampEntry.texture()) { 3401fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com clampEntry = this->createAndLockTexture(key, NULL, desc, 3411fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com srcData, rowBytes); 34250398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrAssert(NULL != clampEntry.texture()); 34350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com if (NULL == clampEntry.texture()) { 34450398bf7f1953e640e5529616e710cf540799731bsalomon@google.com return entry; 34527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 34627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 347fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com GrTextureDesc rtDesc = desc; 348fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com rtDesc.fFlags = rtDesc.fFlags | 349fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com kRenderTarget_GrTextureFlagBit | 350fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com kNoStencil_GrTextureFlagBit; 3519962108c400dadcae913614e8a5ab781780981d8bsalomon@google.com rtDesc.fWidth = GrNextPow2(GrMax(desc.fWidth, 64)); 3529962108c400dadcae913614e8a5ab781780981d8bsalomon@google.com rtDesc.fHeight = GrNextPow2(GrMax(desc.fHeight, 64)); 35327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 35427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrTexture* texture = fGpu->createTexture(rtDesc, NULL, 0); 35527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 35627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL != texture) { 35727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget::AutoStateRestore asr(fGpu); 3588f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = fGpu->drawState(); 3596b67e21b6549598254c1ffa4243bf32615d90fb6bsalomon@google.com reset_draw_state(drawState); 3608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setRenderTarget(texture->asRenderTarget()); 3618f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setTexture(0, clampEntry.texture()); 36282c7bd8f25682fcacfeea12ed899976504a767ffbsalomon@google.com 3636aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com GrSamplerState::Filter filter; 3646aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com // if filtering is not desired then we want to ensure all 3656aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com // texels in the resampled image are copies of texels from 3666aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com // the original. 3671fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com if (GrSamplerState::kNearest_Filter == sampler->getFilter()) { 3686aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com filter = GrSamplerState::kNearest_Filter; 3696aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com } else { 3706aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com filter = GrSamplerState::kBilinear_Filter; 3716aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com } 3721e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com drawState->sampler(0)->reset(GrSamplerState::kClamp_WrapMode, 3731e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com filter); 37427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 37527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com static const GrVertexLayout layout = 37627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget::StageTexCoordVertexLayoutBit(0,0); 37727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget::AutoReleaseGeometry arg(fGpu, layout, 4, 0); 37827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 37927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (arg.succeeded()) { 38027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrPoint* verts = (GrPoint*) arg.vertices(); 38127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[0].setIRectFan(0, 0, 38227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com texture->width(), 38327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com texture->height(), 38427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 2*sizeof(GrPoint)); 38527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[1].setIRectFan(0, 0, 1, 1, 2*sizeof(GrPoint)); 38627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fGpu->drawNonIndexed(kTriangleFan_PrimitiveType, 38727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 0, 4); 38850398bf7f1953e640e5529616e710cf540799731bsalomon@google.com entry.set(fTextureCache->createAndLock(resourceKey, texture)); 38927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 3901da0746fa155cdca982ae8deb68cc64f540c92dfbsalomon@google.com texture->releaseRenderTarget(); 39127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 39227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // TODO: Our CPU stretch doesn't filter. But we create separate 39327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // stretched textures when the sampler state is either filtered or 39427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // not. Either implement filtered stretch blit on CPU or just create 39527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // one when FBO case fails. 39627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 397fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com rtDesc.fFlags = kNone_GrTextureFlags; 39827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // no longer need to clamp at min RT size. 39927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com rtDesc.fWidth = GrNextPow2(desc.fWidth); 40027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com rtDesc.fHeight = GrNextPow2(desc.fHeight); 40164c4fe4113424bcfab8b3e0c7049887fda5ab4ffbsalomon@google.com int bpp = GrBytesPerPixel(desc.fConfig); 4023582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com SkAutoSMalloc<128*128*4> stretchedPixels(bpp * 40327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com rtDesc.fWidth * 40427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com rtDesc.fHeight); 40527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com stretchImage(stretchedPixels.get(), rtDesc.fWidth, rtDesc.fHeight, 40627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com srcData, desc.fWidth, desc.fHeight, bpp); 40727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 40827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com size_t stretchedRowBytes = rtDesc.fWidth * bpp; 40927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 41027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrTexture* texture = fGpu->createTexture(rtDesc, 41127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com stretchedPixels.get(), 41227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com stretchedRowBytes); 41327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrAssert(NULL != texture); 41450398bf7f1953e640e5529616e710cf540799731bsalomon@google.com entry.set(fTextureCache->createAndLock(resourceKey, texture)); 41527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 41650398bf7f1953e640e5529616e710cf540799731bsalomon@google.com fTextureCache->unlock(clampEntry.cacheEntry()); 41727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 41827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 41927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrTexture* texture = fGpu->createTexture(desc, srcData, rowBytes); 42027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL != texture) { 42150398bf7f1953e640e5529616e710cf540799731bsalomon@google.com entry.set(fTextureCache->createAndLock(resourceKey, texture)); 42227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 42327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 42427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return entry; 42527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 42627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 42750398bf7f1953e640e5529616e710cf540799731bsalomon@google.comnamespace { 42850398bf7f1953e640e5529616e710cf540799731bsalomon@google.cominline void gen_scratch_tex_key_values(const GrGpu* gpu, 42950398bf7f1953e640e5529616e710cf540799731bsalomon@google.com const GrTextureDesc& desc, 43050398bf7f1953e640e5529616e710cf540799731bsalomon@google.com uint32_t v[4]) { 43150398bf7f1953e640e5529616e710cf540799731bsalomon@google.com // Instead of a client-provided key of the texture contents 43250398bf7f1953e640e5529616e710cf540799731bsalomon@google.com // we create a key of from the descriptor. 43350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrContext::TextureKey descKey = desc.fAALevel | 43450398bf7f1953e640e5529616e710cf540799731bsalomon@google.com (desc.fFlags << 8) | 43564c4fe4113424bcfab8b3e0c7049887fda5ab4ffbsalomon@google.com ((uint64_t) desc.fConfig << 32); 43650398bf7f1953e640e5529616e710cf540799731bsalomon@google.com // this code path isn't friendly to tiling with NPOT restricitons 43750398bf7f1953e640e5529616e710cf540799731bsalomon@google.com // We just pass ClampNoFilter() 4381fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com gen_texture_key_values(gpu, NULL, descKey, desc.fWidth, 4391fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com desc.fHeight, true, v); 44050398bf7f1953e640e5529616e710cf540799731bsalomon@google.com} 44127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 44227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 44350398bf7f1953e640e5529616e710cf540799731bsalomon@google.comGrContext::TextureCacheEntry GrContext::lockScratchTexture( 44450398bf7f1953e640e5529616e710cf540799731bsalomon@google.com const GrTextureDesc& inDesc, 44550398bf7f1953e640e5529616e710cf540799731bsalomon@google.com ScratchTexMatch match) { 44650398bf7f1953e640e5529616e710cf540799731bsalomon@google.com 447b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com GrTextureDesc desc = inDesc; 44850398bf7f1953e640e5529616e710cf540799731bsalomon@google.com if (kExact_ScratchTexMatch != match) { 44950398bf7f1953e640e5529616e710cf540799731bsalomon@google.com // bin by pow2 with a reasonable min 45050398bf7f1953e640e5529616e710cf540799731bsalomon@google.com static const int MIN_SIZE = 256; 45150398bf7f1953e640e5529616e710cf540799731bsalomon@google.com desc.fWidth = GrMax(MIN_SIZE, GrNextPow2(desc.fWidth)); 45250398bf7f1953e640e5529616e710cf540799731bsalomon@google.com desc.fHeight = GrMax(MIN_SIZE, GrNextPow2(desc.fHeight)); 45350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com } 454b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com 45564c4fe4113424bcfab8b3e0c7049887fda5ab4ffbsalomon@google.com uint32_t p0 = desc.fConfig; 456b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com uint32_t p1 = (desc.fAALevel << 16) | desc.fFlags; 457b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com 45850398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrResourceEntry* entry; 459b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com int origWidth = desc.fWidth; 460b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com int origHeight = desc.fHeight; 461b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com bool doubledW = false; 462b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com bool doubledH = false; 463b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com 464b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com do { 46550398bf7f1953e640e5529616e710cf540799731bsalomon@google.com uint32_t v[4]; 46650398bf7f1953e640e5529616e710cf540799731bsalomon@google.com gen_scratch_tex_key_values(fGpu, desc, v); 46750398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrResourceKey key(v); 468558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com entry = fTextureCache->findAndLock(key, 469558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com GrResourceCache::kNested_LockType); 470b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com // if we miss, relax the fit of the flags... 471b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com // then try doubling width... then height. 47250398bf7f1953e640e5529616e710cf540799731bsalomon@google.com if (NULL != entry || kExact_ScratchTexMatch == match) { 473b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com break; 474b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } 475b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com if (!(desc.fFlags & kRenderTarget_GrTextureFlagBit)) { 476b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fFlags = desc.fFlags | kRenderTarget_GrTextureFlagBit; 477b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } else if (desc.fFlags & kNoStencil_GrTextureFlagBit) { 478b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fFlags = desc.fFlags & ~kNoStencil_GrTextureFlagBit; 479b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } else if (!doubledW) { 480b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fFlags = inDesc.fFlags; 481b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fWidth *= 2; 482b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com doubledW = true; 483b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } else if (!doubledH) { 484b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fFlags = inDesc.fFlags; 485b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fWidth = origWidth; 486b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fHeight *= 2; 487b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com doubledH = true; 488b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } else { 489b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com break; 490b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } 491b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com 492b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } while (true); 493b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com 494b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com if (NULL == entry) { 495b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fFlags = inDesc.fFlags; 496b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fWidth = origWidth; 497b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fHeight = origHeight; 498b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com GrTexture* texture = fGpu->createTexture(desc, NULL, 0); 499b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com if (NULL != texture) { 50050398bf7f1953e640e5529616e710cf540799731bsalomon@google.com uint32_t v[4]; 50150398bf7f1953e640e5529616e710cf540799731bsalomon@google.com gen_scratch_tex_key_values(fGpu, desc, v); 50250398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrResourceKey key(v); 503b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com entry = fTextureCache->createAndLock(key, texture); 504b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } 505b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } 506b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com 507b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com // If the caller gives us the same desc/sampler twice we don't want 508b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com // to return the same texture the second time (unless it was previously 509b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com // released). So we detach the entry from the cache and reattach at release. 510b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com if (NULL != entry) { 511b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com fTextureCache->detach(entry); 512b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } 51350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com return TextureCacheEntry(entry); 514b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com} 515b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com 51650398bf7f1953e640e5529616e710cf540799731bsalomon@google.comvoid GrContext::unlockTexture(TextureCacheEntry entry) { 517bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(entry.texture()); 51850398bf7f1953e640e5529616e710cf540799731bsalomon@google.com // If this is a scratch texture we detached it from the cache 51950398bf7f1953e640e5529616e710cf540799731bsalomon@google.com // while it was locked (to avoid two callers simultaneously getting 52050398bf7f1953e640e5529616e710cf540799731bsalomon@google.com // the same texture). 52150398bf7f1953e640e5529616e710cf540799731bsalomon@google.com if (kScratchBit & entry.cacheEntry()->key().getValue32(3)) { 52250398bf7f1953e640e5529616e710cf540799731bsalomon@google.com fTextureCache->reattachAndUnlock(entry.cacheEntry()); 523fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com } else { 52450398bf7f1953e640e5529616e710cf540799731bsalomon@google.com fTextureCache->unlock(entry.cacheEntry()); 525fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com } 52627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 52727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 528fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.comGrTexture* GrContext::createUncachedTexture(const GrTextureDesc& desc, 52927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com void* srcData, 53027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com size_t rowBytes) { 53127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return fGpu->createTexture(desc, srcData, rowBytes); 53227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 53327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 53427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::getTextureCacheLimits(int* maxTextures, 53527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com size_t* maxTextureBytes) const { 53627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fTextureCache->getLimits(maxTextures, maxTextureBytes); 53727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 53827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 53927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::setTextureCacheLimits(int maxTextures, size_t maxTextureBytes) { 54027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fTextureCache->setLimits(maxTextures, maxTextureBytes); 54127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 54227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 543919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.comint GrContext::getMaxTextureSize() const { 54418c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com return fGpu->getCaps().fMaxTextureSize; 545919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com} 546919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com 547919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.comint GrContext::getMaxRenderTargetSize() const { 54818c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com return fGpu->getCaps().fMaxRenderTargetSize; 54927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 55027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 55127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com/////////////////////////////////////////////////////////////////////////////// 55227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 553e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.comGrTexture* GrContext::createPlatformTexture(const GrPlatformTextureDesc& desc) { 554e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com return fGpu->createPlatformTexture(desc); 555e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com} 556e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com 557e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.comGrRenderTarget* GrContext::createPlatformRenderTarget(const GrPlatformRenderTargetDesc& desc) { 558e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com return fGpu->createPlatformRenderTarget(desc); 559e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com} 560e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com 5615877ffd5ea71a3ea70096d5c11c843798defa690bsalomon@google.comGrResource* GrContext::createPlatformSurface(const GrPlatformSurfaceDesc& desc) { 5625877ffd5ea71a3ea70096d5c11c843798defa690bsalomon@google.com // validate flags here so that GrGpu subclasses don't have to check 5635877ffd5ea71a3ea70096d5c11c843798defa690bsalomon@google.com if (kTexture_GrPlatformSurfaceType == desc.fSurfaceType && 5645877ffd5ea71a3ea70096d5c11c843798defa690bsalomon@google.com 0 != desc.fRenderTargetFlags) { 5655877ffd5ea71a3ea70096d5c11c843798defa690bsalomon@google.com return NULL; 5665877ffd5ea71a3ea70096d5c11c843798defa690bsalomon@google.com } 5675bfc21761e0ce41206acac4c5008fc0f24debd44bsalomon@google.com if (desc.fSampleCnt && 5685bfc21761e0ce41206acac4c5008fc0f24debd44bsalomon@google.com (kGrCanResolve_GrPlatformRenderTargetFlagBit & desc.fRenderTargetFlags)) { 569973b879dfd994fdb2d5d487edc2012ee3a81f326bsalomon@google.com return NULL; 5705bfc21761e0ce41206acac4c5008fc0f24debd44bsalomon@google.com } 5715bfc21761e0ce41206acac4c5008fc0f24debd44bsalomon@google.com if (kTextureRenderTarget_GrPlatformSurfaceType == desc.fSurfaceType && 5725bfc21761e0ce41206acac4c5008fc0f24debd44bsalomon@google.com desc.fSampleCnt && 5735bfc21761e0ce41206acac4c5008fc0f24debd44bsalomon@google.com !(kGrCanResolve_GrPlatformRenderTargetFlagBit & desc.fRenderTargetFlags)) { 5745bfc21761e0ce41206acac4c5008fc0f24debd44bsalomon@google.com return NULL; 5755bfc21761e0ce41206acac4c5008fc0f24debd44bsalomon@google.com } 5765877ffd5ea71a3ea70096d5c11c843798defa690bsalomon@google.com return fGpu->createPlatformSurface(desc); 57727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 57827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 5795877ffd5ea71a3ea70096d5c11c843798defa690bsalomon@google.com/////////////////////////////////////////////////////////////////////////////// 5805877ffd5ea71a3ea70096d5c11c843798defa690bsalomon@google.com 5811fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.combool GrContext::supportsIndex8PixelConfig(const GrSamplerState* sampler, 5821f221a70214fa1ab87b8a32dd66facf485f318eebsalomon@google.com int width, int height) const { 58318c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com const GrDrawTarget::Caps& caps = fGpu->getCaps(); 58418c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com if (!caps.f8BitPaletteSupport) { 58527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return false; 58627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 58727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 58827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com bool isPow2 = GrIsPow2(width) && GrIsPow2(height); 58927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 59027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (!isPow2) { 5911fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com bool tiled = NULL != sampler && 5921fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com (sampler->getWrapX() != GrSamplerState::kClamp_WrapMode || 5931fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com sampler->getWrapY() != GrSamplerState::kClamp_WrapMode); 59418c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com if (tiled && !caps.fNPOTTextureTileSupport) { 59527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return false; 59627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 59727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 59827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return true; 59927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 60027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 60127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 60227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 60305ef510389950e1ae8dcba40e41e001db771b12dbsalomon@google.comconst GrClip& GrContext::getClip() const { return fGpu->getClip(); } 60405ef510389950e1ae8dcba40e41e001db771b12dbsalomon@google.com 60527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::setClip(const GrClip& clip) { 60627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fGpu->setClip(clip); 6078f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com fGpu->drawState()->enableState(GrDrawState::kClip_StateBit); 60827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 60927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 61027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::setClip(const GrIRect& rect) { 61127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrClip clip; 612d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com clip.setFromIRect(rect); 61327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fGpu->setClip(clip); 61427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 61527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 61627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 61727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 6186aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.comvoid GrContext::clear(const GrIRect* rect, const GrColor color) { 619398109cc3e56b8122ad21c4d43a74a83be5b42a8bsalomon@google.com this->flush(); 6206aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com fGpu->clear(rect, color); 62127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 62227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 62327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::drawPaint(const GrPaint& paint) { 62427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // set rect to be big enough to fill the space, but not super-huge, so we 62527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // don't overflow fixed-point implementations 626d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com GrRect r; 627d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com r.setLTRB(0, 0, 628d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com GrIntToScalar(getRenderTarget()->width()), 629d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com GrIntToScalar(getRenderTarget()->height())); 63027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrMatrix inverse; 6318c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com SkTLazy<GrPaint> tmpPaint; 6328c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com const GrPaint* p = &paint; 6338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = fGpu->drawState(); 6348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrAutoMatrix am; 6358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 6364f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com // We attempt to map r by the inverse matrix and draw that. mapRect will 6374f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com // map the four corners and bound them with a new rect. This will not 6384f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com // produce a correct result for some perspective matrices. 6398c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com if (!this->getMatrix().hasPerspective()) { 6408f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com if (!drawState->getViewInverse(&inverse)) { 6418c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com GrPrintf("Could not invert matrix"); 6428c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com return; 6438c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com } 64427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com inverse.mapRect(&r); 64527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 6468c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com if (paint.getActiveMaskStageMask() || paint.getActiveStageMask()) { 6478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com if (!drawState->getViewInverse(&inverse)) { 6488c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com GrPrintf("Could not invert matrix"); 6498c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com return; 6508c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com } 6518c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com tmpPaint.set(paint); 6528c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com tmpPaint.get()->preConcatActiveSamplerMatrices(inverse); 6538c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com p = tmpPaint.get(); 6548c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com } 6554f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com am.set(this, GrMatrix::I()); 65627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 6574f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com // by definition this fills the entire clip, no need for AA 6584f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com if (paint.fAntiAlias) { 6598c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com if (!tmpPaint.isValid()) { 6608c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com tmpPaint.set(paint); 6618c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com p = tmpPaint.get(); 6628c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com } 6638c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com GrAssert(p == tmpPaint.get()); 6648c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com tmpPaint.get()->fAntiAlias = false; 6654f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com } 6664f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com this->drawRect(*p, r); 66727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 66827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 669205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 670205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 671d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.comnamespace { 672d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.cominline bool disable_coverage_aa_for_blend(GrDrawTarget* target) { 673d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com return DISABLE_COVERAGE_AA_FOR_BLEND && !target->canApplyCoverage(); 674d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com} 675d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com} 676d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com 677919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.comstruct GrContext::OffscreenRecord { 678919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com enum Downsample { 679919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com k4x4TwoPass_Downsample, 680919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com k4x4SinglePass_Downsample, 681919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com kFSAA_Downsample 682919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com } fDownsample; 683b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com int fTileSizeX; 684b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com int fTileSizeY; 685919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com int fTileCountX; 686919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com int fTileCountY; 687919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com int fScale; 68850398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrAutoScratchTexture fOffscreen0; 68950398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrAutoScratchTexture fOffscreen1; 690919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com GrDrawTarget::SavedDrawState fSavedState; 691237a461ec96918eef9bd9f61d4d63fc43968b3e8tomhudson@google.com GrClip fClip; 692919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com}; 693919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com 694471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.combool GrContext::doOffscreenAA(GrDrawTarget* target, 695471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com bool isHairLines) const { 696919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com#if !GR_USE_OFFSCREEN_AA 6978295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com return false; 6988295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com#else 6991f221a70214fa1ab87b8a32dd66facf485f318eebsalomon@google.com // Line primitves are always rasterized as 1 pixel wide. 7001f221a70214fa1ab87b8a32dd66facf485f318eebsalomon@google.com // Super-sampling would make them too thin but MSAA would be OK. 7011f221a70214fa1ab87b8a32dd66facf485f318eebsalomon@google.com if (isHairLines && 70218c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com (!PREFER_MSAA_OFFSCREEN_AA || !fGpu->getCaps().fFSAASupport)) { 7038295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com return false; 7048295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com } 7058f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com if (target->getDrawState().getRenderTarget()->isMultisampled()) { 7068295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com return false; 7078295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com } 708d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com if (disable_coverage_aa_for_blend(target)) { 7091983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#if GR_DEBUG 710979432ba2621b617f5e85a9ff48c6b6cd1504a0dbsalomon@google.com //GrPrintf("Turning off AA to correctly apply blend.\n"); 7111983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#endif 7128295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com return false; 7138295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com } 7148295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com return true; 7158295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com#endif 7168295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com} 7178295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com 718919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.combool GrContext::prepareForOffscreenAA(GrDrawTarget* target, 71906afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com bool requireStencil, 7208295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com const GrIRect& boundRect, 721d22b6e4351e552a8379d7781096d9e79feeae263tomhudson@google.com GrPathRenderer* pr, 72206afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com OffscreenRecord* record) { 723919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com 724919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com GrAssert(GR_USE_OFFSCREEN_AA); 72506afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com 72650398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrAssert(NULL == record->fOffscreen0.texture()); 72750398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrAssert(NULL == record->fOffscreen1.texture()); 728919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com GrAssert(!boundRect.isEmpty()); 72906afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com 7308295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com int boundW = boundRect.width(); 7318295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com int boundH = boundRect.height(); 732919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com 733b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com GrTextureDesc desc; 734919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com 735b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fWidth = GrMin(fMaxOffscreenAASize, boundW); 736b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fHeight = GrMin(fMaxOffscreenAASize, boundH); 73706afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com 73806afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com if (requireStencil) { 73906afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com desc.fFlags = kRenderTarget_GrTextureFlagBit; 74006afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com } else { 74106afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com desc.fFlags = kRenderTarget_GrTextureFlagBit | 74206afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com kNoStencil_GrTextureFlagBit; 74306afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com } 74406afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com 745c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com desc.fConfig = kRGBA_8888_PM_GrPixelConfig; 74606afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com 74718c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com if (PREFER_MSAA_OFFSCREEN_AA && fGpu->getCaps().fFSAASupport) { 7486aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com record->fDownsample = OffscreenRecord::kFSAA_Downsample; 749d22b6e4351e552a8379d7781096d9e79feeae263tomhudson@google.com record->fScale = 1; 7508295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com desc.fAALevel = kMed_GrAALevel; 7518295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com } else { 75218c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com record->fDownsample = fGpu->getCaps().fShaderSupport ? 7536aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com OffscreenRecord::k4x4SinglePass_Downsample : 7546aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com OffscreenRecord::k4x4TwoPass_Downsample; 755919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com record->fScale = OFFSCREEN_SSAA_SCALE; 756919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com // both downsample paths assume this 757919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com GR_STATIC_ASSERT(4 == OFFSCREEN_SSAA_SCALE); 7588295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com desc.fAALevel = kNone_GrAALevel; 7598295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com } 760d22b6e4351e552a8379d7781096d9e79feeae263tomhudson@google.com 761b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fWidth *= record->fScale; 762b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fHeight *= record->fScale; 76350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com record->fOffscreen0.set(this, desc); 76450398bf7f1953e640e5529616e710cf540799731bsalomon@google.com if (NULL == record->fOffscreen0.texture()) { 76506afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com return false; 76606afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com } 767b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com // the approximate lookup might have given us some slop space, might as well 768b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com // use it when computing the tiles size. 769b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com // these are scale values, will adjust after considering 770b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com // the possible second offscreen. 77150398bf7f1953e640e5529616e710cf540799731bsalomon@google.com record->fTileSizeX = record->fOffscreen0.texture()->width(); 77250398bf7f1953e640e5529616e710cf540799731bsalomon@google.com record->fTileSizeY = record->fOffscreen0.texture()->height(); 7738295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com 7746aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com if (OffscreenRecord::k4x4TwoPass_Downsample == record->fDownsample) { 7758295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com desc.fWidth /= 2; 7768295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com desc.fHeight /= 2; 77750398bf7f1953e640e5529616e710cf540799731bsalomon@google.com record->fOffscreen1.set(this, desc); 77850398bf7f1953e640e5529616e710cf540799731bsalomon@google.com if (NULL == record->fOffscreen1.texture()) { 7798295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com return false; 7808295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com } 781b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com record->fTileSizeX = GrMin(record->fTileSizeX, 78250398bf7f1953e640e5529616e710cf540799731bsalomon@google.com 2 * record->fOffscreen0.texture()->width()); 783b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com record->fTileSizeY = GrMin(record->fTileSizeY, 78450398bf7f1953e640e5529616e710cf540799731bsalomon@google.com 2 * record->fOffscreen0.texture()->height()); 7858295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com } 786b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com record->fTileSizeX /= record->fScale; 787b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com record->fTileSizeY /= record->fScale; 788b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com 789b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com record->fTileCountX = GrIDivRoundUp(boundW, record->fTileSizeX); 790b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com record->fTileCountY = GrIDivRoundUp(boundH, record->fTileSizeY); 791b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com 792237a461ec96918eef9bd9f61d4d63fc43968b3e8tomhudson@google.com record->fClip = target->getClip(); 793237a461ec96918eef9bd9f61d4d63fc43968b3e8tomhudson@google.com 794919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com target->saveCurrentDrawState(&record->fSavedState); 795919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com return true; 796919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com} 797919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com 798919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.comvoid GrContext::setupOffscreenAAPass1(GrDrawTarget* target, 799919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com const GrIRect& boundRect, 800919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com int tileX, int tileY, 801919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com OffscreenRecord* record) { 8028295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com 80350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrRenderTarget* offRT0 = record->fOffscreen0.texture()->asRenderTarget(); 8048295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com GrAssert(NULL != offRT0); 80506afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com 80606afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com GrPaint tempPaint; 80706afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com tempPaint.reset(); 808bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com this->setPaint(tempPaint, target); 8098f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = target->drawState(); 8108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setRenderTarget(offRT0); 811289533ada623f2238a83771eec977f204f75994fbsalomon@google.com#if PREFER_MSAA_OFFSCREEN_AA 8128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com target->enableState(GrDrawState::kHWAntialias_StateBit); 813289533ada623f2238a83771eec977f204f75994fbsalomon@google.com#endif 81406afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com 8153d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com GrMatrix transM; 816b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com int left = boundRect.fLeft + tileX * record->fTileSizeX; 817b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com int top = boundRect.fTop + tileY * record->fTileSizeY; 8183d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com transM.setTranslate(-left * GR_Scalar1, -top * GR_Scalar1); 8198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->viewMatrix()->postConcat(transM); 8203d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com GrMatrix scaleM; 8213d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com scaleM.setScale(record->fScale * GR_Scalar1, record->fScale * GR_Scalar1); 8228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->viewMatrix()->postConcat(scaleM); 82306afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com 824919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com int w = (tileX == record->fTileCountX-1) ? boundRect.fRight - left : 825b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com record->fTileSizeX; 826919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com int h = (tileY == record->fTileCountY-1) ? boundRect.fBottom - top : 827b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com record->fTileSizeY; 828919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com GrIRect clear = SkIRect::MakeWH(record->fScale * w, 829919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com record->fScale * h); 830237a461ec96918eef9bd9f61d4d63fc43968b3e8tomhudson@google.com target->setClip(GrClip(clear)); 831919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com#if 0 832919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com // visualize tile boundaries by setting edges of offscreen to white 833919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com // and interior to tranparent. black. 834919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com target->clear(&clear, 0xffffffff); 835919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com 836919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com static const int gOffset = 2; 837919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com GrIRect clear2 = SkIRect::MakeLTRB(gOffset, gOffset, 838919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com record->fScale * w - gOffset, 839919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com record->fScale * h - gOffset); 840919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com target->clear(&clear2, 0x0); 841919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com#else 8428295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com target->clear(&clear, 0x0); 843919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com#endif 84406afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com} 84506afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com 846919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.comvoid GrContext::doOffscreenAAPass2(GrDrawTarget* target, 8478295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com const GrPaint& paint, 8488295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com const GrIRect& boundRect, 849919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com int tileX, int tileY, 8508295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com OffscreenRecord* record) { 851278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com SK_TRACE_EVENT0("GrContext::doOffscreenAAPass2"); 85250398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrAssert(NULL != record->fOffscreen0.texture()); 853ee435122d7dcb9cd4be4524004b0de282c42848bbsalomon@google.com GrDrawTarget::AutoGeometryPush agp(target); 854919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com GrIRect tileRect; 855b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com tileRect.fLeft = boundRect.fLeft + tileX * record->fTileSizeX; 856b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com tileRect.fTop = boundRect.fTop + tileY * record->fTileSizeY, 857919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com tileRect.fRight = (tileX == record->fTileCountX-1) ? 858919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com boundRect.fRight : 859b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com tileRect.fLeft + record->fTileSizeX; 860919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com tileRect.fBottom = (tileY == record->fTileCountY-1) ? 861919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com boundRect.fBottom : 862b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com tileRect.fTop + record->fTileSizeY; 86306afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com 8646aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com GrSamplerState::Filter filter; 8656aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com if (OffscreenRecord::k4x4SinglePass_Downsample == record->fDownsample) { 8666aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com filter = GrSamplerState::k4x4Downsample_Filter; 8676aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com } else { 8686aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com filter = GrSamplerState::kBilinear_Filter; 8696aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com } 8706aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com 871a47a48dca5045d71cbc5de343404045209a13e15bsalomon@google.com GrMatrix sampleM; 8728295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com 87350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrTexture* src = record->fOffscreen0.texture(); 8748295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com int scale; 8758295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com 87626c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com enum { 87726c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com kOffscreenStage = GrPaint::kTotalStages, 87826c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com }; 87926c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 8808f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = target->drawState(); 8818f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 8826aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com if (OffscreenRecord::k4x4TwoPass_Downsample == record->fDownsample) { 88350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrAssert(NULL != record->fOffscreen1.texture()); 8848295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com scale = 2; 88550398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrRenderTarget* dst = record->fOffscreen1.texture()->asRenderTarget(); 8868f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 8878295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com // Do 2x2 downsample from first to second 8888f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setTexture(kOffscreenStage, src); 8898f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setRenderTarget(dst); 8908f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setViewMatrix(GrMatrix::I()); 8918295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com sampleM.setScale(scale * GR_Scalar1 / src->width(), 8928295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com scale * GR_Scalar1 / src->height()); 8931e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com GrSamplerState* sampler = drawState->sampler(kOffscreenStage); 8941e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com sampler->reset(GrSamplerState::kClamp_WrapMode, filter); 8951e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com sampler->setMatrix(sampleM); 8969d12f5c11b56ef51ba2c95db721ae7e5bab27023bsalomon@google.com GrRect rect = SkRect::MakeWH(SkIntToScalar(scale * tileRect.width()), 8979d12f5c11b56ef51ba2c95db721ae7e5bab27023bsalomon@google.com SkIntToScalar(scale * tileRect.height())); 8988295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com target->drawSimpleRect(rect, NULL, 1 << kOffscreenStage); 8998295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com 90050398bf7f1953e640e5529616e710cf540799731bsalomon@google.com src = record->fOffscreen1.texture(); 9016aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com } else if (OffscreenRecord::kFSAA_Downsample == record->fDownsample) { 9028295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com scale = 1; 903919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com GrIRect rect = SkIRect::MakeWH(tileRect.width(), tileRect.height()); 9048295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com src->asRenderTarget()->overrideResolveRect(rect); 9056aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com } else { 9066aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com GrAssert(OffscreenRecord::k4x4SinglePass_Downsample == 9076aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com record->fDownsample); 9086aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com scale = 4; 9098295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com } 9108295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com 911919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com // setup for draw back to main RT, we use the original 912919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com // draw state setup by the caller plus an additional coverage 913919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com // stage to handle the AA resolve. Also, we use an identity 914919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com // view matrix and so pre-concat sampler matrices with view inv. 91526c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com int stageMask = paint.getActiveStageMask(); 91626c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 9178295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com target->restoreDrawState(record->fSavedState); 918237a461ec96918eef9bd9f61d4d63fc43968b3e8tomhudson@google.com target->setClip(record->fClip); 91926c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 92026c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com if (stageMask) { 9218295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com GrMatrix invVM; 9228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com if (drawState->getViewInverse(&invVM)) { 9238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->preConcatSamplerMatrices(stageMask, invVM); 9248295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com } 9258295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com } 926919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com // This is important when tiling, otherwise second tile's 927919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com // pass 1 view matrix will be incorrect. 9288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState::AutoViewMatrixRestore avmr(drawState, GrMatrix::I()); 9298295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com 9308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setTexture(kOffscreenStage, src); 9311e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com GrSamplerState* sampler = drawState->sampler(kOffscreenStage); 9321e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com sampler->reset(GrSamplerState::kClamp_WrapMode, filter); 9338295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com sampleM.setScale(scale * GR_Scalar1 / src->width(), 9348295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com scale * GR_Scalar1 / src->height()); 9351e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com 9361e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com sampler->setMatrix(sampleM); 9379d12f5c11b56ef51ba2c95db721ae7e5bab27023bsalomon@google.com sampleM.setTranslate(SkIntToScalar(-tileRect.fLeft), 9389d12f5c11b56ef51ba2c95db721ae7e5bab27023bsalomon@google.com SkIntToScalar(-tileRect.fTop)); 9391e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com sampler->preConcatMatrix(sampleM); 94006afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com 94120efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com GrRect dstRect; 94226c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com int stages = (1 << kOffscreenStage) | stageMask; 943919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com dstRect.set(tileRect); 9448295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com target->drawSimpleRect(dstRect, NULL, stages); 945919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com} 94606afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com 947d22b6e4351e552a8379d7781096d9e79feeae263tomhudson@google.comvoid GrContext::cleanupOffscreenAA(GrDrawTarget* target, 948d22b6e4351e552a8379d7781096d9e79feeae263tomhudson@google.com GrPathRenderer* pr, 949d22b6e4351e552a8379d7781096d9e79feeae263tomhudson@google.com OffscreenRecord* record) { 9508295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com target->restoreDrawState(record->fSavedState); 95106afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com} 95206afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com 95306afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 95406afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com 95527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com/* create a triangle strip that strokes the specified triangle. There are 8 95627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com unique vertices, but we repreat the last 2 to close up. Alternatively we 95727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com could use an indices array, and then only send 8 verts, but not sure that 95827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com would be faster. 95927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com */ 960205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comstatic void setStrokeRectStrip(GrPoint verts[10], GrRect rect, 96127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrScalar width) { 96227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrScalar rad = GrScalarHalf(width); 963205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com rect.sort(); 96427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 96527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[0].set(rect.fLeft + rad, rect.fTop + rad); 96627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[1].set(rect.fLeft - rad, rect.fTop - rad); 96727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[2].set(rect.fRight - rad, rect.fTop + rad); 96827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[3].set(rect.fRight + rad, rect.fTop - rad); 96927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[4].set(rect.fRight - rad, rect.fBottom - rad); 97027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[5].set(rect.fRight + rad, rect.fBottom + rad); 97127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[6].set(rect.fLeft + rad, rect.fBottom - rad); 97227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[7].set(rect.fLeft - rad, rect.fBottom + rad); 97327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[8] = verts[0]; 97427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[9] = verts[1]; 97527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 97627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 977205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comstatic void setInsetFan(GrPoint* pts, size_t stride, 978205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com const GrRect& r, GrScalar dx, GrScalar dy) { 979205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com pts->setRectFan(r.fLeft + dx, r.fTop + dy, r.fRight - dx, r.fBottom - dy, stride); 980205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com} 981205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 982205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comstatic const uint16_t gFillAARectIdx[] = { 983205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 0, 1, 5, 5, 4, 0, 984205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1, 2, 6, 6, 5, 1, 985205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 2, 3, 7, 7, 6, 2, 986205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 3, 0, 4, 4, 7, 3, 987205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 4, 5, 6, 6, 7, 4, 988205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com}; 989205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 990205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comint GrContext::aaFillRectIndexCount() const { 991205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return GR_ARRAY_COUNT(gFillAARectIdx); 992205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com} 993205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 994205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comGrIndexBuffer* GrContext::aaFillRectIndexBuffer() { 995205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (NULL == fAAFillRectIndexBuffer) { 996205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com fAAFillRectIndexBuffer = fGpu->createIndexBuffer(sizeof(gFillAARectIdx), 997205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com false); 9989b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com if (NULL != fAAFillRectIndexBuffer) { 9999b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com #if GR_DEBUG 10009b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com bool updated = 10019b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com #endif 10029b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com fAAFillRectIndexBuffer->updateData(gFillAARectIdx, 10039b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com sizeof(gFillAARectIdx)); 10049b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com GR_DEBUGASSERT(updated); 10059b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com } 1006205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 1007205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return fAAFillRectIndexBuffer; 1008205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com} 1009205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1010205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comstatic const uint16_t gStrokeAARectIdx[] = { 1011205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 0 + 0, 1 + 0, 5 + 0, 5 + 0, 4 + 0, 0 + 0, 1012205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1 + 0, 2 + 0, 6 + 0, 6 + 0, 5 + 0, 1 + 0, 1013205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 2 + 0, 3 + 0, 7 + 0, 7 + 0, 6 + 0, 2 + 0, 1014205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 3 + 0, 0 + 0, 4 + 0, 4 + 0, 7 + 0, 3 + 0, 1015205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1016205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 0 + 4, 1 + 4, 5 + 4, 5 + 4, 4 + 4, 0 + 4, 1017205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1 + 4, 2 + 4, 6 + 4, 6 + 4, 5 + 4, 1 + 4, 1018205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 2 + 4, 3 + 4, 7 + 4, 7 + 4, 6 + 4, 2 + 4, 1019205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 3 + 4, 0 + 4, 4 + 4, 4 + 4, 7 + 4, 3 + 4, 1020205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1021205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 0 + 8, 1 + 8, 5 + 8, 5 + 8, 4 + 8, 0 + 8, 1022205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1 + 8, 2 + 8, 6 + 8, 6 + 8, 5 + 8, 1 + 8, 1023205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 2 + 8, 3 + 8, 7 + 8, 7 + 8, 6 + 8, 2 + 8, 1024205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 3 + 8, 0 + 8, 4 + 8, 4 + 8, 7 + 8, 3 + 8, 1025205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com}; 1026205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1027205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comint GrContext::aaStrokeRectIndexCount() const { 1028205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return GR_ARRAY_COUNT(gStrokeAARectIdx); 1029205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com} 1030205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1031205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comGrIndexBuffer* GrContext::aaStrokeRectIndexBuffer() { 1032205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (NULL == fAAStrokeRectIndexBuffer) { 1033205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com fAAStrokeRectIndexBuffer = fGpu->createIndexBuffer(sizeof(gStrokeAARectIdx), 1034205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com false); 10359b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com if (NULL != fAAStrokeRectIndexBuffer) { 10369b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com #if GR_DEBUG 10379b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com bool updated = 10389b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com #endif 10399b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com fAAStrokeRectIndexBuffer->updateData(gStrokeAARectIdx, 10409b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com sizeof(gStrokeAARectIdx)); 10419b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com GR_DEBUGASSERT(updated); 10429b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com } 1043205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 1044205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return fAAStrokeRectIndexBuffer; 1045205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com} 1046205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1047a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.comstatic GrVertexLayout aa_rect_layout(const GrDrawTarget* target, 1048a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com bool useCoverage) { 1049a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com GrVertexLayout layout = 0; 10509381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com for (int s = 0; s < GrDrawState::kNumStages; ++s) { 10518f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com if (NULL != target->getDrawState().getTexture(s)) { 1052a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com layout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(s); 1053a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com } 1054a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com } 1055a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com if (useCoverage) { 1056a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com layout |= GrDrawTarget::kCoverage_VertexLayoutBit; 1057a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com } else { 1058a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com layout |= GrDrawTarget::kColor_VertexLayoutBit; 1059a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com } 1060a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com return layout; 1061a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com} 1062a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com 1063205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comvoid GrContext::fillAARect(GrDrawTarget* target, 1064a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com const GrRect& devRect, 1065a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com bool useVertexCoverage) { 1066a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com GrVertexLayout layout = aa_rect_layout(target, useVertexCoverage); 1067205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1068205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com size_t vsize = GrDrawTarget::VertexSize(layout); 1069205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1070205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrDrawTarget::AutoReleaseGeometry geo(target, layout, 8, 0); 10716513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com if (!geo.succeeded()) { 10726513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com GrPrintf("Failed to get space for vertices!\n"); 10736513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com return; 10746513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com } 10759b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com GrIndexBuffer* indexBuffer = this->aaFillRectIndexBuffer(); 10769b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com if (NULL == indexBuffer) { 10779b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com GrPrintf("Failed to create index buffer!\n"); 10789b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com return; 10799b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com } 1080205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1081205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com intptr_t verts = reinterpret_cast<intptr_t>(geo.vertices()); 1082205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1083205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrPoint* fan0Pos = reinterpret_cast<GrPoint*>(verts); 1084205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrPoint* fan1Pos = reinterpret_cast<GrPoint*>(verts + 4 * vsize); 1085205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1086205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com setInsetFan(fan0Pos, vsize, devRect, -GR_ScalarHalf, -GR_ScalarHalf); 1087205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com setInsetFan(fan1Pos, vsize, devRect, GR_ScalarHalf, GR_ScalarHalf); 1088205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1089205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com verts += sizeof(GrPoint); 1090205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com for (int i = 0; i < 4; ++i) { 1091205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com *reinterpret_cast<GrColor*>(verts + i * vsize) = 0; 1092205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 1093205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1094a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com GrColor innerColor; 1095a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com if (useVertexCoverage) { 1096e10f6fdf76fa9b627cbb8471b58b13c457af83e8bsalomon@google.com innerColor = 0xffffffff; 1097a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com } else { 10988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com innerColor = target->getDrawState().getColor(); 1099a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com } 1100a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com 1101205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com verts += 4 * vsize; 1102205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com for (int i = 0; i < 4; ++i) { 1103205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com *reinterpret_cast<GrColor*>(verts + i * vsize) = innerColor; 1104205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 1105205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 11069b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com target->setIndexSourceToBuffer(indexBuffer); 1107205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1108205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com target->drawIndexed(kTriangles_PrimitiveType, 0, 1109205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 0, 8, this->aaFillRectIndexCount()); 1110205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com} 1111205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1112a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.comvoid GrContext::strokeAARect(GrDrawTarget* target, 1113a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com const GrRect& devRect, 1114a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com const GrVec& devStrokeSize, 1115a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com bool useVertexCoverage) { 1116205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com const GrScalar& dx = devStrokeSize.fX; 1117205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com const GrScalar& dy = devStrokeSize.fY; 1118205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com const GrScalar rx = GrMul(dx, GR_ScalarHalf); 1119205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com const GrScalar ry = GrMul(dy, GR_ScalarHalf); 1120205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1121205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrScalar spare; 1122205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com { 1123205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrScalar w = devRect.width() - dx; 1124205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrScalar h = devRect.height() - dy; 1125205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com spare = GrMin(w, h); 1126205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 1127205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1128205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (spare <= 0) { 1129205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrRect r(devRect); 1130205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com r.inset(-rx, -ry); 1131a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com fillAARect(target, r, useVertexCoverage); 1132205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return; 1133205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 1134a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com GrVertexLayout layout = aa_rect_layout(target, useVertexCoverage); 1135205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com size_t vsize = GrDrawTarget::VertexSize(layout); 1136205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1137205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrDrawTarget::AutoReleaseGeometry geo(target, layout, 16, 0); 11386513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com if (!geo.succeeded()) { 11396513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com GrPrintf("Failed to get space for vertices!\n"); 11406513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com return; 11416513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com } 11429b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com GrIndexBuffer* indexBuffer = this->aaStrokeRectIndexBuffer(); 11439b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com if (NULL == indexBuffer) { 11449b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com GrPrintf("Failed to create index buffer!\n"); 11459b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com return; 11469b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com } 1147205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1148205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com intptr_t verts = reinterpret_cast<intptr_t>(geo.vertices()); 1149205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1150205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrPoint* fan0Pos = reinterpret_cast<GrPoint*>(verts); 1151205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrPoint* fan1Pos = reinterpret_cast<GrPoint*>(verts + 4 * vsize); 1152205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrPoint* fan2Pos = reinterpret_cast<GrPoint*>(verts + 8 * vsize); 1153205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrPoint* fan3Pos = reinterpret_cast<GrPoint*>(verts + 12 * vsize); 1154205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1155205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com setInsetFan(fan0Pos, vsize, devRect, -rx - GR_ScalarHalf, -ry - GR_ScalarHalf); 1156205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com setInsetFan(fan1Pos, vsize, devRect, -rx + GR_ScalarHalf, -ry + GR_ScalarHalf); 1157205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com setInsetFan(fan2Pos, vsize, devRect, rx - GR_ScalarHalf, ry - GR_ScalarHalf); 1158205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com setInsetFan(fan3Pos, vsize, devRect, rx + GR_ScalarHalf, ry + GR_ScalarHalf); 1159205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1160205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com verts += sizeof(GrPoint); 1161205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com for (int i = 0; i < 4; ++i) { 1162205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com *reinterpret_cast<GrColor*>(verts + i * vsize) = 0; 1163205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 1164205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1165a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com GrColor innerColor; 1166a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com if (useVertexCoverage) { 1167e10f6fdf76fa9b627cbb8471b58b13c457af83e8bsalomon@google.com innerColor = 0xffffffff; 1168a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com } else { 11698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com innerColor = target->getDrawState().getColor(); 1170a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com } 1171205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com verts += 4 * vsize; 1172205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com for (int i = 0; i < 8; ++i) { 1173205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com *reinterpret_cast<GrColor*>(verts + i * vsize) = innerColor; 1174205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 1175205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1176205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com verts += 8 * vsize; 1177205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com for (int i = 0; i < 8; ++i) { 1178205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com *reinterpret_cast<GrColor*>(verts + i * vsize) = 0; 1179205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 1180205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 11819b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com target->setIndexSourceToBuffer(indexBuffer); 1182205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com target->drawIndexed(kTriangles_PrimitiveType, 1183205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 0, 0, 16, aaStrokeRectIndexCount()); 1184205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com} 1185205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 118620efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com/** 118720efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com * Returns true if the rects edges are integer-aligned. 118820efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com */ 118920efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.comstatic bool isIRect(const GrRect& r) { 119020efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com return GrScalarIsInt(r.fLeft) && GrScalarIsInt(r.fTop) && 119120efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com GrScalarIsInt(r.fRight) && GrScalarIsInt(r.fBottom); 119220efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com} 119320efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com 1194205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comstatic bool apply_aa_to_rect(GrDrawTarget* target, 1195205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com const GrRect& rect, 1196205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrScalar width, 1197205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com const GrMatrix* matrix, 1198205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrMatrix* combinedMatrix, 1199a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com GrRect* devRect, 1200a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com bool* useVertexCoverage) { 1201205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com // we use a simple alpha ramp to do aa on axis-aligned rects 1202205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com // do AA with alpha ramp if the caller requested AA, the rect 1203289533ada623f2238a83771eec977f204f75994fbsalomon@google.com // will be axis-aligned, and the rect won't land on integer coords. 1204d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com 1205a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com // we are keeping around the "tweak the alpha" trick because 1206a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com // it is our only hope for the fixed-pipe implementation. 1207a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com // In a shader implementation we can give a separate coverage input 1208289533ada623f2238a83771eec977f204f75994fbsalomon@google.com // TODO: remove this ugliness when we drop the fixed-pipe impl 1209a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com *useVertexCoverage = false; 1210d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com if (!target->canTweakAlphaForCoverage()) { 1211a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com if (target->getCaps().fSupportPerVertexCoverage) { 1212a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com if (disable_coverage_aa_for_blend(target)) { 12131983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#if GR_DEBUG 1214979432ba2621b617f5e85a9ff48c6b6cd1504a0dbsalomon@google.com //GrPrintf("Turning off AA to correctly apply blend.\n"); 12151983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#endif 1216a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com return false; 1217a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com } else { 1218a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com *useVertexCoverage = true; 1219a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com } 1220a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com } else { 1221a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com GrPrintf("Rect AA dropped because no support for coverage.\n"); 1222a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com return false; 1223a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com } 1224205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 12258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com const GrDrawState& drawState = target->getDrawState(); 12268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com if (drawState.getRenderTarget()->isMultisampled()) { 1227205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return false; 1228205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 1229205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1230471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com if (0 == width && target->willUseHWAALines()) { 1231205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return false; 1232205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 1233205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 12348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com if (!drawState.getViewMatrix().preservesAxisAlignment()) { 1235205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return false; 1236205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 1237205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1238205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (NULL != matrix && 1239205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com !matrix->preservesAxisAlignment()) { 1240205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return false; 1241205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 1242205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 12438f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com *combinedMatrix = drawState.getViewMatrix(); 1244205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (NULL != matrix) { 1245205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com combinedMatrix->preConcat(*matrix); 1246205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrAssert(combinedMatrix->preservesAxisAlignment()); 1247205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 1248205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1249205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com combinedMatrix->mapRect(devRect, rect); 1250205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com devRect->sort(); 1251205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1252205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (width < 0) { 125320efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com return !isIRect(*devRect); 1254205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } else { 1255205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return true; 1256205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 1257205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com} 1258205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 125927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::drawRect(const GrPaint& paint, 126027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrRect& rect, 126127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrScalar width, 126227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrMatrix* matrix) { 1263278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com SK_TRACE_EVENT0("GrContext::drawRect"); 126427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 126527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory); 126626c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com int stageMask = paint.getActiveStageMask(); 126727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1268205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrRect devRect = rect; 1269205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrMatrix combinedMatrix; 1270a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com bool useVertexCoverage; 1271289533ada623f2238a83771eec977f204f75994fbsalomon@google.com bool needAA = paint.fAntiAlias && 1272289533ada623f2238a83771eec977f204f75994fbsalomon@google.com !this->getRenderTarget()->isMultisampled(); 1273289533ada623f2238a83771eec977f204f75994fbsalomon@google.com bool doAA = needAA && apply_aa_to_rect(target, rect, width, matrix, 1274289533ada623f2238a83771eec977f204f75994fbsalomon@google.com &combinedMatrix, &devRect, 1275289533ada623f2238a83771eec977f204f75994fbsalomon@google.com &useVertexCoverage); 1276205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1277205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (doAA) { 12788f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawTarget::AutoDeviceCoordDraw adcd(target, stageMask); 1279205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (width >= 0) { 1280205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrVec strokeSize;; 1281205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (width > 0) { 1282205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com strokeSize.set(width, width); 1283cc4dac3dac215dc0dd56f7b30d07cc304671b033bsalomon@google.com combinedMatrix.mapVectors(&strokeSize, 1); 1284205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com strokeSize.setAbs(strokeSize); 1285205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } else { 1286205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com strokeSize.set(GR_Scalar1, GR_Scalar1); 1287205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 1288a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com strokeAARect(target, devRect, strokeSize, useVertexCoverage); 1289205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } else { 1290a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com fillAARect(target, devRect, useVertexCoverage); 1291205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 1292205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return; 1293205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 1294205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 129527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (width >= 0) { 129627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // TODO: consider making static vertex buffers for these cases. 129727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // Hairline could be done by just adding closing vertex to 129827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // unitSquareVertexBuffer() 129926c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com GrVertexLayout layout = PaintStageVertexLayoutBits(paint, NULL); 130026c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 130127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com static const int worstCaseVertCount = 10; 130227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget::AutoReleaseGeometry geo(target, layout, worstCaseVertCount, 0); 130327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 130427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (!geo.succeeded()) { 13056513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com GrPrintf("Failed to get space for vertices!\n"); 130627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return; 130727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 130827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 130927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrPrimitiveType primType; 131027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int vertCount; 131127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrPoint* vertex = geo.positions(); 131227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 131327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (width > 0) { 131427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertCount = 10; 131527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com primType = kTriangleStrip_PrimitiveType; 131627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com setStrokeRectStrip(vertex, rect, width); 131727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 131827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // hairline 131927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertCount = 5; 132027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com primType = kLineStrip_PrimitiveType; 132127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertex[0].set(rect.fLeft, rect.fTop); 132227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertex[1].set(rect.fRight, rect.fTop); 132327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertex[2].set(rect.fRight, rect.fBottom); 132427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertex[3].set(rect.fLeft, rect.fBottom); 132527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertex[4].set(rect.fLeft, rect.fTop); 132627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 132727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 13288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState::AutoViewMatrixRestore avmr; 132927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL != matrix) { 13308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = target->drawState(); 13318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com avmr.set(drawState); 13328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->preConcatViewMatrix(*matrix); 13338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->preConcatSamplerMatrices(stageMask, *matrix); 133427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 133527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 133627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target->drawNonIndexed(primType, 0, vertCount); 133727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 13388f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com#if GR_STATIC_RECT_VB 133926c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com GrVertexLayout layout = PaintStageVertexLayoutBits(paint, NULL); 13406513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com const GrVertexBuffer* sqVB = fGpu->getUnitSquareVertexBuffer(); 13416513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com if (NULL == sqVB) { 13426513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com GrPrintf("Failed to create static rect vb.\n"); 13436513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com return; 13446513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com } 13456513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com target->setVertexSourceToBuffer(layout, sqVB); 13468f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = target->drawState(); 13478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState::AutoViewMatrixRestore avmr(drawState); 134827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrMatrix m; 13498295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com m.setAll(rect.width(), 0, rect.fLeft, 1350205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 0, rect.height(), rect.fTop, 1351205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 0, 0, GrMatrix::I()[8]); 135227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 135327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL != matrix) { 135427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com m.postConcat(*matrix); 135527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 13568f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->preConcatViewMatrix(m); 13578f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->preConcatSamplerMatrices(stageMask, m); 135826c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 135927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target->drawNonIndexed(kTriangleFan_PrimitiveType, 0, 4); 13608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com#else 136126c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com target->drawSimpleRect(rect, matrix, stageMask); 13628f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com#endif 136327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 136427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 136527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 136627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::drawRectToRect(const GrPaint& paint, 136727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrRect& dstRect, 136827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrRect& srcRect, 136927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrMatrix* dstMatrix, 137027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrMatrix* srcMatrix) { 1371278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com SK_TRACE_EVENT0("GrContext::drawRectToRect"); 137227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 137326c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com // srcRect refers to paint's first texture 137426c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com if (NULL == paint.getTexture(0)) { 137527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com drawRect(paint, dstRect, -1, dstMatrix); 137627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return; 137727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 1378de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com 137927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GR_STATIC_ASSERT(!BATCH_RECT_TO_RECT || !GR_STATIC_RECT_VB); 138027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 138127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#if GR_STATIC_RECT_VB 138227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory); 13838f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = target->drawState(); 138426c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com GrVertexLayout layout = PaintStageVertexLayoutBits(paint, NULL); 13858f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState::AutoViewMatrixRestore avmr(drawState); 138627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 138727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrMatrix m; 138827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 138927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com m.setAll(dstRect.width(), 0, dstRect.fLeft, 139027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 0, dstRect.height(), dstRect.fTop, 139127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 0, 0, GrMatrix::I()[8]); 139227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL != dstMatrix) { 139327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com m.postConcat(*dstMatrix); 139427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 13958f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->preConcatViewMatrix(m); 139627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 139726c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com // srcRect refers to first stage 139826c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com int otherStageMask = paint.getActiveStageMask() & 139926c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com (~(1 << GrPaint::kFirstTextureStage)); 140026c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com if (otherStageMask) { 14018f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->preConcatSamplerMatrices(otherStageMask, m); 140226c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com } 140326c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 140427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com m.setAll(srcRect.width(), 0, srcRect.fLeft, 140527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 0, srcRect.height(), srcRect.fTop, 140627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 0, 0, GrMatrix::I()[8]); 140727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL != srcMatrix) { 140827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com m.postConcat(*srcMatrix); 140927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 14108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->sampler(GrPaint::kFirstTextureStage)->preConcatMatrix(m); 141127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 14126513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com const GrVertexBuffer* sqVB = fGpu->getUnitSquareVertexBuffer(); 14136513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com if (NULL == sqVB) { 14146513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com GrPrintf("Failed to create static rect vb.\n"); 14156513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com return; 14166513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com } 14176513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com target->setVertexSourceToBuffer(layout, sqVB); 141827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target->drawNonIndexed(kTriangleFan_PrimitiveType, 0, 4); 141927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#else 142027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 142127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget* target; 1422de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com#if BATCH_RECT_TO_RECT 142327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target = this->prepareToDraw(paint, kBuffered_DrawCategory); 1424de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com#else 142527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target = this->prepareToDraw(paint, kUnbuffered_DrawCategory); 142627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#endif 142727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 14289381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com const GrRect* srcRects[GrDrawState::kNumStages] = {NULL}; 14299381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com const GrMatrix* srcMatrices[GrDrawState::kNumStages] = {NULL}; 143027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com srcRects[0] = &srcRect; 143127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com srcMatrices[0] = srcMatrix; 143227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 143327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target->drawRect(dstRect, dstMatrix, 1, srcRects, srcMatrices); 143427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#endif 143527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 143627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 143727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::drawVertices(const GrPaint& paint, 143827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrPrimitiveType primitiveType, 143927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int vertexCount, 144027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrPoint positions[], 144127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrPoint texCoords[], 144227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrColor colors[], 144327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const uint16_t indices[], 144427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int indexCount) { 1445278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com SK_TRACE_EVENT0("GrContext::drawVertices"); 144627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 144727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget::AutoReleaseGeometry geo; 144827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 144927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory); 145027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 145126c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com bool hasTexCoords[GrPaint::kTotalStages] = { 145226c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com NULL != texCoords, // texCoordSrc provides explicit stage 0 coords 145326c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 0 // remaining stages use positions 145426c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com }; 145526c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 145626c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com GrVertexLayout layout = PaintStageVertexLayoutBits(paint, hasTexCoords); 145727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 145827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL != colors) { 145927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com layout |= GrDrawTarget::kColor_VertexLayoutBit; 146027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 146126c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com int vertexSize = GrDrawTarget::VertexSize(layout); 146227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 146327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (sizeof(GrPoint) != vertexSize) { 146427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (!geo.set(target, layout, vertexCount, 0)) { 14656513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com GrPrintf("Failed to get space for vertices!\n"); 146627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return; 146727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 14689381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com int texOffsets[GrDrawState::kMaxTexCoords]; 146927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int colorOffset; 147026c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com GrDrawTarget::VertexSizeAndOffsetsByIdx(layout, 147126c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com texOffsets, 1472aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com &colorOffset, 1473a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com NULL, 1474a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com NULL); 147527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com void* curVertex = geo.vertices(); 147627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 147727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com for (int i = 0; i < vertexCount; ++i) { 147827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com *((GrPoint*)curVertex) = positions[i]; 147927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 148027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (texOffsets[0] > 0) { 148127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com *(GrPoint*)((intptr_t)curVertex + texOffsets[0]) = texCoords[i]; 148227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 148327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (colorOffset > 0) { 148427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com *(GrColor*)((intptr_t)curVertex + colorOffset) = colors[i]; 148527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 148626c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com curVertex = (void*)((intptr_t)curVertex + vertexSize); 148727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 148827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 148927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target->setVertexSourceToArray(layout, positions, vertexCount); 149027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 149127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1492919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com // we don't currently apply offscreen AA to this path. Need improved 1493919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com // management of GrDrawTarget's geometry to avoid copying points per-tile. 1494a47a48dca5045d71cbc5de343404045209a13e15bsalomon@google.com 14958295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com if (NULL != indices) { 1496919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com target->setIndexSourceToArray(indices, indexCount); 14978295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com target->drawIndexed(primitiveType, 0, 0, vertexCount, indexCount); 149827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 14998295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com target->drawNonIndexed(primitiveType, 0, vertexCount); 15008295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com } 150127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 150227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 150306afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com/////////////////////////////////////////////////////////////////////////////// 150427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 150507f3ee10d34f09342abb93d758b5e151ff78f7a5reed@google.comvoid GrContext::drawPath(const GrPaint& paint, const GrPath& path, 150607f3ee10d34f09342abb93d758b5e151ff78f7a5reed@google.com GrPathFill fill, const GrPoint* translate) { 150727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1508fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com if (path.isEmpty()) { 1509fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com#if GR_DEBUG 1510fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com GrPrintf("Empty path should have been caught by canvas.\n"); 1511fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com#endif 1512fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com if (GrIsFillInverted(fill)) { 1513fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com this->drawPaint(paint); 1514fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 1515fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com return; 1516fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 1517fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com 151827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory); 1519d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com 1520289533ada623f2238a83771eec977f204f75994fbsalomon@google.com bool prAA = paint.fAntiAlias && !this->getRenderTarget()->isMultisampled(); 1521289533ada623f2238a83771eec977f204f75994fbsalomon@google.com 1522d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com // An Assumption here is that path renderer would use some form of tweaking 1523d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com // the src color (either the input alpha or in the frag shader) to implement 1524d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com // aa. If we have some future driver-mojo path AA that can do the right 1525d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com // thing WRT to the blend then we'll need some query on the PR. 1526d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com if (disable_coverage_aa_for_blend(target)) { 15271983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#if GR_DEBUG 1528979432ba2621b617f5e85a9ff48c6b6cd1504a0dbsalomon@google.com //GrPrintf("Turning off AA to correctly apply blend.\n"); 15291983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#endif 1530289533ada623f2238a83771eec977f204f75994fbsalomon@google.com prAA = false; 1531d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com } 1532289533ada623f2238a83771eec977f204f75994fbsalomon@google.com 1533289533ada623f2238a83771eec977f204f75994fbsalomon@google.com bool doOSAA = false; 1534289533ada623f2238a83771eec977f204f75994fbsalomon@google.com GrPathRenderer* pr = NULL; 1535289533ada623f2238a83771eec977f204f75994fbsalomon@google.com if (prAA) { 1536289533ada623f2238a83771eec977f204f75994fbsalomon@google.com pr = this->getPathRenderer(path, fill, true); 1537289533ada623f2238a83771eec977f204f75994fbsalomon@google.com if (NULL == pr) { 1538289533ada623f2238a83771eec977f204f75994fbsalomon@google.com prAA = false; 1539289533ada623f2238a83771eec977f204f75994fbsalomon@google.com doOSAA = this->doOffscreenAA(target, kHairLine_PathFill == fill); 1540289533ada623f2238a83771eec977f204f75994fbsalomon@google.com pr = this->getPathRenderer(path, fill, false); 1541289533ada623f2238a83771eec977f204f75994fbsalomon@google.com } 1542289533ada623f2238a83771eec977f204f75994fbsalomon@google.com } else { 1543289533ada623f2238a83771eec977f204f75994fbsalomon@google.com pr = this->getPathRenderer(path, fill, false); 1544289533ada623f2238a83771eec977f204f75994fbsalomon@google.com } 1545289533ada623f2238a83771eec977f204f75994fbsalomon@google.com 15463008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com if (NULL == pr) { 15471983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#if GR_DEBUG 15483008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com GrPrintf("Unable to find path renderer compatible with path.\n"); 15491983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#endif 15503008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com return; 15513008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com } 15523008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com 1553289533ada623f2238a83771eec977f204f75994fbsalomon@google.com GrPathRenderer::AutoClearPath arp(pr, target, &path, fill, prAA, translate); 155439ee0ffa72fbd5df6d3ec6db4fdad0c1bc3946fdbsalomon@google.com GrDrawState::StageMask stageMask = paint.getActiveStageMask(); 155506afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com 1556289533ada623f2238a83771eec977f204f75994fbsalomon@google.com if (doOSAA) { 15578295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com bool needsStencil = pr->requiresStencilPass(target, path, fill); 15588f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com const GrRenderTarget* rt = target->getDrawState().getRenderTarget(); 15598295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com // compute bounds as intersection of rt size, clip, and path 15608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrIRect bound = SkIRect::MakeWH(rt->width(), rt->height()); 15617ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com GrIRect clipIBounds; 15628295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com if (target->getClip().hasConservativeBounds()) { 15638295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com target->getClip().getConservativeBounds().roundOut(&clipIBounds); 156420efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com if (!bound.intersect(clipIBounds)) { 15658295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com return; 15668295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com } 15678295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com } 156807f3ee10d34f09342abb93d758b5e151ff78f7a5reed@google.com GrRect pathBounds = path.getBounds(); 156907f3ee10d34f09342abb93d758b5e151ff78f7a5reed@google.com if (!pathBounds.isEmpty()) { 15707ca72f33556e9d6c827b8c9493eb9531da5e347bbsalomon@google.com if (NULL != translate) { 15717ca72f33556e9d6c827b8c9493eb9531da5e347bbsalomon@google.com pathBounds.offset(*translate); 15727ca72f33556e9d6c827b8c9493eb9531da5e347bbsalomon@google.com } 15738f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com target->getDrawState().getViewMatrix().mapRect(&pathBounds, 15748f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com pathBounds); 1575919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com GrIRect pathIBounds; 15768295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com pathBounds.roundOut(&pathIBounds); 157720efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com if (!bound.intersect(pathIBounds)) { 15788295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com return; 15798295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com } 15808295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com } 1581919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com OffscreenRecord record; 1582d22b6e4351e552a8379d7781096d9e79feeae263tomhudson@google.com if (this->prepareForOffscreenAA(target, needsStencil, bound, 1583d22b6e4351e552a8379d7781096d9e79feeae263tomhudson@google.com pr, &record)) { 1584919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com for (int tx = 0; tx < record.fTileCountX; ++tx) { 1585919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com for (int ty = 0; ty < record.fTileCountY; ++ty) { 1586919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com this->setupOffscreenAAPass1(target, bound, tx, ty, &record); 1587ee435122d7dcb9cd4be4524004b0de282c42848bbsalomon@google.com pr->drawPath(0); 1588919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com this->doOffscreenAAPass2(target, paint, bound, tx, ty, &record); 1589919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com } 1590919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com } 1591d22b6e4351e552a8379d7781096d9e79feeae263tomhudson@google.com this->cleanupOffscreenAA(target, pr, &record); 1592fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com if (GrIsFillInverted(fill) && bound != clipIBounds) { 15937ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com GrDrawTarget::AutoDeviceCoordDraw adcd(target, stageMask); 15947ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com GrRect rect; 15957ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com if (clipIBounds.fTop < bound.fTop) { 15969d12f5c11b56ef51ba2c95db721ae7e5bab27023bsalomon@google.com rect.iset(clipIBounds.fLeft, clipIBounds.fTop, 15979d12f5c11b56ef51ba2c95db721ae7e5bab27023bsalomon@google.com clipIBounds.fRight, bound.fTop); 15987ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com target->drawSimpleRect(rect, NULL, stageMask); 15997ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com } 16007ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com if (clipIBounds.fLeft < bound.fLeft) { 16019d12f5c11b56ef51ba2c95db721ae7e5bab27023bsalomon@google.com rect.iset(clipIBounds.fLeft, bound.fTop, 16029d12f5c11b56ef51ba2c95db721ae7e5bab27023bsalomon@google.com bound.fLeft, bound.fBottom); 16037ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com target->drawSimpleRect(rect, NULL, stageMask); 16047ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com } 16057ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com if (clipIBounds.fRight > bound.fRight) { 16069d12f5c11b56ef51ba2c95db721ae7e5bab27023bsalomon@google.com rect.iset(bound.fRight, bound.fTop, 16079d12f5c11b56ef51ba2c95db721ae7e5bab27023bsalomon@google.com clipIBounds.fRight, bound.fBottom); 16087ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com target->drawSimpleRect(rect, NULL, stageMask); 16097ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com } 16107ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com if (clipIBounds.fBottom > bound.fBottom) { 16119d12f5c11b56ef51ba2c95db721ae7e5bab27023bsalomon@google.com rect.iset(clipIBounds.fLeft, bound.fBottom, 16129d12f5c11b56ef51ba2c95db721ae7e5bab27023bsalomon@google.com clipIBounds.fRight, clipIBounds.fBottom); 16137ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com target->drawSimpleRect(rect, NULL, stageMask); 16147ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com } 16157ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com } 16168295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com return; 16178295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com } 1618ee435122d7dcb9cd4be4524004b0de282c42848bbsalomon@google.com } 1619ee435122d7dcb9cd4be4524004b0de282c42848bbsalomon@google.com pr->drawPath(stageMask); 162027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 16218295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com 162227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 162327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 16241f221a70214fa1ab87b8a32dd66facf485f318eebsalomon@google.combool GrContext::supportsShaders() const { 162518c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com return fGpu->getCaps().fShaderSupport; 16261f221a70214fa1ab87b8a32dd66facf485f318eebsalomon@google.com} 16271f221a70214fa1ab87b8a32dd66facf485f318eebsalomon@google.com 1628a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.comvoid GrContext::flush(int flagsBitfield) { 1629a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com if (kDiscard_FlushBit & flagsBitfield) { 1630a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com fDrawBuffer->reset(); 1631a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com } else { 1632c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com this->flushDrawBuffer(); 1633a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com } 1634a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com if (kForceCurrentRenderTarget_FlushBit & flagsBitfield) { 163527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fGpu->forceRenderTargetFlush(); 163627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 163727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 163827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 163927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::flushText() { 164027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (kText_DrawCategory == fLastDrawCategory) { 164127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com flushDrawBuffer(); 164227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 164327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 164427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 164527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::flushDrawBuffer() { 164627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#if BATCH_RECT_TO_RECT || DEFER_TEXT_RENDERING 164753a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com if (fDrawBuffer) { 164853a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com fDrawBuffer->playback(fGpu); 164953a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com fDrawBuffer->reset(); 165053a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com } 165127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#endif 165227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 165327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 16546f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.comvoid GrContext::internalWriteTexturePixels(GrTexture* texture, 16556f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com int left, int top, 16566f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com int width, int height, 16576f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com GrPixelConfig config, 16586f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com const void* buffer, 16596f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com size_t rowBytes, 16606f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com uint32_t flags) { 16616f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com SK_TRACE_EVENT0("GrContext::writeTexturePixels"); 1662bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(texture); 1663bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com 16646f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com if (!(kDontFlush_PixelOpsFlag & flags)) { 16656f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com this->flush(); 16666f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com } 16676f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com // TODO: use scratch texture to perform conversion 16686f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com if (GrPixelConfigIsUnpremultiplied(texture->config()) != 16696f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com GrPixelConfigIsUnpremultiplied(config)) { 16706f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com return; 16716f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com } 16726f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com 16736f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com fGpu->writeTexturePixels(texture, left, top, width, height, 16746f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com config, buffer, rowBytes); 16756f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com} 16766f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com 16776f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.combool GrContext::internalReadTexturePixels(GrTexture* texture, 16786f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com int left, int top, 16796f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com int width, int height, 16806f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com GrPixelConfig config, 16816f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com void* buffer, 16826f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com size_t rowBytes, 16836f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com uint32_t flags) { 1684278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com SK_TRACE_EVENT0("GrContext::readTexturePixels"); 1685bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(texture); 1686669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com 1687a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com // TODO: code read pixels for textures that aren't also rendertargets 1688669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com GrRenderTarget* target = texture->asRenderTarget(); 1689669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com if (NULL != target) { 16906f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com return this->internalReadRenderTargetPixels(target, 16916f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com left, top, width, height, 16926f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com config, buffer, rowBytes, 16936f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com flags); 1694669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com } else { 1695669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com return false; 1696669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com } 1697669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com} 1698669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com 16996f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.combool GrContext::internalReadRenderTargetPixels(GrRenderTarget* target, 17006f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com int left, int top, 17016f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com int width, int height, 17026f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com GrPixelConfig config, 17036f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com void* buffer, 17046f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com size_t rowBytes, 17056f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com uint32_t flags) { 1706278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com SK_TRACE_EVENT0("GrContext::readRenderTargetPixels"); 1707bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(target); 1708bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com 1709669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com if (NULL == target) { 17108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com target = fGpu->drawState()->getRenderTarget(); 1711c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com if (NULL == target) { 1712c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com return false; 1713c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } 1714c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } 1715c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 1716c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com // PM <-> UPM conversion requires a draw. Currently we only support drawing 1717c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com // into a UPM target, not reading from a UPM texture. Thus, UPM->PM is not 1718c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com // not supported at this time. 1719c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com if (GrPixelConfigIsUnpremultiplied(target->config()) && 1720c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com !GrPixelConfigIsUnpremultiplied(config)) { 1721c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com return false; 1722669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com } 1723669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com 17246f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com if (!(kDontFlush_PixelOpsFlag & flags)) { 17256f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com this->flush(); 17266f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com } 1727c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 1728c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com GrTexture* src = target->asTexture(); 17290a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com bool swapRAndB = NULL != src && 17300a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com fGpu->preferredReadPixelsConfig(config) == 17310a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com GrPixelConfigSwapRAndB(config); 1732c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 1733c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com bool flipY = NULL != src && 1734c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com fGpu->readPixelsWillPayForYFlip(target, left, top, 1735c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com width, height, config, 1736c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com rowBytes); 17370a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com bool alphaConversion = (!GrPixelConfigIsUnpremultiplied(target->config()) && 17380a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com GrPixelConfigIsUnpremultiplied(config)); 1739c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 17400a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com if (NULL == src && alphaConversion) { 17410a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com // we should fallback to cpu conversion here. This could happen when 17420a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com // we were given an external render target by the client that is not 17430a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com // also a texture (e.g. FBO 0 in GL) 17440a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com return false; 17450a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com } 17460a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com // we draw to a scratch texture if any of these conversion are applied 1747c4ff22a2965616629765b8ffe0e58f6d05f92fa3bsalomon@google.com GrAutoScratchTexture ast; 17480a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com if (flipY || swapRAndB || alphaConversion) { 17490a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com GrAssert(NULL != src); 17500a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com if (swapRAndB) { 17510a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com config = GrPixelConfigSwapRAndB(config); 17520a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com GrAssert(kUnknown_GrPixelConfig != config); 1753c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } 1754c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com // Make the scratch a render target because we don't have a robust 1755c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com // readTexturePixels as of yet (it calls this function). 1756c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com const GrTextureDesc desc = { 1757c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com kRenderTarget_GrTextureFlagBit, 1758c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com kNone_GrAALevel, 1759c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com width, height, 17605bc34f04fe70cdde702ac3bff1fea0ccb275d4a5bsalomon@google.com config 1761c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com }; 1762c4ff22a2965616629765b8ffe0e58f6d05f92fa3bsalomon@google.com 176356d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com // When a full readback is faster than a partial we could always make 176456d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com // the scratch exactly match the passed rect. However, if we see many 176556d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com // different size rectangles we will trash our texture cache and pay the 176656d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com // cost of creating and destroying many textures. So, we only request 176756d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com // an exact match when the caller is reading an entire RT. 176856d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com ScratchTexMatch match = kApprox_ScratchTexMatch; 176956d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com if (0 == left && 177056d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com 0 == top && 177156d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com target->width() == width && 177256d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com target->height() == height && 177356d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com fGpu->fullReadPixelsIsFasterThanPartial()) { 177456d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com match = kExact_ScratchTexMatch; 177556d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com } 177656d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com ast.set(this, desc, match); 1777c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com GrTexture* texture = ast.texture(); 1778c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com if (!texture) { 1779c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com return false; 1780c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } 1781c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com target = texture->asRenderTarget(); 1782c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com GrAssert(NULL != target); 1783c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 1784c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com GrDrawTarget::AutoStateRestore asr(fGpu); 17858f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = fGpu->drawState(); 17866b67e21b6549598254c1ffa4243bf32615d90fb6bsalomon@google.com reset_draw_state(drawState); 17878f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setRenderTarget(target); 1788c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 1789c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com GrMatrix matrix; 1790c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com if (flipY) { 1791c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com matrix.setTranslate(SK_Scalar1 * left, 1792c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com SK_Scalar1 * (top + height)); 1793c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com matrix.set(GrMatrix::kMScaleY, -GR_Scalar1); 1794c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } else { 1795c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com matrix.setTranslate(SK_Scalar1 *left, SK_Scalar1 *top); 1796c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } 1797c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com matrix.postIDiv(src->width(), src->height()); 17981e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com drawState->sampler(0)->reset(matrix); 17991e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com drawState->sampler(0)->setRAndBSwap(swapRAndB); 18008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setTexture(0, src); 1801c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com GrRect rect; 1802c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com rect.setXYWH(0, 0, SK_Scalar1 * width, SK_Scalar1 * height); 1803c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com fGpu->drawSimpleRect(rect, NULL, 0x1); 1804c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com left = 0; 1805c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com top = 0; 1806c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } 1807669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com return fGpu->readPixels(target, 1808c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com left, top, width, height, 1809c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com config, buffer, rowBytes, flipY); 181027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 181127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1812ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.orgvoid GrContext::copyTexture(GrTexture* src, GrRenderTarget* dst) { 1813ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org if (NULL == src || NULL == dst) { 1814ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org return; 1815ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org } 1816ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org ASSERT_OWNED_RESOURCE(src); 1817ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org 1818ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org GrDrawTarget::AutoStateRestore asr(fGpu); 18198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = fGpu->drawState(); 18206b67e21b6549598254c1ffa4243bf32615d90fb6bsalomon@google.com reset_draw_state(drawState); 18218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setRenderTarget(dst); 1822ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org GrMatrix sampleM; 1823ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org sampleM.setIDiv(src->width(), src->height()); 18248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setTexture(0, src); 18251e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com drawState->sampler(0)->reset(sampleM); 1826ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org SkRect rect = SkRect::MakeXYWH(0, 0, src->width(), src->height()); 1827ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org fGpu->drawSimpleRect(rect, NULL, 1 << 0); 1828ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org} 1829ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org 18306f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.comvoid GrContext::internalWriteRenderTargetPixels(GrRenderTarget* target, 18316f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com int left, int top, 18326f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com int width, int height, 18336f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com GrPixelConfig config, 18346f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com const void* buffer, 18356f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com size_t rowBytes, 18366f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com uint32_t flags) { 18376f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com SK_TRACE_EVENT0("GrContext::writeRenderTargetPixels"); 1838bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(target); 18396f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com 18406f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com if (NULL == target) { 18418f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com target = fGpu->drawState()->getRenderTarget(); 18426f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com if (NULL == target) { 18436f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com return; 18446f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com } 18456f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com } 184627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 184727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // TODO: when underlying api has a direct way to do this we should use it 184827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // (e.g. glDrawPixels on desktop GL). 184927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1850a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com // If the RT is also a texture and we don't have to do PM/UPM conversion 1851a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com // then take the texture path, which we expect to be at least as fast or 1852a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com // faster since it doesn't use an intermediate texture as we do below. 1853a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com 1854a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com#if !GR_MAC_BUILD 1855a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com // At least some drivers on the Mac get confused when glTexImage2D is called 1856a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com // on a texture attached to an FBO. The FBO still sees the old image. TODO: 1857a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com // determine what OS versions and/or HW is affected. 1858a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com if (NULL != target->asTexture() && 1859a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com GrPixelConfigIsUnpremultiplied(target->config()) == 1860a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com GrPixelConfigIsUnpremultiplied(config)) { 1861a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com 1862a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com this->internalWriteTexturePixels(target->asTexture(), 1863a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com left, top, width, height, 1864a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com config, buffer, rowBytes, flags); 1865a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com return; 1866a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com } 1867a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com#endif 1868a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com 1869a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com bool swapRAndB = fGpu->preferredReadPixelsConfig(config) == 1870a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com GrPixelConfigSwapRAndB(config); 1871a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com if (swapRAndB) { 1872a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com config = GrPixelConfigSwapRAndB(config); 1873a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com } 1874a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com 1875fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com const GrTextureDesc desc = { 18765bc34f04fe70cdde702ac3bff1fea0ccb275d4a5bsalomon@google.com kNone_GrTextureFlags, kNone_GrAALevel, width, height, config 187727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com }; 187850398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrAutoScratchTexture ast(this, desc); 187950398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrTexture* texture = ast.texture(); 188027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL == texture) { 188127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return; 188227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 18836f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com this->internalWriteTexturePixels(texture, 0, 0, width, height, 18846f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com config, buffer, rowBytes, flags); 188527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 188627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget::AutoStateRestore asr(fGpu); 18878f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = fGpu->drawState(); 18886b67e21b6549598254c1ffa4243bf32615d90fb6bsalomon@google.com reset_draw_state(drawState); 188927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 189027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrMatrix matrix; 189127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com matrix.setTranslate(GrIntToScalar(left), GrIntToScalar(top)); 18928f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setViewMatrix(matrix); 18938f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setRenderTarget(target); 18948f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setTexture(0, texture); 189527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 18965c63865b529eb5714e41419dfa23c70d26ff6e4ebsalomon@google.com matrix.setIDiv(texture->width(), texture->height()); 18971e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com drawState->sampler(0)->reset(GrSamplerState::kClamp_WrapMode, 18981e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com GrSamplerState::kNearest_Filter, 18991e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com matrix); 19001e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com drawState->sampler(0)->setRAndBSwap(swapRAndB); 190127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 190227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrVertexLayout layout = GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0); 190327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com static const int VCOUNT = 4; 19046513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com // TODO: Use GrGpu::drawRect here 190527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget::AutoReleaseGeometry geo(fGpu, layout, VCOUNT, 0); 190627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (!geo.succeeded()) { 19076513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com GrPrintf("Failed to get space for vertices!\n"); 190827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return; 190927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 191027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com ((GrPoint*)geo.vertices())->setIRectFan(0, 0, width, height); 191127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fGpu->drawNonIndexed(kTriangleFan_PrimitiveType, 0, VCOUNT); 191227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 191327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 191427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1915bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.comvoid GrContext::setPaint(const GrPaint& paint, GrDrawTarget* target) { 19168f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = target->drawState(); 191726c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 191826c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com for (int i = 0; i < GrPaint::kMaxTextures; ++i) { 191926c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com int s = i + GrPaint::kFirstTextureStage; 19208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setTexture(s, paint.getTexture(i)); 1921bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(paint.getTexture(i)); 19221e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com *drawState->sampler(s) = paint.getTextureSampler(i); 192326c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com } 192426c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 19258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setFirstCoverageStage(GrPaint::kFirstMaskStage); 192626c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 192726c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com for (int i = 0; i < GrPaint::kMaxMasks; ++i) { 192826c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com int s = i + GrPaint::kFirstMaskStage; 19298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setTexture(s, paint.getMask(i)); 1930bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(paint.getMask(i)); 19311e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com *drawState->sampler(s) = paint.getMaskSampler(i); 193226c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com } 193326c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 19348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setColor(paint.fColor); 193527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 193627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (paint.fDither) { 19378f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->enableState(GrDrawState::kDither_StateBit); 193827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 19398f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->disableState(GrDrawState::kDither_StateBit); 194027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 194127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (paint.fAntiAlias) { 19428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->enableState(GrDrawState::kHWAntialias_StateBit); 194327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 19448f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->disableState(GrDrawState::kHWAntialias_StateBit); 194527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 19466b67e21b6549598254c1ffa4243bf32615d90fb6bsalomon@google.com drawState->setBlendFunc(paint.fSrcBlendCoeff, paint.fDstBlendCoeff); 19478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setColorFilter(paint.fColorFilterColor, paint.fColorFilterXfermode); 1948d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com 1949d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com if (paint.getActiveMaskStageMask() && !target->canApplyCoverage()) { 1950d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com GrPrintf("Partial pixel coverage will be incorrectly blended.\n"); 1951d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com } 195227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 195327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1954de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.comGrDrawTarget* GrContext::prepareToDraw(const GrPaint& paint, 195527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com DrawCategory category) { 195627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (category != fLastDrawCategory) { 195727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com flushDrawBuffer(); 195827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fLastDrawCategory = category; 195927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 1960bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com this->setPaint(paint, fGpu); 196127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget* target = fGpu; 196227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com switch (category) { 196327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com case kText_DrawCategory: 196427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#if DEFER_TEXT_RENDERING 196527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target = fDrawBuffer; 196627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fDrawBuffer->initializeDrawStateAndClip(*fGpu); 196727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#else 196827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target = fGpu; 196927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#endif 197027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com break; 197127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com case kUnbuffered_DrawCategory: 197227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target = fGpu; 197327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com break; 197427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com case kBuffered_DrawCategory: 197527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target = fDrawBuffer; 197627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fDrawBuffer->initializeDrawStateAndClip(*fGpu); 197727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com break; 197827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 197927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return target; 198027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 198127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1982289533ada623f2238a83771eec977f204f75994fbsalomon@google.comGrPathRenderer* GrContext::getPathRenderer(const GrPath& path, 1983289533ada623f2238a83771eec977f204f75994fbsalomon@google.com GrPathFill fill, 1984289533ada623f2238a83771eec977f204f75994fbsalomon@google.com bool antiAlias) { 19853008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com if (NULL == fPathRendererChain) { 19863008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com fPathRendererChain = 19873008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com new GrPathRendererChain(this, GrPathRendererChain::kNone_UsageFlag); 19883008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com } 1989289533ada623f2238a83771eec977f204f75994fbsalomon@google.com return fPathRendererChain->getPathRenderer(fGpu->getCaps(), path, 1990289533ada623f2238a83771eec977f204f75994fbsalomon@google.com fill, antiAlias); 19913008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com} 19923008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com 199327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 199427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 199527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::setRenderTarget(GrRenderTarget* target) { 1996bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(target); 19978fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com this->flush(false); 19988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com fGpu->drawState()->setRenderTarget(target); 199927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 200027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 200127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comGrRenderTarget* GrContext::getRenderTarget() { 20028f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com return fGpu->drawState()->getRenderTarget(); 200327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 200427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 200527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comconst GrRenderTarget* GrContext::getRenderTarget() const { 20068f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com return fGpu->getDrawState().getRenderTarget(); 200727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 200827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 200927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comconst GrMatrix& GrContext::getMatrix() const { 20108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com return fGpu->getDrawState().getViewMatrix(); 201127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 201227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 201327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::setMatrix(const GrMatrix& m) { 20148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com fGpu->drawState()->setViewMatrix(m); 201527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 201627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 201727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::concatMatrix(const GrMatrix& m) const { 20188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com fGpu->drawState()->preConcatViewMatrix(m); 201927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 202027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 202127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comstatic inline intptr_t setOrClear(intptr_t bits, int shift, intptr_t pred) { 202227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com intptr_t mask = 1 << shift; 202327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (pred) { 202427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com bits |= mask; 202527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 202627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com bits &= ~mask; 202727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 202827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return bits; 202927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 203027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 203127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::resetStats() { 203227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fGpu->resetStats(); 203327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 203427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 203505ef510389950e1ae8dcba40e41e001db771b12dbsalomon@google.comconst GrGpuStats& GrContext::getStats() const { 203627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return fGpu->getStats(); 203727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 203827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 203927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::printStats() const { 204027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fGpu->printStats(); 204127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 204227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 2043583a1e38503ebd57ba9bd39a3fabe89bead8e76cbsalomon@google.comGrContext::GrContext(GrGpu* gpu) { 204427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fGpu = gpu; 204527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fGpu->ref(); 2046669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com fGpu->setContext(this); 20478fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 20483008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com fPathRendererChain = NULL; 2049dfe75bcf98b0c04535efbf7fe36492a7fb53c90dbsalomon@google.com 205050398bf7f1953e640e5529616e710cf540799731bsalomon@google.com fTextureCache = new GrResourceCache(MAX_TEXTURE_CACHE_COUNT, 205150398bf7f1953e640e5529616e710cf540799731bsalomon@google.com MAX_TEXTURE_CACHE_BYTES); 205227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fFontCache = new GrFontCache(fGpu); 205327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 205427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fLastDrawCategory = kUnbuffered_DrawCategory; 205527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 20568fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fDrawBuffer = NULL; 20578fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fDrawBufferVBAllocPool = NULL; 20588fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fDrawBufferIBAllocPool = NULL; 20598fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 2060205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com fAAFillRectIndexBuffer = NULL; 2061205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com fAAStrokeRectIndexBuffer = NULL; 2062919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com 206318c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com int gpuMaxOffscreen = gpu->getCaps().fMaxRenderTargetSize; 206418c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com if (!PREFER_MSAA_OFFSCREEN_AA || !gpu->getCaps().fFSAASupport) { 2065919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com gpuMaxOffscreen /= OFFSCREEN_SSAA_SCALE; 2066919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com } 2067919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com fMaxOffscreenAASize = GrMin(GR_MAX_OFFSCREEN_AA_SIZE, gpuMaxOffscreen); 2068205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 20698fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com this->setupDrawBuffer(); 20708fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com} 20718fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 20728fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.comvoid GrContext::setupDrawBuffer() { 20738fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 20748fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com GrAssert(NULL == fDrawBuffer); 20758fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com GrAssert(NULL == fDrawBufferVBAllocPool); 20768fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com GrAssert(NULL == fDrawBufferIBAllocPool); 20778fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 207827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#if DEFER_TEXT_RENDERING || BATCH_RECT_TO_RECT 2079de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com fDrawBufferVBAllocPool = 20808fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com new GrVertexBufferAllocPool(fGpu, false, 208127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com DRAW_BUFFER_VBPOOL_BUFFER_SIZE, 208227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com DRAW_BUFFER_VBPOOL_PREALLOC_BUFFERS); 2083de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com fDrawBufferIBAllocPool = 20848fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com new GrIndexBufferAllocPool(fGpu, false, 2085de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com DRAW_BUFFER_IBPOOL_BUFFER_SIZE, 208627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS); 208727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 2088471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com fDrawBuffer = new GrInOrderDrawBuffer(fGpu, 2089471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com fDrawBufferVBAllocPool, 209027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fDrawBufferIBAllocPool); 209127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#endif 209227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 209327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#if BATCH_RECT_TO_RECT 209427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fDrawBuffer->setQuadIndexBuffer(this->getQuadIndexBuffer()); 209527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#endif 209627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 209727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 209827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comGrDrawTarget* GrContext::getTextTarget(const GrPaint& paint) { 209927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget* target; 210027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#if DEFER_TEXT_RENDERING 210127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target = prepareToDraw(paint, kText_DrawCategory); 210227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#else 210327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target = prepareToDraw(paint, kUnbuffered_DrawCategory); 210427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#endif 2105bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com this->setPaint(paint, target); 210627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return target; 210727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 210827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 210927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comconst GrIndexBuffer* GrContext::getQuadIndexBuffer() const { 211027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return fGpu->getQuadIndexBuffer(); 211127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 2112dfe75bcf98b0c04535efbf7fe36492a7fb53c90dbsalomon@google.com 2113aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.orgvoid GrContext::convolveInX(GrTexture* texture, 2114aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org const SkRect& rect, 2115aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org const float* kernel, 2116aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org int kernelWidth) { 2117bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(texture); 2118bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com 21199962108c400dadcae913614e8a5ab781780981d8bsalomon@google.com float imageIncrement[2] = {1.0f / texture->width(), 0.0f}; 2120aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org convolve(texture, rect, imageIncrement, kernel, kernelWidth); 2121aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org} 2122aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org 2123aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.orgvoid GrContext::convolveInY(GrTexture* texture, 2124aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org const SkRect& rect, 2125aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org const float* kernel, 2126aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org int kernelWidth) { 2127bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(texture); 2128bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com 21299962108c400dadcae913614e8a5ab781780981d8bsalomon@google.com float imageIncrement[2] = {0.0f, 1.0f / texture->height()}; 2130aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org convolve(texture, rect, imageIncrement, kernel, kernelWidth); 2131aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org} 2132aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org 2133aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.orgvoid GrContext::convolve(GrTexture* texture, 2134aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org const SkRect& rect, 2135aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org float imageIncrement[2], 2136aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org const float* kernel, 2137aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org int kernelWidth) { 2138bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(texture); 2139bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com 2140027de5f922e8ad1acc5402829f716b8c513fdd8dsenorblanco@chromium.org GrDrawTarget::AutoStateRestore asr(fGpu); 21411e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com GrDrawState* drawState = fGpu->drawState(); 2142027de5f922e8ad1acc5402829f716b8c513fdd8dsenorblanco@chromium.org GrMatrix sampleM; 214360014ca38710d3fc265f4376b05c0fefd0e044cfsenorblanco@chromium.org sampleM.setIDiv(texture->width(), texture->height()); 21441e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com drawState->sampler(0)->reset(GrSamplerState::kClamp_WrapMode, 21451e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com GrSamplerState::kConvolution_Filter, 21461e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com sampleM); 21471e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com drawState->sampler(0)->setConvolutionParams(kernelWidth, 21481e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com kernel, 21491e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com imageIncrement); 21501e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com 21518f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setViewMatrix(GrMatrix::I()); 21528f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setTexture(0, texture); 21538f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setAlpha(0xFF); 21546b67e21b6549598254c1ffa4243bf32615d90fb6bsalomon@google.com drawState->setBlendFunc(kOne_BlendCoeff, kZero_BlendCoeff); 2155027de5f922e8ad1acc5402829f716b8c513fdd8dsenorblanco@chromium.org fGpu->drawSimpleRect(rect, NULL, 1 << 0); 2156027de5f922e8ad1acc5402829f716b8c513fdd8dsenorblanco@chromium.org} 2157c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 2158c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com/////////////////////////////////////////////////////////////////////////////// 2159