GrContext.cpp revision 05054f1a78a697b507580d0025db6c90423e033f
127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc. 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com */ 827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 9ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 101fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com#include "GrContext.h" 111fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com 12278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com#include "GrBufferAllocPool.h" 13278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com#include "GrClipIterator.h" 1405ef510389950e1ae8dcba40e41e001db771b12dbsalomon@google.com#include "GrGpu.h" 1527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#include "GrIndexBuffer.h" 1627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#include "GrInOrderDrawBuffer.h" 1727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#include "GrPathRenderer.h" 18d22b6e4351e552a8379d7781096d9e79feeae263tomhudson@google.com#include "GrPathUtils.h" 1950398bf7f1953e640e5529616e710cf540799731bsalomon@google.com#include "GrResourceCache.h" 20558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com#include "GrStencilBuffer.h" 21278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com#include "GrTextStrike.h" 228c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com#include "SkTLazy.h" 230c8d93a94099dee2dff8da6000ded9ad59676488tomhudson@google.com#include "SkTrace.h" 2427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 2527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#define DEFER_TEXT_RENDERING 1 2627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 2727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#define BATCH_RECT_TO_RECT (1 && !GR_STATIC_RECT_VB) 2827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 29d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com// When we're using coverage AA but the blend is incompatible (given gpu 30d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com// limitations) should we disable AA or draw wrong? 31950d7a8d8def14efc98d12d6947347fde351b737bsalomon@google.com#define DISABLE_COVERAGE_AA_FOR_BLEND 1 32d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com 338ccadddfa78adbdbbdfa724247318436465a7378bsalomon@google.comstatic const size_t MAX_TEXTURE_CACHE_COUNT = 256; 348ccadddfa78adbdbbdfa724247318436465a7378bsalomon@google.comstatic const size_t MAX_TEXTURE_CACHE_BYTES = 16 * 1024 * 1024; 3527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 3627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comstatic const size_t DRAW_BUFFER_VBPOOL_BUFFER_SIZE = 1 << 18; 3727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comstatic const int DRAW_BUFFER_VBPOOL_PREALLOC_BUFFERS = 4; 3827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 3927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com// We are currently only batching Text and drawRectToRect, both 4027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com// of which use the quad index buffer. 4127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comstatic const size_t DRAW_BUFFER_IBPOOL_BUFFER_SIZE = 0; 4227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comstatic const int DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS = 0; 4327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 44bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com#define ASSERT_OWNED_RESOURCE(R) GrAssert(!(R) || (R)->getContext() == this) 45bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com 4605ef510389950e1ae8dcba40e41e001db771b12dbsalomon@google.comGrContext* GrContext::Create(GrEngine engine, 4705ef510389950e1ae8dcba40e41e001db771b12dbsalomon@google.com GrPlatform3DContext context3D) { 4827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrContext* ctx = NULL; 4927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrGpu* fGpu = GrGpu::Create(engine, context3D); 5027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL != fGpu) { 5127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com ctx = new GrContext(fGpu); 5227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fGpu->unref(); 5327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 5427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return ctx; 5527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 5627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 5727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comGrContext::~GrContext() { 588fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com this->flush(); 5927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com delete fTextureCache; 6027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com delete fFontCache; 6127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com delete fDrawBuffer; 6227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com delete fDrawBufferVBAllocPool; 63de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com delete fDrawBufferIBAllocPool; 643008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com 65205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrSafeUnref(fAAFillRectIndexBuffer); 66205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrSafeUnref(fAAStrokeRectIndexBuffer); 67205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com fGpu->unref(); 683008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com GrSafeUnref(fPathRendererChain); 6927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 7027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 718fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.comvoid GrContext::contextLost() { 7253a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com contextDestroyed(); 7353a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com this->setupDrawBuffer(); 7453a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com} 7553a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com 7653a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.comvoid GrContext::contextDestroyed() { 77205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com // abandon first to so destructors 78205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com // don't try to free the resources in the API. 79205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com fGpu->abandonResources(); 80205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 813008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com // a path renderer may be holding onto resources that 823008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com // are now unusable 833008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com GrSafeSetNull(fPathRendererChain); 843008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com 858fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com delete fDrawBuffer; 868fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fDrawBuffer = NULL; 87205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 888fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com delete fDrawBufferVBAllocPool; 898fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fDrawBufferVBAllocPool = NULL; 90205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 918fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com delete fDrawBufferIBAllocPool; 928fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fDrawBufferIBAllocPool = NULL; 938fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 94205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrSafeSetNull(fAAFillRectIndexBuffer); 95205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrSafeSetNull(fAAStrokeRectIndexBuffer); 96205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 978fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fTextureCache->removeAll(); 988fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fFontCache->freeAll(); 998fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fGpu->markContextDirty(); 1008fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com} 1018fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 1028fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.comvoid GrContext::resetContext() { 1038fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fGpu->markContextDirty(); 1048fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com} 1058fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 1068fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.comvoid GrContext::freeGpuResources() { 1078fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com this->flush(); 1088fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fTextureCache->removeAll(); 1098fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fFontCache->freeAll(); 1103008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com // a path renderer may be holding onto resources 1113008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com GrSafeSetNull(fPathRendererChain); 11227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 11327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 11405e70247c31ae927074ef27ea9893634a8dda543twiz@google.comsize_t GrContext::getGpuTextureCacheBytes() const { 11505e70247c31ae927074ef27ea9893634a8dda543twiz@google.com return fTextureCache->getCachedResourceBytes(); 11605e70247c31ae927074ef27ea9893634a8dda543twiz@google.com} 11705e70247c31ae927074ef27ea9893634a8dda543twiz@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, 16678d6cf9f434d3351b19de14f1eab424c23f0ab6dbsalomon@google.com int sampleCnt, 16750398bf7f1953e640e5529616e710cf540799731bsalomon@google.com bool scratch, 16850398bf7f1953e640e5529616e710cf540799731bsalomon@google.com uint32_t v[4]) { 16950398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GR_STATIC_ASSERT(sizeof(GrContext::TextureKey) == sizeof(uint64_t)); 17050398bf7f1953e640e5529616e710cf540799731bsalomon@google.com // we assume we only need 16 bits of width and height 17150398bf7f1953e640e5529616e710cf540799731bsalomon@google.com // assert that texture creation will fail anyway if this assumption 17250398bf7f1953e640e5529616e710cf540799731bsalomon@google.com // would cause key collisions. 17318c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com GrAssert(gpu->getCaps().fMaxTextureSize <= SK_MaxU16); 17450398bf7f1953e640e5529616e710cf540799731bsalomon@google.com v[0] = clientKey & 0xffffffffUL; 17550398bf7f1953e640e5529616e710cf540799731bsalomon@google.com v[1] = (clientKey >> 32) & 0xffffffffUL; 17650398bf7f1953e640e5529616e710cf540799731bsalomon@google.com v[2] = width | (height << 16); 17750398bf7f1953e640e5529616e710cf540799731bsalomon@google.com 17878d6cf9f434d3351b19de14f1eab424c23f0ab6dbsalomon@google.com v[3] = (sampleCnt << 24); 17978d6cf9f434d3351b19de14f1eab424c23f0ab6dbsalomon@google.com GrAssert(sampleCnt >= 0 && sampleCnt < 256); 18078d6cf9f434d3351b19de14f1eab424c23f0ab6dbsalomon@google.com 18118c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com if (!gpu->getCaps().fNPOTTextureTileSupport) { 182fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com bool isPow2 = GrIsPow2(width) && GrIsPow2(height); 183fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com 1841fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com bool tiled = NULL != sampler && 1851fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com ((sampler->getWrapX() != GrSamplerState::kClamp_WrapMode) || 1861fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com (sampler->getWrapY() != GrSamplerState::kClamp_WrapMode)); 187fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com 188fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com if (tiled && !isPow2) { 18950398bf7f1953e640e5529616e710cf540799731bsalomon@google.com v[3] |= kNPOTBit; 1901fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com if (GrSamplerState::kNearest_Filter != sampler->getFilter()) { 19150398bf7f1953e640e5529616e710cf540799731bsalomon@google.com v[3] |= kFilterBit; 192fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com } 193fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com } 194fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com } 195fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com 19650398bf7f1953e640e5529616e710cf540799731bsalomon@google.com if (scratch) { 19750398bf7f1953e640e5529616e710cf540799731bsalomon@google.com v[3] |= kScratchBit; 198fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com } 19950398bf7f1953e640e5529616e710cf540799731bsalomon@google.com 200558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com v[3] |= kTextureBit; 201558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com 20250398bf7f1953e640e5529616e710cf540799731bsalomon@google.com return v[3] & kNPOTBit; 20350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com} 204558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com 205558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com// we should never have more than one stencil buffer with same combo of 206558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com// (width,height,samplecount) 207558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.comvoid gen_stencil_key_values(int width, int height, 208558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com int sampleCnt, uint32_t v[4]) { 209558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com v[0] = width; 210558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com v[1] = height; 211558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com v[2] = sampleCnt; 212558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com v[3] = kStencilBufferBit; 213558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com} 214558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com 215558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.comvoid gen_stencil_key_values(const GrStencilBuffer* sb, 216558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com uint32_t v[4]) { 217558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com gen_stencil_key_values(sb->width(), sb->height(), 218558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com sb->numSamples(), v); 219558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com} 22082c7bd8f25682fcacfeea12ed899976504a767ffbsalomon@google.com 221fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com} 222fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com 2231fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.comGrContext::TextureCacheEntry GrContext::findAndLockTexture( 2241fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com TextureKey key, 2251fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com int width, 2261fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com int height, 2271fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com const GrSamplerState* sampler) { 22850398bf7f1953e640e5529616e710cf540799731bsalomon@google.com uint32_t v[4]; 22978d6cf9f434d3351b19de14f1eab424c23f0ab6dbsalomon@google.com gen_texture_key_values(fGpu, sampler, key, width, height, 0, false, v); 23050398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrResourceKey resourceKey(v); 231558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com return TextureCacheEntry(fTextureCache->findAndLock(resourceKey, 232558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com GrResourceCache::kNested_LockType)); 233558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com} 234558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com 235fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.combool GrContext::isTextureInCache(TextureKey key, 236fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com int width, 237fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com int height, 2381fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com const GrSamplerState* sampler) const { 239fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com uint32_t v[4]; 24078d6cf9f434d3351b19de14f1eab424c23f0ab6dbsalomon@google.com gen_texture_key_values(fGpu, sampler, key, width, height, 0, false, v); 241fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com GrResourceKey resourceKey(v); 242fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com return fTextureCache->hasKey(resourceKey); 243fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com} 244fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com 245558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.comGrResourceEntry* GrContext::addAndLockStencilBuffer(GrStencilBuffer* sb) { 246bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(sb); 247558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com uint32_t v[4]; 248558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com gen_stencil_key_values(sb, v); 249558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com GrResourceKey resourceKey(v); 250558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com return fTextureCache->createAndLock(resourceKey, sb); 251558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com} 252558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com 253558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.comGrStencilBuffer* GrContext::findStencilBuffer(int width, int height, 254558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com int sampleCnt) { 255558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com uint32_t v[4]; 256558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com gen_stencil_key_values(width, height, sampleCnt, v); 257558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com GrResourceKey resourceKey(v); 258558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com GrResourceEntry* entry = fTextureCache->findAndLock(resourceKey, 259558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com GrResourceCache::kSingle_LockType); 260558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com if (NULL != entry) { 261558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com GrStencilBuffer* sb = (GrStencilBuffer*) entry->resource(); 262558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com return sb; 263558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com } else { 264558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com return NULL; 265558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com } 266558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com} 267558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com 268558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.comvoid GrContext::unlockStencilBuffer(GrResourceEntry* sbEntry) { 269bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(sbEntry->resource()); 270558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com fTextureCache->unlock(sbEntry); 27127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 27227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 27327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comstatic void stretchImage(void* dst, 27427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int dstW, 27527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int dstH, 27627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com void* src, 27727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int srcW, 27827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int srcH, 27927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int bpp) { 28027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrFixed dx = (srcW << 16) / dstW; 28127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrFixed dy = (srcH << 16) / dstH; 28227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 28327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrFixed y = dy >> 1; 28427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 28527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int dstXLimit = dstW*bpp; 28627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com for (int j = 0; j < dstH; ++j) { 28727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrFixed x = dx >> 1; 28827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com void* srcRow = (uint8_t*)src + (y>>16)*srcW*bpp; 28927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com void* dstRow = (uint8_t*)dst + j*dstW*bpp; 29027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com for (int i = 0; i < dstXLimit; i += bpp) { 29127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com memcpy((uint8_t*) dstRow + i, 29227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com (uint8_t*) srcRow + (x>>16)*bpp, 29327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com bpp); 29427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com x += dx; 29527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 29627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com y += dy; 29727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 29827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 29927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 3001fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.comGrContext::TextureCacheEntry GrContext::createAndLockTexture( 3011fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com TextureKey key, 3021fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com const GrSamplerState* sampler, 3031fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com const GrTextureDesc& desc, 3041fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com void* srcData, 3051fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com size_t rowBytes) { 306278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com SK_TRACE_EVENT0("GrContext::createAndLockTexture"); 30727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 30827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#if GR_DUMP_TEXTURE_UPLOAD 30927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrPrintf("GrContext::createAndLockTexture [%d %d]\n", desc.fWidth, desc.fHeight); 31027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#endif 31127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 31250398bf7f1953e640e5529616e710cf540799731bsalomon@google.com TextureCacheEntry entry; 31350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com uint32_t v[4]; 31450398bf7f1953e640e5529616e710cf540799731bsalomon@google.com bool special = gen_texture_key_values(fGpu, sampler, key, 31578d6cf9f434d3351b19de14f1eab424c23f0ab6dbsalomon@google.com desc.fWidth, desc.fHeight, 31678d6cf9f434d3351b19de14f1eab424c23f0ab6dbsalomon@google.com desc.fSampleCnt, false, v); 31750398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrResourceKey resourceKey(v); 31850398bf7f1953e640e5529616e710cf540799731bsalomon@google.com 31927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (special) { 3201fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com GrAssert(NULL != sampler); 3211fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com TextureCacheEntry clampEntry = this->findAndLockTexture(key, 3221fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com desc.fWidth, 3231fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com desc.fHeight, 3241fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com NULL); 32527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 32650398bf7f1953e640e5529616e710cf540799731bsalomon@google.com if (NULL == clampEntry.texture()) { 3271fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com clampEntry = this->createAndLockTexture(key, NULL, desc, 3281fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com srcData, rowBytes); 32950398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrAssert(NULL != clampEntry.texture()); 33050398bf7f1953e640e5529616e710cf540799731bsalomon@google.com if (NULL == clampEntry.texture()) { 33150398bf7f1953e640e5529616e710cf540799731bsalomon@google.com return entry; 33227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 33327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 334fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com GrTextureDesc rtDesc = desc; 335fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com rtDesc.fFlags = rtDesc.fFlags | 336fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com kRenderTarget_GrTextureFlagBit | 337fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com kNoStencil_GrTextureFlagBit; 3389962108c400dadcae913614e8a5ab781780981d8bsalomon@google.com rtDesc.fWidth = GrNextPow2(GrMax(desc.fWidth, 64)); 3399962108c400dadcae913614e8a5ab781780981d8bsalomon@google.com rtDesc.fHeight = GrNextPow2(GrMax(desc.fHeight, 64)); 34027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 34127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrTexture* texture = fGpu->createTexture(rtDesc, NULL, 0); 34227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 34327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL != texture) { 34427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget::AutoStateRestore asr(fGpu); 3458f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = fGpu->drawState(); 34652a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com drawState->reset(); 3478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setRenderTarget(texture->asRenderTarget()); 3488f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setTexture(0, clampEntry.texture()); 34982c7bd8f25682fcacfeea12ed899976504a767ffbsalomon@google.com 3506aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com GrSamplerState::Filter filter; 3516aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com // if filtering is not desired then we want to ensure all 3526aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com // texels in the resampled image are copies of texels from 3536aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com // the original. 3541fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com if (GrSamplerState::kNearest_Filter == sampler->getFilter()) { 3556aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com filter = GrSamplerState::kNearest_Filter; 3566aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com } else { 3576aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com filter = GrSamplerState::kBilinear_Filter; 3586aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com } 3591e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com drawState->sampler(0)->reset(GrSamplerState::kClamp_WrapMode, 3601e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com filter); 36127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 36227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com static const GrVertexLayout layout = 36327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget::StageTexCoordVertexLayoutBit(0,0); 36427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget::AutoReleaseGeometry arg(fGpu, layout, 4, 0); 36527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 36627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (arg.succeeded()) { 36727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrPoint* verts = (GrPoint*) arg.vertices(); 36827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[0].setIRectFan(0, 0, 36927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com texture->width(), 37027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com texture->height(), 37127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 2*sizeof(GrPoint)); 37227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[1].setIRectFan(0, 0, 1, 1, 2*sizeof(GrPoint)); 37327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fGpu->drawNonIndexed(kTriangleFan_PrimitiveType, 37427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 0, 4); 37550398bf7f1953e640e5529616e710cf540799731bsalomon@google.com entry.set(fTextureCache->createAndLock(resourceKey, texture)); 37627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 3771da0746fa155cdca982ae8deb68cc64f540c92dfbsalomon@google.com texture->releaseRenderTarget(); 37827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 37927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // TODO: Our CPU stretch doesn't filter. But we create separate 38027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // stretched textures when the sampler state is either filtered or 38127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // not. Either implement filtered stretch blit on CPU or just create 38227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // one when FBO case fails. 38327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 384fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com rtDesc.fFlags = kNone_GrTextureFlags; 38527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // no longer need to clamp at min RT size. 38627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com rtDesc.fWidth = GrNextPow2(desc.fWidth); 38727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com rtDesc.fHeight = GrNextPow2(desc.fHeight); 38864c4fe4113424bcfab8b3e0c7049887fda5ab4ffbsalomon@google.com int bpp = GrBytesPerPixel(desc.fConfig); 3893582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com SkAutoSMalloc<128*128*4> stretchedPixels(bpp * 39027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com rtDesc.fWidth * 39127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com rtDesc.fHeight); 39227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com stretchImage(stretchedPixels.get(), rtDesc.fWidth, rtDesc.fHeight, 39327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com srcData, desc.fWidth, desc.fHeight, bpp); 39427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 39527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com size_t stretchedRowBytes = rtDesc.fWidth * bpp; 39627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 39727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrTexture* texture = fGpu->createTexture(rtDesc, 39827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com stretchedPixels.get(), 39927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com stretchedRowBytes); 40027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrAssert(NULL != texture); 40150398bf7f1953e640e5529616e710cf540799731bsalomon@google.com entry.set(fTextureCache->createAndLock(resourceKey, texture)); 40227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 40350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com fTextureCache->unlock(clampEntry.cacheEntry()); 40427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 40527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 40627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrTexture* texture = fGpu->createTexture(desc, srcData, rowBytes); 40727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL != texture) { 40850398bf7f1953e640e5529616e710cf540799731bsalomon@google.com entry.set(fTextureCache->createAndLock(resourceKey, texture)); 40927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 41027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 41127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return entry; 41227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 41327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 41450398bf7f1953e640e5529616e710cf540799731bsalomon@google.comnamespace { 41550398bf7f1953e640e5529616e710cf540799731bsalomon@google.cominline void gen_scratch_tex_key_values(const GrGpu* gpu, 41650398bf7f1953e640e5529616e710cf540799731bsalomon@google.com const GrTextureDesc& desc, 41750398bf7f1953e640e5529616e710cf540799731bsalomon@google.com uint32_t v[4]) { 41850398bf7f1953e640e5529616e710cf540799731bsalomon@google.com // Instead of a client-provided key of the texture contents 41950398bf7f1953e640e5529616e710cf540799731bsalomon@google.com // we create a key of from the descriptor. 42078d6cf9f434d3351b19de14f1eab424c23f0ab6dbsalomon@google.com GrContext::TextureKey descKey = (desc.fFlags << 8) | 42164c4fe4113424bcfab8b3e0c7049887fda5ab4ffbsalomon@google.com ((uint64_t) desc.fConfig << 32); 42250398bf7f1953e640e5529616e710cf540799731bsalomon@google.com // this code path isn't friendly to tiling with NPOT restricitons 42350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com // We just pass ClampNoFilter() 4241fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com gen_texture_key_values(gpu, NULL, descKey, desc.fWidth, 42578d6cf9f434d3351b19de14f1eab424c23f0ab6dbsalomon@google.com desc.fHeight, desc.fSampleCnt, true, v); 42650398bf7f1953e640e5529616e710cf540799731bsalomon@google.com} 42727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 42827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 42950398bf7f1953e640e5529616e710cf540799731bsalomon@google.comGrContext::TextureCacheEntry GrContext::lockScratchTexture( 43050398bf7f1953e640e5529616e710cf540799731bsalomon@google.com const GrTextureDesc& inDesc, 43150398bf7f1953e640e5529616e710cf540799731bsalomon@google.com ScratchTexMatch match) { 43250398bf7f1953e640e5529616e710cf540799731bsalomon@google.com 433b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com GrTextureDesc desc = inDesc; 43450398bf7f1953e640e5529616e710cf540799731bsalomon@google.com if (kExact_ScratchTexMatch != match) { 43550398bf7f1953e640e5529616e710cf540799731bsalomon@google.com // bin by pow2 with a reasonable min 43650398bf7f1953e640e5529616e710cf540799731bsalomon@google.com static const int MIN_SIZE = 256; 43750398bf7f1953e640e5529616e710cf540799731bsalomon@google.com desc.fWidth = GrMax(MIN_SIZE, GrNextPow2(desc.fWidth)); 43850398bf7f1953e640e5529616e710cf540799731bsalomon@google.com desc.fHeight = GrMax(MIN_SIZE, GrNextPow2(desc.fHeight)); 43950398bf7f1953e640e5529616e710cf540799731bsalomon@google.com } 440b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com 44150398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrResourceEntry* entry; 442b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com int origWidth = desc.fWidth; 443b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com int origHeight = desc.fHeight; 444b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com bool doubledW = false; 445b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com bool doubledH = false; 446b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com 447b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com do { 44850398bf7f1953e640e5529616e710cf540799731bsalomon@google.com uint32_t v[4]; 44950398bf7f1953e640e5529616e710cf540799731bsalomon@google.com gen_scratch_tex_key_values(fGpu, desc, v); 45050398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrResourceKey key(v); 451558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com entry = fTextureCache->findAndLock(key, 452558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com GrResourceCache::kNested_LockType); 453b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com // if we miss, relax the fit of the flags... 454b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com // then try doubling width... then height. 45550398bf7f1953e640e5529616e710cf540799731bsalomon@google.com if (NULL != entry || kExact_ScratchTexMatch == match) { 456b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com break; 457b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } 458b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com if (!(desc.fFlags & kRenderTarget_GrTextureFlagBit)) { 459b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fFlags = desc.fFlags | kRenderTarget_GrTextureFlagBit; 460b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } else if (desc.fFlags & kNoStencil_GrTextureFlagBit) { 461b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fFlags = desc.fFlags & ~kNoStencil_GrTextureFlagBit; 462b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } else if (!doubledW) { 463b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fFlags = inDesc.fFlags; 464b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fWidth *= 2; 465b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com doubledW = true; 466b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } else if (!doubledH) { 467b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fFlags = inDesc.fFlags; 468b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fWidth = origWidth; 469b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fHeight *= 2; 470b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com doubledH = true; 471b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } else { 472b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com break; 473b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } 474b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com 475b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } while (true); 476b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com 477b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com if (NULL == entry) { 478b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fFlags = inDesc.fFlags; 479b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fWidth = origWidth; 480b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fHeight = origHeight; 481b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com GrTexture* texture = fGpu->createTexture(desc, NULL, 0); 482b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com if (NULL != texture) { 48350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com uint32_t v[4]; 48450398bf7f1953e640e5529616e710cf540799731bsalomon@google.com gen_scratch_tex_key_values(fGpu, desc, v); 48550398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrResourceKey key(v); 486b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com entry = fTextureCache->createAndLock(key, texture); 487b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } 488b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } 489b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com 490b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com // If the caller gives us the same desc/sampler twice we don't want 491b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com // to return the same texture the second time (unless it was previously 492b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com // released). So we detach the entry from the cache and reattach at release. 493b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com if (NULL != entry) { 494b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com fTextureCache->detach(entry); 495b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } 49650398bf7f1953e640e5529616e710cf540799731bsalomon@google.com return TextureCacheEntry(entry); 497b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com} 498b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com 49950398bf7f1953e640e5529616e710cf540799731bsalomon@google.comvoid GrContext::unlockTexture(TextureCacheEntry entry) { 500bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(entry.texture()); 50150398bf7f1953e640e5529616e710cf540799731bsalomon@google.com // If this is a scratch texture we detached it from the cache 50250398bf7f1953e640e5529616e710cf540799731bsalomon@google.com // while it was locked (to avoid two callers simultaneously getting 50350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com // the same texture). 50450398bf7f1953e640e5529616e710cf540799731bsalomon@google.com if (kScratchBit & entry.cacheEntry()->key().getValue32(3)) { 50550398bf7f1953e640e5529616e710cf540799731bsalomon@google.com fTextureCache->reattachAndUnlock(entry.cacheEntry()); 506fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com } else { 50750398bf7f1953e640e5529616e710cf540799731bsalomon@google.com fTextureCache->unlock(entry.cacheEntry()); 508fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com } 50927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 51027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 511fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.comGrTexture* GrContext::createUncachedTexture(const GrTextureDesc& desc, 51227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com void* srcData, 51327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com size_t rowBytes) { 51427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return fGpu->createTexture(desc, srcData, rowBytes); 51527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 51627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 51727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::getTextureCacheLimits(int* maxTextures, 51827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com size_t* maxTextureBytes) const { 51927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fTextureCache->getLimits(maxTextures, maxTextureBytes); 52027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 52127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 52227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::setTextureCacheLimits(int maxTextures, size_t maxTextureBytes) { 52327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fTextureCache->setLimits(maxTextures, maxTextureBytes); 52427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 52527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 526919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.comint GrContext::getMaxTextureSize() const { 52718c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com return fGpu->getCaps().fMaxTextureSize; 528919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com} 529919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com 530919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.comint GrContext::getMaxRenderTargetSize() const { 53118c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com return fGpu->getCaps().fMaxRenderTargetSize; 53227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 53327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 53427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com/////////////////////////////////////////////////////////////////////////////// 53527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 536e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.comGrTexture* GrContext::createPlatformTexture(const GrPlatformTextureDesc& desc) { 537e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com return fGpu->createPlatformTexture(desc); 538e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com} 539e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com 540e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.comGrRenderTarget* GrContext::createPlatformRenderTarget(const GrPlatformRenderTargetDesc& desc) { 541e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com return fGpu->createPlatformRenderTarget(desc); 542e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com} 543e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com 5445877ffd5ea71a3ea70096d5c11c843798defa690bsalomon@google.com/////////////////////////////////////////////////////////////////////////////// 5455877ffd5ea71a3ea70096d5c11c843798defa690bsalomon@google.com 5461fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.combool GrContext::supportsIndex8PixelConfig(const GrSamplerState* sampler, 5471f221a70214fa1ab87b8a32dd66facf485f318eebsalomon@google.com int width, int height) const { 54818c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com const GrDrawTarget::Caps& caps = fGpu->getCaps(); 54918c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com if (!caps.f8BitPaletteSupport) { 55027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return false; 55127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 55227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 55327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com bool isPow2 = GrIsPow2(width) && GrIsPow2(height); 55427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 55527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (!isPow2) { 5561fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com bool tiled = NULL != sampler && 5571fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com (sampler->getWrapX() != GrSamplerState::kClamp_WrapMode || 5581fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com sampler->getWrapY() != GrSamplerState::kClamp_WrapMode); 55918c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com if (tiled && !caps.fNPOTTextureTileSupport) { 56027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return false; 56127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 56227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 56327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return true; 56427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 56527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 56627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 56727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 56805ef510389950e1ae8dcba40e41e001db771b12dbsalomon@google.comconst GrClip& GrContext::getClip() const { return fGpu->getClip(); } 56905ef510389950e1ae8dcba40e41e001db771b12dbsalomon@google.com 57027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::setClip(const GrClip& clip) { 57127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fGpu->setClip(clip); 5728f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com fGpu->drawState()->enableState(GrDrawState::kClip_StateBit); 57327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 57427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 57527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::setClip(const GrIRect& rect) { 57627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrClip clip; 577d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com clip.setFromIRect(rect); 57827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fGpu->setClip(clip); 57927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 58027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 58127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 58227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 5836aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.comvoid GrContext::clear(const GrIRect* rect, const GrColor color) { 584398109cc3e56b8122ad21c4d43a74a83be5b42a8bsalomon@google.com this->flush(); 5856aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com fGpu->clear(rect, color); 58627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 58727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 58827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::drawPaint(const GrPaint& paint) { 58927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // set rect to be big enough to fill the space, but not super-huge, so we 59027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // don't overflow fixed-point implementations 591d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com GrRect r; 592d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com r.setLTRB(0, 0, 593d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com GrIntToScalar(getRenderTarget()->width()), 594d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com GrIntToScalar(getRenderTarget()->height())); 59527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrMatrix inverse; 5968c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com SkTLazy<GrPaint> tmpPaint; 5978c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com const GrPaint* p = &paint; 5988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = fGpu->drawState(); 5998f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrAutoMatrix am; 6008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 6014f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com // We attempt to map r by the inverse matrix and draw that. mapRect will 6024f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com // map the four corners and bound them with a new rect. This will not 6034f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com // produce a correct result for some perspective matrices. 6048c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com if (!this->getMatrix().hasPerspective()) { 6058f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com if (!drawState->getViewInverse(&inverse)) { 6068c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com GrPrintf("Could not invert matrix"); 6078c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com return; 6088c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com } 60927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com inverse.mapRect(&r); 61027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 6118c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com if (paint.getActiveMaskStageMask() || paint.getActiveStageMask()) { 6128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com if (!drawState->getViewInverse(&inverse)) { 6138c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com GrPrintf("Could not invert matrix"); 6148c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com return; 6158c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com } 6168c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com tmpPaint.set(paint); 6178c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com tmpPaint.get()->preConcatActiveSamplerMatrices(inverse); 6188c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com p = tmpPaint.get(); 6198c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com } 6204f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com am.set(this, GrMatrix::I()); 62127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 6224f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com // by definition this fills the entire clip, no need for AA 6234f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com if (paint.fAntiAlias) { 6248c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com if (!tmpPaint.isValid()) { 6258c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com tmpPaint.set(paint); 6268c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com p = tmpPaint.get(); 6278c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com } 6288c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com GrAssert(p == tmpPaint.get()); 6298c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com tmpPaint.get()->fAntiAlias = false; 6304f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com } 6314f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com this->drawRect(*p, r); 63227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 63327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 634205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 635205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 636d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.comnamespace { 637d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.cominline bool disable_coverage_aa_for_blend(GrDrawTarget* target) { 638d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com return DISABLE_COVERAGE_AA_FOR_BLEND && !target->canApplyCoverage(); 639d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com} 640d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com} 641d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com 64206afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 64306afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com 64427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com/* create a triangle strip that strokes the specified triangle. There are 8 64527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com unique vertices, but we repreat the last 2 to close up. Alternatively we 64627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com could use an indices array, and then only send 8 verts, but not sure that 64727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com would be faster. 64827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com */ 649205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comstatic void setStrokeRectStrip(GrPoint verts[10], GrRect rect, 65027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrScalar width) { 65127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrScalar rad = GrScalarHalf(width); 652205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com rect.sort(); 65327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 65427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[0].set(rect.fLeft + rad, rect.fTop + rad); 65527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[1].set(rect.fLeft - rad, rect.fTop - rad); 65627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[2].set(rect.fRight - rad, rect.fTop + rad); 65727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[3].set(rect.fRight + rad, rect.fTop - rad); 65827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[4].set(rect.fRight - rad, rect.fBottom - rad); 65927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[5].set(rect.fRight + rad, rect.fBottom + rad); 66027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[6].set(rect.fLeft + rad, rect.fBottom - rad); 66127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[7].set(rect.fLeft - rad, rect.fBottom + rad); 66227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[8] = verts[0]; 66327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[9] = verts[1]; 66427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 66527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 666205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comstatic void setInsetFan(GrPoint* pts, size_t stride, 667205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com const GrRect& r, GrScalar dx, GrScalar dy) { 668205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com pts->setRectFan(r.fLeft + dx, r.fTop + dy, r.fRight - dx, r.fBottom - dy, stride); 669205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com} 670205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 671205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comstatic const uint16_t gFillAARectIdx[] = { 672205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 0, 1, 5, 5, 4, 0, 673205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1, 2, 6, 6, 5, 1, 674205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 2, 3, 7, 7, 6, 2, 675205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 3, 0, 4, 4, 7, 3, 676205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 4, 5, 6, 6, 7, 4, 677205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com}; 678205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 679205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comint GrContext::aaFillRectIndexCount() const { 680205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return GR_ARRAY_COUNT(gFillAARectIdx); 681205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com} 682205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 683205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comGrIndexBuffer* GrContext::aaFillRectIndexBuffer() { 684205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (NULL == fAAFillRectIndexBuffer) { 685205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com fAAFillRectIndexBuffer = fGpu->createIndexBuffer(sizeof(gFillAARectIdx), 686205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com false); 6879b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com if (NULL != fAAFillRectIndexBuffer) { 6889b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com #if GR_DEBUG 6899b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com bool updated = 6909b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com #endif 6919b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com fAAFillRectIndexBuffer->updateData(gFillAARectIdx, 6929b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com sizeof(gFillAARectIdx)); 6939b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com GR_DEBUGASSERT(updated); 6949b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com } 695205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 696205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return fAAFillRectIndexBuffer; 697205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com} 698205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 699205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comstatic const uint16_t gStrokeAARectIdx[] = { 700205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 0 + 0, 1 + 0, 5 + 0, 5 + 0, 4 + 0, 0 + 0, 701205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1 + 0, 2 + 0, 6 + 0, 6 + 0, 5 + 0, 1 + 0, 702205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 2 + 0, 3 + 0, 7 + 0, 7 + 0, 6 + 0, 2 + 0, 703205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 3 + 0, 0 + 0, 4 + 0, 4 + 0, 7 + 0, 3 + 0, 704205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 705205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 0 + 4, 1 + 4, 5 + 4, 5 + 4, 4 + 4, 0 + 4, 706205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1 + 4, 2 + 4, 6 + 4, 6 + 4, 5 + 4, 1 + 4, 707205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 2 + 4, 3 + 4, 7 + 4, 7 + 4, 6 + 4, 2 + 4, 708205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 3 + 4, 0 + 4, 4 + 4, 4 + 4, 7 + 4, 3 + 4, 709205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 710205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 0 + 8, 1 + 8, 5 + 8, 5 + 8, 4 + 8, 0 + 8, 711205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1 + 8, 2 + 8, 6 + 8, 6 + 8, 5 + 8, 1 + 8, 712205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 2 + 8, 3 + 8, 7 + 8, 7 + 8, 6 + 8, 2 + 8, 713205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 3 + 8, 0 + 8, 4 + 8, 4 + 8, 7 + 8, 3 + 8, 714205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com}; 715205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 716205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comint GrContext::aaStrokeRectIndexCount() const { 717205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return GR_ARRAY_COUNT(gStrokeAARectIdx); 718205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com} 719205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 720205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comGrIndexBuffer* GrContext::aaStrokeRectIndexBuffer() { 721205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (NULL == fAAStrokeRectIndexBuffer) { 722205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com fAAStrokeRectIndexBuffer = fGpu->createIndexBuffer(sizeof(gStrokeAARectIdx), 723205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com false); 7249b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com if (NULL != fAAStrokeRectIndexBuffer) { 7259b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com #if GR_DEBUG 7269b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com bool updated = 7279b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com #endif 7289b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com fAAStrokeRectIndexBuffer->updateData(gStrokeAARectIdx, 7299b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com sizeof(gStrokeAARectIdx)); 7309b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com GR_DEBUGASSERT(updated); 7319b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com } 732205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 733205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return fAAStrokeRectIndexBuffer; 734205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com} 735205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 736a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.comstatic GrVertexLayout aa_rect_layout(const GrDrawTarget* target, 737a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com bool useCoverage) { 738a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com GrVertexLayout layout = 0; 7399381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com for (int s = 0; s < GrDrawState::kNumStages; ++s) { 7408f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com if (NULL != target->getDrawState().getTexture(s)) { 741a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com layout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(s); 742a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com } 743a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com } 744a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com if (useCoverage) { 745a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com layout |= GrDrawTarget::kCoverage_VertexLayoutBit; 746a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com } else { 747a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com layout |= GrDrawTarget::kColor_VertexLayoutBit; 748a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com } 749a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com return layout; 750a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com} 751a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com 752205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comvoid GrContext::fillAARect(GrDrawTarget* target, 753a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com const GrRect& devRect, 754a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com bool useVertexCoverage) { 755a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com GrVertexLayout layout = aa_rect_layout(target, useVertexCoverage); 756205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 757205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com size_t vsize = GrDrawTarget::VertexSize(layout); 758205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 759205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrDrawTarget::AutoReleaseGeometry geo(target, layout, 8, 0); 7606513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com if (!geo.succeeded()) { 7616513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com GrPrintf("Failed to get space for vertices!\n"); 7626513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com return; 7636513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com } 7649b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com GrIndexBuffer* indexBuffer = this->aaFillRectIndexBuffer(); 7659b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com if (NULL == indexBuffer) { 7669b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com GrPrintf("Failed to create index buffer!\n"); 7679b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com return; 7689b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com } 769205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 770205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com intptr_t verts = reinterpret_cast<intptr_t>(geo.vertices()); 771205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 772205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrPoint* fan0Pos = reinterpret_cast<GrPoint*>(verts); 773205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrPoint* fan1Pos = reinterpret_cast<GrPoint*>(verts + 4 * vsize); 774205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 775205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com setInsetFan(fan0Pos, vsize, devRect, -GR_ScalarHalf, -GR_ScalarHalf); 776205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com setInsetFan(fan1Pos, vsize, devRect, GR_ScalarHalf, GR_ScalarHalf); 777205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 778205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com verts += sizeof(GrPoint); 779205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com for (int i = 0; i < 4; ++i) { 780205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com *reinterpret_cast<GrColor*>(verts + i * vsize) = 0; 781205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 782205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 783a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com GrColor innerColor; 784a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com if (useVertexCoverage) { 785e10f6fdf76fa9b627cbb8471b58b13c457af83e8bsalomon@google.com innerColor = 0xffffffff; 786a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com } else { 7878f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com innerColor = target->getDrawState().getColor(); 788a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com } 789a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com 790205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com verts += 4 * vsize; 791205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com for (int i = 0; i < 4; ++i) { 792205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com *reinterpret_cast<GrColor*>(verts + i * vsize) = innerColor; 793205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 794205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 7959b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com target->setIndexSourceToBuffer(indexBuffer); 796205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 797205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com target->drawIndexed(kTriangles_PrimitiveType, 0, 798205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 0, 8, this->aaFillRectIndexCount()); 799205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com} 800205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 801a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.comvoid GrContext::strokeAARect(GrDrawTarget* target, 802a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com const GrRect& devRect, 803a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com const GrVec& devStrokeSize, 804a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com bool useVertexCoverage) { 805205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com const GrScalar& dx = devStrokeSize.fX; 806205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com const GrScalar& dy = devStrokeSize.fY; 807205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com const GrScalar rx = GrMul(dx, GR_ScalarHalf); 808205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com const GrScalar ry = GrMul(dy, GR_ScalarHalf); 809205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 810205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrScalar spare; 811205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com { 812205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrScalar w = devRect.width() - dx; 813205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrScalar h = devRect.height() - dy; 814205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com spare = GrMin(w, h); 815205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 816205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 817205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (spare <= 0) { 818205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrRect r(devRect); 819205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com r.inset(-rx, -ry); 820a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com fillAARect(target, r, useVertexCoverage); 821205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return; 822205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 823a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com GrVertexLayout layout = aa_rect_layout(target, useVertexCoverage); 824205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com size_t vsize = GrDrawTarget::VertexSize(layout); 825205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 826205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrDrawTarget::AutoReleaseGeometry geo(target, layout, 16, 0); 8276513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com if (!geo.succeeded()) { 8286513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com GrPrintf("Failed to get space for vertices!\n"); 8296513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com return; 8306513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com } 8319b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com GrIndexBuffer* indexBuffer = this->aaStrokeRectIndexBuffer(); 8329b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com if (NULL == indexBuffer) { 8339b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com GrPrintf("Failed to create index buffer!\n"); 8349b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com return; 8359b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com } 836205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 837205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com intptr_t verts = reinterpret_cast<intptr_t>(geo.vertices()); 838205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 839205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrPoint* fan0Pos = reinterpret_cast<GrPoint*>(verts); 840205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrPoint* fan1Pos = reinterpret_cast<GrPoint*>(verts + 4 * vsize); 841205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrPoint* fan2Pos = reinterpret_cast<GrPoint*>(verts + 8 * vsize); 842205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrPoint* fan3Pos = reinterpret_cast<GrPoint*>(verts + 12 * vsize); 843205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 844205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com setInsetFan(fan0Pos, vsize, devRect, -rx - GR_ScalarHalf, -ry - GR_ScalarHalf); 845205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com setInsetFan(fan1Pos, vsize, devRect, -rx + GR_ScalarHalf, -ry + GR_ScalarHalf); 846205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com setInsetFan(fan2Pos, vsize, devRect, rx - GR_ScalarHalf, ry - GR_ScalarHalf); 847205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com setInsetFan(fan3Pos, vsize, devRect, rx + GR_ScalarHalf, ry + GR_ScalarHalf); 848205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 849205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com verts += sizeof(GrPoint); 850205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com for (int i = 0; i < 4; ++i) { 851205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com *reinterpret_cast<GrColor*>(verts + i * vsize) = 0; 852205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 853205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 854a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com GrColor innerColor; 855a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com if (useVertexCoverage) { 856e10f6fdf76fa9b627cbb8471b58b13c457af83e8bsalomon@google.com innerColor = 0xffffffff; 857a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com } else { 8588f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com innerColor = target->getDrawState().getColor(); 859a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com } 860205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com verts += 4 * vsize; 861205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com for (int i = 0; i < 8; ++i) { 862205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com *reinterpret_cast<GrColor*>(verts + i * vsize) = innerColor; 863205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 864205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 865205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com verts += 8 * vsize; 866205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com for (int i = 0; i < 8; ++i) { 867205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com *reinterpret_cast<GrColor*>(verts + i * vsize) = 0; 868205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 869205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 8709b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com target->setIndexSourceToBuffer(indexBuffer); 871205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com target->drawIndexed(kTriangles_PrimitiveType, 872205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 0, 0, 16, aaStrokeRectIndexCount()); 873205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com} 874205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 87520efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com/** 87620efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com * Returns true if the rects edges are integer-aligned. 87720efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com */ 87820efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.comstatic bool isIRect(const GrRect& r) { 87920efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com return GrScalarIsInt(r.fLeft) && GrScalarIsInt(r.fTop) && 88020efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com GrScalarIsInt(r.fRight) && GrScalarIsInt(r.fBottom); 88120efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com} 88220efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com 883205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comstatic bool apply_aa_to_rect(GrDrawTarget* target, 884205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com const GrRect& rect, 885205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrScalar width, 886205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com const GrMatrix* matrix, 887205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrMatrix* combinedMatrix, 888a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com GrRect* devRect, 889a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com bool* useVertexCoverage) { 8902eba795bcda66813fdc7a7c4388a99ae9cb2c864bsalomon@google.com // we use a simple coverage ramp to do aa on axis-aligned rects 8912eba795bcda66813fdc7a7c4388a99ae9cb2c864bsalomon@google.com // we check if the rect will be axis-aligned, and the rect won't land on 8922eba795bcda66813fdc7a7c4388a99ae9cb2c864bsalomon@google.com // integer coords. 893d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com 894a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com // we are keeping around the "tweak the alpha" trick because 895a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com // it is our only hope for the fixed-pipe implementation. 896a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com // In a shader implementation we can give a separate coverage input 897289533ada623f2238a83771eec977f204f75994fbsalomon@google.com // TODO: remove this ugliness when we drop the fixed-pipe impl 898a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com *useVertexCoverage = false; 899d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com if (!target->canTweakAlphaForCoverage()) { 9002eba795bcda66813fdc7a7c4388a99ae9cb2c864bsalomon@google.com if (disable_coverage_aa_for_blend(target)) { 9011983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#if GR_DEBUG 9022eba795bcda66813fdc7a7c4388a99ae9cb2c864bsalomon@google.com //GrPrintf("Turning off AA to correctly apply blend.\n"); 9031983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#endif 904a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com return false; 9052eba795bcda66813fdc7a7c4388a99ae9cb2c864bsalomon@google.com } else { 9062eba795bcda66813fdc7a7c4388a99ae9cb2c864bsalomon@google.com *useVertexCoverage = true; 907a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com } 908205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 9098f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com const GrDrawState& drawState = target->getDrawState(); 9108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com if (drawState.getRenderTarget()->isMultisampled()) { 911205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return false; 912205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 913205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 914471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com if (0 == width && target->willUseHWAALines()) { 915205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return false; 916205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 917205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 9188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com if (!drawState.getViewMatrix().preservesAxisAlignment()) { 919205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return false; 920205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 921205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 922205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (NULL != matrix && 923205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com !matrix->preservesAxisAlignment()) { 924205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return false; 925205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 926205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 9278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com *combinedMatrix = drawState.getViewMatrix(); 928205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (NULL != matrix) { 929205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com combinedMatrix->preConcat(*matrix); 930205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrAssert(combinedMatrix->preservesAxisAlignment()); 931205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 932205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 933205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com combinedMatrix->mapRect(devRect, rect); 934205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com devRect->sort(); 935205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 936205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (width < 0) { 93720efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com return !isIRect(*devRect); 938205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } else { 939205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return true; 940205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 941205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com} 942205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 94327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::drawRect(const GrPaint& paint, 94427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrRect& rect, 94527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrScalar width, 94627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrMatrix* matrix) { 947278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com SK_TRACE_EVENT0("GrContext::drawRect"); 94827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 94927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory); 95026c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com int stageMask = paint.getActiveStageMask(); 95127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 952205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrRect devRect = rect; 953205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrMatrix combinedMatrix; 954a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com bool useVertexCoverage; 955289533ada623f2238a83771eec977f204f75994fbsalomon@google.com bool needAA = paint.fAntiAlias && 956289533ada623f2238a83771eec977f204f75994fbsalomon@google.com !this->getRenderTarget()->isMultisampled(); 957289533ada623f2238a83771eec977f204f75994fbsalomon@google.com bool doAA = needAA && apply_aa_to_rect(target, rect, width, matrix, 958289533ada623f2238a83771eec977f204f75994fbsalomon@google.com &combinedMatrix, &devRect, 959289533ada623f2238a83771eec977f204f75994fbsalomon@google.com &useVertexCoverage); 960205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 961205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (doAA) { 9628f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawTarget::AutoDeviceCoordDraw adcd(target, stageMask); 963205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (width >= 0) { 964205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrVec strokeSize;; 965205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (width > 0) { 966205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com strokeSize.set(width, width); 967cc4dac3dac215dc0dd56f7b30d07cc304671b033bsalomon@google.com combinedMatrix.mapVectors(&strokeSize, 1); 968205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com strokeSize.setAbs(strokeSize); 969205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } else { 970205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com strokeSize.set(GR_Scalar1, GR_Scalar1); 971205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 972a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com strokeAARect(target, devRect, strokeSize, useVertexCoverage); 973205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } else { 974a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com fillAARect(target, devRect, useVertexCoverage); 975205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 976205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return; 977205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 978205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 97927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (width >= 0) { 98027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // TODO: consider making static vertex buffers for these cases. 98127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // Hairline could be done by just adding closing vertex to 98227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // unitSquareVertexBuffer() 98326c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com GrVertexLayout layout = PaintStageVertexLayoutBits(paint, NULL); 98426c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 98527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com static const int worstCaseVertCount = 10; 98627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget::AutoReleaseGeometry geo(target, layout, worstCaseVertCount, 0); 98727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 98827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (!geo.succeeded()) { 9896513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com GrPrintf("Failed to get space for vertices!\n"); 99027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return; 99127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 99227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 99327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrPrimitiveType primType; 99427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int vertCount; 99527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrPoint* vertex = geo.positions(); 99627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 99727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (width > 0) { 99827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertCount = 10; 99927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com primType = kTriangleStrip_PrimitiveType; 100027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com setStrokeRectStrip(vertex, rect, width); 100127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 100227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // hairline 100327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertCount = 5; 100427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com primType = kLineStrip_PrimitiveType; 100527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertex[0].set(rect.fLeft, rect.fTop); 100627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertex[1].set(rect.fRight, rect.fTop); 100727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertex[2].set(rect.fRight, rect.fBottom); 100827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertex[3].set(rect.fLeft, rect.fBottom); 100927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertex[4].set(rect.fLeft, rect.fTop); 101027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 101127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 10128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState::AutoViewMatrixRestore avmr; 101327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL != matrix) { 10148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = target->drawState(); 10158f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com avmr.set(drawState); 10168f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->preConcatViewMatrix(*matrix); 10178f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->preConcatSamplerMatrices(stageMask, *matrix); 101827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 101927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 102027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target->drawNonIndexed(primType, 0, vertCount); 102127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 10228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com#if GR_STATIC_RECT_VB 102326c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com GrVertexLayout layout = PaintStageVertexLayoutBits(paint, NULL); 10246513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com const GrVertexBuffer* sqVB = fGpu->getUnitSquareVertexBuffer(); 10256513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com if (NULL == sqVB) { 10266513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com GrPrintf("Failed to create static rect vb.\n"); 10276513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com return; 10286513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com } 10296513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com target->setVertexSourceToBuffer(layout, sqVB); 10308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = target->drawState(); 10318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState::AutoViewMatrixRestore avmr(drawState); 103227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrMatrix m; 10338295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com m.setAll(rect.width(), 0, rect.fLeft, 1034205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 0, rect.height(), rect.fTop, 1035205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 0, 0, GrMatrix::I()[8]); 103627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 103727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL != matrix) { 103827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com m.postConcat(*matrix); 103927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 10408f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->preConcatViewMatrix(m); 10418f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->preConcatSamplerMatrices(stageMask, m); 104226c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 104327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target->drawNonIndexed(kTriangleFan_PrimitiveType, 0, 4); 10448f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com#else 104526c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com target->drawSimpleRect(rect, matrix, stageMask); 10468f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com#endif 104727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 104827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 104927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 105027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::drawRectToRect(const GrPaint& paint, 105127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrRect& dstRect, 105227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrRect& srcRect, 105327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrMatrix* dstMatrix, 105427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrMatrix* srcMatrix) { 1055278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com SK_TRACE_EVENT0("GrContext::drawRectToRect"); 105627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 105726c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com // srcRect refers to paint's first texture 105826c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com if (NULL == paint.getTexture(0)) { 105927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com drawRect(paint, dstRect, -1, dstMatrix); 106027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return; 106127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 1062de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com 106327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GR_STATIC_ASSERT(!BATCH_RECT_TO_RECT || !GR_STATIC_RECT_VB); 106427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 106527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#if GR_STATIC_RECT_VB 106627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory); 10678f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = target->drawState(); 106826c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com GrVertexLayout layout = PaintStageVertexLayoutBits(paint, NULL); 10698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState::AutoViewMatrixRestore avmr(drawState); 107027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 107127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrMatrix m; 107227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 107327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com m.setAll(dstRect.width(), 0, dstRect.fLeft, 107427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 0, dstRect.height(), dstRect.fTop, 107527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 0, 0, GrMatrix::I()[8]); 107627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL != dstMatrix) { 107727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com m.postConcat(*dstMatrix); 107827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 10798f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->preConcatViewMatrix(m); 108027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 108126c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com // srcRect refers to first stage 108226c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com int otherStageMask = paint.getActiveStageMask() & 108326c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com (~(1 << GrPaint::kFirstTextureStage)); 108426c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com if (otherStageMask) { 10858f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->preConcatSamplerMatrices(otherStageMask, m); 108626c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com } 108726c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 108827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com m.setAll(srcRect.width(), 0, srcRect.fLeft, 108927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 0, srcRect.height(), srcRect.fTop, 109027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 0, 0, GrMatrix::I()[8]); 109127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL != srcMatrix) { 109227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com m.postConcat(*srcMatrix); 109327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 10948f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->sampler(GrPaint::kFirstTextureStage)->preConcatMatrix(m); 109527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 10966513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com const GrVertexBuffer* sqVB = fGpu->getUnitSquareVertexBuffer(); 10976513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com if (NULL == sqVB) { 10986513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com GrPrintf("Failed to create static rect vb.\n"); 10996513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com return; 11006513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com } 11016513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com target->setVertexSourceToBuffer(layout, sqVB); 110227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target->drawNonIndexed(kTriangleFan_PrimitiveType, 0, 4); 110327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#else 110427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 110527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget* target; 1106de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com#if BATCH_RECT_TO_RECT 110727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target = this->prepareToDraw(paint, kBuffered_DrawCategory); 1108de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com#else 110927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target = this->prepareToDraw(paint, kUnbuffered_DrawCategory); 111027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#endif 111127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 11129381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com const GrRect* srcRects[GrDrawState::kNumStages] = {NULL}; 11139381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com const GrMatrix* srcMatrices[GrDrawState::kNumStages] = {NULL}; 111427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com srcRects[0] = &srcRect; 111527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com srcMatrices[0] = srcMatrix; 111627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 111727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target->drawRect(dstRect, dstMatrix, 1, srcRects, srcMatrices); 111827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#endif 111927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 112027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 112127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::drawVertices(const GrPaint& paint, 112227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrPrimitiveType primitiveType, 112327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int vertexCount, 112427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrPoint positions[], 112527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrPoint texCoords[], 112627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrColor colors[], 112727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const uint16_t indices[], 112827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int indexCount) { 1129278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com SK_TRACE_EVENT0("GrContext::drawVertices"); 113027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 113127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget::AutoReleaseGeometry geo; 113227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 113327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory); 113427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 113526c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com bool hasTexCoords[GrPaint::kTotalStages] = { 113626c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com NULL != texCoords, // texCoordSrc provides explicit stage 0 coords 113726c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 0 // remaining stages use positions 113826c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com }; 113926c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 114026c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com GrVertexLayout layout = PaintStageVertexLayoutBits(paint, hasTexCoords); 114127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 114227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL != colors) { 114327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com layout |= GrDrawTarget::kColor_VertexLayoutBit; 114427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 114526c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com int vertexSize = GrDrawTarget::VertexSize(layout); 114627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 114727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (sizeof(GrPoint) != vertexSize) { 114827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (!geo.set(target, layout, vertexCount, 0)) { 11496513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com GrPrintf("Failed to get space for vertices!\n"); 115027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return; 115127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 11529381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com int texOffsets[GrDrawState::kMaxTexCoords]; 115327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int colorOffset; 115426c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com GrDrawTarget::VertexSizeAndOffsetsByIdx(layout, 115526c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com texOffsets, 1156aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com &colorOffset, 1157a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com NULL, 1158a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com NULL); 115927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com void* curVertex = geo.vertices(); 116027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 116127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com for (int i = 0; i < vertexCount; ++i) { 116227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com *((GrPoint*)curVertex) = positions[i]; 116327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 116427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (texOffsets[0] > 0) { 116527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com *(GrPoint*)((intptr_t)curVertex + texOffsets[0]) = texCoords[i]; 116627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 116727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (colorOffset > 0) { 116827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com *(GrColor*)((intptr_t)curVertex + colorOffset) = colors[i]; 116927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 117026c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com curVertex = (void*)((intptr_t)curVertex + vertexSize); 117127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 117227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 117327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target->setVertexSourceToArray(layout, positions, vertexCount); 117427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 117527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1176919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com // we don't currently apply offscreen AA to this path. Need improved 1177919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com // management of GrDrawTarget's geometry to avoid copying points per-tile. 1178a47a48dca5045d71cbc5de343404045209a13e15bsalomon@google.com 11798295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com if (NULL != indices) { 1180919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com target->setIndexSourceToArray(indices, indexCount); 11818295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com target->drawIndexed(primitiveType, 0, 0, vertexCount, indexCount); 118227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 11838295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com target->drawNonIndexed(primitiveType, 0, vertexCount); 11848295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com } 118527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 118627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 118706afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com/////////////////////////////////////////////////////////////////////////////// 1188150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com#include "SkDraw.h" 1189150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com#include "SkRasterClip.h" 1190150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com 1191150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.comnamespace { 1192150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com 1193150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.comSkPath::FillType gr_fill_to_sk_fill(GrPathFill fill) { 1194150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com switch (fill) { 1195150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com case kWinding_PathFill: 1196150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com return SkPath::kWinding_FillType; 1197150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com case kEvenOdd_PathFill: 1198150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com return SkPath::kEvenOdd_FillType; 1199150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com case kInverseWinding_PathFill: 1200150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com return SkPath::kInverseWinding_FillType; 1201150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com case kInverseEvenOdd_PathFill: 1202150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com return SkPath::kInverseEvenOdd_FillType; 1203150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com default: 1204150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com GrCrash("Unexpected fill."); 1205150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com return SkPath::kWinding_FillType; 1206150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com } 1207150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com} 1208150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com 1209150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com// gets device coord bounds of path (not considering the fill) and clip. The 1210150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com// path bounds will be a subset of the clip bounds. returns false if path bounds 1211150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com// would be empty. 1212150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.combool get_path_and_clip_bounds(const GrDrawTarget* target, 1213150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com const GrPath& path, 1214150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com const GrVec* translate, 1215150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com GrIRect* pathBounds, 1216150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com GrIRect* clipBounds) { 1217150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com // compute bounds as intersection of rt size, clip, and path 1218150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com const GrRenderTarget* rt = target->getDrawState().getRenderTarget(); 1219150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com if (NULL == rt) { 1220150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com return false; 1221150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com } 1222150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com *pathBounds = GrIRect::MakeWH(rt->width(), rt->height()); 1223150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com const GrClip& clip = target->getClip(); 1224150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com if (clip.hasConservativeBounds()) { 1225150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com clip.getConservativeBounds().roundOut(clipBounds); 1226150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com if (!pathBounds->intersect(*clipBounds)) { 1227150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com return false; 1228150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com } 1229150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com } else { 1230150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com // pathBounds is currently the rt extent, set clip bounds to that rect. 1231150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com *clipBounds = *pathBounds; 1232150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com } 1233150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com GrRect pathSBounds = path.getBounds(); 1234150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com if (!pathSBounds.isEmpty()) { 1235150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com if (NULL != translate) { 1236150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com pathSBounds.offset(*translate); 1237150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com } 1238150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com target->getDrawState().getViewMatrix().mapRect(&pathSBounds, 1239150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com pathSBounds); 1240150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com GrIRect pathIBounds; 1241150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com pathSBounds.roundOut(&pathIBounds); 1242150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com if (!pathBounds->intersect(pathIBounds)) { 1243150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com return false; 1244150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com } 1245150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com } else { 1246150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com return false; 1247150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com } 1248150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com return true; 1249150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com} 1250150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com 1251150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com/** 1252150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com * sw rasterizes path to A8 mask using the context's matrix and uploads to a 1253150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com * scratch texture. 1254150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com */ 1255150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com 1256150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.combool sw_draw_path_to_mask_texture(const GrPath& clientPath, 1257150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com const GrIRect& pathDevBounds, 1258150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com GrPathFill fill, 1259150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com GrContext* context, 1260150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com const GrPoint* translate, 1261150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com GrAutoScratchTexture* tex) { 1262150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com SkPaint paint; 1263150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com SkPath tmpPath; 1264150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com const SkPath* pathToDraw = &clientPath; 1265150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com if (kHairLine_PathFill == fill) { 1266150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com paint.setStyle(SkPaint::kStroke_Style); 1267150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com paint.setStrokeWidth(SK_Scalar1); 1268150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com } else { 1269150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com paint.setStyle(SkPaint::kFill_Style); 1270150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com SkPath::FillType skfill = gr_fill_to_sk_fill(fill); 1271150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com if (skfill != pathToDraw->getFillType()) { 1272150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com tmpPath = *pathToDraw; 1273150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com tmpPath.setFillType(skfill); 1274150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com pathToDraw = &tmpPath; 1275150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com } 1276150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com } 1277150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com paint.setAntiAlias(true); 1278150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com paint.setColor(SK_ColorWHITE); 1279150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com 1280150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com GrMatrix matrix = context->getMatrix(); 1281150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com if (NULL != translate) { 1282150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com matrix.postTranslate(translate->fX, translate->fY); 1283150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com } 1284150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com 1285150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com matrix.postTranslate(-pathDevBounds.fLeft * SK_Scalar1, 1286150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com -pathDevBounds.fTop * SK_Scalar1); 1287150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com GrIRect bounds = GrIRect::MakeWH(pathDevBounds.width(), 1288150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com pathDevBounds.height()); 1289150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com 1290150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com SkBitmap bm; 1291150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com bm.setConfig(SkBitmap::kA8_Config, bounds.fRight, bounds.fBottom); 1292150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com if (!bm.allocPixels()) { 1293150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com return false; 1294150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com } 1295150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com sk_bzero(bm.getPixels(), bm.getSafeSize()); 1296150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com 1297150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com SkDraw draw; 1298150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com sk_bzero(&draw, sizeof(draw)); 1299150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com SkRasterClip rc(bounds); 1300150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com draw.fRC = &rc; 1301150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com draw.fClip = &rc.bwRgn(); 1302150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com draw.fMatrix = &matrix; 1303150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com draw.fBitmap = &bm; 1304150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com draw.drawPath(*pathToDraw, paint); 1305150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com 1306150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com const GrTextureDesc desc = { 1307150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com kNone_GrTextureFlags, 1308150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com bounds.fRight, 1309150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com bounds.fBottom, 131078d6cf9f434d3351b19de14f1eab424c23f0ab6dbsalomon@google.com kAlpha_8_GrPixelConfig, 131178d6cf9f434d3351b19de14f1eab424c23f0ab6dbsalomon@google.com {0} // samples 1312150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com }; 1313150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com 1314150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com tex->set(context, desc); 1315150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com GrTexture* texture = tex->texture(); 1316150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com 1317150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com if (NULL == texture) { 1318150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com return false; 1319150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com } 1320150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com SkAutoLockPixels alp(bm); 1321150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com texture->writePixels(0, 0, desc.fWidth, desc.fHeight, desc.fConfig, 1322150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com bm.getPixels(), bm.rowBytes()); 1323150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com return true; 1324150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com} 1325150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com 1326150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.comvoid draw_around_inv_path(GrDrawTarget* target, 1327150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com GrDrawState::StageMask stageMask, 1328150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com const GrIRect& clipBounds, 1329150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com const GrIRect& pathBounds) { 1330150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com GrDrawTarget::AutoDeviceCoordDraw adcd(target, stageMask); 1331150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com GrRect rect; 1332150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com if (clipBounds.fTop < pathBounds.fTop) { 1333150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com rect.iset(clipBounds.fLeft, clipBounds.fTop, 1334150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com clipBounds.fRight, pathBounds.fTop); 1335150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com target->drawSimpleRect(rect, NULL, stageMask); 1336150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com } 1337150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com if (clipBounds.fLeft < pathBounds.fLeft) { 1338150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com rect.iset(clipBounds.fLeft, pathBounds.fTop, 1339150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com pathBounds.fLeft, pathBounds.fBottom); 1340150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com target->drawSimpleRect(rect, NULL, stageMask); 1341150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com } 1342150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com if (clipBounds.fRight > pathBounds.fRight) { 1343150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com rect.iset(pathBounds.fRight, pathBounds.fTop, 1344150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com clipBounds.fRight, pathBounds.fBottom); 1345150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com target->drawSimpleRect(rect, NULL, stageMask); 1346150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com } 1347150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com if (clipBounds.fBottom > pathBounds.fBottom) { 1348150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com rect.iset(clipBounds.fLeft, pathBounds.fBottom, 1349150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com clipBounds.fRight, clipBounds.fBottom); 1350150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com target->drawSimpleRect(rect, NULL, stageMask); 1351150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com } 1352150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com} 1353150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com 1354150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com} 135527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 135607f3ee10d34f09342abb93d758b5e151ff78f7a5reed@google.comvoid GrContext::drawPath(const GrPaint& paint, const GrPath& path, 135707f3ee10d34f09342abb93d758b5e151ff78f7a5reed@google.com GrPathFill fill, const GrPoint* translate) { 135827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1359fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com if (path.isEmpty()) { 1360fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com if (GrIsFillInverted(fill)) { 1361fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com this->drawPaint(paint); 1362fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 1363fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com return; 1364fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 1365fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com 136627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory); 1367150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com GrDrawState::StageMask stageMask = paint.getActiveStageMask(); 1368d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com 1369289533ada623f2238a83771eec977f204f75994fbsalomon@google.com bool prAA = paint.fAntiAlias && !this->getRenderTarget()->isMultisampled(); 1370289533ada623f2238a83771eec977f204f75994fbsalomon@google.com 1371d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com // An Assumption here is that path renderer would use some form of tweaking 1372d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com // the src color (either the input alpha or in the frag shader) to implement 1373d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com // aa. If we have some future driver-mojo path AA that can do the right 1374d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com // thing WRT to the blend then we'll need some query on the PR. 1375d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com if (disable_coverage_aa_for_blend(target)) { 13761983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#if GR_DEBUG 1377979432ba2621b617f5e85a9ff48c6b6cd1504a0dbsalomon@google.com //GrPrintf("Turning off AA to correctly apply blend.\n"); 13781983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#endif 1379289533ada623f2238a83771eec977f204f75994fbsalomon@google.com prAA = false; 1380d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com } 1381289533ada623f2238a83771eec977f204f75994fbsalomon@google.com 1382289533ada623f2238a83771eec977f204f75994fbsalomon@google.com GrPathRenderer* pr = NULL; 1383289533ada623f2238a83771eec977f204f75994fbsalomon@google.com if (prAA) { 1384289533ada623f2238a83771eec977f204f75994fbsalomon@google.com pr = this->getPathRenderer(path, fill, true); 1385289533ada623f2238a83771eec977f204f75994fbsalomon@google.com if (NULL == pr) { 1386150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com GrAutoScratchTexture ast; 1387150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com GrIRect pathBounds, clipBounds; 1388150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com if (!get_path_and_clip_bounds(target, path, translate, 1389150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com &pathBounds, &clipBounds)) { 1390150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com return; 1391150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com } 1392150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com if (NULL == pr && sw_draw_path_to_mask_texture(path, pathBounds, 1393150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com fill, this, 1394150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com translate, &ast)) { 1395150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com GrTexture* texture = ast.texture(); 1396150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com GrAssert(NULL != texture); 1397150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com GrDrawTarget::AutoDeviceCoordDraw adcd(target, stageMask); 1398150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com enum { 1399150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com kPathMaskStage = GrPaint::kTotalStages, 1400150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com }; 1401150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com target->drawState()->setTexture(kPathMaskStage, texture); 1402150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com target->drawState()->sampler(kPathMaskStage)->reset(); 1403150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com GrScalar w = GrIntToScalar(pathBounds.width()); 1404150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com GrScalar h = GrIntToScalar(pathBounds.height()); 1405150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com GrRect maskRect = GrRect::MakeWH(w / texture->width(), 1406150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com h / texture->height()); 1407150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com const GrRect* srcRects[GrDrawState::kNumStages] = {NULL}; 1408150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com srcRects[kPathMaskStage] = &maskRect; 1409150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com stageMask |= 1 << kPathMaskStage; 14105db3b6cce4e9e02415a0a31d95666c044c953ac2bsalomon@google.com GrRect dstRect = GrRect::MakeLTRB( 14115db3b6cce4e9e02415a0a31d95666c044c953ac2bsalomon@google.com SK_Scalar1* pathBounds.fLeft, 14125db3b6cce4e9e02415a0a31d95666c044c953ac2bsalomon@google.com SK_Scalar1* pathBounds.fTop, 14135db3b6cce4e9e02415a0a31d95666c044c953ac2bsalomon@google.com SK_Scalar1* pathBounds.fRight, 14145db3b6cce4e9e02415a0a31d95666c044c953ac2bsalomon@google.com SK_Scalar1* pathBounds.fBottom); 1415150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com target->drawRect(dstRect, NULL, stageMask, srcRects, NULL); 1416150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com target->drawState()->setTexture(kPathMaskStage, NULL); 1417150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com if (GrIsFillInverted(fill)) { 1418150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com draw_around_inv_path(target, stageMask, 1419150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com clipBounds, pathBounds); 1420150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com } 1421150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com return; 1422150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com } 1423289533ada623f2238a83771eec977f204f75994fbsalomon@google.com } 1424289533ada623f2238a83771eec977f204f75994fbsalomon@google.com } else { 1425289533ada623f2238a83771eec977f204f75994fbsalomon@google.com pr = this->getPathRenderer(path, fill, false); 1426289533ada623f2238a83771eec977f204f75994fbsalomon@google.com } 1427289533ada623f2238a83771eec977f204f75994fbsalomon@google.com 14283008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com if (NULL == pr) { 14291983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#if GR_DEBUG 14303008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com GrPrintf("Unable to find path renderer compatible with path.\n"); 14311983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#endif 14323008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com return; 14333008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com } 14343008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com 1435289533ada623f2238a83771eec977f204f75994fbsalomon@google.com GrPathRenderer::AutoClearPath arp(pr, target, &path, fill, prAA, translate); 143606afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com 1437ee435122d7dcb9cd4be4524004b0de282c42848bbsalomon@google.com pr->drawPath(stageMask); 143827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 14398295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com 144027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 144127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1442a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.comvoid GrContext::flush(int flagsBitfield) { 1443a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com if (kDiscard_FlushBit & flagsBitfield) { 1444a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com fDrawBuffer->reset(); 1445a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com } else { 1446c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com this->flushDrawBuffer(); 1447a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com } 1448a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com if (kForceCurrentRenderTarget_FlushBit & flagsBitfield) { 144927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fGpu->forceRenderTargetFlush(); 145027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 145127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 145227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 145327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::flushText() { 145427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (kText_DrawCategory == fLastDrawCategory) { 145527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com flushDrawBuffer(); 145627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 145727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 145827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 145927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::flushDrawBuffer() { 146027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#if BATCH_RECT_TO_RECT || DEFER_TEXT_RENDERING 146153a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com if (fDrawBuffer) { 146253a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com fDrawBuffer->playback(fGpu); 146353a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com fDrawBuffer->reset(); 146453a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com } 146527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#endif 146627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 146727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 14686f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.comvoid GrContext::internalWriteTexturePixels(GrTexture* texture, 14696f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com int left, int top, 14706f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com int width, int height, 14716f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com GrPixelConfig config, 14726f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com const void* buffer, 14736f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com size_t rowBytes, 14746f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com uint32_t flags) { 14756f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com SK_TRACE_EVENT0("GrContext::writeTexturePixels"); 1476bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(texture); 1477bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com 14786f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com if (!(kDontFlush_PixelOpsFlag & flags)) { 14796f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com this->flush(); 14806f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com } 14816f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com // TODO: use scratch texture to perform conversion 14826f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com if (GrPixelConfigIsUnpremultiplied(texture->config()) != 14836f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com GrPixelConfigIsUnpremultiplied(config)) { 14846f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com return; 14856f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com } 14866f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com 14876f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com fGpu->writeTexturePixels(texture, left, top, width, height, 14886f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com config, buffer, rowBytes); 14896f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com} 14906f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com 14916f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.combool GrContext::internalReadTexturePixels(GrTexture* texture, 14926f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com int left, int top, 14936f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com int width, int height, 14946f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com GrPixelConfig config, 14956f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com void* buffer, 14966f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com size_t rowBytes, 14976f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com uint32_t flags) { 1498278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com SK_TRACE_EVENT0("GrContext::readTexturePixels"); 1499bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(texture); 1500669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com 1501a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com // TODO: code read pixels for textures that aren't also rendertargets 1502669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com GrRenderTarget* target = texture->asRenderTarget(); 1503669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com if (NULL != target) { 15046f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com return this->internalReadRenderTargetPixels(target, 15056f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com left, top, width, height, 15066f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com config, buffer, rowBytes, 15076f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com flags); 1508669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com } else { 1509669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com return false; 1510669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com } 1511669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com} 1512669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com 1513a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com#include "SkConfig8888.h" 1514a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com 1515a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.comnamespace { 1516a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com/** 1517a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com * Converts a GrPixelConfig to a SkCanvas::Config8888. Only byte-per-channel 1518a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com * formats are representable as Config8888 and so the function returns false 1519a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com * if the GrPixelConfig has no equivalent Config8888. 1520a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com */ 1521a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.combool grconfig_to_config8888(GrPixelConfig config, 1522a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com SkCanvas::Config8888* config8888) { 1523a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com switch (config) { 1524a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com case kRGBA_8888_PM_GrPixelConfig: 1525a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com *config8888 = SkCanvas::kRGBA_Premul_Config8888; 1526a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com return true; 1527a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com case kRGBA_8888_UPM_GrPixelConfig: 1528a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com *config8888 = SkCanvas::kRGBA_Unpremul_Config8888; 1529a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com return true; 1530a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com case kBGRA_8888_PM_GrPixelConfig: 1531a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com *config8888 = SkCanvas::kBGRA_Premul_Config8888; 1532a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com return true; 1533a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com case kBGRA_8888_UPM_GrPixelConfig: 1534a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com *config8888 = SkCanvas::kBGRA_Unpremul_Config8888; 1535a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com return true; 1536a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com default: 1537a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com return false; 1538a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com } 1539a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com} 1540a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com} 1541a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com 15426f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.combool GrContext::internalReadRenderTargetPixels(GrRenderTarget* target, 15436f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com int left, int top, 15446f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com int width, int height, 15456f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com GrPixelConfig config, 15466f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com void* buffer, 15476f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com size_t rowBytes, 15486f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com uint32_t flags) { 1549278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com SK_TRACE_EVENT0("GrContext::readRenderTargetPixels"); 1550bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(target); 1551bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com 1552669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com if (NULL == target) { 15538f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com target = fGpu->drawState()->getRenderTarget(); 1554c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com if (NULL == target) { 1555c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com return false; 1556c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } 1557c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } 1558669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com 15596f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com if (!(kDontFlush_PixelOpsFlag & flags)) { 15606f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com this->flush(); 15616f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com } 1562c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 1563a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com if (!GrPixelConfigIsUnpremultiplied(target->config()) && 1564a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com GrPixelConfigIsUnpremultiplied(config) && 1565a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com !fGpu->canPreserveReadWriteUnpremulPixels()) { 1566a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com SkCanvas::Config8888 srcConfig8888, dstConfig8888; 1567a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com if (!grconfig_to_config8888(target->config(), &srcConfig8888) || 1568a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com !grconfig_to_config8888(config, &dstConfig8888)) { 1569a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com return false; 1570a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com } 1571a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com // do read back using target's own config 1572a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com this->internalReadRenderTargetPixels(target, 1573a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com left, top, 1574a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com width, height, 1575a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com target->config(), 1576a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com buffer, rowBytes, 1577a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com kDontFlush_PixelOpsFlag); 1578a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com // sw convert the pixels to unpremul config 1579a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com uint32_t* pixels = reinterpret_cast<uint32_t*>(buffer); 1580a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com SkConvertConfig8888Pixels(pixels, rowBytes, dstConfig8888, 1581a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com pixels, rowBytes, srcConfig8888, 1582a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com width, height); 1583a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com return true; 1584a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com } 1585a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com 1586c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com GrTexture* src = target->asTexture(); 15870a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com bool swapRAndB = NULL != src && 15880a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com fGpu->preferredReadPixelsConfig(config) == 15890a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com GrPixelConfigSwapRAndB(config); 1590c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 1591c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com bool flipY = NULL != src && 1592c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com fGpu->readPixelsWillPayForYFlip(target, left, top, 1593c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com width, height, config, 1594c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com rowBytes); 15950a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com bool alphaConversion = (!GrPixelConfigIsUnpremultiplied(target->config()) && 15960a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com GrPixelConfigIsUnpremultiplied(config)); 1597c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 15980a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com if (NULL == src && alphaConversion) { 15990a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com // we should fallback to cpu conversion here. This could happen when 16000a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com // we were given an external render target by the client that is not 16010a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com // also a texture (e.g. FBO 0 in GL) 16020a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com return false; 16030a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com } 16040a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com // we draw to a scratch texture if any of these conversion are applied 1605c4ff22a2965616629765b8ffe0e58f6d05f92fa3bsalomon@google.com GrAutoScratchTexture ast; 16060a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com if (flipY || swapRAndB || alphaConversion) { 16070a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com GrAssert(NULL != src); 16080a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com if (swapRAndB) { 16090a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com config = GrPixelConfigSwapRAndB(config); 16100a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com GrAssert(kUnknown_GrPixelConfig != config); 1611c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } 1612c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com // Make the scratch a render target because we don't have a robust 1613c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com // readTexturePixels as of yet (it calls this function). 1614c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com const GrTextureDesc desc = { 1615c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com kRenderTarget_GrTextureFlagBit, 1616c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com width, height, 161778d6cf9f434d3351b19de14f1eab424c23f0ab6dbsalomon@google.com config, 161878d6cf9f434d3351b19de14f1eab424c23f0ab6dbsalomon@google.com {0}, // samples 1619c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com }; 1620c4ff22a2965616629765b8ffe0e58f6d05f92fa3bsalomon@google.com 162156d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com // When a full readback is faster than a partial we could always make 162256d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com // the scratch exactly match the passed rect. However, if we see many 162356d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com // different size rectangles we will trash our texture cache and pay the 162456d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com // cost of creating and destroying many textures. So, we only request 162556d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com // an exact match when the caller is reading an entire RT. 162656d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com ScratchTexMatch match = kApprox_ScratchTexMatch; 162756d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com if (0 == left && 162856d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com 0 == top && 162956d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com target->width() == width && 163056d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com target->height() == height && 163156d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com fGpu->fullReadPixelsIsFasterThanPartial()) { 163256d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com match = kExact_ScratchTexMatch; 163356d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com } 163456d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com ast.set(this, desc, match); 1635c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com GrTexture* texture = ast.texture(); 1636c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com if (!texture) { 1637c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com return false; 1638c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } 1639c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com target = texture->asRenderTarget(); 1640c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com GrAssert(NULL != target); 1641c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 1642c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com GrDrawTarget::AutoStateRestore asr(fGpu); 16438f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = fGpu->drawState(); 164452a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com drawState->reset(); 16458f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setRenderTarget(target); 1646c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 1647c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com GrMatrix matrix; 1648c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com if (flipY) { 1649c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com matrix.setTranslate(SK_Scalar1 * left, 1650c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com SK_Scalar1 * (top + height)); 1651c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com matrix.set(GrMatrix::kMScaleY, -GR_Scalar1); 1652c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } else { 1653c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com matrix.setTranslate(SK_Scalar1 *left, SK_Scalar1 *top); 1654c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } 1655c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com matrix.postIDiv(src->width(), src->height()); 16561e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com drawState->sampler(0)->reset(matrix); 16571e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com drawState->sampler(0)->setRAndBSwap(swapRAndB); 16588f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setTexture(0, src); 1659c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com GrRect rect; 1660c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com rect.setXYWH(0, 0, SK_Scalar1 * width, SK_Scalar1 * height); 1661c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com fGpu->drawSimpleRect(rect, NULL, 0x1); 1662c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com left = 0; 1663c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com top = 0; 1664c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } 1665669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com return fGpu->readPixels(target, 1666c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com left, top, width, height, 1667c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com config, buffer, rowBytes, flipY); 166827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 166927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 167075f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.comvoid GrContext::resolveRenderTarget(GrRenderTarget* target) { 167175f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com GrAssert(target); 167275f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com ASSERT_OWNED_RESOURCE(target); 167375f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com // In the future we may track whether there are any pending draws to this 167475f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com // target. We don't today so we always perform a flush. We don't promise 167575f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com // this to our clients, though. 167675f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com this->flush(); 167775f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com fGpu->resolveRenderTarget(target); 167875f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com} 167975f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com 1680ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.orgvoid GrContext::copyTexture(GrTexture* src, GrRenderTarget* dst) { 1681ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org if (NULL == src || NULL == dst) { 1682ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org return; 1683ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org } 1684ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org ASSERT_OWNED_RESOURCE(src); 1685ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org 1686ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org GrDrawTarget::AutoStateRestore asr(fGpu); 16878f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = fGpu->drawState(); 168852a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com drawState->reset(); 16898f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setRenderTarget(dst); 1690ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org GrMatrix sampleM; 1691ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org sampleM.setIDiv(src->width(), src->height()); 16928f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setTexture(0, src); 16931e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com drawState->sampler(0)->reset(sampleM); 16945db3b6cce4e9e02415a0a31d95666c044c953ac2bsalomon@google.com SkRect rect = SkRect::MakeXYWH(0, 0, 16955db3b6cce4e9e02415a0a31d95666c044c953ac2bsalomon@google.com SK_Scalar1 * src->width(), 16965db3b6cce4e9e02415a0a31d95666c044c953ac2bsalomon@google.com SK_Scalar1 * src->height()); 1697ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org fGpu->drawSimpleRect(rect, NULL, 1 << 0); 1698ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org} 1699ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org 17006f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.comvoid GrContext::internalWriteRenderTargetPixels(GrRenderTarget* target, 17016f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com int left, int top, 17026f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com int width, int height, 17036f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com GrPixelConfig config, 17046f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com const void* buffer, 17056f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com size_t rowBytes, 17066f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com uint32_t flags) { 17076f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com SK_TRACE_EVENT0("GrContext::writeRenderTargetPixels"); 1708bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(target); 17096f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com 17106f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com if (NULL == target) { 17118f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com target = fGpu->drawState()->getRenderTarget(); 17126f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com if (NULL == target) { 17136f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com return; 17146f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com } 17156f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com } 171627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 171727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // TODO: when underlying api has a direct way to do this we should use it 171827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // (e.g. glDrawPixels on desktop GL). 171927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1720a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com // If the RT is also a texture and we don't have to do PM/UPM conversion 1721a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com // then take the texture path, which we expect to be at least as fast or 1722a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com // faster since it doesn't use an intermediate texture as we do below. 1723a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com 1724a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com#if !GR_MAC_BUILD 1725a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com // At least some drivers on the Mac get confused when glTexImage2D is called 1726a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com // on a texture attached to an FBO. The FBO still sees the old image. TODO: 1727a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com // determine what OS versions and/or HW is affected. 1728a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com if (NULL != target->asTexture() && 1729a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com GrPixelConfigIsUnpremultiplied(target->config()) == 1730a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com GrPixelConfigIsUnpremultiplied(config)) { 1731a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com 1732a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com this->internalWriteTexturePixels(target->asTexture(), 1733a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com left, top, width, height, 1734a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com config, buffer, rowBytes, flags); 1735a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com return; 1736a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com } 1737a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com#endif 1738a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com if (!GrPixelConfigIsUnpremultiplied(target->config()) && 1739a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com GrPixelConfigIsUnpremultiplied(config) && 1740a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com !fGpu->canPreserveReadWriteUnpremulPixels()) { 1741a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com SkCanvas::Config8888 srcConfig8888, dstConfig8888; 1742a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com if (!grconfig_to_config8888(config, &srcConfig8888) || 1743a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com !grconfig_to_config8888(target->config(), &dstConfig8888)) { 1744a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com return; 1745a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com } 1746a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com // allocate a tmp buffer and sw convert the pixels to premul 1747a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com SkAutoSTMalloc<128 * 128, uint32_t> tmpPixels(width * height); 1748a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com const uint32_t* src = reinterpret_cast<const uint32_t*>(buffer); 1749a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com SkConvertConfig8888Pixels(tmpPixels.get(), 4 * width, dstConfig8888, 1750a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com src, rowBytes, srcConfig8888, 1751a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com width, height); 1752a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com // upload the already premul pixels 1753a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com this->internalWriteRenderTargetPixels(target, 1754a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com left, top, 1755a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com width, height, 1756a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com target->config(), 1757a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com tmpPixels, 4 * width, flags); 1758a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com return; 1759a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com } 1760a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com 1761a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com bool swapRAndB = fGpu->preferredReadPixelsConfig(config) == 1762a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com GrPixelConfigSwapRAndB(config); 1763a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com if (swapRAndB) { 1764a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com config = GrPixelConfigSwapRAndB(config); 1765a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com } 1766a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com 1767fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com const GrTextureDesc desc = { 176878d6cf9f434d3351b19de14f1eab424c23f0ab6dbsalomon@google.com kNone_GrTextureFlags, width, height, config, {0} 176927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com }; 177050398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrAutoScratchTexture ast(this, desc); 177150398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrTexture* texture = ast.texture(); 177227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL == texture) { 177327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return; 177427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 17756f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com this->internalWriteTexturePixels(texture, 0, 0, width, height, 17766f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com config, buffer, rowBytes, flags); 177727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 177827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget::AutoStateRestore asr(fGpu); 17798f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = fGpu->drawState(); 178052a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com drawState->reset(); 178127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 178227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrMatrix matrix; 178327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com matrix.setTranslate(GrIntToScalar(left), GrIntToScalar(top)); 17848f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setViewMatrix(matrix); 17858f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setRenderTarget(target); 17868f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setTexture(0, texture); 178727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 17885c63865b529eb5714e41419dfa23c70d26ff6e4ebsalomon@google.com matrix.setIDiv(texture->width(), texture->height()); 17891e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com drawState->sampler(0)->reset(GrSamplerState::kClamp_WrapMode, 17901e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com GrSamplerState::kNearest_Filter, 17911e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com matrix); 17921e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com drawState->sampler(0)->setRAndBSwap(swapRAndB); 179327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 179427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrVertexLayout layout = GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0); 179527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com static const int VCOUNT = 4; 17966513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com // TODO: Use GrGpu::drawRect here 179727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget::AutoReleaseGeometry geo(fGpu, layout, VCOUNT, 0); 179827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (!geo.succeeded()) { 17996513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com GrPrintf("Failed to get space for vertices!\n"); 180027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return; 180127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 180227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com ((GrPoint*)geo.vertices())->setIRectFan(0, 0, width, height); 180327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fGpu->drawNonIndexed(kTriangleFan_PrimitiveType, 0, VCOUNT); 180427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 180527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 180627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1807bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.comvoid GrContext::setPaint(const GrPaint& paint, GrDrawTarget* target) { 18088f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = target->drawState(); 180926c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 181026c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com for (int i = 0; i < GrPaint::kMaxTextures; ++i) { 181126c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com int s = i + GrPaint::kFirstTextureStage; 18128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setTexture(s, paint.getTexture(i)); 1813bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(paint.getTexture(i)); 1814f864ec467dfd518e32f6e4d709fafe57f1b3dbc6bsalomon@google.com if (paint.getTexture(i)) { 1815f864ec467dfd518e32f6e4d709fafe57f1b3dbc6bsalomon@google.com *drawState->sampler(s) = paint.getTextureSampler(i); 1816f864ec467dfd518e32f6e4d709fafe57f1b3dbc6bsalomon@google.com } 181726c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com } 181826c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 18198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setFirstCoverageStage(GrPaint::kFirstMaskStage); 182026c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 182126c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com for (int i = 0; i < GrPaint::kMaxMasks; ++i) { 182226c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com int s = i + GrPaint::kFirstMaskStage; 18238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setTexture(s, paint.getMask(i)); 1824bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(paint.getMask(i)); 1825f864ec467dfd518e32f6e4d709fafe57f1b3dbc6bsalomon@google.com if (paint.getMask(i)) { 1826f864ec467dfd518e32f6e4d709fafe57f1b3dbc6bsalomon@google.com *drawState->sampler(s) = paint.getMaskSampler(i); 1827f864ec467dfd518e32f6e4d709fafe57f1b3dbc6bsalomon@google.com } 182826c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com } 182926c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 18308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setColor(paint.fColor); 183127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 183227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (paint.fDither) { 18338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->enableState(GrDrawState::kDither_StateBit); 183427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 18358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->disableState(GrDrawState::kDither_StateBit); 183627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 183727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (paint.fAntiAlias) { 18388f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->enableState(GrDrawState::kHWAntialias_StateBit); 183927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 18408f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->disableState(GrDrawState::kHWAntialias_StateBit); 184127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 184250bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org if (paint.fColorMatrixEnabled) { 184350bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org drawState->enableState(GrDrawState::kColorMatrix_StateBit); 184450bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org } else { 184550bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org drawState->disableState(GrDrawState::kColorMatrix_StateBit); 184650bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org } 18476b67e21b6549598254c1ffa4243bf32615d90fb6bsalomon@google.com drawState->setBlendFunc(paint.fSrcBlendCoeff, paint.fDstBlendCoeff); 18488f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setColorFilter(paint.fColorFilterColor, paint.fColorFilterXfermode); 184950bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org drawState->setColorMatrix(paint.fColorMatrix); 1850dd1be60702b3622f49d97651e31d13eaf2175cf8bsalomon@google.com drawState->setCoverage(paint.fCoverage); 1851d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com 1852d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com if (paint.getActiveMaskStageMask() && !target->canApplyCoverage()) { 1853d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com GrPrintf("Partial pixel coverage will be incorrectly blended.\n"); 1854d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com } 185527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 185627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1857de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.comGrDrawTarget* GrContext::prepareToDraw(const GrPaint& paint, 185827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com DrawCategory category) { 185927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (category != fLastDrawCategory) { 186027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com flushDrawBuffer(); 186127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fLastDrawCategory = category; 186227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 1863bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com this->setPaint(paint, fGpu); 186427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget* target = fGpu; 186527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com switch (category) { 186627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com case kText_DrawCategory: 186727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#if DEFER_TEXT_RENDERING 186827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target = fDrawBuffer; 186927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fDrawBuffer->initializeDrawStateAndClip(*fGpu); 187027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#else 187127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target = fGpu; 187227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#endif 187327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com break; 187427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com case kUnbuffered_DrawCategory: 187527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target = fGpu; 187627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com break; 187727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com case kBuffered_DrawCategory: 187827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target = fDrawBuffer; 187927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fDrawBuffer->initializeDrawStateAndClip(*fGpu); 188027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com break; 188127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 188227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return target; 188327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 188427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1885289533ada623f2238a83771eec977f204f75994fbsalomon@google.comGrPathRenderer* GrContext::getPathRenderer(const GrPath& path, 1886289533ada623f2238a83771eec977f204f75994fbsalomon@google.com GrPathFill fill, 1887289533ada623f2238a83771eec977f204f75994fbsalomon@google.com bool antiAlias) { 18883008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com if (NULL == fPathRendererChain) { 18893008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com fPathRendererChain = 18903008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com new GrPathRendererChain(this, GrPathRendererChain::kNone_UsageFlag); 18913008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com } 1892289533ada623f2238a83771eec977f204f75994fbsalomon@google.com return fPathRendererChain->getPathRenderer(fGpu->getCaps(), path, 1893289533ada623f2238a83771eec977f204f75994fbsalomon@google.com fill, antiAlias); 18943008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com} 18953008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com 189627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 189727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 189827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::setRenderTarget(GrRenderTarget* target) { 1899bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(target); 19008fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com this->flush(false); 19018f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com fGpu->drawState()->setRenderTarget(target); 190227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 190327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 190427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comGrRenderTarget* GrContext::getRenderTarget() { 19058f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com return fGpu->drawState()->getRenderTarget(); 190627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 190727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 190827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comconst GrRenderTarget* GrContext::getRenderTarget() const { 19098f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com return fGpu->getDrawState().getRenderTarget(); 191027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 191127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 191227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comconst GrMatrix& GrContext::getMatrix() const { 19138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com return fGpu->getDrawState().getViewMatrix(); 191427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 191527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 191627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::setMatrix(const GrMatrix& m) { 19178f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com fGpu->drawState()->setViewMatrix(m); 191827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 191927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 192027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::concatMatrix(const GrMatrix& m) const { 19218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com fGpu->drawState()->preConcatViewMatrix(m); 192227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 192327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 192427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comstatic inline intptr_t setOrClear(intptr_t bits, int shift, intptr_t pred) { 192527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com intptr_t mask = 1 << shift; 192627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (pred) { 192727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com bits |= mask; 192827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 192927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com bits &= ~mask; 193027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 193127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return bits; 193227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 193327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 193427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::resetStats() { 193527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fGpu->resetStats(); 193627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 193727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 193805ef510389950e1ae8dcba40e41e001db771b12dbsalomon@google.comconst GrGpuStats& GrContext::getStats() const { 193927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return fGpu->getStats(); 194027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 194127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 194227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::printStats() const { 194327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fGpu->printStats(); 194427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 194527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1946583a1e38503ebd57ba9bd39a3fabe89bead8e76cbsalomon@google.comGrContext::GrContext(GrGpu* gpu) { 194727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fGpu = gpu; 194827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fGpu->ref(); 1949669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com fGpu->setContext(this); 19508fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 19513008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com fPathRendererChain = NULL; 1952dfe75bcf98b0c04535efbf7fe36492a7fb53c90dbsalomon@google.com 195350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com fTextureCache = new GrResourceCache(MAX_TEXTURE_CACHE_COUNT, 195450398bf7f1953e640e5529616e710cf540799731bsalomon@google.com MAX_TEXTURE_CACHE_BYTES); 195527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fFontCache = new GrFontCache(fGpu); 195627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 195727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fLastDrawCategory = kUnbuffered_DrawCategory; 195827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 19598fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fDrawBuffer = NULL; 19608fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fDrawBufferVBAllocPool = NULL; 19618fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fDrawBufferIBAllocPool = NULL; 19628fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 1963205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com fAAFillRectIndexBuffer = NULL; 1964205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com fAAStrokeRectIndexBuffer = NULL; 1965919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com 19668fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com this->setupDrawBuffer(); 19678fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com} 19688fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 19698fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.comvoid GrContext::setupDrawBuffer() { 19708fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 19718fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com GrAssert(NULL == fDrawBuffer); 19728fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com GrAssert(NULL == fDrawBufferVBAllocPool); 19738fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com GrAssert(NULL == fDrawBufferIBAllocPool); 19748fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 197527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#if DEFER_TEXT_RENDERING || BATCH_RECT_TO_RECT 1976de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com fDrawBufferVBAllocPool = 19778fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com new GrVertexBufferAllocPool(fGpu, false, 197827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com DRAW_BUFFER_VBPOOL_BUFFER_SIZE, 197927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com DRAW_BUFFER_VBPOOL_PREALLOC_BUFFERS); 1980de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com fDrawBufferIBAllocPool = 19818fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com new GrIndexBufferAllocPool(fGpu, false, 1982de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com DRAW_BUFFER_IBPOOL_BUFFER_SIZE, 198327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS); 198427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1985471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com fDrawBuffer = new GrInOrderDrawBuffer(fGpu, 1986471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com fDrawBufferVBAllocPool, 198727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fDrawBufferIBAllocPool); 198827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#endif 198927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 199027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#if BATCH_RECT_TO_RECT 199127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fDrawBuffer->setQuadIndexBuffer(this->getQuadIndexBuffer()); 199227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#endif 199327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 199427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 199527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comGrDrawTarget* GrContext::getTextTarget(const GrPaint& paint) { 199627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget* target; 199727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#if DEFER_TEXT_RENDERING 199827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target = prepareToDraw(paint, kText_DrawCategory); 199927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#else 200027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target = prepareToDraw(paint, kUnbuffered_DrawCategory); 200127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#endif 2002bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com this->setPaint(paint, target); 200327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return target; 200427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 200527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 200627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comconst GrIndexBuffer* GrContext::getQuadIndexBuffer() const { 200727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return fGpu->getQuadIndexBuffer(); 200827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 2009dfe75bcf98b0c04535efbf7fe36492a7fb53c90dbsalomon@google.com 2010aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.orgvoid GrContext::convolve(GrTexture* texture, 2011aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org const SkRect& rect, 2012aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org const float* kernel, 201305054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org int kernelWidth, 201405054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org GrSamplerState::FilterDirection direction) { 2015bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(texture); 2016bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com 2017027de5f922e8ad1acc5402829f716b8c513fdd8dsenorblanco@chromium.org GrDrawTarget::AutoStateRestore asr(fGpu); 20181e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com GrDrawState* drawState = fGpu->drawState(); 2019dd1be60702b3622f49d97651e31d13eaf2175cf8bsalomon@google.com GrRenderTarget* target = drawState->getRenderTarget(); 2020dd1be60702b3622f49d97651e31d13eaf2175cf8bsalomon@google.com drawState->reset(); 2021dd1be60702b3622f49d97651e31d13eaf2175cf8bsalomon@google.com drawState->setRenderTarget(target); 2022027de5f922e8ad1acc5402829f716b8c513fdd8dsenorblanco@chromium.org GrMatrix sampleM; 202360014ca38710d3fc265f4376b05c0fefd0e044cfsenorblanco@chromium.org sampleM.setIDiv(texture->width(), texture->height()); 20241e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com drawState->sampler(0)->reset(GrSamplerState::kClamp_WrapMode, 20251e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com GrSamplerState::kConvolution_Filter, 20261e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com sampleM); 202705054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org drawState->sampler(0)->setConvolutionParams(kernelWidth, kernel); 202805054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org drawState->sampler(0)->setFilterDirection(direction); 202905054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org drawState->setTexture(0, texture); 203005054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org fGpu->drawSimpleRect(rect, NULL, 1 << 0); 203105054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org} 20321e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com 203305054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.orgvoid GrContext::applyMorphology(GrTexture* texture, 203405054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org const SkRect& rect, 203505054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org int radius, 203605054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org GrSamplerState::Filter filter, 203705054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org GrSamplerState::FilterDirection direction) { 203805054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org ASSERT_OWNED_RESOURCE(texture); 203905054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org GrAssert(filter == GrSamplerState::kErode_Filter || 204005054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org filter == GrSamplerState::kDilate_Filter); 204105054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org 204205054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org GrDrawTarget::AutoStateRestore asr(fGpu); 204305054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org GrDrawState* drawState = fGpu->drawState(); 204405054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org GrRenderTarget* target = drawState->getRenderTarget(); 204505054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org drawState->reset(); 204605054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org drawState->setRenderTarget(target); 204705054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org GrMatrix sampleM; 204805054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org sampleM.setIDiv(texture->width(), texture->height()); 204905054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org drawState->sampler(0)->reset(GrSamplerState::kClamp_WrapMode, 205005054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org filter, 205105054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org sampleM); 205205054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org drawState->sampler(0)->setMorphologyRadius(radius); 205305054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org drawState->sampler(0)->setFilterDirection(direction); 20548f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setTexture(0, texture); 2055027de5f922e8ad1acc5402829f716b8c513fdd8dsenorblanco@chromium.org fGpu->drawSimpleRect(rect, NULL, 1 << 0); 2056027de5f922e8ad1acc5402829f716b8c513fdd8dsenorblanco@chromium.org} 2057c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 2058c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com/////////////////////////////////////////////////////////////////////////////// 2059