GrContext.cpp revision f864ec467dfd518e32f6e4d709fafe57f1b3dbc6
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 87150398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrTexture* src = record->fOffscreen0.texture(); 8728295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com int scale; 8738295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com 87426c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com enum { 87526c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com kOffscreenStage = GrPaint::kTotalStages, 87626c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com }; 87726c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 8788f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = target->drawState(); 8798f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 8806aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com if (OffscreenRecord::k4x4TwoPass_Downsample == record->fDownsample) { 88150398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrAssert(NULL != record->fOffscreen1.texture()); 8828295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com scale = 2; 88350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrRenderTarget* dst = record->fOffscreen1.texture()->asRenderTarget(); 8848f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 8858295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com // Do 2x2 downsample from first to second 8868f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setTexture(kOffscreenStage, src); 8878f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setRenderTarget(dst); 8888f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setViewMatrix(GrMatrix::I()); 8891e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com GrSamplerState* sampler = drawState->sampler(kOffscreenStage); 8901e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com sampler->reset(GrSamplerState::kClamp_WrapMode, filter); 891aa814fe4a148b05f9160a5f77cb4e630406ea62dbsalomon@google.com sampler->matrix()->setScale(scale * GR_Scalar1 / src->width(), 892aa814fe4a148b05f9160a5f77cb4e630406ea62dbsalomon@google.com scale * GR_Scalar1 / src->height()); 8939d12f5c11b56ef51ba2c95db721ae7e5bab27023bsalomon@google.com GrRect rect = SkRect::MakeWH(SkIntToScalar(scale * tileRect.width()), 8949d12f5c11b56ef51ba2c95db721ae7e5bab27023bsalomon@google.com SkIntToScalar(scale * tileRect.height())); 8958295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com target->drawSimpleRect(rect, NULL, 1 << kOffscreenStage); 8968295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com 89750398bf7f1953e640e5529616e710cf540799731bsalomon@google.com src = record->fOffscreen1.texture(); 8986aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com } else if (OffscreenRecord::kFSAA_Downsample == record->fDownsample) { 8998295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com scale = 1; 900919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com GrIRect rect = SkIRect::MakeWH(tileRect.width(), tileRect.height()); 9018295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com src->asRenderTarget()->overrideResolveRect(rect); 9026aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com } else { 9036aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com GrAssert(OffscreenRecord::k4x4SinglePass_Downsample == 9046aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com record->fDownsample); 9056aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com scale = 4; 9068295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com } 9078295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com 908919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com // setup for draw back to main RT, we use the original 909919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com // draw state setup by the caller plus an additional coverage 910919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com // stage to handle the AA resolve. Also, we use an identity 911919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com // view matrix and so pre-concat sampler matrices with view inv. 91226c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com int stageMask = paint.getActiveStageMask(); 91326c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 9148295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com target->restoreDrawState(record->fSavedState); 915237a461ec96918eef9bd9f61d4d63fc43968b3e8tomhudson@google.com target->setClip(record->fClip); 91626c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 91726c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com if (stageMask) { 9188295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com GrMatrix invVM; 9198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com if (drawState->getViewInverse(&invVM)) { 9208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->preConcatSamplerMatrices(stageMask, invVM); 9218295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com } 9228295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com } 923919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com // This is important when tiling, otherwise second tile's 924919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com // pass 1 view matrix will be incorrect. 9258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState::AutoViewMatrixRestore avmr(drawState, GrMatrix::I()); 9268295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com 9278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setTexture(kOffscreenStage, src); 9281e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com GrSamplerState* sampler = drawState->sampler(kOffscreenStage); 9291e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com sampler->reset(GrSamplerState::kClamp_WrapMode, filter); 930aa814fe4a148b05f9160a5f77cb4e630406ea62dbsalomon@google.com sampler->matrix()->setScale(scale * GR_Scalar1 / src->width(), 931aa814fe4a148b05f9160a5f77cb4e630406ea62dbsalomon@google.com scale * GR_Scalar1 / src->height()); 932aa814fe4a148b05f9160a5f77cb4e630406ea62dbsalomon@google.com sampler->matrix()->preTranslate(SkIntToScalar(-tileRect.fLeft), 933aa814fe4a148b05f9160a5f77cb4e630406ea62dbsalomon@google.com SkIntToScalar(-tileRect.fTop)); 93406afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com 93520efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com GrRect dstRect; 93626c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com int stages = (1 << kOffscreenStage) | stageMask; 937919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com dstRect.set(tileRect); 9388295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com target->drawSimpleRect(dstRect, NULL, stages); 939919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com} 94006afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com 941d22b6e4351e552a8379d7781096d9e79feeae263tomhudson@google.comvoid GrContext::cleanupOffscreenAA(GrDrawTarget* target, 942d22b6e4351e552a8379d7781096d9e79feeae263tomhudson@google.com GrPathRenderer* pr, 943d22b6e4351e552a8379d7781096d9e79feeae263tomhudson@google.com OffscreenRecord* record) { 9448295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com target->restoreDrawState(record->fSavedState); 94506afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com} 94606afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com 94706afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 94806afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com 94927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com/* create a triangle strip that strokes the specified triangle. There are 8 95027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com unique vertices, but we repreat the last 2 to close up. Alternatively we 95127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com could use an indices array, and then only send 8 verts, but not sure that 95227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com would be faster. 95327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com */ 954205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comstatic void setStrokeRectStrip(GrPoint verts[10], GrRect rect, 95527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrScalar width) { 95627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrScalar rad = GrScalarHalf(width); 957205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com rect.sort(); 95827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 95927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[0].set(rect.fLeft + rad, rect.fTop + rad); 96027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[1].set(rect.fLeft - rad, rect.fTop - rad); 96127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[2].set(rect.fRight - rad, rect.fTop + rad); 96227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[3].set(rect.fRight + rad, rect.fTop - rad); 96327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[4].set(rect.fRight - rad, rect.fBottom - rad); 96427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[5].set(rect.fRight + rad, rect.fBottom + rad); 96527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[6].set(rect.fLeft + rad, rect.fBottom - rad); 96627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[7].set(rect.fLeft - rad, rect.fBottom + rad); 96727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[8] = verts[0]; 96827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[9] = verts[1]; 96927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 97027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 971205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comstatic void setInsetFan(GrPoint* pts, size_t stride, 972205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com const GrRect& r, GrScalar dx, GrScalar dy) { 973205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com pts->setRectFan(r.fLeft + dx, r.fTop + dy, r.fRight - dx, r.fBottom - dy, stride); 974205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com} 975205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 976205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comstatic const uint16_t gFillAARectIdx[] = { 977205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 0, 1, 5, 5, 4, 0, 978205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1, 2, 6, 6, 5, 1, 979205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 2, 3, 7, 7, 6, 2, 980205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 3, 0, 4, 4, 7, 3, 981205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 4, 5, 6, 6, 7, 4, 982205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com}; 983205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 984205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comint GrContext::aaFillRectIndexCount() const { 985205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return GR_ARRAY_COUNT(gFillAARectIdx); 986205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com} 987205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 988205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comGrIndexBuffer* GrContext::aaFillRectIndexBuffer() { 989205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (NULL == fAAFillRectIndexBuffer) { 990205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com fAAFillRectIndexBuffer = fGpu->createIndexBuffer(sizeof(gFillAARectIdx), 991205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com false); 9929b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com if (NULL != fAAFillRectIndexBuffer) { 9939b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com #if GR_DEBUG 9949b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com bool updated = 9959b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com #endif 9969b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com fAAFillRectIndexBuffer->updateData(gFillAARectIdx, 9979b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com sizeof(gFillAARectIdx)); 9989b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com GR_DEBUGASSERT(updated); 9999b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com } 1000205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 1001205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return fAAFillRectIndexBuffer; 1002205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com} 1003205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1004205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comstatic const uint16_t gStrokeAARectIdx[] = { 1005205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 0 + 0, 1 + 0, 5 + 0, 5 + 0, 4 + 0, 0 + 0, 1006205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1 + 0, 2 + 0, 6 + 0, 6 + 0, 5 + 0, 1 + 0, 1007205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 2 + 0, 3 + 0, 7 + 0, 7 + 0, 6 + 0, 2 + 0, 1008205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 3 + 0, 0 + 0, 4 + 0, 4 + 0, 7 + 0, 3 + 0, 1009205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1010205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 0 + 4, 1 + 4, 5 + 4, 5 + 4, 4 + 4, 0 + 4, 1011205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1 + 4, 2 + 4, 6 + 4, 6 + 4, 5 + 4, 1 + 4, 1012205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 2 + 4, 3 + 4, 7 + 4, 7 + 4, 6 + 4, 2 + 4, 1013205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 3 + 4, 0 + 4, 4 + 4, 4 + 4, 7 + 4, 3 + 4, 1014205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1015205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 0 + 8, 1 + 8, 5 + 8, 5 + 8, 4 + 8, 0 + 8, 1016205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1 + 8, 2 + 8, 6 + 8, 6 + 8, 5 + 8, 1 + 8, 1017205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 2 + 8, 3 + 8, 7 + 8, 7 + 8, 6 + 8, 2 + 8, 1018205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 3 + 8, 0 + 8, 4 + 8, 4 + 8, 7 + 8, 3 + 8, 1019205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com}; 1020205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1021205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comint GrContext::aaStrokeRectIndexCount() const { 1022205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return GR_ARRAY_COUNT(gStrokeAARectIdx); 1023205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com} 1024205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1025205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comGrIndexBuffer* GrContext::aaStrokeRectIndexBuffer() { 1026205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (NULL == fAAStrokeRectIndexBuffer) { 1027205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com fAAStrokeRectIndexBuffer = fGpu->createIndexBuffer(sizeof(gStrokeAARectIdx), 1028205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com false); 10299b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com if (NULL != fAAStrokeRectIndexBuffer) { 10309b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com #if GR_DEBUG 10319b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com bool updated = 10329b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com #endif 10339b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com fAAStrokeRectIndexBuffer->updateData(gStrokeAARectIdx, 10349b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com sizeof(gStrokeAARectIdx)); 10359b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com GR_DEBUGASSERT(updated); 10369b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com } 1037205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 1038205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return fAAStrokeRectIndexBuffer; 1039205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com} 1040205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1041a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.comstatic GrVertexLayout aa_rect_layout(const GrDrawTarget* target, 1042a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com bool useCoverage) { 1043a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com GrVertexLayout layout = 0; 10449381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com for (int s = 0; s < GrDrawState::kNumStages; ++s) { 10458f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com if (NULL != target->getDrawState().getTexture(s)) { 1046a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com layout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(s); 1047a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com } 1048a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com } 1049a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com if (useCoverage) { 1050a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com layout |= GrDrawTarget::kCoverage_VertexLayoutBit; 1051a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com } else { 1052a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com layout |= GrDrawTarget::kColor_VertexLayoutBit; 1053a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com } 1054a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com return layout; 1055a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com} 1056a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com 1057205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comvoid GrContext::fillAARect(GrDrawTarget* target, 1058a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com const GrRect& devRect, 1059a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com bool useVertexCoverage) { 1060a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com GrVertexLayout layout = aa_rect_layout(target, useVertexCoverage); 1061205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1062205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com size_t vsize = GrDrawTarget::VertexSize(layout); 1063205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1064205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrDrawTarget::AutoReleaseGeometry geo(target, layout, 8, 0); 10656513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com if (!geo.succeeded()) { 10666513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com GrPrintf("Failed to get space for vertices!\n"); 10676513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com return; 10686513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com } 10699b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com GrIndexBuffer* indexBuffer = this->aaFillRectIndexBuffer(); 10709b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com if (NULL == indexBuffer) { 10719b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com GrPrintf("Failed to create index buffer!\n"); 10729b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com return; 10739b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com } 1074205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1075205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com intptr_t verts = reinterpret_cast<intptr_t>(geo.vertices()); 1076205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1077205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrPoint* fan0Pos = reinterpret_cast<GrPoint*>(verts); 1078205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrPoint* fan1Pos = reinterpret_cast<GrPoint*>(verts + 4 * vsize); 1079205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1080205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com setInsetFan(fan0Pos, vsize, devRect, -GR_ScalarHalf, -GR_ScalarHalf); 1081205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com setInsetFan(fan1Pos, vsize, devRect, GR_ScalarHalf, GR_ScalarHalf); 1082205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1083205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com verts += sizeof(GrPoint); 1084205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com for (int i = 0; i < 4; ++i) { 1085205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com *reinterpret_cast<GrColor*>(verts + i * vsize) = 0; 1086205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 1087205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1088a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com GrColor innerColor; 1089a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com if (useVertexCoverage) { 1090e10f6fdf76fa9b627cbb8471b58b13c457af83e8bsalomon@google.com innerColor = 0xffffffff; 1091a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com } else { 10928f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com innerColor = target->getDrawState().getColor(); 1093a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com } 1094a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com 1095205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com verts += 4 * vsize; 1096205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com for (int i = 0; i < 4; ++i) { 1097205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com *reinterpret_cast<GrColor*>(verts + i * vsize) = innerColor; 1098205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 1099205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 11009b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com target->setIndexSourceToBuffer(indexBuffer); 1101205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1102205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com target->drawIndexed(kTriangles_PrimitiveType, 0, 1103205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 0, 8, this->aaFillRectIndexCount()); 1104205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com} 1105205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1106a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.comvoid GrContext::strokeAARect(GrDrawTarget* target, 1107a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com const GrRect& devRect, 1108a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com const GrVec& devStrokeSize, 1109a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com bool useVertexCoverage) { 1110205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com const GrScalar& dx = devStrokeSize.fX; 1111205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com const GrScalar& dy = devStrokeSize.fY; 1112205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com const GrScalar rx = GrMul(dx, GR_ScalarHalf); 1113205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com const GrScalar ry = GrMul(dy, GR_ScalarHalf); 1114205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1115205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrScalar spare; 1116205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com { 1117205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrScalar w = devRect.width() - dx; 1118205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrScalar h = devRect.height() - dy; 1119205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com spare = GrMin(w, h); 1120205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 1121205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1122205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (spare <= 0) { 1123205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrRect r(devRect); 1124205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com r.inset(-rx, -ry); 1125a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com fillAARect(target, r, useVertexCoverage); 1126205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return; 1127205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 1128a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com GrVertexLayout layout = aa_rect_layout(target, useVertexCoverage); 1129205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com size_t vsize = GrDrawTarget::VertexSize(layout); 1130205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1131205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrDrawTarget::AutoReleaseGeometry geo(target, layout, 16, 0); 11326513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com if (!geo.succeeded()) { 11336513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com GrPrintf("Failed to get space for vertices!\n"); 11346513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com return; 11356513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com } 11369b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com GrIndexBuffer* indexBuffer = this->aaStrokeRectIndexBuffer(); 11379b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com if (NULL == indexBuffer) { 11389b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com GrPrintf("Failed to create index buffer!\n"); 11399b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com return; 11409b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com } 1141205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1142205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com intptr_t verts = reinterpret_cast<intptr_t>(geo.vertices()); 1143205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1144205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrPoint* fan0Pos = reinterpret_cast<GrPoint*>(verts); 1145205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrPoint* fan1Pos = reinterpret_cast<GrPoint*>(verts + 4 * vsize); 1146205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrPoint* fan2Pos = reinterpret_cast<GrPoint*>(verts + 8 * vsize); 1147205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrPoint* fan3Pos = reinterpret_cast<GrPoint*>(verts + 12 * vsize); 1148205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1149205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com setInsetFan(fan0Pos, vsize, devRect, -rx - GR_ScalarHalf, -ry - GR_ScalarHalf); 1150205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com setInsetFan(fan1Pos, vsize, devRect, -rx + GR_ScalarHalf, -ry + GR_ScalarHalf); 1151205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com setInsetFan(fan2Pos, vsize, devRect, rx - GR_ScalarHalf, ry - GR_ScalarHalf); 1152205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com setInsetFan(fan3Pos, vsize, devRect, rx + GR_ScalarHalf, ry + GR_ScalarHalf); 1153205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1154205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com verts += sizeof(GrPoint); 1155205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com for (int i = 0; i < 4; ++i) { 1156205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com *reinterpret_cast<GrColor*>(verts + i * vsize) = 0; 1157205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 1158205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1159a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com GrColor innerColor; 1160a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com if (useVertexCoverage) { 1161e10f6fdf76fa9b627cbb8471b58b13c457af83e8bsalomon@google.com innerColor = 0xffffffff; 1162a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com } else { 11638f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com innerColor = target->getDrawState().getColor(); 1164a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com } 1165205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com verts += 4 * vsize; 1166205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com for (int i = 0; i < 8; ++i) { 1167205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com *reinterpret_cast<GrColor*>(verts + i * vsize) = innerColor; 1168205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 1169205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1170205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com verts += 8 * vsize; 1171205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com for (int i = 0; i < 8; ++i) { 1172205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com *reinterpret_cast<GrColor*>(verts + i * vsize) = 0; 1173205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 1174205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 11759b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com target->setIndexSourceToBuffer(indexBuffer); 1176205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com target->drawIndexed(kTriangles_PrimitiveType, 1177205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 0, 0, 16, aaStrokeRectIndexCount()); 1178205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com} 1179205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 118020efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com/** 118120efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com * Returns true if the rects edges are integer-aligned. 118220efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com */ 118320efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.comstatic bool isIRect(const GrRect& r) { 118420efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com return GrScalarIsInt(r.fLeft) && GrScalarIsInt(r.fTop) && 118520efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com GrScalarIsInt(r.fRight) && GrScalarIsInt(r.fBottom); 118620efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com} 118720efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com 1188205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comstatic bool apply_aa_to_rect(GrDrawTarget* target, 1189205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com const GrRect& rect, 1190205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrScalar width, 1191205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com const GrMatrix* matrix, 1192205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrMatrix* combinedMatrix, 1193a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com GrRect* devRect, 1194a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com bool* useVertexCoverage) { 1195205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com // we use a simple alpha ramp to do aa on axis-aligned rects 1196205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com // do AA with alpha ramp if the caller requested AA, the rect 1197289533ada623f2238a83771eec977f204f75994fbsalomon@google.com // will be axis-aligned, and the rect won't land on integer coords. 1198d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com 1199a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com // we are keeping around the "tweak the alpha" trick because 1200a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com // it is our only hope for the fixed-pipe implementation. 1201a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com // In a shader implementation we can give a separate coverage input 1202289533ada623f2238a83771eec977f204f75994fbsalomon@google.com // TODO: remove this ugliness when we drop the fixed-pipe impl 1203a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com *useVertexCoverage = false; 1204d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com if (!target->canTweakAlphaForCoverage()) { 1205a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com if (target->getCaps().fSupportPerVertexCoverage) { 1206a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com if (disable_coverage_aa_for_blend(target)) { 12071983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#if GR_DEBUG 1208979432ba2621b617f5e85a9ff48c6b6cd1504a0dbsalomon@google.com //GrPrintf("Turning off AA to correctly apply blend.\n"); 12091983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#endif 1210a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com return false; 1211a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com } else { 1212a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com *useVertexCoverage = true; 1213a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com } 1214a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com } else { 1215a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com GrPrintf("Rect AA dropped because no support for coverage.\n"); 1216a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com return false; 1217a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com } 1218205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 12198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com const GrDrawState& drawState = target->getDrawState(); 12208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com if (drawState.getRenderTarget()->isMultisampled()) { 1221205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return false; 1222205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 1223205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1224471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com if (0 == width && target->willUseHWAALines()) { 1225205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return false; 1226205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 1227205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 12288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com if (!drawState.getViewMatrix().preservesAxisAlignment()) { 1229205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return false; 1230205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 1231205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1232205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (NULL != matrix && 1233205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com !matrix->preservesAxisAlignment()) { 1234205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return false; 1235205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 1236205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 12378f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com *combinedMatrix = drawState.getViewMatrix(); 1238205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (NULL != matrix) { 1239205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com combinedMatrix->preConcat(*matrix); 1240205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrAssert(combinedMatrix->preservesAxisAlignment()); 1241205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 1242205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1243205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com combinedMatrix->mapRect(devRect, rect); 1244205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com devRect->sort(); 1245205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1246205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (width < 0) { 124720efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com return !isIRect(*devRect); 1248205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } else { 1249205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return true; 1250205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 1251205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com} 1252205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 125327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::drawRect(const GrPaint& paint, 125427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrRect& rect, 125527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrScalar width, 125627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrMatrix* matrix) { 1257278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com SK_TRACE_EVENT0("GrContext::drawRect"); 125827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 125927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory); 126026c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com int stageMask = paint.getActiveStageMask(); 126127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1262205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrRect devRect = rect; 1263205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrMatrix combinedMatrix; 1264a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com bool useVertexCoverage; 1265289533ada623f2238a83771eec977f204f75994fbsalomon@google.com bool needAA = paint.fAntiAlias && 1266289533ada623f2238a83771eec977f204f75994fbsalomon@google.com !this->getRenderTarget()->isMultisampled(); 1267289533ada623f2238a83771eec977f204f75994fbsalomon@google.com bool doAA = needAA && apply_aa_to_rect(target, rect, width, matrix, 1268289533ada623f2238a83771eec977f204f75994fbsalomon@google.com &combinedMatrix, &devRect, 1269289533ada623f2238a83771eec977f204f75994fbsalomon@google.com &useVertexCoverage); 1270205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1271205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (doAA) { 12728f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawTarget::AutoDeviceCoordDraw adcd(target, stageMask); 1273205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (width >= 0) { 1274205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrVec strokeSize;; 1275205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (width > 0) { 1276205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com strokeSize.set(width, width); 1277cc4dac3dac215dc0dd56f7b30d07cc304671b033bsalomon@google.com combinedMatrix.mapVectors(&strokeSize, 1); 1278205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com strokeSize.setAbs(strokeSize); 1279205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } else { 1280205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com strokeSize.set(GR_Scalar1, GR_Scalar1); 1281205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 1282a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com strokeAARect(target, devRect, strokeSize, useVertexCoverage); 1283205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } else { 1284a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com fillAARect(target, devRect, useVertexCoverage); 1285205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 1286205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return; 1287205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 1288205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 128927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (width >= 0) { 129027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // TODO: consider making static vertex buffers for these cases. 129127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // Hairline could be done by just adding closing vertex to 129227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // unitSquareVertexBuffer() 129326c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com GrVertexLayout layout = PaintStageVertexLayoutBits(paint, NULL); 129426c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 129527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com static const int worstCaseVertCount = 10; 129627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget::AutoReleaseGeometry geo(target, layout, worstCaseVertCount, 0); 129727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 129827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (!geo.succeeded()) { 12996513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com GrPrintf("Failed to get space for vertices!\n"); 130027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return; 130127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 130227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 130327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrPrimitiveType primType; 130427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int vertCount; 130527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrPoint* vertex = geo.positions(); 130627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 130727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (width > 0) { 130827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertCount = 10; 130927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com primType = kTriangleStrip_PrimitiveType; 131027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com setStrokeRectStrip(vertex, rect, width); 131127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 131227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // hairline 131327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertCount = 5; 131427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com primType = kLineStrip_PrimitiveType; 131527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertex[0].set(rect.fLeft, rect.fTop); 131627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertex[1].set(rect.fRight, rect.fTop); 131727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertex[2].set(rect.fRight, rect.fBottom); 131827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertex[3].set(rect.fLeft, rect.fBottom); 131927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertex[4].set(rect.fLeft, rect.fTop); 132027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 132127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 13228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState::AutoViewMatrixRestore avmr; 132327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL != matrix) { 13248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = target->drawState(); 13258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com avmr.set(drawState); 13268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->preConcatViewMatrix(*matrix); 13278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->preConcatSamplerMatrices(stageMask, *matrix); 132827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 132927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 133027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target->drawNonIndexed(primType, 0, vertCount); 133127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 13328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com#if GR_STATIC_RECT_VB 133326c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com GrVertexLayout layout = PaintStageVertexLayoutBits(paint, NULL); 13346513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com const GrVertexBuffer* sqVB = fGpu->getUnitSquareVertexBuffer(); 13356513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com if (NULL == sqVB) { 13366513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com GrPrintf("Failed to create static rect vb.\n"); 13376513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com return; 13386513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com } 13396513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com target->setVertexSourceToBuffer(layout, sqVB); 13408f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = target->drawState(); 13418f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState::AutoViewMatrixRestore avmr(drawState); 134227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrMatrix m; 13438295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com m.setAll(rect.width(), 0, rect.fLeft, 1344205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 0, rect.height(), rect.fTop, 1345205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 0, 0, GrMatrix::I()[8]); 134627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 134727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL != matrix) { 134827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com m.postConcat(*matrix); 134927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 13508f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->preConcatViewMatrix(m); 13518f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->preConcatSamplerMatrices(stageMask, m); 135226c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 135327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target->drawNonIndexed(kTriangleFan_PrimitiveType, 0, 4); 13548f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com#else 135526c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com target->drawSimpleRect(rect, matrix, stageMask); 13568f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com#endif 135727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 135827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 135927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 136027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::drawRectToRect(const GrPaint& paint, 136127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrRect& dstRect, 136227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrRect& srcRect, 136327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrMatrix* dstMatrix, 136427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrMatrix* srcMatrix) { 1365278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com SK_TRACE_EVENT0("GrContext::drawRectToRect"); 136627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 136726c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com // srcRect refers to paint's first texture 136826c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com if (NULL == paint.getTexture(0)) { 136927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com drawRect(paint, dstRect, -1, dstMatrix); 137027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return; 137127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 1372de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com 137327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GR_STATIC_ASSERT(!BATCH_RECT_TO_RECT || !GR_STATIC_RECT_VB); 137427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 137527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#if GR_STATIC_RECT_VB 137627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory); 13778f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = target->drawState(); 137826c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com GrVertexLayout layout = PaintStageVertexLayoutBits(paint, NULL); 13798f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState::AutoViewMatrixRestore avmr(drawState); 138027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 138127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrMatrix m; 138227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 138327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com m.setAll(dstRect.width(), 0, dstRect.fLeft, 138427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 0, dstRect.height(), dstRect.fTop, 138527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 0, 0, GrMatrix::I()[8]); 138627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL != dstMatrix) { 138727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com m.postConcat(*dstMatrix); 138827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 13898f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->preConcatViewMatrix(m); 139027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 139126c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com // srcRect refers to first stage 139226c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com int otherStageMask = paint.getActiveStageMask() & 139326c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com (~(1 << GrPaint::kFirstTextureStage)); 139426c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com if (otherStageMask) { 13958f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->preConcatSamplerMatrices(otherStageMask, m); 139626c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com } 139726c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 139827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com m.setAll(srcRect.width(), 0, srcRect.fLeft, 139927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 0, srcRect.height(), srcRect.fTop, 140027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 0, 0, GrMatrix::I()[8]); 140127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL != srcMatrix) { 140227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com m.postConcat(*srcMatrix); 140327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 14048f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->sampler(GrPaint::kFirstTextureStage)->preConcatMatrix(m); 140527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 14066513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com const GrVertexBuffer* sqVB = fGpu->getUnitSquareVertexBuffer(); 14076513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com if (NULL == sqVB) { 14086513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com GrPrintf("Failed to create static rect vb.\n"); 14096513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com return; 14106513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com } 14116513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com target->setVertexSourceToBuffer(layout, sqVB); 141227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target->drawNonIndexed(kTriangleFan_PrimitiveType, 0, 4); 141327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#else 141427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 141527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget* target; 1416de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com#if BATCH_RECT_TO_RECT 141727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target = this->prepareToDraw(paint, kBuffered_DrawCategory); 1418de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com#else 141927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target = this->prepareToDraw(paint, kUnbuffered_DrawCategory); 142027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#endif 142127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 14229381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com const GrRect* srcRects[GrDrawState::kNumStages] = {NULL}; 14239381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com const GrMatrix* srcMatrices[GrDrawState::kNumStages] = {NULL}; 142427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com srcRects[0] = &srcRect; 142527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com srcMatrices[0] = srcMatrix; 142627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 142727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target->drawRect(dstRect, dstMatrix, 1, srcRects, srcMatrices); 142827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#endif 142927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 143027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 143127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::drawVertices(const GrPaint& paint, 143227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrPrimitiveType primitiveType, 143327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int vertexCount, 143427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrPoint positions[], 143527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrPoint texCoords[], 143627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrColor colors[], 143727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const uint16_t indices[], 143827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int indexCount) { 1439278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com SK_TRACE_EVENT0("GrContext::drawVertices"); 144027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 144127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget::AutoReleaseGeometry geo; 144227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 144327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory); 144427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 144526c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com bool hasTexCoords[GrPaint::kTotalStages] = { 144626c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com NULL != texCoords, // texCoordSrc provides explicit stage 0 coords 144726c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 0 // remaining stages use positions 144826c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com }; 144926c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 145026c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com GrVertexLayout layout = PaintStageVertexLayoutBits(paint, hasTexCoords); 145127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 145227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL != colors) { 145327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com layout |= GrDrawTarget::kColor_VertexLayoutBit; 145427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 145526c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com int vertexSize = GrDrawTarget::VertexSize(layout); 145627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 145727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (sizeof(GrPoint) != vertexSize) { 145827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (!geo.set(target, layout, vertexCount, 0)) { 14596513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com GrPrintf("Failed to get space for vertices!\n"); 146027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return; 146127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 14629381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com int texOffsets[GrDrawState::kMaxTexCoords]; 146327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int colorOffset; 146426c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com GrDrawTarget::VertexSizeAndOffsetsByIdx(layout, 146526c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com texOffsets, 1466aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com &colorOffset, 1467a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com NULL, 1468a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com NULL); 146927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com void* curVertex = geo.vertices(); 147027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 147127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com for (int i = 0; i < vertexCount; ++i) { 147227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com *((GrPoint*)curVertex) = positions[i]; 147327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 147427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (texOffsets[0] > 0) { 147527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com *(GrPoint*)((intptr_t)curVertex + texOffsets[0]) = texCoords[i]; 147627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 147727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (colorOffset > 0) { 147827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com *(GrColor*)((intptr_t)curVertex + colorOffset) = colors[i]; 147927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 148026c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com curVertex = (void*)((intptr_t)curVertex + vertexSize); 148127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 148227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 148327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target->setVertexSourceToArray(layout, positions, vertexCount); 148427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 148527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1486919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com // we don't currently apply offscreen AA to this path. Need improved 1487919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com // management of GrDrawTarget's geometry to avoid copying points per-tile. 1488a47a48dca5045d71cbc5de343404045209a13e15bsalomon@google.com 14898295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com if (NULL != indices) { 1490919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com target->setIndexSourceToArray(indices, indexCount); 14918295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com target->drawIndexed(primitiveType, 0, 0, vertexCount, indexCount); 149227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 14938295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com target->drawNonIndexed(primitiveType, 0, vertexCount); 14948295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com } 149527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 149627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 149706afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com/////////////////////////////////////////////////////////////////////////////// 149827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 149907f3ee10d34f09342abb93d758b5e151ff78f7a5reed@google.comvoid GrContext::drawPath(const GrPaint& paint, const GrPath& path, 150007f3ee10d34f09342abb93d758b5e151ff78f7a5reed@google.com GrPathFill fill, const GrPoint* translate) { 150127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1502fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com if (path.isEmpty()) { 1503fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com#if GR_DEBUG 1504fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com GrPrintf("Empty path should have been caught by canvas.\n"); 1505fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com#endif 1506fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com if (GrIsFillInverted(fill)) { 1507fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com this->drawPaint(paint); 1508fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 1509fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com return; 1510fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 1511fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com 151227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory); 1513d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com 1514289533ada623f2238a83771eec977f204f75994fbsalomon@google.com bool prAA = paint.fAntiAlias && !this->getRenderTarget()->isMultisampled(); 1515289533ada623f2238a83771eec977f204f75994fbsalomon@google.com 1516d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com // An Assumption here is that path renderer would use some form of tweaking 1517d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com // the src color (either the input alpha or in the frag shader) to implement 1518d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com // aa. If we have some future driver-mojo path AA that can do the right 1519d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com // thing WRT to the blend then we'll need some query on the PR. 1520d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com if (disable_coverage_aa_for_blend(target)) { 15211983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#if GR_DEBUG 1522979432ba2621b617f5e85a9ff48c6b6cd1504a0dbsalomon@google.com //GrPrintf("Turning off AA to correctly apply blend.\n"); 15231983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#endif 1524289533ada623f2238a83771eec977f204f75994fbsalomon@google.com prAA = false; 1525d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com } 1526289533ada623f2238a83771eec977f204f75994fbsalomon@google.com 1527289533ada623f2238a83771eec977f204f75994fbsalomon@google.com bool doOSAA = false; 1528289533ada623f2238a83771eec977f204f75994fbsalomon@google.com GrPathRenderer* pr = NULL; 1529289533ada623f2238a83771eec977f204f75994fbsalomon@google.com if (prAA) { 1530289533ada623f2238a83771eec977f204f75994fbsalomon@google.com pr = this->getPathRenderer(path, fill, true); 1531289533ada623f2238a83771eec977f204f75994fbsalomon@google.com if (NULL == pr) { 1532289533ada623f2238a83771eec977f204f75994fbsalomon@google.com prAA = false; 1533289533ada623f2238a83771eec977f204f75994fbsalomon@google.com doOSAA = this->doOffscreenAA(target, kHairLine_PathFill == fill); 1534289533ada623f2238a83771eec977f204f75994fbsalomon@google.com pr = this->getPathRenderer(path, fill, false); 1535289533ada623f2238a83771eec977f204f75994fbsalomon@google.com } 1536289533ada623f2238a83771eec977f204f75994fbsalomon@google.com } else { 1537289533ada623f2238a83771eec977f204f75994fbsalomon@google.com pr = this->getPathRenderer(path, fill, false); 1538289533ada623f2238a83771eec977f204f75994fbsalomon@google.com } 1539289533ada623f2238a83771eec977f204f75994fbsalomon@google.com 15403008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com if (NULL == pr) { 15411983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#if GR_DEBUG 15423008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com GrPrintf("Unable to find path renderer compatible with path.\n"); 15431983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#endif 15443008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com return; 15453008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com } 15463008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com 1547289533ada623f2238a83771eec977f204f75994fbsalomon@google.com GrPathRenderer::AutoClearPath arp(pr, target, &path, fill, prAA, translate); 154839ee0ffa72fbd5df6d3ec6db4fdad0c1bc3946fdbsalomon@google.com GrDrawState::StageMask stageMask = paint.getActiveStageMask(); 154906afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com 1550289533ada623f2238a83771eec977f204f75994fbsalomon@google.com if (doOSAA) { 15518295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com bool needsStencil = pr->requiresStencilPass(target, path, fill); 15528f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com const GrRenderTarget* rt = target->getDrawState().getRenderTarget(); 15538295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com // compute bounds as intersection of rt size, clip, and path 15548f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrIRect bound = SkIRect::MakeWH(rt->width(), rt->height()); 15557ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com GrIRect clipIBounds; 15568295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com if (target->getClip().hasConservativeBounds()) { 15578295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com target->getClip().getConservativeBounds().roundOut(&clipIBounds); 155820efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com if (!bound.intersect(clipIBounds)) { 15598295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com return; 15608295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com } 15618295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com } 156207f3ee10d34f09342abb93d758b5e151ff78f7a5reed@google.com GrRect pathBounds = path.getBounds(); 156307f3ee10d34f09342abb93d758b5e151ff78f7a5reed@google.com if (!pathBounds.isEmpty()) { 15647ca72f33556e9d6c827b8c9493eb9531da5e347bbsalomon@google.com if (NULL != translate) { 15657ca72f33556e9d6c827b8c9493eb9531da5e347bbsalomon@google.com pathBounds.offset(*translate); 15667ca72f33556e9d6c827b8c9493eb9531da5e347bbsalomon@google.com } 15678f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com target->getDrawState().getViewMatrix().mapRect(&pathBounds, 15688f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com pathBounds); 1569919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com GrIRect pathIBounds; 15708295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com pathBounds.roundOut(&pathIBounds); 157120efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com if (!bound.intersect(pathIBounds)) { 15728295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com return; 15738295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com } 15748295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com } 1575919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com OffscreenRecord record; 1576d22b6e4351e552a8379d7781096d9e79feeae263tomhudson@google.com if (this->prepareForOffscreenAA(target, needsStencil, bound, 1577d22b6e4351e552a8379d7781096d9e79feeae263tomhudson@google.com pr, &record)) { 1578919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com for (int tx = 0; tx < record.fTileCountX; ++tx) { 1579919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com for (int ty = 0; ty < record.fTileCountY; ++ty) { 1580919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com this->setupOffscreenAAPass1(target, bound, tx, ty, &record); 1581ee435122d7dcb9cd4be4524004b0de282c42848bbsalomon@google.com pr->drawPath(0); 1582919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com this->doOffscreenAAPass2(target, paint, bound, tx, ty, &record); 1583919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com } 1584919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com } 1585d22b6e4351e552a8379d7781096d9e79feeae263tomhudson@google.com this->cleanupOffscreenAA(target, pr, &record); 1586fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com if (GrIsFillInverted(fill) && bound != clipIBounds) { 15877ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com GrDrawTarget::AutoDeviceCoordDraw adcd(target, stageMask); 15887ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com GrRect rect; 15897ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com if (clipIBounds.fTop < bound.fTop) { 15909d12f5c11b56ef51ba2c95db721ae7e5bab27023bsalomon@google.com rect.iset(clipIBounds.fLeft, clipIBounds.fTop, 15919d12f5c11b56ef51ba2c95db721ae7e5bab27023bsalomon@google.com clipIBounds.fRight, bound.fTop); 15927ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com target->drawSimpleRect(rect, NULL, stageMask); 15937ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com } 15947ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com if (clipIBounds.fLeft < bound.fLeft) { 15959d12f5c11b56ef51ba2c95db721ae7e5bab27023bsalomon@google.com rect.iset(clipIBounds.fLeft, bound.fTop, 15969d12f5c11b56ef51ba2c95db721ae7e5bab27023bsalomon@google.com bound.fLeft, bound.fBottom); 15977ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com target->drawSimpleRect(rect, NULL, stageMask); 15987ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com } 15997ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com if (clipIBounds.fRight > bound.fRight) { 16009d12f5c11b56ef51ba2c95db721ae7e5bab27023bsalomon@google.com rect.iset(bound.fRight, bound.fTop, 16019d12f5c11b56ef51ba2c95db721ae7e5bab27023bsalomon@google.com clipIBounds.fRight, bound.fBottom); 16027ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com target->drawSimpleRect(rect, NULL, stageMask); 16037ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com } 16047ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com if (clipIBounds.fBottom > bound.fBottom) { 16059d12f5c11b56ef51ba2c95db721ae7e5bab27023bsalomon@google.com rect.iset(clipIBounds.fLeft, bound.fBottom, 16069d12f5c11b56ef51ba2c95db721ae7e5bab27023bsalomon@google.com clipIBounds.fRight, clipIBounds.fBottom); 16077ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com target->drawSimpleRect(rect, NULL, stageMask); 16087ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com } 16097ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com } 16108295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com return; 16118295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com } 1612ee435122d7dcb9cd4be4524004b0de282c42848bbsalomon@google.com } 1613ee435122d7dcb9cd4be4524004b0de282c42848bbsalomon@google.com pr->drawPath(stageMask); 161427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 16158295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com 161627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 161727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 16181f221a70214fa1ab87b8a32dd66facf485f318eebsalomon@google.combool GrContext::supportsShaders() const { 161918c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com return fGpu->getCaps().fShaderSupport; 16201f221a70214fa1ab87b8a32dd66facf485f318eebsalomon@google.com} 16211f221a70214fa1ab87b8a32dd66facf485f318eebsalomon@google.com 1622a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.comvoid GrContext::flush(int flagsBitfield) { 1623a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com if (kDiscard_FlushBit & flagsBitfield) { 1624a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com fDrawBuffer->reset(); 1625a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com } else { 1626c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com this->flushDrawBuffer(); 1627a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com } 1628a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com if (kForceCurrentRenderTarget_FlushBit & flagsBitfield) { 162927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fGpu->forceRenderTargetFlush(); 163027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 163127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 163227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 163327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::flushText() { 163427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (kText_DrawCategory == fLastDrawCategory) { 163527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com flushDrawBuffer(); 163627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 163727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 163827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 163927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::flushDrawBuffer() { 164027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#if BATCH_RECT_TO_RECT || DEFER_TEXT_RENDERING 164153a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com if (fDrawBuffer) { 164253a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com fDrawBuffer->playback(fGpu); 164353a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com fDrawBuffer->reset(); 164453a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com } 164527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#endif 164627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 164727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 16486f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.comvoid GrContext::internalWriteTexturePixels(GrTexture* texture, 16496f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com int left, int top, 16506f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com int width, int height, 16516f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com GrPixelConfig config, 16526f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com const void* buffer, 16536f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com size_t rowBytes, 16546f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com uint32_t flags) { 16556f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com SK_TRACE_EVENT0("GrContext::writeTexturePixels"); 1656bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(texture); 1657bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com 16586f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com if (!(kDontFlush_PixelOpsFlag & flags)) { 16596f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com this->flush(); 16606f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com } 16616f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com // TODO: use scratch texture to perform conversion 16626f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com if (GrPixelConfigIsUnpremultiplied(texture->config()) != 16636f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com GrPixelConfigIsUnpremultiplied(config)) { 16646f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com return; 16656f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com } 16666f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com 16676f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com fGpu->writeTexturePixels(texture, left, top, width, height, 16686f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com config, buffer, rowBytes); 16696f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com} 16706f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com 16716f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.combool GrContext::internalReadTexturePixels(GrTexture* texture, 16726f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com int left, int top, 16736f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com int width, int height, 16746f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com GrPixelConfig config, 16756f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com void* buffer, 16766f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com size_t rowBytes, 16776f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com uint32_t flags) { 1678278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com SK_TRACE_EVENT0("GrContext::readTexturePixels"); 1679bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(texture); 1680669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com 1681a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com // TODO: code read pixels for textures that aren't also rendertargets 1682669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com GrRenderTarget* target = texture->asRenderTarget(); 1683669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com if (NULL != target) { 16846f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com return this->internalReadRenderTargetPixels(target, 16856f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com left, top, width, height, 16866f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com config, buffer, rowBytes, 16876f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com flags); 1688669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com } else { 1689669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com return false; 1690669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com } 1691669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com} 1692669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com 16936f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.combool GrContext::internalReadRenderTargetPixels(GrRenderTarget* target, 16946f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com int left, int top, 16956f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com int width, int height, 16966f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com GrPixelConfig config, 16976f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com void* buffer, 16986f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com size_t rowBytes, 16996f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com uint32_t flags) { 1700278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com SK_TRACE_EVENT0("GrContext::readRenderTargetPixels"); 1701bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(target); 1702bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com 1703669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com if (NULL == target) { 17048f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com target = fGpu->drawState()->getRenderTarget(); 1705c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com if (NULL == target) { 1706c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com return false; 1707c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } 1708c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } 1709c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 1710c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com // PM <-> UPM conversion requires a draw. Currently we only support drawing 1711c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com // into a UPM target, not reading from a UPM texture. Thus, UPM->PM is not 1712c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com // not supported at this time. 1713c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com if (GrPixelConfigIsUnpremultiplied(target->config()) && 1714c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com !GrPixelConfigIsUnpremultiplied(config)) { 1715c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com return false; 1716669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com } 1717669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com 17186f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com if (!(kDontFlush_PixelOpsFlag & flags)) { 17196f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com this->flush(); 17206f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com } 1721c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 1722c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com GrTexture* src = target->asTexture(); 17230a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com bool swapRAndB = NULL != src && 17240a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com fGpu->preferredReadPixelsConfig(config) == 17250a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com GrPixelConfigSwapRAndB(config); 1726c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 1727c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com bool flipY = NULL != src && 1728c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com fGpu->readPixelsWillPayForYFlip(target, left, top, 1729c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com width, height, config, 1730c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com rowBytes); 17310a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com bool alphaConversion = (!GrPixelConfigIsUnpremultiplied(target->config()) && 17320a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com GrPixelConfigIsUnpremultiplied(config)); 1733c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 17340a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com if (NULL == src && alphaConversion) { 17350a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com // we should fallback to cpu conversion here. This could happen when 17360a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com // we were given an external render target by the client that is not 17370a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com // also a texture (e.g. FBO 0 in GL) 17380a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com return false; 17390a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com } 17400a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com // we draw to a scratch texture if any of these conversion are applied 1741c4ff22a2965616629765b8ffe0e58f6d05f92fa3bsalomon@google.com GrAutoScratchTexture ast; 17420a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com if (flipY || swapRAndB || alphaConversion) { 17430a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com GrAssert(NULL != src); 17440a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com if (swapRAndB) { 17450a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com config = GrPixelConfigSwapRAndB(config); 17460a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com GrAssert(kUnknown_GrPixelConfig != config); 1747c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } 1748c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com // Make the scratch a render target because we don't have a robust 1749c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com // readTexturePixels as of yet (it calls this function). 1750c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com const GrTextureDesc desc = { 1751c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com kRenderTarget_GrTextureFlagBit, 1752c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com kNone_GrAALevel, 1753c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com width, height, 17545bc34f04fe70cdde702ac3bff1fea0ccb275d4a5bsalomon@google.com config 1755c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com }; 1756c4ff22a2965616629765b8ffe0e58f6d05f92fa3bsalomon@google.com 175756d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com // When a full readback is faster than a partial we could always make 175856d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com // the scratch exactly match the passed rect. However, if we see many 175956d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com // different size rectangles we will trash our texture cache and pay the 176056d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com // cost of creating and destroying many textures. So, we only request 176156d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com // an exact match when the caller is reading an entire RT. 176256d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com ScratchTexMatch match = kApprox_ScratchTexMatch; 176356d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com if (0 == left && 176456d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com 0 == top && 176556d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com target->width() == width && 176656d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com target->height() == height && 176756d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com fGpu->fullReadPixelsIsFasterThanPartial()) { 176856d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com match = kExact_ScratchTexMatch; 176956d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com } 177056d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com ast.set(this, desc, match); 1771c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com GrTexture* texture = ast.texture(); 1772c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com if (!texture) { 1773c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com return false; 1774c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } 1775c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com target = texture->asRenderTarget(); 1776c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com GrAssert(NULL != target); 1777c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 1778c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com GrDrawTarget::AutoStateRestore asr(fGpu); 17798f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = fGpu->drawState(); 17806b67e21b6549598254c1ffa4243bf32615d90fb6bsalomon@google.com reset_draw_state(drawState); 17818f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setRenderTarget(target); 1782c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 1783c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com GrMatrix matrix; 1784c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com if (flipY) { 1785c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com matrix.setTranslate(SK_Scalar1 * left, 1786c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com SK_Scalar1 * (top + height)); 1787c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com matrix.set(GrMatrix::kMScaleY, -GR_Scalar1); 1788c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } else { 1789c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com matrix.setTranslate(SK_Scalar1 *left, SK_Scalar1 *top); 1790c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } 1791c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com matrix.postIDiv(src->width(), src->height()); 17921e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com drawState->sampler(0)->reset(matrix); 17931e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com drawState->sampler(0)->setRAndBSwap(swapRAndB); 17948f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setTexture(0, src); 1795c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com GrRect rect; 1796c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com rect.setXYWH(0, 0, SK_Scalar1 * width, SK_Scalar1 * height); 1797c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com fGpu->drawSimpleRect(rect, NULL, 0x1); 1798c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com left = 0; 1799c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com top = 0; 1800c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } 1801669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com return fGpu->readPixels(target, 1802c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com left, top, width, height, 1803c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com config, buffer, rowBytes, flipY); 180427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 180527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1806ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.orgvoid GrContext::copyTexture(GrTexture* src, GrRenderTarget* dst) { 1807ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org if (NULL == src || NULL == dst) { 1808ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org return; 1809ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org } 1810ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org ASSERT_OWNED_RESOURCE(src); 1811ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org 1812ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org GrDrawTarget::AutoStateRestore asr(fGpu); 18138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = fGpu->drawState(); 18146b67e21b6549598254c1ffa4243bf32615d90fb6bsalomon@google.com reset_draw_state(drawState); 18158f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setRenderTarget(dst); 1816ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org GrMatrix sampleM; 1817ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org sampleM.setIDiv(src->width(), src->height()); 18188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setTexture(0, src); 18191e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com drawState->sampler(0)->reset(sampleM); 1820ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org SkRect rect = SkRect::MakeXYWH(0, 0, src->width(), src->height()); 1821ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org fGpu->drawSimpleRect(rect, NULL, 1 << 0); 1822ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org} 1823ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org 18246f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.comvoid GrContext::internalWriteRenderTargetPixels(GrRenderTarget* target, 18256f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com int left, int top, 18266f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com int width, int height, 18276f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com GrPixelConfig config, 18286f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com const void* buffer, 18296f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com size_t rowBytes, 18306f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com uint32_t flags) { 18316f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com SK_TRACE_EVENT0("GrContext::writeRenderTargetPixels"); 1832bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(target); 18336f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com 18346f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com if (NULL == target) { 18358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com target = fGpu->drawState()->getRenderTarget(); 18366f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com if (NULL == target) { 18376f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com return; 18386f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com } 18396f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com } 184027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 184127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // TODO: when underlying api has a direct way to do this we should use it 184227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // (e.g. glDrawPixels on desktop GL). 184327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1844a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com // If the RT is also a texture and we don't have to do PM/UPM conversion 1845a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com // then take the texture path, which we expect to be at least as fast or 1846a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com // faster since it doesn't use an intermediate texture as we do below. 1847a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com 1848a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com#if !GR_MAC_BUILD 1849a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com // At least some drivers on the Mac get confused when glTexImage2D is called 1850a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com // on a texture attached to an FBO. The FBO still sees the old image. TODO: 1851a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com // determine what OS versions and/or HW is affected. 1852a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com if (NULL != target->asTexture() && 1853a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com GrPixelConfigIsUnpremultiplied(target->config()) == 1854a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com GrPixelConfigIsUnpremultiplied(config)) { 1855a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com 1856a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com this->internalWriteTexturePixels(target->asTexture(), 1857a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com left, top, width, height, 1858a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com config, buffer, rowBytes, flags); 1859a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com return; 1860a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com } 1861a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com#endif 1862a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com 1863a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com bool swapRAndB = fGpu->preferredReadPixelsConfig(config) == 1864a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com GrPixelConfigSwapRAndB(config); 1865a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com if (swapRAndB) { 1866a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com config = GrPixelConfigSwapRAndB(config); 1867a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com } 1868a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com 1869fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com const GrTextureDesc desc = { 18705bc34f04fe70cdde702ac3bff1fea0ccb275d4a5bsalomon@google.com kNone_GrTextureFlags, kNone_GrAALevel, width, height, config 187127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com }; 187250398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrAutoScratchTexture ast(this, desc); 187350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrTexture* texture = ast.texture(); 187427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL == texture) { 187527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return; 187627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 18776f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com this->internalWriteTexturePixels(texture, 0, 0, width, height, 18786f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com config, buffer, rowBytes, flags); 187927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 188027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget::AutoStateRestore asr(fGpu); 18818f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = fGpu->drawState(); 18826b67e21b6549598254c1ffa4243bf32615d90fb6bsalomon@google.com reset_draw_state(drawState); 188327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 188427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrMatrix matrix; 188527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com matrix.setTranslate(GrIntToScalar(left), GrIntToScalar(top)); 18868f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setViewMatrix(matrix); 18878f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setRenderTarget(target); 18888f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setTexture(0, texture); 188927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 18905c63865b529eb5714e41419dfa23c70d26ff6e4ebsalomon@google.com matrix.setIDiv(texture->width(), texture->height()); 18911e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com drawState->sampler(0)->reset(GrSamplerState::kClamp_WrapMode, 18921e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com GrSamplerState::kNearest_Filter, 18931e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com matrix); 18941e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com drawState->sampler(0)->setRAndBSwap(swapRAndB); 189527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 189627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrVertexLayout layout = GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0); 189727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com static const int VCOUNT = 4; 18986513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com // TODO: Use GrGpu::drawRect here 189927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget::AutoReleaseGeometry geo(fGpu, layout, VCOUNT, 0); 190027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (!geo.succeeded()) { 19016513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com GrPrintf("Failed to get space for vertices!\n"); 190227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return; 190327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 190427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com ((GrPoint*)geo.vertices())->setIRectFan(0, 0, width, height); 190527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fGpu->drawNonIndexed(kTriangleFan_PrimitiveType, 0, VCOUNT); 190627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 190727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 190827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1909bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.comvoid GrContext::setPaint(const GrPaint& paint, GrDrawTarget* target) { 19108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = target->drawState(); 191126c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 191226c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com for (int i = 0; i < GrPaint::kMaxTextures; ++i) { 191326c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com int s = i + GrPaint::kFirstTextureStage; 19148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setTexture(s, paint.getTexture(i)); 1915bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(paint.getTexture(i)); 1916f864ec467dfd518e32f6e4d709fafe57f1b3dbc6bsalomon@google.com if (paint.getTexture(i)) { 1917f864ec467dfd518e32f6e4d709fafe57f1b3dbc6bsalomon@google.com *drawState->sampler(s) = paint.getTextureSampler(i); 1918f864ec467dfd518e32f6e4d709fafe57f1b3dbc6bsalomon@google.com } 191926c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com } 192026c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 19218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setFirstCoverageStage(GrPaint::kFirstMaskStage); 192226c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 192326c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com for (int i = 0; i < GrPaint::kMaxMasks; ++i) { 192426c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com int s = i + GrPaint::kFirstMaskStage; 19258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setTexture(s, paint.getMask(i)); 1926bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(paint.getMask(i)); 1927f864ec467dfd518e32f6e4d709fafe57f1b3dbc6bsalomon@google.com if (paint.getMask(i)) { 1928f864ec467dfd518e32f6e4d709fafe57f1b3dbc6bsalomon@google.com *drawState->sampler(s) = paint.getMaskSampler(i); 1929f864ec467dfd518e32f6e4d709fafe57f1b3dbc6bsalomon@google.com } 193026c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com } 193126c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 19328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setColor(paint.fColor); 193327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 193427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (paint.fDither) { 19358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->enableState(GrDrawState::kDither_StateBit); 193627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 19378f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->disableState(GrDrawState::kDither_StateBit); 193827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 193927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (paint.fAntiAlias) { 19408f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->enableState(GrDrawState::kHWAntialias_StateBit); 194127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 19428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->disableState(GrDrawState::kHWAntialias_StateBit); 194327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 19446b67e21b6549598254c1ffa4243bf32615d90fb6bsalomon@google.com drawState->setBlendFunc(paint.fSrcBlendCoeff, paint.fDstBlendCoeff); 19458f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setColorFilter(paint.fColorFilterColor, paint.fColorFilterXfermode); 1946d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com 1947d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com if (paint.getActiveMaskStageMask() && !target->canApplyCoverage()) { 1948d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com GrPrintf("Partial pixel coverage will be incorrectly blended.\n"); 1949d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com } 195027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 195127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1952de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.comGrDrawTarget* GrContext::prepareToDraw(const GrPaint& paint, 195327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com DrawCategory category) { 195427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (category != fLastDrawCategory) { 195527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com flushDrawBuffer(); 195627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fLastDrawCategory = category; 195727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 1958bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com this->setPaint(paint, fGpu); 195927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget* target = fGpu; 196027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com switch (category) { 196127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com case kText_DrawCategory: 196227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#if DEFER_TEXT_RENDERING 196327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target = fDrawBuffer; 196427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fDrawBuffer->initializeDrawStateAndClip(*fGpu); 196527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#else 196627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target = fGpu; 196727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#endif 196827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com break; 196927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com case kUnbuffered_DrawCategory: 197027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target = fGpu; 197127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com break; 197227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com case kBuffered_DrawCategory: 197327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target = fDrawBuffer; 197427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fDrawBuffer->initializeDrawStateAndClip(*fGpu); 197527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com break; 197627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 197727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return target; 197827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 197927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1980289533ada623f2238a83771eec977f204f75994fbsalomon@google.comGrPathRenderer* GrContext::getPathRenderer(const GrPath& path, 1981289533ada623f2238a83771eec977f204f75994fbsalomon@google.com GrPathFill fill, 1982289533ada623f2238a83771eec977f204f75994fbsalomon@google.com bool antiAlias) { 19833008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com if (NULL == fPathRendererChain) { 19843008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com fPathRendererChain = 19853008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com new GrPathRendererChain(this, GrPathRendererChain::kNone_UsageFlag); 19863008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com } 1987289533ada623f2238a83771eec977f204f75994fbsalomon@google.com return fPathRendererChain->getPathRenderer(fGpu->getCaps(), path, 1988289533ada623f2238a83771eec977f204f75994fbsalomon@google.com fill, antiAlias); 19893008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com} 19903008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com 199127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 199227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 199327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::setRenderTarget(GrRenderTarget* target) { 1994bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(target); 19958fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com this->flush(false); 19968f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com fGpu->drawState()->setRenderTarget(target); 199727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 199827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 199927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comGrRenderTarget* GrContext::getRenderTarget() { 20008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com return fGpu->drawState()->getRenderTarget(); 200127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 200227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 200327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comconst GrRenderTarget* GrContext::getRenderTarget() const { 20048f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com return fGpu->getDrawState().getRenderTarget(); 200527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 200627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 200727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comconst GrMatrix& GrContext::getMatrix() const { 20088f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com return fGpu->getDrawState().getViewMatrix(); 200927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 201027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 201127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::setMatrix(const GrMatrix& m) { 20128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com fGpu->drawState()->setViewMatrix(m); 201327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 201427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 201527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::concatMatrix(const GrMatrix& m) const { 20168f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com fGpu->drawState()->preConcatViewMatrix(m); 201727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 201827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 201927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comstatic inline intptr_t setOrClear(intptr_t bits, int shift, intptr_t pred) { 202027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com intptr_t mask = 1 << shift; 202127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (pred) { 202227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com bits |= mask; 202327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 202427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com bits &= ~mask; 202527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 202627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return bits; 202727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 202827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 202927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::resetStats() { 203027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fGpu->resetStats(); 203127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 203227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 203305ef510389950e1ae8dcba40e41e001db771b12dbsalomon@google.comconst GrGpuStats& GrContext::getStats() const { 203427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return fGpu->getStats(); 203527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 203627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 203727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::printStats() const { 203827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fGpu->printStats(); 203927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 204027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 2041583a1e38503ebd57ba9bd39a3fabe89bead8e76cbsalomon@google.comGrContext::GrContext(GrGpu* gpu) { 204227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fGpu = gpu; 204327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fGpu->ref(); 2044669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com fGpu->setContext(this); 20458fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 20463008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com fPathRendererChain = NULL; 2047dfe75bcf98b0c04535efbf7fe36492a7fb53c90dbsalomon@google.com 204850398bf7f1953e640e5529616e710cf540799731bsalomon@google.com fTextureCache = new GrResourceCache(MAX_TEXTURE_CACHE_COUNT, 204950398bf7f1953e640e5529616e710cf540799731bsalomon@google.com MAX_TEXTURE_CACHE_BYTES); 205027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fFontCache = new GrFontCache(fGpu); 205127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 205227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fLastDrawCategory = kUnbuffered_DrawCategory; 205327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 20548fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fDrawBuffer = NULL; 20558fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fDrawBufferVBAllocPool = NULL; 20568fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fDrawBufferIBAllocPool = NULL; 20578fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 2058205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com fAAFillRectIndexBuffer = NULL; 2059205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com fAAStrokeRectIndexBuffer = NULL; 2060919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com 206118c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com int gpuMaxOffscreen = gpu->getCaps().fMaxRenderTargetSize; 206218c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com if (!PREFER_MSAA_OFFSCREEN_AA || !gpu->getCaps().fFSAASupport) { 2063919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com gpuMaxOffscreen /= OFFSCREEN_SSAA_SCALE; 2064919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com } 2065919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com fMaxOffscreenAASize = GrMin(GR_MAX_OFFSCREEN_AA_SIZE, gpuMaxOffscreen); 2066205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 20678fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com this->setupDrawBuffer(); 20688fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com} 20698fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 20708fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.comvoid GrContext::setupDrawBuffer() { 20718fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 20728fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com GrAssert(NULL == fDrawBuffer); 20738fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com GrAssert(NULL == fDrawBufferVBAllocPool); 20748fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com GrAssert(NULL == fDrawBufferIBAllocPool); 20758fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 207627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#if DEFER_TEXT_RENDERING || BATCH_RECT_TO_RECT 2077de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com fDrawBufferVBAllocPool = 20788fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com new GrVertexBufferAllocPool(fGpu, false, 207927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com DRAW_BUFFER_VBPOOL_BUFFER_SIZE, 208027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com DRAW_BUFFER_VBPOOL_PREALLOC_BUFFERS); 2081de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com fDrawBufferIBAllocPool = 20828fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com new GrIndexBufferAllocPool(fGpu, false, 2083de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com DRAW_BUFFER_IBPOOL_BUFFER_SIZE, 208427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS); 208527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 2086471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com fDrawBuffer = new GrInOrderDrawBuffer(fGpu, 2087471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com fDrawBufferVBAllocPool, 208827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fDrawBufferIBAllocPool); 208927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#endif 209027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 209127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#if BATCH_RECT_TO_RECT 209227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fDrawBuffer->setQuadIndexBuffer(this->getQuadIndexBuffer()); 209327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#endif 209427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 209527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 209627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comGrDrawTarget* GrContext::getTextTarget(const GrPaint& paint) { 209727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget* target; 209827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#if DEFER_TEXT_RENDERING 209927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target = prepareToDraw(paint, kText_DrawCategory); 210027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#else 210127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target = prepareToDraw(paint, kUnbuffered_DrawCategory); 210227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#endif 2103bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com this->setPaint(paint, target); 210427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return target; 210527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 210627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 210727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comconst GrIndexBuffer* GrContext::getQuadIndexBuffer() const { 210827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return fGpu->getQuadIndexBuffer(); 210927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 2110dfe75bcf98b0c04535efbf7fe36492a7fb53c90dbsalomon@google.com 2111aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.orgvoid GrContext::convolveInX(GrTexture* texture, 2112aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org const SkRect& rect, 2113aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org const float* kernel, 2114aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org int kernelWidth) { 2115bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(texture); 2116bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com 21179962108c400dadcae913614e8a5ab781780981d8bsalomon@google.com float imageIncrement[2] = {1.0f / texture->width(), 0.0f}; 2118aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org convolve(texture, rect, imageIncrement, kernel, kernelWidth); 2119aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org} 2120aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org 2121aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.orgvoid GrContext::convolveInY(GrTexture* texture, 2122aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org const SkRect& rect, 2123aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org const float* kernel, 2124aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org int kernelWidth) { 2125bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(texture); 2126bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com 21279962108c400dadcae913614e8a5ab781780981d8bsalomon@google.com float imageIncrement[2] = {0.0f, 1.0f / texture->height()}; 2128aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org convolve(texture, rect, imageIncrement, kernel, kernelWidth); 2129aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org} 2130aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org 2131aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.orgvoid GrContext::convolve(GrTexture* texture, 2132aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org const SkRect& rect, 2133aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org float imageIncrement[2], 2134aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org const float* kernel, 2135aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org int kernelWidth) { 2136bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(texture); 2137bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com 2138027de5f922e8ad1acc5402829f716b8c513fdd8dsenorblanco@chromium.org GrDrawTarget::AutoStateRestore asr(fGpu); 21391e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com GrDrawState* drawState = fGpu->drawState(); 2140027de5f922e8ad1acc5402829f716b8c513fdd8dsenorblanco@chromium.org GrMatrix sampleM; 214160014ca38710d3fc265f4376b05c0fefd0e044cfsenorblanco@chromium.org sampleM.setIDiv(texture->width(), texture->height()); 21421e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com drawState->sampler(0)->reset(GrSamplerState::kClamp_WrapMode, 21431e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com GrSamplerState::kConvolution_Filter, 21441e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com sampleM); 21451e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com drawState->sampler(0)->setConvolutionParams(kernelWidth, 21461e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com kernel, 21471e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com imageIncrement); 21481e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com 21498f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setViewMatrix(GrMatrix::I()); 21508f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setTexture(0, texture); 21518f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setAlpha(0xFF); 21526b67e21b6549598254c1ffa4243bf32615d90fb6bsalomon@google.com drawState->setBlendFunc(kOne_BlendCoeff, kZero_BlendCoeff); 2153027de5f922e8ad1acc5402829f716b8c513fdd8dsenorblanco@chromium.org fGpu->drawSimpleRect(rect, NULL, 1 << 0); 2154027de5f922e8ad1acc5402829f716b8c513fdd8dsenorblanco@chromium.org} 2155c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 2156c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com/////////////////////////////////////////////////////////////////////////////// 2157