GrContext.cpp revision beb1af78d016d2700c350487a383c6bcfa7e2e20
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 12b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com#include "effects/GrMorphologyEffect.h" 13b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com#include "effects/GrConvolutionEffect.h" 14aa72eab5d82d4c2aa9f6f41755a001282443b042tomhudson@google.com#include "effects/GrSingleTextureEffect.h" 15b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com 16278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com#include "GrBufferAllocPool.h" 17278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com#include "GrClipIterator.h" 1805ef510389950e1ae8dcba40e41e001db771b12dbsalomon@google.com#include "GrGpu.h" 1927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#include "GrIndexBuffer.h" 2027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#include "GrInOrderDrawBuffer.h" 2127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#include "GrPathRenderer.h" 22d22b6e4351e552a8379d7781096d9e79feeae263tomhudson@google.com#include "GrPathUtils.h" 2350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com#include "GrResourceCache.h" 2472176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com#include "GrSoftwarePathRenderer.h" 25558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com#include "GrStencilBuffer.h" 26278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com#include "GrTextStrike.h" 278c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com#include "SkTLazy.h" 28c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.com#include "SkTLS.h" 290c8d93a94099dee2dff8da6000ded9ad59676488tomhudson@google.com#include "SkTrace.h" 3027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 31fa35e3ddcc9d130ce87c927218bdf27879c38711reed@google.comSK_DEFINE_INST_COUNT(GrContext) 32fa35e3ddcc9d130ce87c927218bdf27879c38711reed@google.comSK_DEFINE_INST_COUNT(GrDrawState) 33fa35e3ddcc9d130ce87c927218bdf27879c38711reed@google.com 343c4d032aeb2831a64fd6eff570667d590e3ed209bsalomon@google.com#define DEFER_TEXT_RENDERING 1 3527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 363c4d032aeb2831a64fd6eff570667d590e3ed209bsalomon@google.com#define DEFER_PATHS 1 37fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.com 383c4d032aeb2831a64fd6eff570667d590e3ed209bsalomon@google.com#define BATCH_RECT_TO_RECT (1 && !GR_STATIC_RECT_VB) 3927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 403b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org#define MAX_BLUR_SIGMA 4.0f 413b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org 42d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com// When we're using coverage AA but the blend is incompatible (given gpu 43d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com// limitations) should we disable AA or draw wrong? 44950d7a8d8def14efc98d12d6947347fde351b737bsalomon@google.com#define DISABLE_COVERAGE_AA_FOR_BLEND 1 45d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com 464b2d3f30d047435263642ef8ed170a37ca642c1breed@google.com#if GR_DEBUG 474b2d3f30d047435263642ef8ed170a37ca642c1breed@google.com // change this to a 1 to see notifications when partial coverage fails 484b2d3f30d047435263642ef8ed170a37ca642c1breed@google.com #define GR_DEBUG_PARTIAL_COVERAGE_CHECK 0 494b2d3f30d047435263642ef8ed170a37ca642c1breed@google.com#else 504b2d3f30d047435263642ef8ed170a37ca642c1breed@google.com #define GR_DEBUG_PARTIAL_COVERAGE_CHECK 0 514b2d3f30d047435263642ef8ed170a37ca642c1breed@google.com#endif 524b2d3f30d047435263642ef8ed170a37ca642c1breed@google.com 5307fc0d178e20f74a88dd78384f817b53204e625fbsalomon@google.comstatic const size_t MAX_TEXTURE_CACHE_COUNT = 256; 5407fc0d178e20f74a88dd78384f817b53204e625fbsalomon@google.comstatic const size_t MAX_TEXTURE_CACHE_BYTES = 16 * 1024 * 1024; 5527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 5660361493548d5259d0a8afae84274c2a3c31dcacbsalomon@google.comstatic const size_t DRAW_BUFFER_VBPOOL_BUFFER_SIZE = 1 << 15; 5727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comstatic const int DRAW_BUFFER_VBPOOL_PREALLOC_BUFFERS = 4; 5827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 59fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.com// path rendering is the only thing we defer today that uses non-static indices 60fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.comstatic const size_t DRAW_BUFFER_IBPOOL_BUFFER_SIZE = DEFER_PATHS ? 1 << 11 : 0; 61fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.comstatic const int DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS = DEFER_PATHS ? 4 : 0; 6227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 63bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com#define ASSERT_OWNED_RESOURCE(R) GrAssert(!(R) || (R)->getContext() == this) 64bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com 6505ef510389950e1ae8dcba40e41e001db771b12dbsalomon@google.comGrContext* GrContext::Create(GrEngine engine, 6605ef510389950e1ae8dcba40e41e001db771b12dbsalomon@google.com GrPlatform3DContext context3D) { 6727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrContext* ctx = NULL; 6827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrGpu* fGpu = GrGpu::Create(engine, context3D); 6927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL != fGpu) { 70c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com ctx = SkNEW_ARGS(GrContext, (fGpu)); 7127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fGpu->unref(); 7227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 7327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return ctx; 7427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 7527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 76c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.comnamespace { 77c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.comvoid* CreateThreadInstanceCount() { 78c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com return SkNEW_ARGS(int, (0)); 79c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.com} 80c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.comvoid DeleteThreadInstanceCount(void* v) { 81c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.com delete reinterpret_cast<int*>(v); 82c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.com} 83c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.com#define THREAD_INSTANCE_COUNT \ 84c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.com (*reinterpret_cast<int*>(SkTLS::Get(CreateThreadInstanceCount, \ 85c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.com DeleteThreadInstanceCount))) 86c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.com 87c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.com} 88c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.com 89c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.comint GrContext::GetThreadInstanceCount() { 90c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.com return THREAD_INSTANCE_COUNT; 91c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.com} 92c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.com 9327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comGrContext::~GrContext() { 948fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com this->flush(); 955acc0e36d987dff3172fd45a14b66c52a51d49e4robertphillips@google.com 965acc0e36d987dff3172fd45a14b66c52a51d49e4robertphillips@google.com // Since the gpu can hold scratch textures, give it a chance to let go 975acc0e36d987dff3172fd45a14b66c52a51d49e4robertphillips@google.com // of them before freeing the texture cache 985acc0e36d987dff3172fd45a14b66c52a51d49e4robertphillips@google.com fGpu->purgeResources(); 995acc0e36d987dff3172fd45a14b66c52a51d49e4robertphillips@google.com 10027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com delete fTextureCache; 10127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com delete fFontCache; 10227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com delete fDrawBuffer; 10327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com delete fDrawBufferVBAllocPool; 104de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com delete fDrawBufferIBAllocPool; 1053008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com 106f6747b0b90b3a270ec7b7bdfdc211cf5c19f28c2robertphillips@google.com fAARectRenderer->unref(); 107f6747b0b90b3a270ec7b7bdfdc211cf5c19f28c2robertphillips@google.com 108205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com fGpu->unref(); 1093008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com GrSafeUnref(fPathRendererChain); 11072176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com GrSafeUnref(fSoftwarePathRenderer); 11110e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com fDrawState->unref(); 112c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.com 113c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.com --THREAD_INSTANCE_COUNT; 11427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 11527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1168fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.comvoid GrContext::contextLost() { 11753a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com contextDestroyed(); 11853a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com this->setupDrawBuffer(); 11953a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com} 12053a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com 12153a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.comvoid GrContext::contextDestroyed() { 122205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com // abandon first to so destructors 123205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com // don't try to free the resources in the API. 124205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com fGpu->abandonResources(); 125205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1263008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com // a path renderer may be holding onto resources that 1273008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com // are now unusable 1283008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com GrSafeSetNull(fPathRendererChain); 12972176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com GrSafeSetNull(fSoftwarePathRenderer); 1303008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com 1318fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com delete fDrawBuffer; 1328fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fDrawBuffer = NULL; 133205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1348fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com delete fDrawBufferVBAllocPool; 1358fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fDrawBufferVBAllocPool = NULL; 136205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1378fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com delete fDrawBufferIBAllocPool; 1388fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fDrawBufferIBAllocPool = NULL; 1398fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 140f6747b0b90b3a270ec7b7bdfdc211cf5c19f28c2robertphillips@google.com fAARectRenderer->reset(); 141205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 1428fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fTextureCache->removeAll(); 1438fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fFontCache->freeAll(); 1448fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fGpu->markContextDirty(); 1458fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com} 1468fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 1478fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.comvoid GrContext::resetContext() { 1488fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fGpu->markContextDirty(); 1498fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com} 1508fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 1518fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.comvoid GrContext::freeGpuResources() { 1528fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com this->flush(); 153ff17584e1c15f68ccc296be517e8a6776a9ddabdrobertphillips@google.com 154ff17584e1c15f68ccc296be517e8a6776a9ddabdrobertphillips@google.com fGpu->purgeResources(); 155ff17584e1c15f68ccc296be517e8a6776a9ddabdrobertphillips@google.com 156f6747b0b90b3a270ec7b7bdfdc211cf5c19f28c2robertphillips@google.com fAARectRenderer->reset(); 157f6747b0b90b3a270ec7b7bdfdc211cf5c19f28c2robertphillips@google.com 1588fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fTextureCache->removeAll(); 1598fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fFontCache->freeAll(); 1603008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com // a path renderer may be holding onto resources 1613008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com GrSafeSetNull(fPathRendererChain); 16272176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com GrSafeSetNull(fSoftwarePathRenderer); 16327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 16427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 16505e70247c31ae927074ef27ea9893634a8dda543twiz@google.comsize_t GrContext::getGpuTextureCacheBytes() const { 16605e70247c31ae927074ef27ea9893634a8dda543twiz@google.com return fTextureCache->getCachedResourceBytes(); 16705e70247c31ae927074ef27ea9893634a8dda543twiz@google.com} 16805e70247c31ae927074ef27ea9893634a8dda543twiz@google.com 169fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 170fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com 17150398bf7f1953e640e5529616e710cf540799731bsalomon@google.comGrTexture* GrContext::TextureCacheEntry::texture() const { 17250398bf7f1953e640e5529616e710cf540799731bsalomon@google.com if (NULL == fEntry) { 17350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com return NULL; 17450398bf7f1953e640e5529616e710cf540799731bsalomon@google.com } else { 17550398bf7f1953e640e5529616e710cf540799731bsalomon@google.com return (GrTexture*) fEntry->resource(); 17650398bf7f1953e640e5529616e710cf540799731bsalomon@google.com } 17750398bf7f1953e640e5529616e710cf540799731bsalomon@google.com} 17850398bf7f1953e640e5529616e710cf540799731bsalomon@google.com 17950398bf7f1953e640e5529616e710cf540799731bsalomon@google.comnamespace { 180558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com 181558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com// we should never have more than one stencil buffer with same combo of 182558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com// (width,height,samplecount) 183558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.comvoid gen_stencil_key_values(int width, int height, 184558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com int sampleCnt, uint32_t v[4]) { 185558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com v[0] = width; 186558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com v[1] = height; 187558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com v[2] = sampleCnt; 188a1e5795279bd085496fa04c59e588f440bf30457robertphillips@google.com v[3] = GrResourceKey::kStencilBuffer_TypeBit; 189558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com} 190558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com 191558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.comvoid gen_stencil_key_values(const GrStencilBuffer* sb, 192558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com uint32_t v[4]) { 193558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com gen_stencil_key_values(sb->width(), sb->height(), 194558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com sb->numSamples(), v); 195558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com} 19682c7bd8f25682fcacfeea12ed899976504a767ffbsalomon@google.com 1973b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.orgvoid scale_rect(SkRect* rect, float xScale, float yScale) { 1985af56069010b33562d337a4f76543d898ca8d485robertphillips@google.com rect->fLeft = SkScalarMul(rect->fLeft, SkFloatToScalar(xScale)); 1995af56069010b33562d337a4f76543d898ca8d485robertphillips@google.com rect->fTop = SkScalarMul(rect->fTop, SkFloatToScalar(yScale)); 2005af56069010b33562d337a4f76543d898ca8d485robertphillips@google.com rect->fRight = SkScalarMul(rect->fRight, SkFloatToScalar(xScale)); 2015af56069010b33562d337a4f76543d898ca8d485robertphillips@google.com rect->fBottom = SkScalarMul(rect->fBottom, SkFloatToScalar(yScale)); 2023b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org} 2033b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org 204b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.comfloat adjust_sigma(float sigma, int *scaleFactor, int *radius) { 2053b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org *scaleFactor = 1; 2063b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org while (sigma > MAX_BLUR_SIGMA) { 2073b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org *scaleFactor *= 2; 2083b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org sigma *= 0.5f; 2093b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org } 210b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com *radius = static_cast<int>(ceilf(sigma * 3.0f)); 211b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com GrAssert(*radius <= GrConvolutionEffect::kMaxKernelRadius); 2123b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org return sigma; 2133b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org} 2143b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org 2153b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.orgvoid apply_morphology(GrGpu* gpu, 2163b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrTexture* texture, 2173b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org const SkRect& rect, 2183b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org int radius, 219b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com GrContext::MorphologyType morphType, 220b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com Gr1DKernelEffect::Direction direction) { 2213b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org 222873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com GrRenderTarget* target = gpu->drawState()->getRenderTarget(); 223873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com GrDrawTarget::AutoStateRestore asr(gpu, GrDrawTarget::kReset_ASRInit); 2243b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrDrawState* drawState = gpu->drawState(); 2253b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org drawState->setRenderTarget(target); 2263b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrMatrix sampleM; 2273b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org sampleM.setIDiv(texture->width(), texture->height()); 228b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com drawState->sampler(0)->reset(sampleM); 229b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com SkAutoTUnref<GrCustomStage> morph( 230d0c1a06cb98dd4a009dfa79e37ba6ca23a8c180btomhudson@google.com SkNEW_ARGS(GrMorphologyEffect, (texture, direction, radius, morphType))); 231b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com drawState->sampler(0)->setCustomStage(morph); 232e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com gpu->drawSimpleRect(rect, NULL); 2333b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org} 2343b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org 235b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.comvoid convolve_gaussian(GrGpu* gpu, 236b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com GrTexture* texture, 237b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com const SkRect& rect, 238b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com float sigma, 239b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com int radius, 240b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com Gr1DKernelEffect::Direction direction) { 241873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com GrRenderTarget* target = gpu->drawState()->getRenderTarget(); 242873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com GrDrawTarget::AutoStateRestore asr(gpu, GrDrawTarget::kReset_ASRInit); 2433b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrDrawState* drawState = gpu->drawState(); 2443b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org drawState->setRenderTarget(target); 2453b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrMatrix sampleM; 2463b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org sampleM.setIDiv(texture->width(), texture->height()); 247b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com drawState->sampler(0)->reset(sampleM); 248c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com SkAutoTUnref<GrConvolutionEffect> conv(SkNEW_ARGS(GrConvolutionEffect, 249fde2c0af2fd5aae19ab6c8b5228debd5b6209856tomhudson@google.com (texture, direction, radius, 250fde2c0af2fd5aae19ab6c8b5228debd5b6209856tomhudson@google.com sigma))); 251b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com drawState->sampler(0)->setCustomStage(conv); 252e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com gpu->drawSimpleRect(rect, NULL); 2533b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org} 2543b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org 255fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com} 256fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com 257b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.comGrContext::TextureCacheEntry GrContext::findAndLockTexture(const GrTextureDesc& desc, 258b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com const GrTextureParams* params) { 259b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com GrResourceKey resourceKey = GrTexture::ComputeKey(fGpu, params, desc, false); 260558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com return TextureCacheEntry(fTextureCache->findAndLock(resourceKey, 261558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com GrResourceCache::kNested_LockType)); 262558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com} 263558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com 26475b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.combool GrContext::isTextureInCache(const GrTextureDesc& desc, 265b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com const GrTextureParams* params) const { 266b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com GrResourceKey resourceKey = GrTexture::ComputeKey(fGpu, params, desc, false); 267fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com return fTextureCache->hasKey(resourceKey); 268fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com} 269fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com 270558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.comGrResourceEntry* GrContext::addAndLockStencilBuffer(GrStencilBuffer* sb) { 271bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(sb); 272558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com uint32_t v[4]; 273558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com gen_stencil_key_values(sb, v); 274558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com GrResourceKey resourceKey(v); 275558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com return fTextureCache->createAndLock(resourceKey, sb); 276558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com} 277558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com 278558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.comGrStencilBuffer* GrContext::findStencilBuffer(int width, int height, 279558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com int sampleCnt) { 280558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com uint32_t v[4]; 281558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com gen_stencil_key_values(width, height, sampleCnt, v); 282558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com GrResourceKey resourceKey(v); 283558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com GrResourceEntry* entry = fTextureCache->findAndLock(resourceKey, 284558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com GrResourceCache::kSingle_LockType); 285558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com if (NULL != entry) { 286558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com GrStencilBuffer* sb = (GrStencilBuffer*) entry->resource(); 287558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com return sb; 288558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com } else { 289558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com return NULL; 290558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com } 291558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com} 292558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com 293558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.comvoid GrContext::unlockStencilBuffer(GrResourceEntry* sbEntry) { 294bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(sbEntry->resource()); 295558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com fTextureCache->unlock(sbEntry); 29627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 29727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 29827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comstatic void stretchImage(void* dst, 29927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int dstW, 30027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int dstH, 30127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com void* src, 30227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int srcW, 30327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int srcH, 30427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int bpp) { 30527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrFixed dx = (srcW << 16) / dstW; 30627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrFixed dy = (srcH << 16) / dstH; 30727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 30827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrFixed y = dy >> 1; 30927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 31027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int dstXLimit = dstW*bpp; 31127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com for (int j = 0; j < dstH; ++j) { 31227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrFixed x = dx >> 1; 31327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com void* srcRow = (uint8_t*)src + (y>>16)*srcW*bpp; 31427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com void* dstRow = (uint8_t*)dst + j*dstW*bpp; 31527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com for (int i = 0; i < dstXLimit; i += bpp) { 31627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com memcpy((uint8_t*) dstRow + i, 31727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com (uint8_t*) srcRow + (x>>16)*bpp, 31827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com bpp); 31927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com x += dx; 32027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 32127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com y += dy; 32227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 32327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 32427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 3251fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.comGrContext::TextureCacheEntry GrContext::createAndLockTexture( 326b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com const GrTextureParams* params, 3271fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com const GrTextureDesc& desc, 3281fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com void* srcData, 3291fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com size_t rowBytes) { 330278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com SK_TRACE_EVENT0("GrContext::createAndLockTexture"); 33127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 33227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#if GR_DUMP_TEXTURE_UPLOAD 33327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrPrintf("GrContext::createAndLockTexture [%d %d]\n", desc.fWidth, desc.fHeight); 33427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#endif 33527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 33650398bf7f1953e640e5529616e710cf540799731bsalomon@google.com TextureCacheEntry entry; 33750398bf7f1953e640e5529616e710cf540799731bsalomon@google.com 338b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com GrResourceKey resourceKey = GrTexture::ComputeKey(fGpu, params, desc, false); 339a1e5795279bd085496fa04c59e588f440bf30457robertphillips@google.com 340a1e5795279bd085496fa04c59e588f440bf30457robertphillips@google.com if (GrTexture::NeedsResizing(resourceKey)) { 341a1e5795279bd085496fa04c59e588f440bf30457robertphillips@google.com // The desired texture is NPOT and tiled but that isn't supported by 342a1e5795279bd085496fa04c59e588f440bf30457robertphillips@google.com // the current hardware. Resize the texture to be a POT 343b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com GrAssert(NULL != params); 344b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com TextureCacheEntry clampEntry = this->findAndLockTexture(desc, NULL); 34527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 34650398bf7f1953e640e5529616e710cf540799731bsalomon@google.com if (NULL == clampEntry.texture()) { 347b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com clampEntry = this->createAndLockTexture(NULL, desc, srcData, rowBytes); 34850398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrAssert(NULL != clampEntry.texture()); 34950398bf7f1953e640e5529616e710cf540799731bsalomon@google.com if (NULL == clampEntry.texture()) { 35050398bf7f1953e640e5529616e710cf540799731bsalomon@google.com return entry; 35127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 35227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 353fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com GrTextureDesc rtDesc = desc; 354fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com rtDesc.fFlags = rtDesc.fFlags | 355fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com kRenderTarget_GrTextureFlagBit | 356fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com kNoStencil_GrTextureFlagBit; 3579962108c400dadcae913614e8a5ab781780981d8bsalomon@google.com rtDesc.fWidth = GrNextPow2(GrMax(desc.fWidth, 64)); 3589962108c400dadcae913614e8a5ab781780981d8bsalomon@google.com rtDesc.fHeight = GrNextPow2(GrMax(desc.fHeight, 64)); 35927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 36027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrTexture* texture = fGpu->createTexture(rtDesc, NULL, 0); 36127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 36227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL != texture) { 363b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com GrDrawTarget::AutoStateRestore asr(fGpu, GrDrawTarget::kReset_ASRInit); 3648f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = fGpu->drawState(); 3658f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setRenderTarget(texture->asRenderTarget()); 36682c7bd8f25682fcacfeea12ed899976504a767ffbsalomon@google.com 3676aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com // if filtering is not desired then we want to ensure all 3686aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com // texels in the resampled image are copies of texels from 3696aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com // the original. 370b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com drawState->sampler(0)->reset(SkShader::kClamp_TileMode, 371b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com GrTexture::NeedsFiltering(resourceKey)); 3728f4fdc9968123d508d4bb17b5d15946a990613d4bsalomon@google.com drawState->createTextureEffect(0, clampEntry.texture()); 37327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 37427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com static const GrVertexLayout layout = 37527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget::StageTexCoordVertexLayoutBit(0,0); 37627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget::AutoReleaseGeometry arg(fGpu, layout, 4, 0); 37727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 37827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (arg.succeeded()) { 37927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrPoint* verts = (GrPoint*) arg.vertices(); 38027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[0].setIRectFan(0, 0, 38127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com texture->width(), 38227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com texture->height(), 38327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 2*sizeof(GrPoint)); 38427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[1].setIRectFan(0, 0, 1, 1, 2*sizeof(GrPoint)); 38547059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com fGpu->drawNonIndexed(kTriangleFan_GrPrimitiveType, 38627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 0, 4); 38750398bf7f1953e640e5529616e710cf540799731bsalomon@google.com entry.set(fTextureCache->createAndLock(resourceKey, texture)); 38827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 3891da0746fa155cdca982ae8deb68cc64f540c92dfbsalomon@google.com texture->releaseRenderTarget(); 39027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 39127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // TODO: Our CPU stretch doesn't filter. But we create separate 39227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // stretched textures when the sampler state is either filtered or 39327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // not. Either implement filtered stretch blit on CPU or just create 39427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // one when FBO case fails. 39527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 396fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com rtDesc.fFlags = kNone_GrTextureFlags; 39727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // no longer need to clamp at min RT size. 39827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com rtDesc.fWidth = GrNextPow2(desc.fWidth); 39927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com rtDesc.fHeight = GrNextPow2(desc.fHeight); 40064c4fe4113424bcfab8b3e0c7049887fda5ab4ffbsalomon@google.com int bpp = GrBytesPerPixel(desc.fConfig); 4013582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com SkAutoSMalloc<128*128*4> stretchedPixels(bpp * 40227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com rtDesc.fWidth * 40327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com rtDesc.fHeight); 40427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com stretchImage(stretchedPixels.get(), rtDesc.fWidth, rtDesc.fHeight, 40527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com srcData, desc.fWidth, desc.fHeight, bpp); 40627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 40727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com size_t stretchedRowBytes = rtDesc.fWidth * bpp; 40827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 40927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrTexture* texture = fGpu->createTexture(rtDesc, 41027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com stretchedPixels.get(), 41127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com stretchedRowBytes); 41227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrAssert(NULL != texture); 41350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com entry.set(fTextureCache->createAndLock(resourceKey, texture)); 41427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 41550398bf7f1953e640e5529616e710cf540799731bsalomon@google.com fTextureCache->unlock(clampEntry.cacheEntry()); 41627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 41727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 41827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrTexture* texture = fGpu->createTexture(desc, srcData, rowBytes); 41927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL != texture) { 42050398bf7f1953e640e5529616e710cf540799731bsalomon@google.com entry.set(fTextureCache->createAndLock(resourceKey, texture)); 42127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 42227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 42327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return entry; 42427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 42527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 42650398bf7f1953e640e5529616e710cf540799731bsalomon@google.comGrContext::TextureCacheEntry GrContext::lockScratchTexture( 42750398bf7f1953e640e5529616e710cf540799731bsalomon@google.com const GrTextureDesc& inDesc, 42850398bf7f1953e640e5529616e710cf540799731bsalomon@google.com ScratchTexMatch match) { 429b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com GrTextureDesc desc = inDesc; 43075b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com desc.fClientCacheID = kScratch_CacheID; 43175b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com 43250398bf7f1953e640e5529616e710cf540799731bsalomon@google.com if (kExact_ScratchTexMatch != match) { 43350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com // bin by pow2 with a reasonable min 43450398bf7f1953e640e5529616e710cf540799731bsalomon@google.com static const int MIN_SIZE = 256; 43550398bf7f1953e640e5529616e710cf540799731bsalomon@google.com desc.fWidth = GrMax(MIN_SIZE, GrNextPow2(desc.fWidth)); 43650398bf7f1953e640e5529616e710cf540799731bsalomon@google.com desc.fHeight = GrMax(MIN_SIZE, GrNextPow2(desc.fHeight)); 43750398bf7f1953e640e5529616e710cf540799731bsalomon@google.com } 438b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com 43950398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrResourceEntry* entry; 440b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com int origWidth = desc.fWidth; 441b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com int origHeight = desc.fHeight; 442b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com bool doubledW = false; 443b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com bool doubledH = false; 444b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com 445b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com do { 44675b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com GrResourceKey key = GrTexture::ComputeKey(fGpu, NULL, desc, true); 447558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com entry = fTextureCache->findAndLock(key, 448558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com GrResourceCache::kNested_LockType); 449b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com // if we miss, relax the fit of the flags... 450b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com // then try doubling width... then height. 45150398bf7f1953e640e5529616e710cf540799731bsalomon@google.com if (NULL != entry || kExact_ScratchTexMatch == match) { 452b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com break; 453b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } 454b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com if (!(desc.fFlags & kRenderTarget_GrTextureFlagBit)) { 455b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fFlags = desc.fFlags | kRenderTarget_GrTextureFlagBit; 456b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } else if (desc.fFlags & kNoStencil_GrTextureFlagBit) { 457b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fFlags = desc.fFlags & ~kNoStencil_GrTextureFlagBit; 458b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } else if (!doubledW) { 459b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fFlags = inDesc.fFlags; 460b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fWidth *= 2; 461b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com doubledW = true; 462b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } else if (!doubledH) { 463b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fFlags = inDesc.fFlags; 464b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fWidth = origWidth; 465b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fHeight *= 2; 466b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com doubledH = true; 467b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } else { 468b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com break; 469b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } 470b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com 471b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } while (true); 472b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com 473b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com if (NULL == entry) { 474b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fFlags = inDesc.fFlags; 475b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fWidth = origWidth; 476b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com desc.fHeight = origHeight; 477b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com GrTexture* texture = fGpu->createTexture(desc, NULL, 0); 478b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com if (NULL != texture) { 47975b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com GrResourceKey key = GrTexture::ComputeKey(fGpu, NULL, 480a1e5795279bd085496fa04c59e588f440bf30457robertphillips@google.com texture->desc(), 481a1e5795279bd085496fa04c59e588f440bf30457robertphillips@google.com true); 482b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com entry = fTextureCache->createAndLock(key, texture); 483b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } 484b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } 485b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com 486b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com // If the caller gives us the same desc/sampler twice we don't want 487b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com // to return the same texture the second time (unless it was previously 488b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com // released). So we detach the entry from the cache and reattach at release. 489b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com if (NULL != entry) { 490b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com fTextureCache->detach(entry); 491b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com } 49250398bf7f1953e640e5529616e710cf540799731bsalomon@google.com return TextureCacheEntry(entry); 493b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com} 494b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com 49515c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.comvoid GrContext::addExistingTextureToCache(GrTexture* texture) { 49615c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com 49715c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com if (NULL == texture) { 49815c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com return; 49915c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com } 50015c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com 50115c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com GrResourceKey key = GrTexture::ComputeKey(fGpu, NULL, 50215c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com texture->desc(), 50315c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com true); 50415c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com fTextureCache->attach(key, texture); 50515c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com} 50615c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com 50750398bf7f1953e640e5529616e710cf540799731bsalomon@google.comvoid GrContext::unlockTexture(TextureCacheEntry entry) { 508bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(entry.texture()); 50950398bf7f1953e640e5529616e710cf540799731bsalomon@google.com // If this is a scratch texture we detached it from the cache 51050398bf7f1953e640e5529616e710cf540799731bsalomon@google.com // while it was locked (to avoid two callers simultaneously getting 51150398bf7f1953e640e5529616e710cf540799731bsalomon@google.com // the same texture). 512a1e5795279bd085496fa04c59e588f440bf30457robertphillips@google.com if (GrTexture::IsScratchTexture(entry.cacheEntry()->key())) { 51350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com fTextureCache->reattachAndUnlock(entry.cacheEntry()); 514fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com } else { 51550398bf7f1953e640e5529616e710cf540799731bsalomon@google.com fTextureCache->unlock(entry.cacheEntry()); 516fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com } 51727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 51827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 51915c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.comvoid GrContext::freeEntry(TextureCacheEntry entry) { 52015c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com ASSERT_OWNED_RESOURCE(entry.texture()); 52115c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com 52215c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com fTextureCache->freeEntry(entry.cacheEntry()); 52315c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com} 52415c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com 52575b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.comGrTexture* GrContext::createUncachedTexture(const GrTextureDesc& descIn, 52627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com void* srcData, 52727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com size_t rowBytes) { 52875b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com GrTextureDesc descCopy = descIn; 52975b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com descCopy.fClientCacheID = kUncached_CacheID; 53075b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com return fGpu->createTexture(descCopy, srcData, rowBytes); 53127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 53227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 53307fc0d178e20f74a88dd78384f817b53204e625fbsalomon@google.comvoid GrContext::getTextureCacheLimits(int* maxTextures, 53407fc0d178e20f74a88dd78384f817b53204e625fbsalomon@google.com size_t* maxTextureBytes) const { 53507fc0d178e20f74a88dd78384f817b53204e625fbsalomon@google.com fTextureCache->getLimits(maxTextures, maxTextureBytes); 53627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 53727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 53807fc0d178e20f74a88dd78384f817b53204e625fbsalomon@google.comvoid GrContext::setTextureCacheLimits(int maxTextures, size_t maxTextureBytes) { 53907fc0d178e20f74a88dd78384f817b53204e625fbsalomon@google.com fTextureCache->setLimits(maxTextures, maxTextureBytes); 54027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 54127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 542919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.comint GrContext::getMaxTextureSize() const { 54318c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com return fGpu->getCaps().fMaxTextureSize; 544919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com} 545919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com 546919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.comint GrContext::getMaxRenderTargetSize() const { 54718c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com return fGpu->getCaps().fMaxRenderTargetSize; 54827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 54927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 55027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com/////////////////////////////////////////////////////////////////////////////// 55127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 552e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.comGrTexture* GrContext::createPlatformTexture(const GrPlatformTextureDesc& desc) { 553e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com return fGpu->createPlatformTexture(desc); 554e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com} 555e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com 556e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.comGrRenderTarget* GrContext::createPlatformRenderTarget(const GrPlatformRenderTargetDesc& desc) { 557e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com return fGpu->createPlatformRenderTarget(desc); 558e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com} 559e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com 5605877ffd5ea71a3ea70096d5c11c843798defa690bsalomon@google.com/////////////////////////////////////////////////////////////////////////////// 5615877ffd5ea71a3ea70096d5c11c843798defa690bsalomon@google.com 562b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.combool GrContext::supportsIndex8PixelConfig(const GrTextureParams* params, 5631f221a70214fa1ab87b8a32dd66facf485f318eebsalomon@google.com int width, int height) const { 56418c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com const GrDrawTarget::Caps& caps = fGpu->getCaps(); 56518c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com if (!caps.f8BitPaletteSupport) { 56627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return false; 56727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 56827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 56927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com bool isPow2 = GrIsPow2(width) && GrIsPow2(height); 57027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 57127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (!isPow2) { 572b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com bool tiled = NULL != params && params->isTiled(); 57318c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com if (tiled && !caps.fNPOTTextureTileSupport) { 57427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return false; 57527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 57627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 57727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return true; 57827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 57927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 58027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 58127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 582beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.comconst GrClipData* GrContext::getClip() const { 583beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.com return fGpu->getClip(); 584beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.com} 58505ef510389950e1ae8dcba40e41e001db771b12dbsalomon@google.com 586beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.comvoid GrContext::setClip(const GrClipData* clipData) { 587beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.com fGpu->setClip(clipData); 58810e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com fDrawState->enableState(GrDrawState::kClip_StateBit); 58927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 59027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 59127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 59227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 593c82a8b7aa4ec19fba508c394920a9e88d3e5bd12robertphillips@google.comvoid GrContext::clear(const GrIRect* rect, 594c82a8b7aa4ec19fba508c394920a9e88d3e5bd12robertphillips@google.com const GrColor color, 595c82a8b7aa4ec19fba508c394920a9e88d3e5bd12robertphillips@google.com GrRenderTarget* target) { 596398109cc3e56b8122ad21c4d43a74a83be5b42a8bsalomon@google.com this->flush(); 597c82a8b7aa4ec19fba508c394920a9e88d3e5bd12robertphillips@google.com fGpu->clear(rect, color, target); 59827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 59927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 60027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::drawPaint(const GrPaint& paint) { 60127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // set rect to be big enough to fill the space, but not super-huge, so we 60227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // don't overflow fixed-point implementations 603d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com GrRect r; 604d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com r.setLTRB(0, 0, 605d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com GrIntToScalar(getRenderTarget()->width()), 606d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com GrIntToScalar(getRenderTarget()->height())); 60727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrMatrix inverse; 6088c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com SkTLazy<GrPaint> tmpPaint; 6098c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com const GrPaint* p = &paint; 610fea85ac3e31842f80493e2df8a93a28f21cd815frobertphillips@google.com AutoMatrix am; 6118f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com 6124f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com // We attempt to map r by the inverse matrix and draw that. mapRect will 6134f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com // map the four corners and bound them with a new rect. This will not 6144f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com // produce a correct result for some perspective matrices. 6158c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com if (!this->getMatrix().hasPerspective()) { 61610e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com if (!fDrawState->getViewInverse(&inverse)) { 617e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com GrPrintf("Could not invert matrix\n"); 6188c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com return; 6198c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com } 62027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com inverse.mapRect(&r); 62127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 622e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com if (paint.hasTextureOrMask()) { 6238c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com tmpPaint.set(paint); 6248c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com p = tmpPaint.get(); 625e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com if (!tmpPaint.get()->preConcatSamplerMatricesWithInverse(fDrawState->getViewMatrix())) { 626e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com GrPrintf("Could not invert matrix\n"); 627e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com } 6288c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com } 6294f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com am.set(this, GrMatrix::I()); 63027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 6314f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com // by definition this fills the entire clip, no need for AA 6324f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com if (paint.fAntiAlias) { 6338c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com if (!tmpPaint.isValid()) { 6348c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com tmpPaint.set(paint); 6358c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com p = tmpPaint.get(); 6368c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com } 6378c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com GrAssert(p == tmpPaint.get()); 6388c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com tmpPaint.get()->fAntiAlias = false; 6394f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com } 6404f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com this->drawRect(*p, r); 64127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 64227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 643205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 644205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 645d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.comnamespace { 646d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.cominline bool disable_coverage_aa_for_blend(GrDrawTarget* target) { 647d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com return DISABLE_COVERAGE_AA_FOR_BLEND && !target->canApplyCoverage(); 648d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com} 649d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com} 650d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com 65106afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 65206afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com 65327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com/* create a triangle strip that strokes the specified triangle. There are 8 65427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com unique vertices, but we repreat the last 2 to close up. Alternatively we 65527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com could use an indices array, and then only send 8 verts, but not sure that 65627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com would be faster. 65727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com */ 658205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comstatic void setStrokeRectStrip(GrPoint verts[10], GrRect rect, 65927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrScalar width) { 66027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrScalar rad = GrScalarHalf(width); 661205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com rect.sort(); 66227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 66327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[0].set(rect.fLeft + rad, rect.fTop + rad); 66427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[1].set(rect.fLeft - rad, rect.fTop - rad); 66527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[2].set(rect.fRight - rad, rect.fTop + rad); 66627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[3].set(rect.fRight + rad, rect.fTop - rad); 66727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[4].set(rect.fRight - rad, rect.fBottom - rad); 66827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[5].set(rect.fRight + rad, rect.fBottom + rad); 66927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[6].set(rect.fLeft + rad, rect.fBottom - rad); 67027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[7].set(rect.fLeft - rad, rect.fBottom + rad); 67127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[8] = verts[0]; 67227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com verts[9] = verts[1]; 67327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 67427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 67520efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com/** 67620efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com * Returns true if the rects edges are integer-aligned. 67720efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com */ 67820efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.comstatic bool isIRect(const GrRect& r) { 67920efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com return GrScalarIsInt(r.fLeft) && GrScalarIsInt(r.fTop) && 68020efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com GrScalarIsInt(r.fRight) && GrScalarIsInt(r.fBottom); 68120efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com} 68220efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com 683205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comstatic bool apply_aa_to_rect(GrDrawTarget* target, 684205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com const GrRect& rect, 685205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrScalar width, 686205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com const GrMatrix* matrix, 687205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrMatrix* combinedMatrix, 688a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com GrRect* devRect, 689a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com bool* useVertexCoverage) { 6902eba795bcda66813fdc7a7c4388a99ae9cb2c864bsalomon@google.com // we use a simple coverage ramp to do aa on axis-aligned rects 6912eba795bcda66813fdc7a7c4388a99ae9cb2c864bsalomon@google.com // we check if the rect will be axis-aligned, and the rect won't land on 6922eba795bcda66813fdc7a7c4388a99ae9cb2c864bsalomon@google.com // integer coords. 693d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com 694a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com // we are keeping around the "tweak the alpha" trick because 695a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com // it is our only hope for the fixed-pipe implementation. 696a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com // In a shader implementation we can give a separate coverage input 697289533ada623f2238a83771eec977f204f75994fbsalomon@google.com // TODO: remove this ugliness when we drop the fixed-pipe impl 698a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com *useVertexCoverage = false; 699d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com if (!target->canTweakAlphaForCoverage()) { 7002eba795bcda66813fdc7a7c4388a99ae9cb2c864bsalomon@google.com if (disable_coverage_aa_for_blend(target)) { 7011983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#if GR_DEBUG 7022eba795bcda66813fdc7a7c4388a99ae9cb2c864bsalomon@google.com //GrPrintf("Turning off AA to correctly apply blend.\n"); 7031983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#endif 704a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com return false; 7052eba795bcda66813fdc7a7c4388a99ae9cb2c864bsalomon@google.com } else { 7062eba795bcda66813fdc7a7c4388a99ae9cb2c864bsalomon@google.com *useVertexCoverage = true; 707a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com } 708205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 7098f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com const GrDrawState& drawState = target->getDrawState(); 7108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com if (drawState.getRenderTarget()->isMultisampled()) { 711205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return false; 712205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 713205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 714471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com if (0 == width && target->willUseHWAALines()) { 715205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return false; 716205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 717205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 7188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com if (!drawState.getViewMatrix().preservesAxisAlignment()) { 719205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return false; 720205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 721205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 722205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (NULL != matrix && 723205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com !matrix->preservesAxisAlignment()) { 724205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return false; 725205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 726205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 7278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com *combinedMatrix = drawState.getViewMatrix(); 728205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (NULL != matrix) { 729205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com combinedMatrix->preConcat(*matrix); 730205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrAssert(combinedMatrix->preservesAxisAlignment()); 731205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 732205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 733205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com combinedMatrix->mapRect(devRect, rect); 734205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com devRect->sort(); 735205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 736205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (width < 0) { 73720efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com return !isIRect(*devRect); 738205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } else { 739205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return true; 740205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 741205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com} 742205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 74327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::drawRect(const GrPaint& paint, 74427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrRect& rect, 74527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrScalar width, 74627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrMatrix* matrix) { 747278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com SK_TRACE_EVENT0("GrContext::drawRect"); 74827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 74927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory); 7507d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com GrDrawState::AutoStageDisable atr(fDrawState); 75127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 752205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrRect devRect = rect; 753205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrMatrix combinedMatrix; 754a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com bool useVertexCoverage; 755289533ada623f2238a83771eec977f204f75994fbsalomon@google.com bool needAA = paint.fAntiAlias && 756289533ada623f2238a83771eec977f204f75994fbsalomon@google.com !this->getRenderTarget()->isMultisampled(); 757289533ada623f2238a83771eec977f204f75994fbsalomon@google.com bool doAA = needAA && apply_aa_to_rect(target, rect, width, matrix, 758289533ada623f2238a83771eec977f204f75994fbsalomon@google.com &combinedMatrix, &devRect, 759289533ada623f2238a83771eec977f204f75994fbsalomon@google.com &useVertexCoverage); 760205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 761205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (doAA) { 762e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com GrDrawTarget::AutoDeviceCoordDraw adcd(target); 763e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com if (!adcd.succeeded()) { 764e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com return; 765e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com } 766205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (width >= 0) { 767205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com GrVec strokeSize;; 768205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com if (width > 0) { 769205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com strokeSize.set(width, width); 770cc4dac3dac215dc0dd56f7b30d07cc304671b033bsalomon@google.com combinedMatrix.mapVectors(&strokeSize, 1); 771205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com strokeSize.setAbs(strokeSize); 772205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } else { 773205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com strokeSize.set(GR_Scalar1, GR_Scalar1); 774205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 775f6747b0b90b3a270ec7b7bdfdc211cf5c19f28c2robertphillips@google.com fAARectRenderer->strokeAARect(this->getGpu(), target, devRect, 776f6747b0b90b3a270ec7b7bdfdc211cf5c19f28c2robertphillips@google.com strokeSize, useVertexCoverage); 777205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } else { 778f6747b0b90b3a270ec7b7bdfdc211cf5c19f28c2robertphillips@google.com fAARectRenderer->fillAARect(this->getGpu(), target, 779f6747b0b90b3a270ec7b7bdfdc211cf5c19f28c2robertphillips@google.com devRect, useVertexCoverage); 780205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 781205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com return; 782205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com } 783205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 78427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (width >= 0) { 78527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // TODO: consider making static vertex buffers for these cases. 78627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // Hairline could be done by just adding closing vertex to 78727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // unitSquareVertexBuffer() 78826c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 78927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com static const int worstCaseVertCount = 10; 790e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com GrDrawTarget::AutoReleaseGeometry geo(target, 0, worstCaseVertCount, 0); 79127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 79227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (!geo.succeeded()) { 7936513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com GrPrintf("Failed to get space for vertices!\n"); 79427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return; 79527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 79627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 79727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrPrimitiveType primType; 79827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int vertCount; 79927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrPoint* vertex = geo.positions(); 80027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 80127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (width > 0) { 80227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertCount = 10; 80347059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com primType = kTriangleStrip_GrPrimitiveType; 80427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com setStrokeRectStrip(vertex, rect, width); 80527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 80627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // hairline 80727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertCount = 5; 80847059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com primType = kLineStrip_GrPrimitiveType; 80927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertex[0].set(rect.fLeft, rect.fTop); 81027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertex[1].set(rect.fRight, rect.fTop); 81127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertex[2].set(rect.fRight, rect.fBottom); 81227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertex[3].set(rect.fLeft, rect.fBottom); 81327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com vertex[4].set(rect.fLeft, rect.fTop); 81427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 81527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 8168f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState::AutoViewMatrixRestore avmr; 81727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL != matrix) { 8188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = target->drawState(); 8198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com avmr.set(drawState); 8208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->preConcatViewMatrix(*matrix); 821e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com drawState->preConcatSamplerMatrices(*matrix); 82227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 82327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 82427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target->drawNonIndexed(primType, 0, vertCount); 82527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 8268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com#if GR_STATIC_RECT_VB 8276513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com const GrVertexBuffer* sqVB = fGpu->getUnitSquareVertexBuffer(); 8286513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com if (NULL == sqVB) { 8296513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com GrPrintf("Failed to create static rect vb.\n"); 8306513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com return; 8316513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com } 832e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com target->setVertexSourceToBuffer(0, sqVB); 8338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = target->drawState(); 8348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState::AutoViewMatrixRestore avmr(drawState); 83527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrMatrix m; 8368295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com m.setAll(rect.width(), 0, rect.fLeft, 837205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 0, rect.height(), rect.fTop, 838205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com 0, 0, GrMatrix::I()[8]); 83927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 84027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL != matrix) { 84127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com m.postConcat(*matrix); 84227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 8438f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->preConcatViewMatrix(m); 844e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com drawState->preConcatSamplerMatrices(m); 84526c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 84647059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com target->drawNonIndexed(kTriangleFan_GrPrimitiveType, 0, 4); 8478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com#else 848e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com target->drawSimpleRect(rect, matrix); 8498f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com#endif 85027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 85127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 85227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 85327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::drawRectToRect(const GrPaint& paint, 85427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrRect& dstRect, 85527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrRect& srcRect, 85627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrMatrix* dstMatrix, 85727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrMatrix* srcMatrix) { 858278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com SK_TRACE_EVENT0("GrContext::drawRectToRect"); 85927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 86026c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com // srcRect refers to paint's first texture 861f13f58804659175925042a291304d483a4fd9278tomhudson@google.com if (!paint.isTextureStageEnabled(0)) { 86227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com drawRect(paint, dstRect, -1, dstMatrix); 86327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return; 86427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 865de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com 86627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GR_STATIC_ASSERT(!BATCH_RECT_TO_RECT || !GR_STATIC_RECT_VB); 86727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 86827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#if GR_STATIC_RECT_VB 86927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory); 8707d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com GrDrawState::AutoStageDisable atr(fDrawState); 8718f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = target->drawState(); 8728f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState::AutoViewMatrixRestore avmr(drawState); 87327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 87427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrMatrix m; 87527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 87627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com m.setAll(dstRect.width(), 0, dstRect.fLeft, 87727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 0, dstRect.height(), dstRect.fTop, 87827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 0, 0, GrMatrix::I()[8]); 87927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL != dstMatrix) { 88027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com m.postConcat(*dstMatrix); 88127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 8828f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->preConcatViewMatrix(m); 88327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 884e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com // we explicitly setup the correct coords for the first stage. The others 885e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com // must know about the view matrix change. 886e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com for (int s = 1; s < GrPaint::kTotalStages; ++s) { 887e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com if (drawState->isStageEnabled(s)) { 888e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com drawState->sampler(s)->preConcatMatrix(m); 889e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com } 89026c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com } 89126c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 89227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com m.setAll(srcRect.width(), 0, srcRect.fLeft, 89327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 0, srcRect.height(), srcRect.fTop, 89427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 0, 0, GrMatrix::I()[8]); 89527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL != srcMatrix) { 89627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com m.postConcat(*srcMatrix); 89727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 8988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->sampler(GrPaint::kFirstTextureStage)->preConcatMatrix(m); 89927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 9006513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com const GrVertexBuffer* sqVB = fGpu->getUnitSquareVertexBuffer(); 9016513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com if (NULL == sqVB) { 9026513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com GrPrintf("Failed to create static rect vb.\n"); 9036513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com return; 9046513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com } 905e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com target->setVertexSourceToBuffer(0, sqVB); 90647059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com target->drawNonIndexed(kTriangleFan_GrPrimitiveType, 0, 4); 90727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#else 90827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 90927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget* target; 910de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com#if BATCH_RECT_TO_RECT 91127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target = this->prepareToDraw(paint, kBuffered_DrawCategory); 912de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com#else 91327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target = this->prepareToDraw(paint, kUnbuffered_DrawCategory); 91427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#endif 9157d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com GrDrawState::AutoStageDisable atr(fDrawState); 91627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 9179381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com const GrRect* srcRects[GrDrawState::kNumStages] = {NULL}; 9189381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com const GrMatrix* srcMatrices[GrDrawState::kNumStages] = {NULL}; 91927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com srcRects[0] = &srcRect; 92027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com srcMatrices[0] = srcMatrix; 92127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 922e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com target->drawRect(dstRect, dstMatrix, srcRects, srcMatrices); 92327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#endif 92427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 92527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 92627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::drawVertices(const GrPaint& paint, 92727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrPrimitiveType primitiveType, 92827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int vertexCount, 92927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrPoint positions[], 93027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrPoint texCoords[], 93127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const GrColor colors[], 93227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com const uint16_t indices[], 93327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int indexCount) { 934278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com SK_TRACE_EVENT0("GrContext::drawVertices"); 93527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 93627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget::AutoReleaseGeometry geo; 93727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 93827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory); 9397d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com GrDrawState::AutoStageDisable atr(fDrawState); 94027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 941e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com GrVertexLayout layout = 0; 942e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com if (NULL != texCoords) { 943e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com layout |= GrDrawTarget::StageTexCoordVertexLayoutBit(0, 0); 944e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com } 94527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL != colors) { 94627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com layout |= GrDrawTarget::kColor_VertexLayoutBit; 94727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 94826c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com int vertexSize = GrDrawTarget::VertexSize(layout); 94927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 95027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (sizeof(GrPoint) != vertexSize) { 95127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (!geo.set(target, layout, vertexCount, 0)) { 9526513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com GrPrintf("Failed to get space for vertices!\n"); 95327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return; 95427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 9559381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com int texOffsets[GrDrawState::kMaxTexCoords]; 95627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com int colorOffset; 95726c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com GrDrawTarget::VertexSizeAndOffsetsByIdx(layout, 95826c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com texOffsets, 959aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com &colorOffset, 960a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com NULL, 961a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com NULL); 96227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com void* curVertex = geo.vertices(); 96327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 96427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com for (int i = 0; i < vertexCount; ++i) { 96527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com *((GrPoint*)curVertex) = positions[i]; 96627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 96727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (texOffsets[0] > 0) { 96827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com *(GrPoint*)((intptr_t)curVertex + texOffsets[0]) = texCoords[i]; 96927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 97027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (colorOffset > 0) { 97127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com *(GrColor*)((intptr_t)curVertex + colorOffset) = colors[i]; 97227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 97326c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com curVertex = (void*)((intptr_t)curVertex + vertexSize); 97427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 97527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 97627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com target->setVertexSourceToArray(layout, positions, vertexCount); 97727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 97827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 979919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com // we don't currently apply offscreen AA to this path. Need improved 980919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com // management of GrDrawTarget's geometry to avoid copying points per-tile. 981a47a48dca5045d71cbc5de343404045209a13e15bsalomon@google.com 9828295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com if (NULL != indices) { 983919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com target->setIndexSourceToArray(indices, indexCount); 9848295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com target->drawIndexed(primitiveType, 0, 0, vertexCount, indexCount); 98527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 9868295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com target->drawNonIndexed(primitiveType, 0, vertexCount); 9878295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com } 98827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 98927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 99006afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com/////////////////////////////////////////////////////////////////////////////// 991150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.comnamespace { 992150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com 99393c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.comstruct CircleVertex { 99493c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com GrPoint fPos; 99593c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com GrPoint fCenter; 99693c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com GrScalar fOuterRadius; 99793c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com GrScalar fInnerRadius; 99893c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com}; 99993c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 100093c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com/* Returns true if will map a circle to another circle. This can be true 100193c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com * if the matrix only includes square-scale, rotation, translation. 100293c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com */ 100393c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.cominline bool isSimilarityTransformation(const SkMatrix& matrix, 100493c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com SkScalar tol = SK_ScalarNearlyZero) { 100593c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com if (matrix.isIdentity() || matrix.getType() == SkMatrix::kTranslate_Mask) { 100693c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com return true; 100793c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com } 100893c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com if (matrix.hasPerspective()) { 100993c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com return false; 101093c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com } 101193c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 101293c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com SkScalar mx = matrix.get(SkMatrix::kMScaleX); 101393c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com SkScalar sx = matrix.get(SkMatrix::kMSkewX); 101493c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com SkScalar my = matrix.get(SkMatrix::kMScaleY); 101593c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com SkScalar sy = matrix.get(SkMatrix::kMSkewY); 101693c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 101793c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com if (mx == 0 && sx == 0 && my == 0 && sy == 0) { 101893c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com return false; 101993c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com } 102093c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 102193c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com // it has scales or skews, but it could also be rotation, check it out. 102293c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com SkVector vec[2]; 102393c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com vec[0].set(mx, sx); 102493c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com vec[1].set(sy, my); 102593c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 102693c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com return SkScalarNearlyZero(vec[0].dot(vec[1]), SkScalarSquare(tol)) && 102793c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com SkScalarNearlyEqual(vec[0].lengthSqd(), vec[1].lengthSqd(), 102893c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com SkScalarSquare(tol)); 102993c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com} 103093c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 103193c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com} 103293c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 103393c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com// TODO: strokeWidth can't be larger than zero right now. 103493c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com// It will be fixed when drawPath() can handle strokes. 103593c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.comvoid GrContext::drawOval(const GrPaint& paint, 103693c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com const GrRect& rect, 103793c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com SkScalar strokeWidth) { 103893c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com DrawCategory category = (DEFER_PATHS) ? kBuffered_DrawCategory : 103993c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com kUnbuffered_DrawCategory; 104093c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com GrDrawTarget* target = this->prepareToDraw(paint, category); 10417d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com GrDrawState::AutoStageDisable atr(fDrawState); 104293c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com GrDrawState* drawState = target->drawState(); 104393c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com GrMatrix vm = drawState->getViewMatrix(); 104493c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 104593c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com if (!isSimilarityTransformation(vm) || 104693c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com !paint.fAntiAlias || 104793c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com rect.height() != rect.width()) { 104893c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com SkPath path; 104993c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com path.addOval(rect); 105093c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com GrPathFill fill = (strokeWidth == 0) ? 105147059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com kHairLine_GrPathFill : kWinding_GrPathFill; 105293c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com this->internalDrawPath(paint, path, fill, NULL); 105393c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com return; 105493c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com } 105593c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 105693c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com const GrRenderTarget* rt = drawState->getRenderTarget(); 105793c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com if (NULL == rt) { 105893c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com return; 105993c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com } 106093c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 1061e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com GrDrawTarget::AutoDeviceCoordDraw adcd(target); 1062e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com if (!adcd.succeeded()) { 1063e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com return; 1064e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com } 106593c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 1066e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com GrVertexLayout layout = GrDrawTarget::kEdge_VertexLayoutBit; 106793c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com GrAssert(sizeof(CircleVertex) == GrDrawTarget::VertexSize(layout)); 106893c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 106993c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com GrPoint center = GrPoint::Make(rect.centerX(), rect.centerY()); 107093c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com GrScalar radius = SkScalarHalf(rect.width()); 107193c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 107293c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com vm.mapPoints(¢er, 1); 107393c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com radius = vm.mapRadius(radius); 107493c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 107593c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com GrScalar outerRadius = radius; 107693c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com GrScalar innerRadius = 0; 107793c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com SkScalar halfWidth = 0; 107893c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com if (strokeWidth == 0) { 107993c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com halfWidth = SkScalarHalf(SK_Scalar1); 108093c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 108193c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com outerRadius += halfWidth; 108293c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com innerRadius = SkMaxScalar(0, radius - halfWidth); 108393c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com } 108493c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 108593c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com GrDrawTarget::AutoReleaseGeometry geo(target, layout, 4, 0); 108693c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com if (!geo.succeeded()) { 108793c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com GrPrintf("Failed to get space for vertices!\n"); 108893c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com return; 108993c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com } 109093c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 109193c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com CircleVertex* verts = reinterpret_cast<CircleVertex*>(geo.vertices()); 109293c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 1093a0a66c118392fdc6f84f18ac634473468e31becbrobertphillips@google.com // The fragment shader will extend the radius out half a pixel 1094a0a66c118392fdc6f84f18ac634473468e31becbrobertphillips@google.com // to antialias. Expand the drawn rect here so all the pixels 1095a0a66c118392fdc6f84f18ac634473468e31becbrobertphillips@google.com // will be captured. 1096a0a66c118392fdc6f84f18ac634473468e31becbrobertphillips@google.com SkScalar L = center.fX - outerRadius - SkFloatToScalar(0.5f); 1097a0a66c118392fdc6f84f18ac634473468e31becbrobertphillips@google.com SkScalar R = center.fX + outerRadius + SkFloatToScalar(0.5f); 1098a0a66c118392fdc6f84f18ac634473468e31becbrobertphillips@google.com SkScalar T = center.fY - outerRadius - SkFloatToScalar(0.5f); 1099a0a66c118392fdc6f84f18ac634473468e31becbrobertphillips@google.com SkScalar B = center.fY + outerRadius + SkFloatToScalar(0.5f); 110093c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 110193c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com verts[0].fPos = SkPoint::Make(L, T); 110293c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com verts[1].fPos = SkPoint::Make(R, T); 110393c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com verts[2].fPos = SkPoint::Make(L, B); 110493c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com verts[3].fPos = SkPoint::Make(R, B); 110593c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 110693c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com for (int i = 0; i < 4; ++i) { 110793c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com // this goes to fragment shader, it should be in y-points-up space. 110893c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com verts[i].fCenter = SkPoint::Make(center.fX, rt->height() - center.fY); 110993c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 111093c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com verts[i].fOuterRadius = outerRadius; 111193c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com verts[i].fInnerRadius = innerRadius; 111293c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com } 111393c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 111493c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com drawState->setVertexEdgeType(GrDrawState::kCircle_EdgeType); 111547059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com target->drawNonIndexed(kTriangleStrip_GrPrimitiveType, 0, 4); 1116150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com} 111727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 11188d033a1b125886c62906d975b5cc28a382064526bsalomon@google.comvoid GrContext::drawPath(const GrPaint& paint, const SkPath& path, 111907f3ee10d34f09342abb93d758b5e151ff78f7a5reed@google.com GrPathFill fill, const GrPoint* translate) { 112027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1121fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com if (path.isEmpty()) { 1122fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com if (GrIsFillInverted(fill)) { 1123fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com this->drawPaint(paint); 1124fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 1125fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com return; 1126fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com } 1127fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com 112893c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com SkRect ovalRect; 112993c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com if (!GrIsFillInverted(fill) && path.isOval(&ovalRect)) { 113093c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com if (translate) { 113193c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com ovalRect.offset(*translate); 113293c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com } 113347059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com SkScalar width = (fill == kHairLine_GrPathFill) ? 0 : -SK_Scalar1; 113493c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com this->drawOval(paint, ovalRect, width); 113593c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com return; 113693c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com } 113793c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 113893c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com internalDrawPath(paint, path, fill, translate); 113993c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com} 114093c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 11418d033a1b125886c62906d975b5cc28a382064526bsalomon@google.comvoid GrContext::internalDrawPath(const GrPaint& paint, const SkPath& path, 114293c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com GrPathFill fill, const GrPoint* translate) { 114393c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com 1144fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.com // Note that below we may sw-rasterize the path into a scratch texture. 1145fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.com // Scratch textures can be recycled after they are returned to the texture 1146fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.com // cache. This presents a potential hazard for buffered drawing. However, 1147fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.com // the writePixels that uploads to the scratch will perform a flush so we're 1148fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.com // OK. 1149fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.com DrawCategory category = (DEFER_PATHS) ? kBuffered_DrawCategory : 1150fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.com kUnbuffered_DrawCategory; 1151fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.com GrDrawTarget* target = this->prepareToDraw(paint, category); 11527d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com GrDrawState::AutoStageDisable atr(fDrawState); 1153d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com 1154289533ada623f2238a83771eec977f204f75994fbsalomon@google.com bool prAA = paint.fAntiAlias && !this->getRenderTarget()->isMultisampled(); 1155289533ada623f2238a83771eec977f204f75994fbsalomon@google.com 1156d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com // An Assumption here is that path renderer would use some form of tweaking 1157d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com // the src color (either the input alpha or in the frag shader) to implement 1158d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com // aa. If we have some future driver-mojo path AA that can do the right 1159d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com // thing WRT to the blend then we'll need some query on the PR. 1160d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com if (disable_coverage_aa_for_blend(target)) { 11611983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#if GR_DEBUG 1162979432ba2621b617f5e85a9ff48c6b6cd1504a0dbsalomon@google.com //GrPrintf("Turning off AA to correctly apply blend.\n"); 11631983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#endif 1164289533ada623f2238a83771eec977f204f75994fbsalomon@google.com prAA = false; 1165d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com } 1166289533ada623f2238a83771eec977f204f75994fbsalomon@google.com 116772176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com GrPathRenderer* pr = this->getPathRenderer(path, fill, target, prAA, true); 11683008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com if (NULL == pr) { 11691983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#if GR_DEBUG 11703008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com GrPrintf("Unable to find path renderer compatible with path.\n"); 11711983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#endif 11723008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com return; 11733008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com } 11743008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com 1175e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com pr->drawPath(path, fill, translate, target, prAA); 117627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 11778295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com 117827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 117927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1180a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.comvoid GrContext::flush(int flagsBitfield) { 1181a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com if (kDiscard_FlushBit & flagsBitfield) { 1182a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com fDrawBuffer->reset(); 1183a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com } else { 1184c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com this->flushDrawBuffer(); 1185a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com } 1186a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com if (kForceCurrentRenderTarget_FlushBit & flagsBitfield) { 118727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fGpu->forceRenderTargetFlush(); 118827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 118927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 119027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 119127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::flushDrawBuffer() { 119253a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com if (fDrawBuffer) { 119358b381841cb8d234d09c85af43720cbff00e6212robertphillips@google.com // With addition of the AA clip path, flushing the draw buffer can 119458b381841cb8d234d09c85af43720cbff00e6212robertphillips@google.com // result in the generation of an AA clip mask. During this 119558b381841cb8d234d09c85af43720cbff00e6212robertphillips@google.com // process the SW path renderer may be invoked which recusively 119658b381841cb8d234d09c85af43720cbff00e6212robertphillips@google.com // calls this method (via internalWriteTexturePixels) creating 119758b381841cb8d234d09c85af43720cbff00e6212robertphillips@google.com // infinite recursion 119858b381841cb8d234d09c85af43720cbff00e6212robertphillips@google.com GrInOrderDrawBuffer* temp = fDrawBuffer; 119958b381841cb8d234d09c85af43720cbff00e6212robertphillips@google.com fDrawBuffer = NULL; 120058b381841cb8d234d09c85af43720cbff00e6212robertphillips@google.com 120158b381841cb8d234d09c85af43720cbff00e6212robertphillips@google.com temp->flushTo(fGpu); 120258b381841cb8d234d09c85af43720cbff00e6212robertphillips@google.com 120358b381841cb8d234d09c85af43720cbff00e6212robertphillips@google.com fDrawBuffer = temp; 120453a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com } 120527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 120627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 12076f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.comvoid GrContext::internalWriteTexturePixels(GrTexture* texture, 12086f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com int left, int top, 12096f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com int width, int height, 12106f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com GrPixelConfig config, 12116f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com const void* buffer, 12126f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com size_t rowBytes, 12136f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com uint32_t flags) { 12146f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com SK_TRACE_EVENT0("GrContext::writeTexturePixels"); 1215bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(texture); 1216bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com 12176f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com if (!(kDontFlush_PixelOpsFlag & flags)) { 12186f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com this->flush(); 12196f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com } 12206f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com // TODO: use scratch texture to perform conversion 12216f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com if (GrPixelConfigIsUnpremultiplied(texture->config()) != 12226f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com GrPixelConfigIsUnpremultiplied(config)) { 12236f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com return; 12246f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com } 12256f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com 12266f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com fGpu->writeTexturePixels(texture, left, top, width, height, 12276f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com config, buffer, rowBytes); 12286f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com} 12296f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com 12306f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.combool GrContext::internalReadTexturePixels(GrTexture* texture, 12316f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com int left, int top, 12326f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com int width, int height, 12336f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com GrPixelConfig config, 12346f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com void* buffer, 12356f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com size_t rowBytes, 12366f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com uint32_t flags) { 1237278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com SK_TRACE_EVENT0("GrContext::readTexturePixels"); 1238bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(texture); 1239669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com 1240a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com // TODO: code read pixels for textures that aren't also rendertargets 1241669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com GrRenderTarget* target = texture->asRenderTarget(); 1242669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com if (NULL != target) { 12436f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com return this->internalReadRenderTargetPixels(target, 12446f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com left, top, width, height, 12456f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com config, buffer, rowBytes, 12466f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com flags); 1247669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com } else { 1248669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com return false; 1249669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com } 1250669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com} 1251669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com 1252a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com#include "SkConfig8888.h" 1253a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com 1254a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.comnamespace { 1255a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com/** 1256a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com * Converts a GrPixelConfig to a SkCanvas::Config8888. Only byte-per-channel 1257a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com * formats are representable as Config8888 and so the function returns false 1258a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com * if the GrPixelConfig has no equivalent Config8888. 1259a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com */ 1260a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.combool grconfig_to_config8888(GrPixelConfig config, 1261a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com SkCanvas::Config8888* config8888) { 1262a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com switch (config) { 1263a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com case kRGBA_8888_PM_GrPixelConfig: 1264a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com *config8888 = SkCanvas::kRGBA_Premul_Config8888; 1265a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com return true; 1266a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com case kRGBA_8888_UPM_GrPixelConfig: 1267a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com *config8888 = SkCanvas::kRGBA_Unpremul_Config8888; 1268a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com return true; 1269a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com case kBGRA_8888_PM_GrPixelConfig: 1270a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com *config8888 = SkCanvas::kBGRA_Premul_Config8888; 1271a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com return true; 1272a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com case kBGRA_8888_UPM_GrPixelConfig: 1273a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com *config8888 = SkCanvas::kBGRA_Unpremul_Config8888; 1274a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com return true; 1275a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com default: 1276a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com return false; 1277a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com } 1278a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com} 1279a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com} 1280a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com 12816f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.combool GrContext::internalReadRenderTargetPixels(GrRenderTarget* target, 12826f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com int left, int top, 12836f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com int width, int height, 12846f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com GrPixelConfig config, 12856f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com void* buffer, 12866f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com size_t rowBytes, 12876f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com uint32_t flags) { 1288278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com SK_TRACE_EVENT0("GrContext::readRenderTargetPixels"); 1289bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(target); 1290bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com 1291669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com if (NULL == target) { 129210e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com target = fDrawState->getRenderTarget(); 1293c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com if (NULL == target) { 1294c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com return false; 1295c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } 1296c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } 1297669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com 12986f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com if (!(kDontFlush_PixelOpsFlag & flags)) { 12996f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com this->flush(); 13006f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com } 1301c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 1302a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com if (!GrPixelConfigIsUnpremultiplied(target->config()) && 1303a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com GrPixelConfigIsUnpremultiplied(config) && 1304a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com !fGpu->canPreserveReadWriteUnpremulPixels()) { 1305a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com SkCanvas::Config8888 srcConfig8888, dstConfig8888; 1306a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com if (!grconfig_to_config8888(target->config(), &srcConfig8888) || 1307a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com !grconfig_to_config8888(config, &dstConfig8888)) { 1308a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com return false; 1309a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com } 1310a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com // do read back using target's own config 1311a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com this->internalReadRenderTargetPixels(target, 1312a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com left, top, 1313a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com width, height, 1314a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com target->config(), 1315a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com buffer, rowBytes, 1316a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com kDontFlush_PixelOpsFlag); 1317a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com // sw convert the pixels to unpremul config 1318a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com uint32_t* pixels = reinterpret_cast<uint32_t*>(buffer); 1319a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com SkConvertConfig8888Pixels(pixels, rowBytes, dstConfig8888, 1320a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com pixels, rowBytes, srcConfig8888, 1321a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com width, height); 1322a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com return true; 1323a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com } 1324a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com 1325c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com GrTexture* src = target->asTexture(); 13260a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com bool swapRAndB = NULL != src && 13270a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com fGpu->preferredReadPixelsConfig(config) == 13280a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com GrPixelConfigSwapRAndB(config); 1329c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 1330c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com bool flipY = NULL != src && 1331c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com fGpu->readPixelsWillPayForYFlip(target, left, top, 1332c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com width, height, config, 1333c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com rowBytes); 13340a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com bool alphaConversion = (!GrPixelConfigIsUnpremultiplied(target->config()) && 13350a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com GrPixelConfigIsUnpremultiplied(config)); 1336c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 13370a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com if (NULL == src && alphaConversion) { 13380a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com // we should fallback to cpu conversion here. This could happen when 13390a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com // we were given an external render target by the client that is not 13400a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com // also a texture (e.g. FBO 0 in GL) 13410a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com return false; 13420a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com } 13430a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com // we draw to a scratch texture if any of these conversion are applied 1344c4ff22a2965616629765b8ffe0e58f6d05f92fa3bsalomon@google.com GrAutoScratchTexture ast; 13450a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com if (flipY || swapRAndB || alphaConversion) { 13460a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com GrAssert(NULL != src); 13470a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com if (swapRAndB) { 13480a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com config = GrPixelConfigSwapRAndB(config); 13490a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com GrAssert(kUnknown_GrPixelConfig != config); 1350c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } 1351c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com // Make the scratch a render target because we don't have a robust 1352c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com // readTexturePixels as of yet (it calls this function). 135375b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com GrTextureDesc desc; 135475b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com desc.fFlags = kRenderTarget_GrTextureFlagBit; 135575b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com desc.fWidth = width; 135675b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com desc.fHeight = height; 135775b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com desc.fConfig = config; 1358c4ff22a2965616629765b8ffe0e58f6d05f92fa3bsalomon@google.com 135956d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com // When a full readback is faster than a partial we could always make 136056d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com // the scratch exactly match the passed rect. However, if we see many 136156d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com // different size rectangles we will trash our texture cache and pay the 136256d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com // cost of creating and destroying many textures. So, we only request 136356d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com // an exact match when the caller is reading an entire RT. 136456d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com ScratchTexMatch match = kApprox_ScratchTexMatch; 136556d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com if (0 == left && 136656d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com 0 == top && 136756d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com target->width() == width && 136856d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com target->height() == height && 136956d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com fGpu->fullReadPixelsIsFasterThanPartial()) { 137056d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com match = kExact_ScratchTexMatch; 137156d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com } 137256d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com ast.set(this, desc, match); 1373c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com GrTexture* texture = ast.texture(); 1374c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com if (!texture) { 1375c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com return false; 1376c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } 1377c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com target = texture->asRenderTarget(); 1378c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com GrAssert(NULL != target); 1379c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 1380873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com GrDrawTarget::AutoStateRestore asr(fGpu, 1381873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com GrDrawTarget::kReset_ASRInit); 13828f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = fGpu->drawState(); 13838f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setRenderTarget(target); 1384c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 1385c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com GrMatrix matrix; 1386c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com if (flipY) { 1387c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com matrix.setTranslate(SK_Scalar1 * left, 1388c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com SK_Scalar1 * (top + height)); 1389c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com matrix.set(GrMatrix::kMScaleY, -GR_Scalar1); 1390c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } else { 1391c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com matrix.setTranslate(SK_Scalar1 *left, SK_Scalar1 *top); 1392c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } 1393c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com matrix.postIDiv(src->width(), src->height()); 13941e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com drawState->sampler(0)->reset(matrix); 13951e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com drawState->sampler(0)->setRAndBSwap(swapRAndB); 13961e8f016305805d4d8cad74aba3a21b78486f9d6ftomhudson@google.com drawState->createTextureEffect(0, src); 1397c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com GrRect rect; 1398c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com rect.setXYWH(0, 0, SK_Scalar1 * width, SK_Scalar1 * height); 1399e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com fGpu->drawSimpleRect(rect, NULL); 1400c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com left = 0; 1401c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com top = 0; 1402c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com } 1403669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com return fGpu->readPixels(target, 1404c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com left, top, width, height, 1405c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com config, buffer, rowBytes, flipY); 140627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 140727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 140875f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.comvoid GrContext::resolveRenderTarget(GrRenderTarget* target) { 140975f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com GrAssert(target); 141075f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com ASSERT_OWNED_RESOURCE(target); 141175f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com // In the future we may track whether there are any pending draws to this 141275f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com // target. We don't today so we always perform a flush. We don't promise 141375f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com // this to our clients, though. 141475f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com this->flush(); 141575f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com fGpu->resolveRenderTarget(target); 141675f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com} 141775f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com 1418ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.orgvoid GrContext::copyTexture(GrTexture* src, GrRenderTarget* dst) { 1419ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org if (NULL == src || NULL == dst) { 1420ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org return; 1421ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org } 1422ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org ASSERT_OWNED_RESOURCE(src); 1423ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org 14241ac87ff5aaff284b337652cf3ac0b41bd56fb781twiz@google.com // Writes pending to the source texture are not tracked, so a flush 14251ac87ff5aaff284b337652cf3ac0b41bd56fb781twiz@google.com // is required to ensure that the copy captures the most recent contents 14261ac87ff5aaff284b337652cf3ac0b41bd56fb781twiz@google.com // of the source texture. See similar behaviour in 14271ac87ff5aaff284b337652cf3ac0b41bd56fb781twiz@google.com // GrContext::resolveRenderTarget. 14281ac87ff5aaff284b337652cf3ac0b41bd56fb781twiz@google.com this->flush(); 14291ac87ff5aaff284b337652cf3ac0b41bd56fb781twiz@google.com 1430873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com GrDrawTarget::AutoStateRestore asr(fGpu, GrDrawTarget::kReset_ASRInit); 14318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = fGpu->drawState(); 14328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setRenderTarget(dst); 1433ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org GrMatrix sampleM; 1434ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org sampleM.setIDiv(src->width(), src->height()); 14351e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com drawState->sampler(0)->reset(sampleM); 14361e8f016305805d4d8cad74aba3a21b78486f9d6ftomhudson@google.com drawState->createTextureEffect(0, src); 14375db3b6cce4e9e02415a0a31d95666c044c953ac2bsalomon@google.com SkRect rect = SkRect::MakeXYWH(0, 0, 14385db3b6cce4e9e02415a0a31d95666c044c953ac2bsalomon@google.com SK_Scalar1 * src->width(), 14395db3b6cce4e9e02415a0a31d95666c044c953ac2bsalomon@google.com SK_Scalar1 * src->height()); 1440e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com fGpu->drawSimpleRect(rect, NULL); 1441ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org} 1442ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org 14436f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.comvoid GrContext::internalWriteRenderTargetPixels(GrRenderTarget* target, 14446f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com int left, int top, 14456f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com int width, int height, 14466f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com GrPixelConfig config, 14476f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com const void* buffer, 14486f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com size_t rowBytes, 14496f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com uint32_t flags) { 14506f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com SK_TRACE_EVENT0("GrContext::writeRenderTargetPixels"); 1451bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(target); 14526f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com 14536f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com if (NULL == target) { 1454873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com target = fDrawState->getRenderTarget(); 14556f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com if (NULL == target) { 14566f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com return; 14576f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com } 14586f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com } 145927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 146027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // TODO: when underlying api has a direct way to do this we should use it 146127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com // (e.g. glDrawPixels on desktop GL). 146227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1463a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com // If the RT is also a texture and we don't have to do PM/UPM conversion 1464a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com // then take the texture path, which we expect to be at least as fast or 1465a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com // faster since it doesn't use an intermediate texture as we do below. 1466a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com 1467a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com#if !GR_MAC_BUILD 1468a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com // At least some drivers on the Mac get confused when glTexImage2D is called 1469a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com // on a texture attached to an FBO. The FBO still sees the old image. TODO: 1470a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com // determine what OS versions and/or HW is affected. 1471a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com if (NULL != target->asTexture() && 1472a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com GrPixelConfigIsUnpremultiplied(target->config()) == 1473a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com GrPixelConfigIsUnpremultiplied(config)) { 1474a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com 1475a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com this->internalWriteTexturePixels(target->asTexture(), 1476a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com left, top, width, height, 1477a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com config, buffer, rowBytes, flags); 1478a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com return; 1479a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com } 1480a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com#endif 1481a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com if (!GrPixelConfigIsUnpremultiplied(target->config()) && 1482a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com GrPixelConfigIsUnpremultiplied(config) && 1483a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com !fGpu->canPreserveReadWriteUnpremulPixels()) { 1484a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com SkCanvas::Config8888 srcConfig8888, dstConfig8888; 1485a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com if (!grconfig_to_config8888(config, &srcConfig8888) || 1486a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com !grconfig_to_config8888(target->config(), &dstConfig8888)) { 1487a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com return; 1488a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com } 1489a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com // allocate a tmp buffer and sw convert the pixels to premul 1490a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com SkAutoSTMalloc<128 * 128, uint32_t> tmpPixels(width * height); 1491a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com const uint32_t* src = reinterpret_cast<const uint32_t*>(buffer); 1492a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com SkConvertConfig8888Pixels(tmpPixels.get(), 4 * width, dstConfig8888, 1493a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com src, rowBytes, srcConfig8888, 1494a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com width, height); 1495a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com // upload the already premul pixels 1496a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com this->internalWriteRenderTargetPixels(target, 1497a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com left, top, 1498a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com width, height, 1499a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com target->config(), 1500a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com tmpPixels, 4 * width, flags); 1501a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com return; 1502a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com } 1503a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com 1504a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com bool swapRAndB = fGpu->preferredReadPixelsConfig(config) == 1505a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com GrPixelConfigSwapRAndB(config); 1506a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com if (swapRAndB) { 1507a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com config = GrPixelConfigSwapRAndB(config); 1508a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com } 1509a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com 151075b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com GrTextureDesc desc; 151175b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com desc.fWidth = width; 151275b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com desc.fHeight = height; 151375b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com desc.fConfig = config; 151475b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com 151550398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrAutoScratchTexture ast(this, desc); 151650398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrTexture* texture = ast.texture(); 151727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (NULL == texture) { 151827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return; 151927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 15206f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com this->internalWriteTexturePixels(texture, 0, 0, width, height, 15216f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com config, buffer, rowBytes, flags); 152227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1523873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com GrDrawTarget::AutoStateRestore asr(fGpu, GrDrawTarget::kReset_ASRInit); 15248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com GrDrawState* drawState = fGpu->drawState(); 152527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 152627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrMatrix matrix; 152727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com matrix.setTranslate(GrIntToScalar(left), GrIntToScalar(top)); 15288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setViewMatrix(matrix); 15298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com drawState->setRenderTarget(target); 153027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 15315c63865b529eb5714e41419dfa23c70d26ff6e4ebsalomon@google.com matrix.setIDiv(texture->width(), texture->height()); 1532b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com drawState->sampler(0)->reset(matrix); 15331e8f016305805d4d8cad74aba3a21b78486f9d6ftomhudson@google.com drawState->createTextureEffect(0, texture); 15341e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com drawState->sampler(0)->setRAndBSwap(swapRAndB); 153527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1536b213ed8b767b424cb076bfbab11e936d16526635tomhudson@google.com static const GrVertexLayout layout = 0; 153727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com static const int VCOUNT = 4; 15386513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com // TODO: Use GrGpu::drawRect here 153927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget::AutoReleaseGeometry geo(fGpu, layout, VCOUNT, 0); 154027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (!geo.succeeded()) { 15416513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com GrPrintf("Failed to get space for vertices!\n"); 154227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return; 154327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 154427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com ((GrPoint*)geo.vertices())->setIRectFan(0, 0, width, height); 154547059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com fGpu->drawNonIndexed(kTriangleFan_GrPrimitiveType, 0, VCOUNT); 154627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 154727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 154827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 154910e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.comvoid GrContext::setPaint(const GrPaint& paint) { 1550cb325ceda16fab97fd3281785e6ae10fcb8dcf83tomhudson@google.com GrAssert(fDrawState->stagesDisabled()); 155126c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 155226c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com for (int i = 0; i < GrPaint::kMaxTextures; ++i) { 155326c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com int s = i + GrPaint::kFirstTextureStage; 1554bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(paint.getTexture(i)); 1555f13f58804659175925042a291304d483a4fd9278tomhudson@google.com if (paint.isTextureStageEnabled(i)) { 1556f13f58804659175925042a291304d483a4fd9278tomhudson@google.com fDrawState->setTexture(s, paint.getTexture(i)); 155710e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com *fDrawState->sampler(s) = paint.getTextureSampler(i); 1558f864ec467dfd518e32f6e4d709fafe57f1b3dbc6bsalomon@google.com } 155926c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com } 156026c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 156110e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com fDrawState->setFirstCoverageStage(GrPaint::kFirstMaskStage); 156226c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 156326c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com for (int i = 0; i < GrPaint::kMaxMasks; ++i) { 156426c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com int s = i + GrPaint::kFirstMaskStage; 1565bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(paint.getMask(i)); 1566f13f58804659175925042a291304d483a4fd9278tomhudson@google.com if (paint.isMaskStageEnabled(i)) { 1567f13f58804659175925042a291304d483a4fd9278tomhudson@google.com fDrawState->setTexture(s, paint.getMask(i)); 156810e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com *fDrawState->sampler(s) = paint.getMaskSampler(i); 1569f864ec467dfd518e32f6e4d709fafe57f1b3dbc6bsalomon@google.com } 157026c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com } 157126936d071f9e426e11db9a8cf67f5ce86e83feb1bsalomon@google.com 157226936d071f9e426e11db9a8cf67f5ce86e83feb1bsalomon@google.com // disable all stages not accessible via the paint 157326936d071f9e426e11db9a8cf67f5ce86e83feb1bsalomon@google.com for (int s = GrPaint::kTotalStages; s < GrDrawState::kNumStages; ++s) { 1574676e66096c60615bac52f365111596de5c4ca8a6tomhudson@google.com fDrawState->disableStage(s); 157526936d071f9e426e11db9a8cf67f5ce86e83feb1bsalomon@google.com } 157626c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com 157710e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com fDrawState->setColor(paint.fColor); 157827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 157927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (paint.fDither) { 158010e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com fDrawState->enableState(GrDrawState::kDither_StateBit); 158127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 158210e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com fDrawState->disableState(GrDrawState::kDither_StateBit); 158327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 158427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (paint.fAntiAlias) { 158510e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com fDrawState->enableState(GrDrawState::kHWAntialias_StateBit); 158627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 158710e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com fDrawState->disableState(GrDrawState::kHWAntialias_StateBit); 158827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 158950bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org if (paint.fColorMatrixEnabled) { 159010e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com fDrawState->enableState(GrDrawState::kColorMatrix_StateBit); 159110e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com fDrawState->setColorMatrix(paint.fColorMatrix); 159250bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org } else { 159310e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com fDrawState->disableState(GrDrawState::kColorMatrix_StateBit); 159450bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org } 159510e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com fDrawState->setBlendFunc(paint.fSrcBlendCoeff, paint.fDstBlendCoeff); 159610e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com fDrawState->setColorFilter(paint.fColorFilterColor, paint.fColorFilterXfermode); 159710e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com fDrawState->setCoverage(paint.fCoverage); 15984b2d3f30d047435263642ef8ed170a37ca642c1breed@google.com#if GR_DEBUG_PARTIAL_COVERAGE_CHECK 1599e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com if ((paint.hasMask() || 0xff != paint.fCoverage) && 160010e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com !fGpu->canApplyCoverage()) { 1601d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com GrPrintf("Partial pixel coverage will be incorrectly blended.\n"); 1602d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com } 160395cd7bdf2b4dee54739f0a375fe99a02f86178b0bsalomon@google.com#endif 160427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 160527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1606de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.comGrDrawTarget* GrContext::prepareToDraw(const GrPaint& paint, 160727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com DrawCategory category) { 160827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (category != fLastDrawCategory) { 1609fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.com this->flushDrawBuffer(); 161027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fLastDrawCategory = category; 161127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 161210e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com this->setPaint(paint); 161327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com GrDrawTarget* target = fGpu; 161427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com switch (category) { 1615193395c7a391bc0046b7793d633487d510457aecbsalomon@google.com case kUnbuffered_DrawCategory: 1616193395c7a391bc0046b7793d633487d510457aecbsalomon@google.com target = fGpu; 1617193395c7a391bc0046b7793d633487d510457aecbsalomon@google.com break; 1618193395c7a391bc0046b7793d633487d510457aecbsalomon@google.com case kBuffered_DrawCategory: 1619193395c7a391bc0046b7793d633487d510457aecbsalomon@google.com target = fDrawBuffer; 1620193395c7a391bc0046b7793d633487d510457aecbsalomon@google.com fDrawBuffer->setClip(fGpu->getClip()); 1621193395c7a391bc0046b7793d633487d510457aecbsalomon@google.com break; 1622193395c7a391bc0046b7793d633487d510457aecbsalomon@google.com default: 1623193395c7a391bc0046b7793d633487d510457aecbsalomon@google.com GrCrash("Unexpected DrawCategory."); 1624193395c7a391bc0046b7793d633487d510457aecbsalomon@google.com break; 162527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 162627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return target; 162727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 162827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 162972176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com/* 163072176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com * This method finds a path renderer that can draw the specified path on 163172176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com * the provided target. 163272176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com * Due to its expense, the software path renderer has split out so it can 163372176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com * can be individually allowed/disallowed via the "allowSW" boolean. 163472176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com */ 16358d033a1b125886c62906d975b5cc28a382064526bsalomon@google.comGrPathRenderer* GrContext::getPathRenderer(const SkPath& path, 1636289533ada623f2238a83771eec977f204f75994fbsalomon@google.com GrPathFill fill, 1637c2099d2707abcc94e139627399aed4b8894b69bbbsalomon@google.com const GrDrawTarget* target, 163872176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com bool antiAlias, 163972176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com bool allowSW) { 16403008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com if (NULL == fPathRendererChain) { 16413008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com fPathRendererChain = 1642c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com SkNEW_ARGS(GrPathRendererChain, 1643c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com (this, GrPathRendererChain::kNone_UsageFlag)); 16443008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com } 164572176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com 164672176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com GrPathRenderer* pr = fPathRendererChain->getPathRenderer(path, fill, 164772176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com target, 164872176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com antiAlias); 164972176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com 165072176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com if (NULL == pr && allowSW) { 165172176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com if (NULL == fSoftwarePathRenderer) { 1652c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com fSoftwarePathRenderer = SkNEW_ARGS(GrSoftwarePathRenderer, (this)); 165372176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com } 165472176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com 165572176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com pr = fSoftwarePathRenderer; 165672176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com } 165772176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com 165872176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com return pr; 16593008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com} 16603008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com 166127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 166227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 166327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::setRenderTarget(GrRenderTarget* target) { 1664bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com ASSERT_OWNED_RESOURCE(target); 166510e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com if (fDrawState->getRenderTarget() != target) { 1666fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.com this->flush(false); 166710e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com fDrawState->setRenderTarget(target); 1668fb4ce6fe9f3f09bf9828aa50b36287f7d22bb78bbsalomon@google.com } 166927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 167027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 167127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comGrRenderTarget* GrContext::getRenderTarget() { 167210e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com return fDrawState->getRenderTarget(); 167327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 167427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 167527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comconst GrRenderTarget* GrContext::getRenderTarget() const { 167610e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com return fDrawState->getRenderTarget(); 167727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 167827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 167999a5ac0b67a14048a1db3f429878775854d29397robertphillips@google.combool GrContext::isConfigRenderable(GrPixelConfig config) const { 168099a5ac0b67a14048a1db3f429878775854d29397robertphillips@google.com return fGpu->isConfigRenderable(config); 168199a5ac0b67a14048a1db3f429878775854d29397robertphillips@google.com} 168299a5ac0b67a14048a1db3f429878775854d29397robertphillips@google.com 168327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comconst GrMatrix& GrContext::getMatrix() const { 168410e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com return fDrawState->getViewMatrix(); 168527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 168627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 168727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::setMatrix(const GrMatrix& m) { 168810e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com fDrawState->setViewMatrix(m); 168927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 169027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 169127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::concatMatrix(const GrMatrix& m) const { 169210e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com fDrawState->preConcatViewMatrix(m); 169327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 169427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 169527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comstatic inline intptr_t setOrClear(intptr_t bits, int shift, intptr_t pred) { 169627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com intptr_t mask = 1 << shift; 169727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com if (pred) { 169827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com bits |= mask; 169927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } else { 170027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com bits &= ~mask; 170127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com } 170227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return bits; 170327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 170427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1705583a1e38503ebd57ba9bd39a3fabe89bead8e76cbsalomon@google.comGrContext::GrContext(GrGpu* gpu) { 1706c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.com ++THREAD_INSTANCE_COUNT; 1707c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.com 170827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fGpu = gpu; 170927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fGpu->ref(); 1710669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com fGpu->setContext(this); 17118fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 1712c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com fDrawState = SkNEW(GrDrawState); 171310e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com fGpu->setDrawState(fDrawState); 171410e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com 17153008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com fPathRendererChain = NULL; 171672176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com fSoftwarePathRenderer = NULL; 1717dfe75bcf98b0c04535efbf7fe36492a7fb53c90dbsalomon@google.com 1718c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com fTextureCache = SkNEW_ARGS(GrResourceCache, 1719c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com (MAX_TEXTURE_CACHE_COUNT, 1720c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com MAX_TEXTURE_CACHE_BYTES)); 1721c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com fFontCache = SkNEW_ARGS(GrFontCache, (fGpu)); 172227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 172327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fLastDrawCategory = kUnbuffered_DrawCategory; 172427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 17258fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fDrawBuffer = NULL; 17268fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fDrawBufferVBAllocPool = NULL; 17278fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com fDrawBufferIBAllocPool = NULL; 17288fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 1729c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com fAARectRenderer = SkNEW(GrAARectRenderer); 173010e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com 17318fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com this->setupDrawBuffer(); 17328fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com} 17338fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 17348fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.comvoid GrContext::setupDrawBuffer() { 17358fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 17368fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com GrAssert(NULL == fDrawBuffer); 17378fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com GrAssert(NULL == fDrawBufferVBAllocPool); 17388fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com GrAssert(NULL == fDrawBufferIBAllocPool); 17398fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com 174092edd316e5425f7f7fbecbae28483da2851248bbbsalomon@google.com#if DEFER_TEXT_RENDERING || BATCH_RECT_TO_RECT || DEFER_PATHS 1741de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com fDrawBufferVBAllocPool = 1742c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com SkNEW_ARGS(GrVertexBufferAllocPool, (fGpu, false, 174327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com DRAW_BUFFER_VBPOOL_BUFFER_SIZE, 1744c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com DRAW_BUFFER_VBPOOL_PREALLOC_BUFFERS)); 1745de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com fDrawBufferIBAllocPool = 1746c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com SkNEW_ARGS(GrIndexBufferAllocPool, (fGpu, false, 1747de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com DRAW_BUFFER_IBPOOL_BUFFER_SIZE, 1748c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS)); 174927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 1750c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com fDrawBuffer = SkNEW_ARGS(GrInOrderDrawBuffer, (fGpu, 1751471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com fDrawBufferVBAllocPool, 1752c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com fDrawBufferIBAllocPool)); 17533c4d032aeb2831a64fd6eff570667d590e3ed209bsalomon@google.com#endif 17543c4d032aeb2831a64fd6eff570667d590e3ed209bsalomon@google.com 17553c4d032aeb2831a64fd6eff570667d590e3ed209bsalomon@google.com#if BATCH_RECT_TO_RECT 175627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com fDrawBuffer->setQuadIndexBuffer(this->getQuadIndexBuffer()); 17573c4d032aeb2831a64fd6eff570667d590e3ed209bsalomon@google.com#endif 17581015e034676a90d88544c396ff4dce3849186aa9bsalomon@google.com if (fDrawBuffer) { 17591015e034676a90d88544c396ff4dce3849186aa9bsalomon@google.com fDrawBuffer->setAutoFlushTarget(fGpu); 17601015e034676a90d88544c396ff4dce3849186aa9bsalomon@google.com fDrawBuffer->setDrawState(fDrawState); 17611015e034676a90d88544c396ff4dce3849186aa9bsalomon@google.com } 176227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 176327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 176427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comGrDrawTarget* GrContext::getTextTarget(const GrPaint& paint) { 176527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#if DEFER_TEXT_RENDERING 1766193395c7a391bc0046b7793d633487d510457aecbsalomon@google.com return prepareToDraw(paint, kBuffered_DrawCategory); 176727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#else 176810e04bf1c5025389d999f22467405782e9f9ffccbsalomon@google.com return prepareToDraw(paint, kUnbuffered_DrawCategory); 176927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#endif 177027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 177127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com 177227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comconst GrIndexBuffer* GrContext::getQuadIndexBuffer() const { 177327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com return fGpu->getQuadIndexBuffer(); 177427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com} 1775dfe75bcf98b0c04535efbf7fe36492a7fb53c90dbsalomon@google.com 17763b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.orgGrTexture* GrContext::gaussianBlur(GrTexture* srcTexture, 17771e95d715d06c5125ef6e5439e953fd0353be92b2senorblanco@chromium.org bool canClobberSrc, 17783b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org const SkRect& rect, 17793b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org float sigmaX, float sigmaY) { 1780ceb441476e1712861e87a9bb428f119349ef6bb5senorblanco@chromium.org ASSERT_OWNED_RESOURCE(srcTexture); 17813b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrRenderTarget* oldRenderTarget = this->getRenderTarget(); 1782fea85ac3e31842f80493e2df8a93a28f21cd815frobertphillips@google.com AutoMatrix avm(this, GrMatrix::I()); 17833b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org SkIRect clearRect; 1784b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com int scaleFactorX, radiusX; 1785b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com int scaleFactorY, radiusY; 1786b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com sigmaX = adjust_sigma(sigmaX, &scaleFactorX, &radiusX); 1787b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com sigmaY = adjust_sigma(sigmaY, &scaleFactorY, &radiusY); 17883b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org 17893b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org SkRect srcRect(rect); 17903b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org scale_rect(&srcRect, 1.0f / scaleFactorX, 1.0f / scaleFactorY); 17913b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org srcRect.roundOut(); 17928637a365518a82901d313d61eecd83a0c5102fe9robertphillips@google.com scale_rect(&srcRect, static_cast<float>(scaleFactorX), 17938637a365518a82901d313d61eecd83a0c5102fe9robertphillips@google.com static_cast<float>(scaleFactorY)); 17943e11c0bd92fbd12f59080c3f9450201d6105db83robertphillips@google.com 179556c79b10377e358b8092d9c6ab3e1aacf2cd60e5robertphillips@google.com AutoClip acs(this, srcRect); 1796bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com 179799a5ac0b67a14048a1db3f429878775854d29397robertphillips@google.com GrAssert(kBGRA_8888_PM_GrPixelConfig == srcTexture->config() || 179899a5ac0b67a14048a1db3f429878775854d29397robertphillips@google.com kRGBA_8888_PM_GrPixelConfig == srcTexture->config() || 179999a5ac0b67a14048a1db3f429878775854d29397robertphillips@google.com kAlpha_8_GrPixelConfig == srcTexture->config()); 180099a5ac0b67a14048a1db3f429878775854d29397robertphillips@google.com 180175b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com GrTextureDesc desc; 180275b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit; 180375b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com desc.fWidth = SkScalarFloorToInt(srcRect.width()); 180475b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com desc.fHeight = SkScalarFloorToInt(srcRect.height()); 180575b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com desc.fConfig = srcTexture->config(); 18061e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com 18071e95d715d06c5125ef6e5439e953fd0353be92b2senorblanco@chromium.org GrAutoScratchTexture temp1, temp2; 18081e95d715d06c5125ef6e5439e953fd0353be92b2senorblanco@chromium.org GrTexture* dstTexture = temp1.set(this, desc); 18091e95d715d06c5125ef6e5439e953fd0353be92b2senorblanco@chromium.org GrTexture* tempTexture = canClobberSrc ? srcTexture : temp2.set(this, desc); 18103b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org 18113b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrPaint paint; 18123b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org paint.reset(); 1813b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com paint.textureSampler(0)->textureParams()->setBilerp(true); 18143b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org 18153b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org for (int i = 1; i < scaleFactorX || i < scaleFactorY; i *= 2) { 18163b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org paint.textureSampler(0)->matrix()->setIDiv(srcTexture->width(), 18173b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org srcTexture->height()); 18183b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->setRenderTarget(dstTexture->asRenderTarget()); 18193b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org SkRect dstRect(srcRect); 18203b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org scale_rect(&dstRect, i < scaleFactorX ? 0.5f : 1.0f, 18213b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org i < scaleFactorY ? 0.5f : 1.0f); 1822aa72eab5d82d4c2aa9f6f41755a001282443b042tomhudson@google.com paint.textureSampler(0)->setCustomStage(SkNEW_ARGS(GrSingleTextureEffect, 1823aa72eab5d82d4c2aa9f6f41755a001282443b042tomhudson@google.com (srcTexture)))->unref(); 18243b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->drawRectToRect(paint, dstRect, srcRect); 18253b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org srcRect = dstRect; 18261e95d715d06c5125ef6e5439e953fd0353be92b2senorblanco@chromium.org srcTexture = dstTexture; 18271e95d715d06c5125ef6e5439e953fd0353be92b2senorblanco@chromium.org SkTSwap(dstTexture, tempTexture); 18283b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org } 18293b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org 18307a39633318f8ae41488f03d3258deade4b36b996robertphillips@google.com SkIRect srcIRect; 18317a39633318f8ae41488f03d3258deade4b36b996robertphillips@google.com srcRect.roundOut(&srcIRect); 18327a39633318f8ae41488f03d3258deade4b36b996robertphillips@google.com 18333b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org if (sigmaX > 0.0f) { 18343b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org if (scaleFactorX > 1) { 1835b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com // Clear out a radius to the right of the srcRect to prevent the 18363b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org // X convolution from reading garbage. 18377a39633318f8ae41488f03d3258deade4b36b996robertphillips@google.com clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop, 1838b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com radiusX, srcIRect.height()); 18393b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->clear(&clearRect, 0x0); 18403b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org } 184105054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org 18423b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->setRenderTarget(dstTexture->asRenderTarget()); 1843b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com convolve_gaussian(fGpu, srcTexture, srcRect, sigmaX, radiusX, 1844b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com Gr1DKernelEffect::kX_Direction); 18451e95d715d06c5125ef6e5439e953fd0353be92b2senorblanco@chromium.org srcTexture = dstTexture; 18461e95d715d06c5125ef6e5439e953fd0353be92b2senorblanco@chromium.org SkTSwap(dstTexture, tempTexture); 18473b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org } 18483b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org 18493b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org if (sigmaY > 0.0f) { 18503b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org if (scaleFactorY > 1 || sigmaX > 0.0f) { 1851b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com // Clear out a radius below the srcRect to prevent the Y 18523b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org // convolution from reading garbage. 18537a39633318f8ae41488f03d3258deade4b36b996robertphillips@google.com clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom, 1854b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com srcIRect.width(), radiusY); 18553b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->clear(&clearRect, 0x0); 18563b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org } 18573b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org 18583b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->setRenderTarget(dstTexture->asRenderTarget()); 1859b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com convolve_gaussian(fGpu, srcTexture, srcRect, sigmaY, radiusY, 1860b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com Gr1DKernelEffect::kY_Direction); 18611e95d715d06c5125ef6e5439e953fd0353be92b2senorblanco@chromium.org srcTexture = dstTexture; 18621e95d715d06c5125ef6e5439e953fd0353be92b2senorblanco@chromium.org SkTSwap(dstTexture, tempTexture); 18633b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org } 18643b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org 18653b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org if (scaleFactorX > 1 || scaleFactorY > 1) { 18663b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org // Clear one pixel to the right and below, to accommodate bilinear 18673b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org // upsampling. 18687a39633318f8ae41488f03d3258deade4b36b996robertphillips@google.com clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom, 18697a39633318f8ae41488f03d3258deade4b36b996robertphillips@google.com srcIRect.width() + 1, 1); 18703b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->clear(&clearRect, 0x0); 18717a39633318f8ae41488f03d3258deade4b36b996robertphillips@google.com clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop, 18727a39633318f8ae41488f03d3258deade4b36b996robertphillips@google.com 1, srcIRect.height()); 18733b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->clear(&clearRect, 0x0); 18743b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org // FIXME: This should be mitchell, not bilinear. 1875b8670998a59d305cd22a3c0cbdc6e075b0a37a6ebsalomon@google.com paint.textureSampler(0)->textureParams()->setBilerp(true); 18763b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org paint.textureSampler(0)->matrix()->setIDiv(srcTexture->width(), 18773b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org srcTexture->height()); 18783b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->setRenderTarget(dstTexture->asRenderTarget()); 1879aa72eab5d82d4c2aa9f6f41755a001282443b042tomhudson@google.com paint.textureSampler(0)->setCustomStage(SkNEW_ARGS(GrSingleTextureEffect, 1880aa72eab5d82d4c2aa9f6f41755a001282443b042tomhudson@google.com (srcTexture)))->unref(); 18813b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org SkRect dstRect(srcRect); 18827a39633318f8ae41488f03d3258deade4b36b996robertphillips@google.com scale_rect(&dstRect, (float) scaleFactorX, (float) scaleFactorY); 18833b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->drawRectToRect(paint, dstRect, srcRect); 18843b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org srcRect = dstRect; 18851e95d715d06c5125ef6e5439e953fd0353be92b2senorblanco@chromium.org srcTexture = dstTexture; 18861e95d715d06c5125ef6e5439e953fd0353be92b2senorblanco@chromium.org SkTSwap(dstTexture, tempTexture); 18873b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org } 18883b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->setRenderTarget(oldRenderTarget); 18891e95d715d06c5125ef6e5439e953fd0353be92b2senorblanco@chromium.org if (srcTexture == temp1.texture()) { 18901e95d715d06c5125ef6e5439e953fd0353be92b2senorblanco@chromium.org return temp1.detach(); 18911e95d715d06c5125ef6e5439e953fd0353be92b2senorblanco@chromium.org } else if (srcTexture == temp2.texture()) { 18921e95d715d06c5125ef6e5439e953fd0353be92b2senorblanco@chromium.org return temp2.detach(); 18931e95d715d06c5125ef6e5439e953fd0353be92b2senorblanco@chromium.org } else { 18941e95d715d06c5125ef6e5439e953fd0353be92b2senorblanco@chromium.org srcTexture->ref(); 18951e95d715d06c5125ef6e5439e953fd0353be92b2senorblanco@chromium.org return srcTexture; 18961e95d715d06c5125ef6e5439e953fd0353be92b2senorblanco@chromium.org } 18973b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org} 18983b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org 18993b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.orgGrTexture* GrContext::applyMorphology(GrTexture* srcTexture, 19003b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org const GrRect& rect, 1901b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com MorphologyType morphType, 19023b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org SkISize radius) { 1903ceb441476e1712861e87a9bb428f119349ef6bb5senorblanco@chromium.org ASSERT_OWNED_RESOURCE(srcTexture); 19041e95d715d06c5125ef6e5439e953fd0353be92b2senorblanco@chromium.org srcTexture->ref(); 19053b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org GrRenderTarget* oldRenderTarget = this->getRenderTarget(); 190656c79b10377e358b8092d9c6ab3e1aacf2cd60e5robertphillips@google.com 1907fea85ac3e31842f80493e2df8a93a28f21cd815frobertphillips@google.com AutoMatrix avm(this, GrMatrix::I()); 19083e11c0bd92fbd12f59080c3f9450201d6105db83robertphillips@google.com 190956c79b10377e358b8092d9c6ab3e1aacf2cd60e5robertphillips@google.com AutoClip acs(this, GrRect::MakeWH(SkIntToScalar(srcTexture->width()), 1910beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.com SkIntToScalar(srcTexture->height()))); 19111e95d715d06c5125ef6e5439e953fd0353be92b2senorblanco@chromium.org GrTextureDesc desc; 19121e95d715d06c5125ef6e5439e953fd0353be92b2senorblanco@chromium.org desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit; 19131e95d715d06c5125ef6e5439e953fd0353be92b2senorblanco@chromium.org desc.fWidth = SkScalarCeilToInt(rect.width()); 19141e95d715d06c5125ef6e5439e953fd0353be92b2senorblanco@chromium.org desc.fHeight = SkScalarCeilToInt(rect.height()); 19151e95d715d06c5125ef6e5439e953fd0353be92b2senorblanco@chromium.org desc.fConfig = kRGBA_8888_PM_GrPixelConfig; 19163b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org if (radius.fWidth > 0) { 19171e95d715d06c5125ef6e5439e953fd0353be92b2senorblanco@chromium.org GrAutoScratchTexture ast(this, desc); 19181e95d715d06c5125ef6e5439e953fd0353be92b2senorblanco@chromium.org this->setRenderTarget(ast.texture()->asRenderTarget()); 1919b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com apply_morphology(fGpu, srcTexture, rect, radius.fWidth, morphType, 1920b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com Gr1DKernelEffect::kX_Direction); 19217a39633318f8ae41488f03d3258deade4b36b996robertphillips@google.com SkIRect clearRect = SkIRect::MakeXYWH( 19227a39633318f8ae41488f03d3258deade4b36b996robertphillips@google.com SkScalarFloorToInt(rect.fLeft), 19237a39633318f8ae41488f03d3258deade4b36b996robertphillips@google.com SkScalarFloorToInt(rect.fBottom), 19247a39633318f8ae41488f03d3258deade4b36b996robertphillips@google.com SkScalarFloorToInt(rect.width()), 19257a39633318f8ae41488f03d3258deade4b36b996robertphillips@google.com radius.fHeight); 19263b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->clear(&clearRect, 0x0); 19271e95d715d06c5125ef6e5439e953fd0353be92b2senorblanco@chromium.org srcTexture->unref(); 19281e95d715d06c5125ef6e5439e953fd0353be92b2senorblanco@chromium.org srcTexture = ast.detach(); 19293b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org } 19303b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org if (radius.fHeight > 0) { 19311e95d715d06c5125ef6e5439e953fd0353be92b2senorblanco@chromium.org GrAutoScratchTexture ast(this, desc); 19321e95d715d06c5125ef6e5439e953fd0353be92b2senorblanco@chromium.org this->setRenderTarget(ast.texture()->asRenderTarget()); 1933b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com apply_morphology(fGpu, srcTexture, rect, radius.fHeight, morphType, 1934b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com Gr1DKernelEffect::kY_Direction); 19351e95d715d06c5125ef6e5439e953fd0353be92b2senorblanco@chromium.org srcTexture->unref(); 19361e95d715d06c5125ef6e5439e953fd0353be92b2senorblanco@chromium.org srcTexture = ast.detach(); 19373b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org } 19383b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org this->setRenderTarget(oldRenderTarget); 19393b4dd90282932c9cd695d13f3876f98c9c6d6d5esenorblanco@chromium.org return srcTexture; 1940027de5f922e8ad1acc5402829f716b8c513fdd8dsenorblanco@chromium.org} 1941c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com 1942c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com/////////////////////////////////////////////////////////////////////////////// 1943