180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* 380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2011 Google Inc. 480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be 680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file. 780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "GrContext.h" 1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "effects/GrSingleTextureEffect.h" 1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "effects/GrConfigConversionEffect.h" 1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "GrBufferAllocPool.h" 1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "GrGpu.h" 177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "GrDrawTargetCaps.h" 1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "GrIndexBuffer.h" 1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "GrInOrderDrawBuffer.h" 20e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger#include "GrOvalRenderer.h" 2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "GrPathRenderer.h" 2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "GrPathUtils.h" 2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "GrResourceCache.h" 2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "GrSoftwarePathRenderer.h" 2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "GrStencilBuffer.h" 2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "GrTextStrike.h" 27096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#include "SkRTConf.h" 28e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger#include "SkRRect.h" 29363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#include "SkStrokeRec.h" 3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkTLazy.h" 3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkTLS.h" 3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkTrace.h" 3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSK_DEFINE_INST_COUNT(GrContext) 3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSK_DEFINE_INST_COUNT(GrDrawState) 3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 37096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger// It can be useful to set this to false to test whether a bug is caused by using the 3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// InOrderDrawBuffer, to compare performance of using/not using InOrderDrawBuffer, or to make 39096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger// debugging simpler. 40096defe64d408e54474fe19f418c95bf1a554fc7Derek SollenbergerSK_CONF_DECLARE(bool, c_Defer, "gpu.deferContext", true, 41096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger "Defers rendering in GrContext via GrInOrderDrawBuffer."); 42096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 43096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#define BUFFERED_DRAW (c_Defer ? kYes_BufferedDraw : kNo_BufferedDraw) 4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// When we're using coverage AA but the blend is incompatible (given gpu 4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// limitations) should we disable AA or draw wrong? 4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define DISABLE_COVERAGE_AA_FOR_BLEND 1 4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if GR_DEBUG 5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // change this to a 1 to see notifications when partial coverage fails 5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru #define GR_DEBUG_PARTIAL_COVERAGE_CHECK 0 5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#else 5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru #define GR_DEBUG_PARTIAL_COVERAGE_CHECK 0 5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 56363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerstatic const size_t MAX_TEXTURE_CACHE_COUNT = 2048; 57363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerstatic const size_t MAX_TEXTURE_CACHE_BYTES = GR_DEFAULT_TEXTURE_CACHE_MB_LIMIT * 1024 * 1024; 5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic const size_t DRAW_BUFFER_VBPOOL_BUFFER_SIZE = 1 << 15; 6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic const int DRAW_BUFFER_VBPOOL_PREALLOC_BUFFERS = 4; 6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic const size_t DRAW_BUFFER_IBPOOL_BUFFER_SIZE = 1 << 11; 6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic const int DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS = 4; 6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define ASSERT_OWNED_RESOURCE(R) GrAssert(!(R) || (R)->getContext() == this) 6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger// Glorified typedef to avoid including GrDrawState.h in GrContext.h 6858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerclass GrContext::AutoRestoreEffects : public GrDrawState::AutoRestoreEffects {}; 6958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 70096defe64d408e54474fe19f418c95bf1a554fc7Derek SollenbergerGrContext* GrContext::Create(GrBackend backend, GrBackendContext backendContext) { 71096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger GrContext* context = SkNEW(GrContext); 72096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger if (context->init(backend, backendContext)) { 73096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger return context; 74096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } else { 75096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger context->unref(); 76096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger return NULL; 7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querunamespace { 8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid* CreateThreadInstanceCount() { 8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkNEW_ARGS(int, (0)); 8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid DeleteThreadInstanceCount(void* v) { 8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru delete reinterpret_cast<int*>(v); 8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 87096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#define THREAD_INSTANCE_COUNT \ 88096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger (*reinterpret_cast<int*>(SkTLS::Get(CreateThreadInstanceCount, DeleteThreadInstanceCount))) 89096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger} 90096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 91096defe64d408e54474fe19f418c95bf1a554fc7Derek SollenbergerGrContext::GrContext() { 92096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger ++THREAD_INSTANCE_COUNT; 93096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger fDrawState = NULL; 94096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger fGpu = NULL; 9558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger fClip = NULL; 96096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger fPathRendererChain = NULL; 97096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger fSoftwarePathRenderer = NULL; 98096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger fTextureCache = NULL; 99096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger fFontCache = NULL; 100096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger fDrawBuffer = NULL; 101096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger fDrawBufferVBAllocPool = NULL; 102096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger fDrawBufferIBAllocPool = NULL; 103096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger fAARectRenderer = NULL; 104e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger fOvalRenderer = NULL; 10558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger fViewMatrix.reset(); 10658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger fMaxTextureSizeOverride = 1 << 20; 107096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger} 108096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 109096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenbergerbool GrContext::init(GrBackend backend, GrBackendContext backendContext) { 110096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger GrAssert(NULL == fGpu); 111096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 112096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger fGpu = GrGpu::Create(backend, backendContext, this); 113096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger if (NULL == fGpu) { 114096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger return false; 115096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 116096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 117096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger fDrawState = SkNEW(GrDrawState); 118096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger fGpu->setDrawState(fDrawState); 119096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 120096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger fTextureCache = SkNEW_ARGS(GrResourceCache, 121096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger (MAX_TEXTURE_CACHE_COUNT, 122096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger MAX_TEXTURE_CACHE_BYTES)); 12358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger fTextureCache->setOverbudgetCallback(OverbudgetCB, this); 12458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 125096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger fFontCache = SkNEW_ARGS(GrFontCache, (fGpu)); 126096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 127096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger fLastDrawWasBuffered = kNo_BufferedDraw; 128096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 129096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger fAARectRenderer = SkNEW(GrAARectRenderer); 130e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger fOvalRenderer = SkNEW(GrOvalRenderer); 13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 132096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger fDidTestPMConversions = false; 133096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 134096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger this->setupDrawBuffer(); 135096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 136096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger return true; 13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruint GrContext::GetThreadInstanceCount() { 14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return THREAD_INSTANCE_COUNT; 14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruGrContext::~GrContext() { 14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = 0; i < fCleanUpData.count(); ++i) { 14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru (*fCleanUpData[i].fFunc)(this, fCleanUpData[i].fInfo); 14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (NULL == fGpu) { 1497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger return; 1507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 1517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->flush(); 15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Since the gpu can hold scratch textures, give it a chance to let go 15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // of them before freeing the texture cache 15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fGpu->purgeResources(); 15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru delete fTextureCache; 15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fTextureCache = NULL; 16080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru delete fFontCache; 16180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru delete fDrawBuffer; 16280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru delete fDrawBufferVBAllocPool; 16380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru delete fDrawBufferIBAllocPool; 16480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 16580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fAARectRenderer->unref(); 166e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger fOvalRenderer->unref(); 16780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 16880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fGpu->unref(); 16980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrSafeUnref(fPathRendererChain); 17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrSafeUnref(fSoftwarePathRenderer); 17180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDrawState->unref(); 17280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 17380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru --THREAD_INSTANCE_COUNT; 17480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 17580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 17680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrContext::contextLost() { 177096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger this->contextDestroyed(); 17880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->setupDrawBuffer(); 17980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 18080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 18180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrContext::contextDestroyed() { 18280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // abandon first to so destructors 18380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // don't try to free the resources in the API. 18480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fGpu->abandonResources(); 18580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 18680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // a path renderer may be holding onto resources that 18780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // are now unusable 18880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrSafeSetNull(fPathRendererChain); 18980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrSafeSetNull(fSoftwarePathRenderer); 19080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 19180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru delete fDrawBuffer; 19280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDrawBuffer = NULL; 19380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 19480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru delete fDrawBufferVBAllocPool; 19580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDrawBufferVBAllocPool = NULL; 19680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 19780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru delete fDrawBufferIBAllocPool; 19880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDrawBufferIBAllocPool = NULL; 19980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 20080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fAARectRenderer->reset(); 20158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger fOvalRenderer->reset(); 20280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 20380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fTextureCache->purgeAllUnlocked(); 20480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fFontCache->freeAll(); 20580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fGpu->markContextDirty(); 20680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 20780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 20858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergervoid GrContext::resetContext(uint32_t state) { 20958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger fGpu->markContextDirty(state); 21080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 21180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 21280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrContext::freeGpuResources() { 21380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->flush(); 21480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 21580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fGpu->purgeResources(); 21680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 21780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fAARectRenderer->reset(); 21858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger fOvalRenderer->reset(); 21980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 22080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fTextureCache->purgeAllUnlocked(); 22180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fFontCache->freeAll(); 22280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // a path renderer may be holding onto resources 22380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrSafeSetNull(fPathRendererChain); 22480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrSafeSetNull(fSoftwarePathRenderer); 22580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 22680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 22780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querusize_t GrContext::getGpuTextureCacheBytes() const { 22880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return fTextureCache->getCachedResourceBytes(); 22980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 23080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 23180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//////////////////////////////////////////////////////////////////////////////// 23280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 233d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek SollenbergerGrTexture* GrContext::findAndRefTexture(const GrTextureDesc& desc, 234d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger const GrCacheID& cacheID, 235d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger const GrTextureParams* params) { 236d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrResourceKey resourceKey = GrTexture::ComputeKey(fGpu, params, desc, cacheID); 23780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrResource* resource = fTextureCache->find(resourceKey); 238d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkSafeRef(resource); 23980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return static_cast<GrTexture*>(resource); 24080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 24180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 24280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool GrContext::isTextureInCache(const GrTextureDesc& desc, 243d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger const GrCacheID& cacheID, 24480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const GrTextureParams* params) const { 245d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrResourceKey resourceKey = GrTexture::ComputeKey(fGpu, params, desc, cacheID); 24680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return fTextureCache->hasKey(resourceKey); 24780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 24880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 24980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrContext::addStencilBuffer(GrStencilBuffer* sb) { 25080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ASSERT_OWNED_RESOURCE(sb); 25180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 25280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrResourceKey resourceKey = GrStencilBuffer::ComputeKey(sb->width(), 25380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru sb->height(), 25480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru sb->numSamples()); 255363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fTextureCache->addResource(resourceKey, sb); 25680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 25780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 25880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruGrStencilBuffer* GrContext::findStencilBuffer(int width, int height, 25980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int sampleCnt) { 26080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrResourceKey resourceKey = GrStencilBuffer::ComputeKey(width, 26180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru height, 26280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru sampleCnt); 26380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrResource* resource = fTextureCache->find(resourceKey); 26480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return static_cast<GrStencilBuffer*>(resource); 26580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 26680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 26780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void stretchImage(void* dst, 26880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int dstW, 26980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int dstH, 27080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void* src, 27180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int srcW, 27280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int srcH, 27380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int bpp) { 27480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrFixed dx = (srcW << 16) / dstW; 27580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrFixed dy = (srcH << 16) / dstH; 27680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 27780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrFixed y = dy >> 1; 27880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 27980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int dstXLimit = dstW*bpp; 28080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int j = 0; j < dstH; ++j) { 28180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrFixed x = dx >> 1; 28280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void* srcRow = (uint8_t*)src + (y>>16)*srcW*bpp; 28380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void* dstRow = (uint8_t*)dst + j*dstW*bpp; 28480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = 0; i < dstXLimit; i += bpp) { 28580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru memcpy((uint8_t*) dstRow + i, 28680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru (uint8_t*) srcRow + (x>>16)*bpp, 28780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bpp); 28880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru x += dx; 28980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 29080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru y += dy; 29180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 29280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 29380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergernamespace { 2957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 2967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger// position + local coordinate 2977839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerextern const GrVertexAttrib gVertexAttribs[] = { 2987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding}, 2997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {kVec2f_GrVertexAttribType, sizeof(GrPoint), kLocalCoord_GrVertexAttribBinding} 3007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}; 3017839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 3027839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}; 3037839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 30480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// The desired texture is NPOT and tiled but that isn't supported by 30580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// the current hardware. Resize the texture to be a POT 30680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruGrTexture* GrContext::createResizedTexture(const GrTextureDesc& desc, 307d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger const GrCacheID& cacheID, 30880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void* srcData, 30980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t rowBytes, 31058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger bool filter) { 311d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkAutoTUnref<GrTexture> clampedTexture(this->findAndRefTexture(desc, cacheID, NULL)); 31280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == clampedTexture) { 313d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger clampedTexture.reset(this->createTexture(NULL, desc, cacheID, srcData, rowBytes)); 31480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 31580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == clampedTexture) { 31680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return NULL; 31780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 31880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 31980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 32080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrTextureDesc rtDesc = desc; 32180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru rtDesc.fFlags = rtDesc.fFlags | 32280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kRenderTarget_GrTextureFlagBit | 32380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kNoStencil_GrTextureFlagBit; 32480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru rtDesc.fWidth = GrNextPow2(GrMax(desc.fWidth, 64)); 32580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru rtDesc.fHeight = GrNextPow2(GrMax(desc.fHeight, 64)); 32680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 32780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrTexture* texture = fGpu->createTexture(rtDesc, NULL, 0); 32880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 32980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL != texture) { 33080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrDrawTarget::AutoStateRestore asr(fGpu, GrDrawTarget::kReset_ASRInit); 33180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrDrawState* drawState = fGpu->drawState(); 33280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru drawState->setRenderTarget(texture->asRenderTarget()); 33380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 33480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // if filtering is not desired then we want to ensure all 33580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // texels in the resampled image are copies of texels from 33680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // the original. 33758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger GrTextureParams params(SkShader::kClamp_TileMode, filter ? GrTextureParams::kBilerp_FilterMode : 33858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger GrTextureParams::kNone_FilterMode); 33958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger drawState->addColorTextureEffect(clampedTexture, SkMatrix::I(), params); 34080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger drawState->setVertexAttribs<gVertexAttribs>(SK_ARRAY_COUNT(gVertexAttribs)); 3427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 343096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger GrDrawTarget::AutoReleaseGeometry arg(fGpu, 4, 0); 34480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 34580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (arg.succeeded()) { 34680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPoint* verts = (GrPoint*) arg.vertices(); 347d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger verts[0].setIRectFan(0, 0, texture->width(), texture->height(), 2 * sizeof(GrPoint)); 348d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger verts[1].setIRectFan(0, 0, 1, 1, 2 * sizeof(GrPoint)); 349d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger fGpu->drawNonIndexed(kTriangleFan_GrPrimitiveType, 0, 4); 35080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 35180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 35280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // TODO: Our CPU stretch doesn't filter. But we create separate 353363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // stretched textures when the texture params is either filtered or 35480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // not. Either implement filtered stretch blit on CPU or just create 35580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // one when FBO case fails. 35680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 35780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru rtDesc.fFlags = kNone_GrTextureFlags; 35880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // no longer need to clamp at min RT size. 35980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru rtDesc.fWidth = GrNextPow2(desc.fWidth); 36080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru rtDesc.fHeight = GrNextPow2(desc.fHeight); 36180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int bpp = GrBytesPerPixel(desc.fConfig); 362363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkAutoSMalloc<128*128*4> stretchedPixels(bpp * rtDesc.fWidth * rtDesc.fHeight); 36380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru stretchImage(stretchedPixels.get(), rtDesc.fWidth, rtDesc.fHeight, 364363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger srcData, desc.fWidth, desc.fHeight, bpp); 36580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 36680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t stretchedRowBytes = rtDesc.fWidth * bpp; 36780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 368096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SkDEBUGCODE(GrTexture* texture = )fGpu->createTexture(rtDesc, stretchedPixels.get(), 369096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger stretchedRowBytes); 37080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(NULL != texture); 37180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 37280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 37380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return texture; 37480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 37580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 376d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek SollenbergerGrTexture* GrContext::createTexture(const GrTextureParams* params, 377d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger const GrTextureDesc& desc, 378d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger const GrCacheID& cacheID, 379d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger void* srcData, 380d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger size_t rowBytes) { 381d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SK_TRACE_EVENT0("GrContext::createTexture"); 38280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 383d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrResourceKey resourceKey = GrTexture::ComputeKey(fGpu, params, desc, cacheID); 38480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 385d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrTexture* texture; 38680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (GrTexture::NeedsResizing(resourceKey)) { 387d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger texture = this->createResizedTexture(desc, cacheID, 38880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru srcData, rowBytes, 38958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger GrTexture::NeedsBilerp(resourceKey)); 39080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 391d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger texture= fGpu->createTexture(desc, srcData, rowBytes); 39280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 39380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 39480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL != texture) { 39558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // Adding a resource could put us overbudget. Try to free up the 39658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // necessary space before adding it. 39758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger fTextureCache->purgeAsNeeded(1, texture->sizeInBytes()); 398363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fTextureCache->addResource(resourceKey, texture); 39980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 40080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 40180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return texture; 40280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 40380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 40458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerstatic GrTexture* create_scratch_texture(GrGpu* gpu, 40558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger GrResourceCache* textureCache, 40658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger const GrTextureDesc& desc) { 40758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger GrTexture* texture = gpu->createTexture(desc, NULL, 0); 40858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (NULL != texture) { 40958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger GrResourceKey key = GrTexture::ComputeScratchKey(texture->desc()); 41058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // Adding a resource could put us overbudget. Try to free up the 41158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // necessary space before adding it. 41258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger textureCache->purgeAsNeeded(1, texture->sizeInBytes()); 41358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // Make the resource exclusive so future 'find' calls don't return it 41458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger textureCache->addResource(key, texture, GrResourceCache::kHide_OwnershipFlag); 41558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 41658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger return texture; 41758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger} 41858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 419d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek SollenbergerGrTexture* GrContext::lockAndRefScratchTexture(const GrTextureDesc& inDesc, ScratchTexMatch match) { 42080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 42158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger GrAssert((inDesc.fFlags & kRenderTarget_GrTextureFlagBit) || 42258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger !(inDesc.fFlags & kNoStencil_GrTextureFlagBit)); 42358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 42458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // Renderable A8 targets are not universally supported (e.g., not on ANGLE) 42558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger GrAssert(this->isConfigRenderable(kAlpha_8_GrPixelConfig) || 42658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger !(inDesc.fFlags & kRenderTarget_GrTextureFlagBit) || 42758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger (inDesc.fConfig != kAlpha_8_GrPixelConfig)); 42858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 42958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (!fGpu->caps()->reuseScratchTextures()) { 43058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // If we're never recycling scratch textures we can 43158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // always make them the right size 43258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger return create_scratch_texture(fGpu, fTextureCache, inDesc); 43358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 43458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 43558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger GrTextureDesc desc = inDesc; 43680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 437d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (kApprox_ScratchTexMatch == match) { 43880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // bin by pow2 with a reasonable min 439096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger static const int MIN_SIZE = 16; 44080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fWidth = GrMax(MIN_SIZE, GrNextPow2(desc.fWidth)); 44180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fHeight = GrMax(MIN_SIZE, GrNextPow2(desc.fHeight)); 44280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 44380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 44480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrResource* resource = NULL; 44580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int origWidth = desc.fWidth; 44680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int origHeight = desc.fHeight; 44780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 44880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru do { 449d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrResourceKey key = GrTexture::ComputeScratchKey(desc); 450363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // Ensure we have exclusive access to the texture so future 'find' calls don't return it 451363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger resource = fTextureCache->find(key, GrResourceCache::kHide_OwnershipFlag); 452d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (NULL != resource) { 453d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger resource->ref(); 45480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 45580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 456d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (kExact_ScratchTexMatch == match) { 457d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger break; 458d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } 459096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger // We had a cache miss and we are in approx mode, relax the fit of the flags. 460d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 46180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // We no longer try to reuse textures that were previously used as render targets in 46280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // situations where no RT is needed; doing otherwise can confuse the video driver and 46380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // cause significant performance problems in some cases. 46480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (desc.fFlags & kNoStencil_GrTextureFlagBit) { 46580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fFlags = desc.fFlags & ~kNoStencil_GrTextureFlagBit; 46680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 46780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 46880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 46980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 47080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } while (true); 47180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 47280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == resource) { 47380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fFlags = inDesc.fFlags; 47480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fWidth = origWidth; 47580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fHeight = origHeight; 47658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger resource = create_scratch_texture(fGpu, fTextureCache, desc); 47780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 47880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 47980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return static_cast<GrTexture*>(resource); 48080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 48180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 48280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrContext::addExistingTextureToCache(GrTexture* texture) { 48380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 48480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == texture) { 48580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 48680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 48780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 48880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // This texture should already have a cache entry since it was once 48980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // attached 49080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(NULL != texture->getCacheEntry()); 49180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 49280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Conceptually, the cache entry is going to assume responsibility 49380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // for the creation ref. 49458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger GrAssert(texture->unique()); 49580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 49680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Since this texture came from an AutoScratchTexture it should 49780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // still be in the exclusive pile 49880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fTextureCache->makeNonExclusive(texture->getCacheEntry()); 49980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 50058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (fGpu->caps()->reuseScratchTextures()) { 50158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger this->purgeCache(); 50258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } else { 50358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // When we aren't reusing textures we know this scratch texture 50458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // will never be reused and would be just wasting time in the cache 50558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger fTextureCache->deleteResource(texture->getCacheEntry()); 50658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 50780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 50880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 50980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 51080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrContext::unlockScratchTexture(GrTexture* texture) { 51180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ASSERT_OWNED_RESOURCE(texture); 51280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(NULL != texture->getCacheEntry()); 51380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 51480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // If this is a scratch texture we detached it from the cache 51580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // while it was locked (to avoid two callers simultaneously getting 51680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // the same texture). 517d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (texture->getCacheEntry()->key().isScratch()) { 51880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fTextureCache->makeNonExclusive(texture->getCacheEntry()); 51958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger this->purgeCache(); 52080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 52180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 52280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 52380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrContext::purgeCache() { 52480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL != fTextureCache) { 52580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fTextureCache->purgeAsNeeded(); 52680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 52780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 52880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 52958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerbool GrContext::OverbudgetCB(void* data) { 53058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger GrAssert(NULL != data); 53158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 53258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger GrContext* context = reinterpret_cast<GrContext*>(data); 53358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 53458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // Flush the InOrderDrawBuffer to possibly free up some textures 53558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger context->flush(); 53658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 53758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // TODO: actually track flush's behavior rather than always just 53858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // returning true. 53958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger return true; 54058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger} 54158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 54258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 54380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruGrTexture* GrContext::createUncachedTexture(const GrTextureDesc& descIn, 54480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void* srcData, 54580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t rowBytes) { 54680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrTextureDesc descCopy = descIn; 54780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return fGpu->createTexture(descCopy, srcData, rowBytes); 54880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 54980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 55080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrContext::getTextureCacheLimits(int* maxTextures, 55180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t* maxTextureBytes) const { 55280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fTextureCache->getLimits(maxTextures, maxTextureBytes); 55380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 55480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 55580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrContext::setTextureCacheLimits(int maxTextures, size_t maxTextureBytes) { 55680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fTextureCache->setLimits(maxTextures, maxTextureBytes); 55780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 55880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 55980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruint GrContext::getMaxTextureSize() const { 56058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger return GrMin(fGpu->caps()->maxTextureSize(), fMaxTextureSizeOverride); 56180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 56280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 56380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruint GrContext::getMaxRenderTargetSize() const { 5647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger return fGpu->caps()->maxRenderTargetSize(); 56580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 56680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 567096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenbergerint GrContext::getMaxSampleCount() const { 5687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger return fGpu->caps()->maxSampleCount(); 569096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger} 570096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 57180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 57280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 573363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek SollenbergerGrTexture* GrContext::wrapBackendTexture(const GrBackendTextureDesc& desc) { 574363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return fGpu->wrapBackendTexture(desc); 57580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 57680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 577363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek SollenbergerGrRenderTarget* GrContext::wrapBackendRenderTarget(const GrBackendRenderTargetDesc& desc) { 578363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return fGpu->wrapBackendRenderTarget(desc); 57980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 58080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 58180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 58280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 58380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool GrContext::supportsIndex8PixelConfig(const GrTextureParams* params, 58480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int width, int height) const { 5857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const GrDrawTargetCaps* caps = fGpu->caps(); 5867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (!caps->eightBitPaletteSupport()) { 58780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 58880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 58980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 59080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool isPow2 = GrIsPow2(width) && GrIsPow2(height); 59180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 59280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!isPow2) { 59380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool tiled = NULL != params && params->isTiled(); 5947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (tiled && !caps->npotTextureTileSupport()) { 59580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 59680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 59780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 59880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 59980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 60080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 60180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 60280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//////////////////////////////////////////////////////////////////////////////// 60380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 60458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergervoid GrContext::clear(const SkIRect* rect, 60580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const GrColor color, 60680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrRenderTarget* target) { 60758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger AutoRestoreEffects are; 60858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger this->prepareToDraw(NULL, BUFFERED_DRAW, &are)->clear(rect, color, target); 60980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 61080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 61180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrContext::drawPaint(const GrPaint& origPaint) { 61280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // set rect to be big enough to fill the space, but not super-huge, so we 61380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // don't overflow fixed-point implementations 61458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkRect r; 61580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru r.setLTRB(0, 0, 616363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkIntToScalar(getRenderTarget()->width()), 617363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkIntToScalar(getRenderTarget()->height())); 618363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkMatrix inverse; 61980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkTCopyOnFirstWrite<GrPaint> paint(origPaint); 62080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru AutoMatrix am; 62180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 62280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // We attempt to map r by the inverse matrix and draw that. mapRect will 62380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // map the four corners and bound them with a new rect. This will not 62480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // produce a correct result for some perspective matrices. 62580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!this->getMatrix().hasPerspective()) { 62658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (!fViewMatrix.invert(&inverse)) { 62780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPrintf("Could not invert matrix\n"); 62880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 62980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 63080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru inverse.mapRect(&r); 63180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 63280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!am.setIdentity(this, paint.writable())) { 63380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPrintf("Could not invert matrix\n"); 63480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 63580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 63680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 63780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // by definition this fills the entire clip, no need for AA 63880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (paint->isAntiAlias()) { 63980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru paint.writable()->setAntiAlias(false); 64080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 64180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->drawRect(*paint, r); 64280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 64380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 64480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//////////////////////////////////////////////////////////////////////////////// 64580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 64680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querunamespace { 64780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruinline bool disable_coverage_aa_for_blend(GrDrawTarget* target) { 64880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return DISABLE_COVERAGE_AA_FOR_BLEND && !target->canApplyCoverage(); 64980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 65080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 65180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 65280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//////////////////////////////////////////////////////////////////////////////// 65380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 65480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* create a triangle strip that strokes the specified triangle. There are 8 65580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unique vertices, but we repreat the last 2 to close up. Alternatively we 65680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru could use an indices array, and then only send 8 verts, but not sure that 65780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru would be faster. 65880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 65958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerstatic void setStrokeRectStrip(GrPoint verts[10], SkRect rect, 660363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkScalar width) { 661363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const SkScalar rad = SkScalarHalf(width); 66280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru rect.sort(); 66380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 66480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru verts[0].set(rect.fLeft + rad, rect.fTop + rad); 66580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru verts[1].set(rect.fLeft - rad, rect.fTop - rad); 66680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru verts[2].set(rect.fRight - rad, rect.fTop + rad); 66780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru verts[3].set(rect.fRight + rad, rect.fTop - rad); 66880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru verts[4].set(rect.fRight - rad, rect.fBottom - rad); 66980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru verts[5].set(rect.fRight + rad, rect.fBottom + rad); 67080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru verts[6].set(rect.fLeft + rad, rect.fBottom - rad); 67180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru verts[7].set(rect.fLeft - rad, rect.fBottom + rad); 67280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru verts[8] = verts[0]; 67380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru verts[9] = verts[1]; 67480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 67580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 67658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerstatic bool isIRect(const SkRect& r) { 6777839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger return SkScalarIsInt(r.fLeft) && SkScalarIsInt(r.fTop) && 678363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkScalarIsInt(r.fRight) && SkScalarIsInt(r.fBottom); 67980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 68080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 68180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic bool apply_aa_to_rect(GrDrawTarget* target, 68258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger const SkRect& rect, 6837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkScalar strokeWidth, 684363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const SkMatrix* matrix, 685363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkMatrix* combinedMatrix, 68658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkRect* devRect, 68780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool* useVertexCoverage) { 68880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // we use a simple coverage ramp to do aa on axis-aligned rects 68980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // we check if the rect will be axis-aligned, and the rect won't land on 69080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // integer coords. 69180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 69280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // we are keeping around the "tweak the alpha" trick because 69380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // it is our only hope for the fixed-pipe implementation. 69480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // In a shader implementation we can give a separate coverage input 69580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // TODO: remove this ugliness when we drop the fixed-pipe impl 69680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *useVertexCoverage = false; 697096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger if (!target->getDrawState().canTweakAlphaForCoverage()) { 69880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (disable_coverage_aa_for_blend(target)) { 69980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if GR_DEBUG 70080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru //GrPrintf("Turning off AA to correctly apply blend.\n"); 70180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 70280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 70380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 70480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *useVertexCoverage = true; 70580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 70680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 70780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const GrDrawState& drawState = target->getDrawState(); 70880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (drawState.getRenderTarget()->isMultisampled()) { 70980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 71080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 71180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (0 == strokeWidth && target->willUseHWAALines()) { 71380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 71480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 71580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT) 7177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (strokeWidth >= 0) { 7187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#endif 7197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (!drawState.getViewMatrix().preservesAxisAlignment()) { 7207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger return false; 7217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 72280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (NULL != matrix && !matrix->preservesAxisAlignment()) { 7247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger return false; 7257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 7267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT) 7277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } else { 7287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (!drawState.getViewMatrix().preservesAxisAlignment() && 7297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger !drawState.getViewMatrix().preservesRightAngles()) { 7307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger return false; 7317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 7327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 7337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (NULL != matrix && !matrix->preservesRightAngles()) { 7347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger return false; 7357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 73680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 7377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#endif 73880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 73980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *combinedMatrix = drawState.getViewMatrix(); 74080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL != matrix) { 74180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru combinedMatrix->preConcat(*matrix); 7427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 7437839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#if GR_DEBUG 7447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT) 7457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (strokeWidth >= 0) { 7467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#endif 7477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger GrAssert(combinedMatrix->preservesAxisAlignment()); 7487839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT) 7497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } else { 7507839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger GrAssert(combinedMatrix->preservesRightAngles()); 7517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 7527839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#endif 7537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#endif 75480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 75580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 75680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru combinedMatrix->mapRect(devRect, rect); 75780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (strokeWidth < 0) { 75980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return !isIRect(*devRect); 76080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 76180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 76280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 76380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 76480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 76580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrContext::drawRect(const GrPaint& paint, 76658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger const SkRect& rect, 767363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkScalar width, 768363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const SkMatrix* matrix) { 76980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_TRACE_EVENT0("GrContext::drawRect"); 77080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 77158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger AutoRestoreEffects are; 77258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are); 77380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 77458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkRect devRect; 775363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkMatrix combinedMatrix; 77680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool useVertexCoverage; 77780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool needAA = paint.isAntiAlias() && 77858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger !target->getDrawState().getRenderTarget()->isMultisampled(); 77980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool doAA = needAA && apply_aa_to_rect(target, rect, width, matrix, 78080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru &combinedMatrix, &devRect, 78180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru &useVertexCoverage); 78280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (doAA) { 78358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger GrDrawState::AutoViewMatrixRestore avmr; 78458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (!avmr.setIdentity(target->drawState())) { 78580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 78680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 78780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (width >= 0) { 7887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger fAARectRenderer->strokeAARect(this->getGpu(), target, 7897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger rect, combinedMatrix, devRect, 7907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger width, useVertexCoverage); 79180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 7927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // filled AA rect 79380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fAARectRenderer->fillAARect(this->getGpu(), target, 7947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger rect, combinedMatrix, devRect, 7957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger useVertexCoverage); 79680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 79780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 79880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 79980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 80080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (width >= 0) { 80180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // TODO: consider making static vertex buffers for these cases. 80280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Hairline could be done by just adding closing vertex to 80380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // unitSquareVertexBuffer() 80480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 80580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static const int worstCaseVertCount = 10; 806096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger target->drawState()->setDefaultVertexAttribs(); 807096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger GrDrawTarget::AutoReleaseGeometry geo(target, worstCaseVertCount, 0); 80880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 80980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!geo.succeeded()) { 81080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPrintf("Failed to get space for vertices!\n"); 81180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 81280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 81380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 81480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPrimitiveType primType; 81580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int vertCount; 81680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPoint* vertex = geo.positions(); 81780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 81880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (width > 0) { 81980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru vertCount = 10; 82080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru primType = kTriangleStrip_GrPrimitiveType; 82180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru setStrokeRectStrip(vertex, rect, width); 82280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 82380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // hairline 82480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru vertCount = 5; 82580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru primType = kLineStrip_GrPrimitiveType; 82680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru vertex[0].set(rect.fLeft, rect.fTop); 82780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru vertex[1].set(rect.fRight, rect.fTop); 82880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru vertex[2].set(rect.fRight, rect.fBottom); 82980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru vertex[3].set(rect.fLeft, rect.fBottom); 83080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru vertex[4].set(rect.fLeft, rect.fTop); 83180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 83280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 83380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrDrawState::AutoViewMatrixRestore avmr; 83480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL != matrix) { 83580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrDrawState* drawState = target->drawState(); 83680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru avmr.set(drawState, *matrix); 83780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 83880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 83980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru target->drawNonIndexed(primType, 0, vertCount); 84080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 8417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // filled BW rect 8427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger target->drawSimpleRect(rect, matrix); 84380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 84480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 84580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 84680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrContext::drawRectToRect(const GrPaint& paint, 84758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger const SkRect& dstRect, 84858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger const SkRect& localRect, 849363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const SkMatrix* dstMatrix, 850e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger const SkMatrix* localMatrix) { 85180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_TRACE_EVENT0("GrContext::drawRectToRect"); 85258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger AutoRestoreEffects are; 85358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are); 85480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger target->drawRect(dstRect, dstMatrix, &localRect, localMatrix); 8567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger} 85780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergernamespace { 85980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerextern const GrVertexAttrib gPosUVColorAttribs[] = { 8617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding }, 8627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {kVec2f_GrVertexAttribType, sizeof(GrPoint), kLocalCoord_GrVertexAttribBinding }, 8637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {kVec4ub_GrVertexAttribType, 2*sizeof(GrPoint), kColor_GrVertexAttribBinding} 8647839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}; 8657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 8667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerextern const GrVertexAttrib gPosColorAttribs[] = { 8677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding}, 8687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger {kVec4ub_GrVertexAttribType, sizeof(GrPoint), kColor_GrVertexAttribBinding}, 8697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}; 8707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 8717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerstatic void set_vertex_attributes(GrDrawState* drawState, 8727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const GrPoint* texCoords, 8737839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const GrColor* colors, 8747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger int* colorOffset, 8757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger int* texOffset) { 8767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger *texOffset = -1; 8777839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger *colorOffset = -1; 8787839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 8797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (NULL != texCoords && NULL != colors) { 8807839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger *texOffset = sizeof(GrPoint); 8817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger *colorOffset = 2*sizeof(GrPoint); 8827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger drawState->setVertexAttribs<gPosUVColorAttribs>(3); 8837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } else if (NULL != texCoords) { 8847839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger *texOffset = sizeof(GrPoint); 8857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger drawState->setVertexAttribs<gPosUVColorAttribs>(2); 8867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } else if (NULL != colors) { 8877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger *colorOffset = sizeof(GrPoint); 8887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger drawState->setVertexAttribs<gPosColorAttribs>(2); 8897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } else { 8907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger drawState->setVertexAttribs<gPosColorAttribs>(1); 89180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 89280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 89380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}; 8957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 89680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrContext::drawVertices(const GrPaint& paint, 89780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPrimitiveType primitiveType, 89880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int vertexCount, 89980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const GrPoint positions[], 90080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const GrPoint texCoords[], 90180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const GrColor colors[], 90280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const uint16_t indices[], 90380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int indexCount) { 90480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_TRACE_EVENT0("GrContext::drawVertices"); 90580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 90680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrDrawTarget::AutoReleaseGeometry geo; 90780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 90858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger AutoRestoreEffects are; 90958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are); 91080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 911096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger GrDrawState* drawState = target->drawState(); 912096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 913096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger int colorOffset = -1, texOffset = -1; 9147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger set_vertex_attributes(drawState, texCoords, colors, &colorOffset, &texOffset); 915096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 916096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger size_t vertexSize = drawState->getVertexSize(); 91780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (sizeof(GrPoint) != vertexSize) { 918096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger if (!geo.set(target, vertexCount, 0)) { 91980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPrintf("Failed to get space for vertices!\n"); 92080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 92180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 92280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void* curVertex = geo.vertices(); 92380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 92480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = 0; i < vertexCount; ++i) { 92580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *((GrPoint*)curVertex) = positions[i]; 92680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 927096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger if (texOffset >= 0) { 928096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger *(GrPoint*)((intptr_t)curVertex + texOffset) = texCoords[i]; 92980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 930096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger if (colorOffset >= 0) { 93180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *(GrColor*)((intptr_t)curVertex + colorOffset) = colors[i]; 93280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 93380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru curVertex = (void*)((intptr_t)curVertex + vertexSize); 93480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 93580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 936096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger target->setVertexSourceToArray(positions, vertexCount); 93780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 93880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 93980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // we don't currently apply offscreen AA to this path. Need improved 94080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // management of GrDrawTarget's geometry to avoid copying points per-tile. 94180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 94280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL != indices) { 94380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru target->setIndexSourceToArray(indices, indexCount); 94480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru target->drawIndexed(primitiveType, 0, 0, vertexCount, indexCount); 9457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger target->resetIndexSource(); 94680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 94780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru target->drawNonIndexed(primitiveType, 0, vertexCount); 94880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 94980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 95080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 95180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 952d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 9537839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergervoid GrContext::drawRRect(const GrPaint& paint, 9547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const SkRRect& rect, 9557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const SkStrokeRec& stroke) { 956e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger if (rect.isEmpty()) { 957e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger return; 958e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger } 9597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 96058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger AutoRestoreEffects are; 96158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are); 9627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 9637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger bool useAA = paint.isAntiAlias() && 96458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger !target->getDrawState().getRenderTarget()->isMultisampled() && 9657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger !disable_coverage_aa_for_blend(target); 9667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 9677839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (!fOvalRenderer->drawSimpleRRect(target, this, useAA, rect, stroke)) { 9687839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkPath path; 9697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger path.addRRect(rect); 9707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger this->internalDrawPath(target, useAA, path, stroke); 9717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 9727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger} 9737839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 9747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 9757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 976d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergervoid GrContext::drawOval(const GrPaint& paint, 97758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger const SkRect& oval, 978d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger const SkStrokeRec& stroke) { 979e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger if (oval.isEmpty()) { 980e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger return; 981e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger } 982d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 98358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger AutoRestoreEffects are; 98458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are); 985096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 9867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger bool useAA = paint.isAntiAlias() && 98758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger !target->getDrawState().getRenderTarget()->isMultisampled() && 9887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger !disable_coverage_aa_for_blend(target); 9897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 9907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (!fOvalRenderer->drawOval(target, this, useAA, oval, stroke)) { 991e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger SkPath path; 992e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger path.addOval(oval); 9937839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger this->internalDrawPath(target, useAA, path, stroke); 9947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 9957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger} 9967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 9977839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger// Can 'path' be drawn as a pair of filled nested rectangles? 9987839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerstatic bool is_nested_rects(GrDrawTarget* target, 9997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const SkPath& path, 10007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const SkStrokeRec& stroke, 10017839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkRect rects[2], 10027839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger bool* useVertexCoverage) { 10037839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkASSERT(stroke.isFillStyle()); 10047839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 10057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (path.isInverseFillType()) { 10067839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger return false; 10077839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 10087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 10097839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const GrDrawState& drawState = target->getDrawState(); 10107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 10117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // TODO: this restriction could be lifted if we were willing to apply 10127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // the matrix to all the points individually rather than just to the rect 10137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (!drawState.getViewMatrix().preservesAxisAlignment()) { 10147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger return false; 10157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 10167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 10177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger *useVertexCoverage = false; 10187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (!target->getDrawState().canTweakAlphaForCoverage()) { 10197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (disable_coverage_aa_for_blend(target)) { 10207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger return false; 10217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } else { 10227839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger *useVertexCoverage = true; 10237839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 10247839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 10257839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 10267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkPath::Direction dirs[2]; 10277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (!path.isNestedRects(rects, dirs)) { 10287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger return false; 10297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 10307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 1031bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger if (SkPath::kWinding_FillType == path.getFillType() && dirs[0] == dirs[1]) { 10327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // The two rects need to be wound opposite to each other 1033bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger return false; 1034d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } 103580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1036bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger // Right now, nested rects where the margin is not the same width 1037bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger // all around do not render correctly 1038bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger const SkScalar* outer = rects[0].asScalars(); 1039bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger const SkScalar* inner = rects[1].asScalars(); 1040bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger 1041bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger SkScalar margin = SkScalarAbs(outer[0] - inner[0]); 1042bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger for (int i = 1; i < 4; ++i) { 1043bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger SkScalar temp = SkScalarAbs(outer[i] - inner[i]); 1044bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger if (!SkScalarNearlyEqual(margin, temp)) { 1045bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger return false; 1046bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger } 1047bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger } 1048bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger 1049bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger return true; 1050bd353162926d4e7adf5b4345552be4bf62f5397aDerek Sollenberger} 10517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 1052363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergervoid GrContext::drawPath(const GrPaint& paint, const SkPath& path, const SkStrokeRec& stroke) { 105380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 105480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (path.isEmpty()) { 1055363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (path.isInverseFillType()) { 105680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->drawPaint(paint); 105780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 105880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 105980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 106080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1061e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger // Note that internalDrawPath may sw-rasterize the path into a scratch texture. 1062e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger // Scratch textures can be recycled after they are returned to the texture 1063e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger // cache. This presents a potential hazard for buffered drawing. However, 1064e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger // the writePixels that uploads to the scratch will perform a flush so we're 1065e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger // OK. 106658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger AutoRestoreEffects are; 106758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are); 1068e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger 106958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger bool useAA = paint.isAntiAlias() && !target->getDrawState().getRenderTarget()->isMultisampled(); 10707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (useAA && stroke.getWidth() < 0 && !path.isConvex()) { 10717839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // Concave AA paths are expensive - try to avoid them for special cases 10727839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger bool useVertexCoverage; 10737839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkRect rects[2]; 10747839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 10757839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (is_nested_rects(target, path, stroke, rects, &useVertexCoverage)) { 107658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkMatrix origViewMatrix = target->getDrawState().getViewMatrix(); 107758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger GrDrawState::AutoViewMatrixRestore avmr; 107858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (!avmr.setIdentity(target->drawState())) { 10797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger return; 10807839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 10817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 10827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger fAARectRenderer->fillAANestedRects(this->getGpu(), target, 10837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger rects, 108458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger origViewMatrix, 10857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger useVertexCoverage); 10867839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger return; 10877839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 10887839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 10897839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 109080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkRect ovalRect; 1091d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger bool isOval = path.isOval(&ovalRect); 1092d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 1093e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger if (!isOval || path.isInverseFillType() 10947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger || !fOvalRenderer->drawOval(target, this, useAA, ovalRect, stroke)) { 10957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger this->internalDrawPath(target, useAA, path, stroke); 109680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 109780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 109880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 10997839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergervoid GrContext::internalDrawPath(GrDrawTarget* target, bool useAA, const SkPath& path, 1100096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger const SkStrokeRec& stroke) { 1101e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger SkASSERT(!path.isEmpty()); 110280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 110380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // An Assumption here is that path renderer would use some form of tweaking 110480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // the src color (either the input alpha or in the frag shader) to implement 110580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // aa. If we have some future driver-mojo path AA that can do the right 110680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // thing WRT to the blend then we'll need some query on the PR. 110780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (disable_coverage_aa_for_blend(target)) { 110880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if GR_DEBUG 110980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru //GrPrintf("Turning off AA to correctly apply blend.\n"); 111080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 11117839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger useAA = false; 111280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 111380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 11147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger GrPathRendererChain::DrawType type = useAA ? GrPathRendererChain::kColorAntiAlias_DrawType : 11157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger GrPathRendererChain::kColor_DrawType; 1116363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 1117d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger const SkPath* pathPtr = &path; 1118d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkPath tmpPath; 1119d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkStrokeRec strokeRec(stroke); 1120d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 1121d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger // Try a 1st time without stroking the path and without allowing the SW renderer 1122d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrPathRenderer* pr = this->getPathRenderer(*pathPtr, strokeRec, target, false, type); 1123d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 1124d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (NULL == pr) { 1125d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (!strokeRec.isHairlineStyle()) { 1126d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger // It didn't work the 1st time, so try again with the stroked path 1127d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (strokeRec.applyToPath(&tmpPath, *pathPtr)) { 1128d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger pathPtr = &tmpPath; 1129d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger strokeRec.setFillStyle(); 1130d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } 1131d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } 1132e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger if (pathPtr->isEmpty()) { 1133e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger return; 1134e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger } 1135e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger 1136d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger // This time, allow SW renderer 1137d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger pr = this->getPathRenderer(*pathPtr, strokeRec, target, true, type); 1138d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } 1139d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 114080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == pr) { 114180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if GR_DEBUG 114280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPrintf("Unable to find path renderer compatible with path.\n"); 114380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 114480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 114580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 114680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 11477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger pr->drawPath(*pathPtr, strokeRec, target, useAA); 114880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 114980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 115080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//////////////////////////////////////////////////////////////////////////////// 115180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 115280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrContext::flush(int flagsBitfield) { 115358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (NULL == fDrawBuffer) { 115458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger return; 115558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 115658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 115780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (kDiscard_FlushBit & flagsBitfield) { 115880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDrawBuffer->reset(); 115980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 1160096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger fDrawBuffer->flush(); 116180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 116280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 116380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1164096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenbergerbool GrContext::writeTexturePixels(GrTexture* texture, 116580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int left, int top, int width, int height, 116680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPixelConfig config, const void* buffer, size_t rowBytes, 116780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru uint32_t flags) { 116880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_TRACE_EVENT0("GrContext::writeTexturePixels"); 116980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ASSERT_OWNED_RESOURCE(texture); 117080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1171096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger if ((kUnpremul_PixelOpsFlag & flags) || !fGpu->canWriteTexturePixels(texture, config)) { 1172096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger if (NULL != texture->asRenderTarget()) { 1173096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger return this->writeRenderTargetPixels(texture->asRenderTarget(), 1174096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger left, top, width, height, 1175096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger config, buffer, rowBytes, flags); 1176096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } else { 1177096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger return false; 1178096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 117980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 1180096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 118180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!(kDontFlush_PixelOpsFlag & flags)) { 118280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->flush(); 118380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 118480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1185096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger return fGpu->writeTexturePixels(texture, left, top, width, height, 1186096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger config, buffer, rowBytes); 118780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 118880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 118980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool GrContext::readTexturePixels(GrTexture* texture, 119080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int left, int top, int width, int height, 119180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPixelConfig config, void* buffer, size_t rowBytes, 119280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru uint32_t flags) { 119380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_TRACE_EVENT0("GrContext::readTexturePixels"); 119480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ASSERT_OWNED_RESOURCE(texture); 119580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 119680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // TODO: code read pixels for textures that aren't also rendertargets 119780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrRenderTarget* target = texture->asRenderTarget(); 119880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL != target) { 119980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return this->readRenderTargetPixels(target, 120080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru left, top, width, height, 120180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru config, buffer, rowBytes, 120280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru flags); 120380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 120480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 120580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 120680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 120780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 120880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkConfig8888.h" 120980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 121080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querunamespace { 121180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/** 121280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Converts a GrPixelConfig to a SkCanvas::Config8888. Only byte-per-channel 121380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * formats are representable as Config8888 and so the function returns false 121480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * if the GrPixelConfig has no equivalent Config8888. 121580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 121680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool grconfig_to_config8888(GrPixelConfig config, 121780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool unpremul, 121880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkCanvas::Config8888* config8888) { 121980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru switch (config) { 122080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case kRGBA_8888_GrPixelConfig: 122180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (unpremul) { 122280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *config8888 = SkCanvas::kRGBA_Unpremul_Config8888; 122380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 122480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *config8888 = SkCanvas::kRGBA_Premul_Config8888; 122580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 122680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 122780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case kBGRA_8888_GrPixelConfig: 122880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (unpremul) { 122980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *config8888 = SkCanvas::kBGRA_Unpremul_Config8888; 123080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 123180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *config8888 = SkCanvas::kBGRA_Premul_Config8888; 123280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 123380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 123480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru default: 123580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 123680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 123780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 123880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 123980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// It returns a configuration with where the byte position of the R & B components are swapped in 124080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// relation to the input config. This should only be called with the result of 124180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// grconfig_to_config8888 as it will fail for other configs. 124280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkCanvas::Config8888 swap_config8888_red_and_blue(SkCanvas::Config8888 config8888) { 124380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru switch (config8888) { 124480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case SkCanvas::kBGRA_Premul_Config8888: 124580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkCanvas::kRGBA_Premul_Config8888; 124680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case SkCanvas::kBGRA_Unpremul_Config8888: 124780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkCanvas::kRGBA_Unpremul_Config8888; 124880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case SkCanvas::kRGBA_Premul_Config8888: 124980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkCanvas::kBGRA_Premul_Config8888; 125080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case SkCanvas::kRGBA_Unpremul_Config8888: 125180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkCanvas::kBGRA_Unpremul_Config8888; 125280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru default: 125380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrCrash("Unexpected input"); 125480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkCanvas::kBGRA_Unpremul_Config8888;; 125580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 125680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 125780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 125880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 125980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool GrContext::readRenderTargetPixels(GrRenderTarget* target, 126080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int left, int top, int width, int height, 1261096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger GrPixelConfig dstConfig, void* buffer, size_t rowBytes, 126280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru uint32_t flags) { 126380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_TRACE_EVENT0("GrContext::readRenderTargetPixels"); 126480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ASSERT_OWNED_RESOURCE(target); 126580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 126680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == target) { 126758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger target = fRenderTarget.get(); 126880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == target) { 126980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 127080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 127180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 127280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 127380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!(kDontFlush_PixelOpsFlag & flags)) { 127480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->flush(); 127580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 127680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 127780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Determine which conversions have to be applied: flipY, swapRAnd, and/or unpremul. 127880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 127980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // If fGpu->readPixels would incur a y-flip cost then we will read the pixels upside down. We'll 128080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // either do the flipY by drawing into a scratch with a matrix or on the cpu after the read. 128180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool flipY = fGpu->readPixelsWillPayForYFlip(target, left, top, 1282096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger width, height, dstConfig, 128380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru rowBytes); 1284096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger // We ignore the preferred config if it is different than our config unless it is an R/B swap. 1285096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger // In that case we'll perform an R and B swap while drawing to a scratch texture of the swapped 1286096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger // config. Then we will call readPixels on the scratch with the swapped config. The swaps during 1287096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger // the draw cancels out the fact that we call readPixels with a config that is R/B swapped from 1288096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger // dstConfig. 1289096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger GrPixelConfig readConfig = dstConfig; 1290096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger bool swapRAndB = false; 1291779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger if (GrPixelConfigSwapRAndB(dstConfig) == 1292779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger fGpu->preferredReadPixelsConfig(dstConfig, target->config())) { 1293096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger readConfig = GrPixelConfigSwapRAndB(readConfig); 1294096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger swapRAndB = true; 1295096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 129680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 129780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool unpremul = SkToBool(kUnpremul_PixelOpsFlag & flags); 129880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1299096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger if (unpremul && !GrPixelConfigIs8888(dstConfig)) { 130080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // The unpremul flag is only allowed for these two configs. 130180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 130280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 130380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 130480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // If the src is a texture and we would have to do conversions after read pixels, we instead 130580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // do the conversions by drawing the src to a scratch texture. If we handle any of the 130680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // conversions in the draw we set the corresponding bool to false so that we don't reapply it 130780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // on the read back pixels. 130880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrTexture* src = target->asTexture(); 130980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAutoScratchTexture ast; 131080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL != src && (swapRAndB || unpremul || flipY)) { 131180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Make the scratch a render target because we don't have a robust readTexturePixels as of 131280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // yet. It calls this function. 131380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrTextureDesc desc; 131480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fFlags = kRenderTarget_GrTextureFlagBit; 131580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fWidth = width; 131680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fHeight = height; 131780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fConfig = readConfig; 1318096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger desc.fOrigin = kTopLeft_GrSurfaceOrigin; 131980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1320096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger // When a full read back is faster than a partial we could always make the scratch exactly 132180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // match the passed rect. However, if we see many different size rectangles we will trash 132280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // our texture cache and pay the cost of creating and destroying many textures. So, we only 132380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // request an exact match when the caller is reading an entire RT. 132480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ScratchTexMatch match = kApprox_ScratchTexMatch; 132580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (0 == left && 132680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 0 == top && 132780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru target->width() == width && 132880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru target->height() == height && 132980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fGpu->fullReadPixelsIsFasterThanPartial()) { 133080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru match = kExact_ScratchTexMatch; 133180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 133280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ast.set(this, desc, match); 133380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrTexture* texture = ast.texture(); 133480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (texture) { 1335363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // compute a matrix to perform the draw 1336363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkMatrix textureMatrix; 1337096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger textureMatrix.setTranslate(SK_Scalar1 *left, SK_Scalar1 *top); 1338363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger textureMatrix.postIDiv(src->width(), src->height()); 1339363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 1340d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkAutoTUnref<const GrEffectRef> effect; 134180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (unpremul) { 1342d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger effect.reset(this->createPMToUPMEffect(src, swapRAndB, textureMatrix)); 1343d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (NULL != effect) { 1344096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger unpremul = false; // we no longer need to do this on CPU after the read back. 1345363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 134680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 134780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // If we failed to create a PM->UPM effect and have no other conversions to perform then 134880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // there is no longer any point to using the scratch. 1349d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (NULL != effect || flipY || swapRAndB) { 1350d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (!effect) { 1351d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger effect.reset(GrConfigConversionEffect::Create( 1352d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger src, 1353d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger swapRAndB, 1354d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrConfigConversionEffect::kNone_PMConversion, 1355d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger textureMatrix)); 135680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 135780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru swapRAndB = false; // we will handle the swap in the draw. 135880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1359096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger // We protect the existing geometry here since it may not be 1360096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger // clear to the caller that a draw operation (i.e., drawSimpleRect) 1361096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger // can be invoked in this method 1362096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger GrDrawTarget::AutoGeometryAndStatePush agasp(fGpu, GrDrawTarget::kReset_ASRInit); 136380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrDrawState* drawState = fGpu->drawState(); 1364d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrAssert(effect); 136558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger drawState->addColorEffect(effect); 1366363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 136780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru drawState->setRenderTarget(texture->asRenderTarget()); 136858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height)); 136980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fGpu->drawSimpleRect(rect, NULL); 137080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // we want to read back from the scratch's origin 137180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru left = 0; 137280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru top = 0; 137380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru target = texture->asRenderTarget(); 137480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 137580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 137680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 137780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!fGpu->readPixels(target, 137880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru left, top, width, height, 1379096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger readConfig, buffer, rowBytes)) { 138080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 138180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 1382363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // Perform any conversions we weren't able to perform using a scratch texture. 1383096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger if (unpremul || swapRAndB) { 138480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // These are initialized to suppress a warning 138580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkCanvas::Config8888 srcC8888 = SkCanvas::kNative_Premul_Config8888; 138680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkCanvas::Config8888 dstC8888 = SkCanvas::kNative_Premul_Config8888; 138780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1388096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SkDEBUGCODE(bool c8888IsValid =) grconfig_to_config8888(dstConfig, false, &srcC8888); 1389096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger grconfig_to_config8888(dstConfig, unpremul, &dstC8888); 139080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 139180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (swapRAndB) { 139280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(c8888IsValid); // we should only do r/b swap on 8888 configs 139380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru srcC8888 = swap_config8888_red_and_blue(srcC8888); 139480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 1395096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger GrAssert(c8888IsValid); 1396096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger uint32_t* b32 = reinterpret_cast<uint32_t*>(buffer); 1397096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger SkConvertConfig8888Pixels(b32, rowBytes, dstC8888, 1398096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger b32, rowBytes, srcC8888, 1399096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger width, height); 140080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 140180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 140280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 140380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 140480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrContext::resolveRenderTarget(GrRenderTarget* target) { 140580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(target); 140680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ASSERT_OWNED_RESOURCE(target); 140780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // In the future we may track whether there are any pending draws to this 140880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // target. We don't today so we always perform a flush. We don't promise 140980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // this to our clients, though. 141080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->flush(); 141180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fGpu->resolveRenderTarget(target); 141280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 141380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1414363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergervoid GrContext::copyTexture(GrTexture* src, GrRenderTarget* dst, const SkIPoint* topLeft) { 141580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == src || NULL == dst) { 141680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 141780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 141880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ASSERT_OWNED_RESOURCE(src); 141980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 142080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Writes pending to the source texture are not tracked, so a flush 142180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // is required to ensure that the copy captures the most recent contents 1422d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger // of the source texture. See similar behavior in 142380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // GrContext::resolveRenderTarget. 142480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->flush(); 142580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 142680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrDrawTarget::AutoStateRestore asr(fGpu, GrDrawTarget::kReset_ASRInit); 142780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrDrawState* drawState = fGpu->drawState(); 142880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru drawState->setRenderTarget(dst); 1429363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkMatrix sampleM; 143080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru sampleM.setIDiv(src->width(), src->height()); 1431363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkIRect srcRect = SkIRect::MakeWH(dst->width(), dst->height()); 1432363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (NULL != topLeft) { 1433363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger srcRect.offset(*topLeft); 1434363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 1435363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkIRect srcBounds = SkIRect::MakeWH(src->width(), src->height()); 1436363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (!srcRect.intersect(srcBounds)) { 1437363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return; 1438363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 1439363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger sampleM.preTranslate(SkIntToScalar(srcRect.fLeft), SkIntToScalar(srcRect.fTop)); 144058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger drawState->addColorTextureEffect(src, sampleM); 1441363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkRect dstR = SkRect::MakeWH(SkIntToScalar(srcRect.width()), SkIntToScalar(srcRect.height())); 1442363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fGpu->drawSimpleRect(dstR, NULL); 144380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 144480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1445096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenbergerbool GrContext::writeRenderTargetPixels(GrRenderTarget* target, 144680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int left, int top, int width, int height, 1447096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger GrPixelConfig srcConfig, 144880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const void* buffer, 144980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t rowBytes, 145080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru uint32_t flags) { 145180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_TRACE_EVENT0("GrContext::writeRenderTargetPixels"); 145280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ASSERT_OWNED_RESOURCE(target); 145380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 145480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == target) { 145558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger target = fRenderTarget.get(); 145680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == target) { 1457096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger return false; 145880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 145980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 146080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 146180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // TODO: when underlying api has a direct way to do this we should use it (e.g. glDrawPixels on 146280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // desktop GL). 146380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 146480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // We will always call some form of writeTexturePixels and we will pass our flags on to it. 146580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Thus, we don't perform a flush here since that call will do it (if the kNoFlush flag isn't 146680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // set.) 146780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 146880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // If the RT is also a texture and we don't have to premultiply then take the texture path. 146980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // We expect to be at least as fast or faster since it doesn't use an intermediate texture as 147080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // we do below. 147180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 147280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if !GR_MAC_BUILD 147380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // At least some drivers on the Mac get confused when glTexImage2D is called on a texture 147480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // attached to an FBO. The FBO still sees the old image. TODO: determine what OS versions and/or 147580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // HW is affected. 1476096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger if (NULL != target->asTexture() && !(kUnpremul_PixelOpsFlag & flags) && 1477096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger fGpu->canWriteTexturePixels(target->asTexture(), srcConfig)) { 1478096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger return this->writeTexturePixels(target->asTexture(), 1479096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger left, top, width, height, 1480096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger srcConfig, buffer, rowBytes, flags); 148180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 148280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 1483363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 1484096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger // We ignore the preferred config unless it is a R/B swap of the src config. In that case 1485096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger // we will upload the original src data to a scratch texture but we will spoof it as the swapped 1486096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger // config. This scratch will then have R and B swapped. We correct for this by swapping again 1487096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger // when drawing the scratch to the dst using a conversion effect. 1488096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger bool swapRAndB = false; 1489096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger GrPixelConfig writeConfig = srcConfig; 1490779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger if (GrPixelConfigSwapRAndB(srcConfig) == 1491779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger fGpu->preferredWritePixelsConfig(srcConfig, target->config())) { 1492096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger writeConfig = GrPixelConfigSwapRAndB(srcConfig); 1493096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger swapRAndB = true; 149480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 149580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 149680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrTextureDesc desc; 149780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fWidth = width; 149880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fHeight = height; 1499096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger desc.fConfig = writeConfig; 150080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAutoScratchTexture ast(this, desc); 150180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrTexture* texture = ast.texture(); 150280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == texture) { 1503096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger return false; 150480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 1505363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 1506d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkAutoTUnref<const GrEffectRef> effect; 1507363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkMatrix textureMatrix; 1508363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger textureMatrix.setIDiv(texture->width(), texture->height()); 1509363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 151080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // allocate a tmp buffer and sw convert the pixels to premul 151180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkAutoSTMalloc<128 * 128, uint32_t> tmpPixels(0); 151280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 151380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (kUnpremul_PixelOpsFlag & flags) { 1514096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger if (!GrPixelConfigIs8888(srcConfig)) { 1515096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger return false; 151680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 1517d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger effect.reset(this->createUPMToPMEffect(texture, swapRAndB, textureMatrix)); 1518096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger // handle the unpremul step on the CPU if we couldn't create an effect to do it. 1519d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (NULL == effect) { 152080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkCanvas::Config8888 srcConfig8888, dstConfig8888; 152180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GR_DEBUGCODE(bool success = ) 1522096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger grconfig_to_config8888(srcConfig, true, &srcConfig8888); 152380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(success); 152480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GR_DEBUGCODE(success = ) 1525096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger grconfig_to_config8888(srcConfig, false, &dstConfig8888); 152680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(success); 152780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const uint32_t* src = reinterpret_cast<const uint32_t*>(buffer); 152880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tmpPixels.reset(width * height); 152980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkConvertConfig8888Pixels(tmpPixels.get(), 4 * width, dstConfig8888, 153080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru src, rowBytes, srcConfig8888, 153180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru width, height); 153280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru buffer = tmpPixels.get(); 153380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru rowBytes = 4 * width; 153480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 153580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 1536d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (NULL == effect) { 1537d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger effect.reset(GrConfigConversionEffect::Create(texture, 1538d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger swapRAndB, 1539d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrConfigConversionEffect::kNone_PMConversion, 1540d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger textureMatrix)); 154180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 154280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1543096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger if (!this->writeTexturePixels(texture, 1544096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 0, 0, width, height, 1545096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger writeConfig, buffer, rowBytes, 1546096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger flags & ~kUnpremul_PixelOpsFlag)) { 1547096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger return false; 1548096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 154980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1550096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger // writeRenderTargetPixels can be called in the midst of drawing another 1551096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger // object (e.g., when uploading a SW path rendering to the gpu while 1552096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger // drawing a rect) so preserve the current geometry. 155358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkMatrix matrix; 155458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger matrix.setTranslate(SkIntToScalar(left), SkIntToScalar(top)); 155558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger GrDrawTarget::AutoGeometryAndStatePush agasp(fGpu, GrDrawTarget::kReset_ASRInit, &matrix); 155680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrDrawState* drawState = fGpu->drawState(); 1557d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrAssert(effect); 155858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger drawState->addColorEffect(effect); 155980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 156080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru drawState->setRenderTarget(target); 156180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 156258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger fGpu->drawSimpleRect(SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height)), NULL); 1563096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger return true; 156480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 156580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//////////////////////////////////////////////////////////////////////////////// 156680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 156758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek SollenbergerGrDrawTarget* GrContext::prepareToDraw(const GrPaint* paint, 156858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger BufferedDraw buffered, 156958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger AutoRestoreEffects* are) { 157058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // All users of this draw state should be freeing up all effects when they're done. 157158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // Otherwise effects that own resources may keep those resources alive indefinitely. 157258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger GrAssert(0 == fDrawState->numColorStages() && 0 == fDrawState->numCoverageStages()); 157358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 157480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (kNo_BufferedDraw == buffered && kYes_BufferedDraw == fLastDrawWasBuffered) { 157558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger fDrawBuffer->flush(); 157680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fLastDrawWasBuffered = kNo_BufferedDraw; 157780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 157858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger ASSERT_OWNED_RESOURCE(fRenderTarget.get()); 157980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL != paint) { 158058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger GrAssert(NULL != are); 158158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger are->set(fDrawState); 158258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger fDrawState->setFromPaint(*paint, fViewMatrix, fRenderTarget.get()); 158380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if GR_DEBUG_PARTIAL_COVERAGE_CHECK 158480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if ((paint->hasMask() || 0xff != paint->fCoverage) && 158580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru !fGpu->canApplyCoverage()) { 158680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPrintf("Partial pixel coverage will be incorrectly blended.\n"); 158780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 158880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 158958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } else { 159058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger fDrawState->reset(fViewMatrix); 159158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger fDrawState->setRenderTarget(fRenderTarget.get()); 159280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 159358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger GrDrawTarget* target; 159480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (kYes_BufferedDraw == buffered) { 159580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fLastDrawWasBuffered = kYes_BufferedDraw; 159658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger target = fDrawBuffer; 159780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 159880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(kNo_BufferedDraw == buffered); 159958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger fLastDrawWasBuffered = kNo_BufferedDraw; 160058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger target = fGpu; 160180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 160258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger fDrawState->setState(GrDrawState::kClip_StateBit, NULL != fClip && 160358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger !fClip->fClipStack->isWideOpen()); 160458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger target->setClip(fClip); 160558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger GrAssert(fDrawState == target->drawState()); 160658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger return target; 160780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 160880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 160980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* 161080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * This method finds a path renderer that can draw the specified path on 161180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * the provided target. 161280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Due to its expense, the software path renderer has split out so it can 161380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * can be individually allowed/disallowed via the "allowSW" boolean. 161480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 161580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruGrPathRenderer* GrContext::getPathRenderer(const SkPath& path, 1616363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const SkStrokeRec& stroke, 161780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const GrDrawTarget* target, 1618363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger bool allowSW, 1619363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger GrPathRendererChain::DrawType drawType, 1620363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger GrPathRendererChain::StencilSupport* stencilSupport) { 1621363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 162280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == fPathRendererChain) { 1623363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fPathRendererChain = SkNEW_ARGS(GrPathRendererChain, (this)); 162480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 162580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1626363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger GrPathRenderer* pr = fPathRendererChain->getPathRenderer(path, 1627363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger stroke, 162880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru target, 1629363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger drawType, 1630363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger stencilSupport); 163180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 163280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == pr && allowSW) { 163380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == fSoftwarePathRenderer) { 163480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fSoftwarePathRenderer = SkNEW_ARGS(GrSoftwarePathRenderer, (this)); 163580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 163680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru pr = fSoftwarePathRenderer; 163780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 163880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 163980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return pr; 164080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 164180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 164280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//////////////////////////////////////////////////////////////////////////////// 164380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 164480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool GrContext::isConfigRenderable(GrPixelConfig config) const { 164580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return fGpu->isConfigRenderable(config); 164680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 164780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 164880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline intptr_t setOrClear(intptr_t bits, int shift, intptr_t pred) { 164980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru intptr_t mask = 1 << shift; 165080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (pred) { 165180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bits |= mask; 165280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 165380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bits &= ~mask; 165480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 165580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return bits; 165680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 165780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 165880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrContext::setupDrawBuffer() { 165980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 166080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(NULL == fDrawBuffer); 166180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(NULL == fDrawBufferVBAllocPool); 166280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(NULL == fDrawBufferIBAllocPool); 166380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 166480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDrawBufferVBAllocPool = 166580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkNEW_ARGS(GrVertexBufferAllocPool, (fGpu, false, 166680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru DRAW_BUFFER_VBPOOL_BUFFER_SIZE, 166780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru DRAW_BUFFER_VBPOOL_PREALLOC_BUFFERS)); 166880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDrawBufferIBAllocPool = 166980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkNEW_ARGS(GrIndexBufferAllocPool, (fGpu, false, 167080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru DRAW_BUFFER_IBPOOL_BUFFER_SIZE, 167180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS)); 167280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 167380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDrawBuffer = SkNEW_ARGS(GrInOrderDrawBuffer, (fGpu, 1674096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger fDrawBufferVBAllocPool, 1675096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger fDrawBufferIBAllocPool)); 167680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1677096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger fDrawBuffer->setDrawState(fDrawState); 167880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 167980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 168058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek SollenbergerGrDrawTarget* GrContext::getTextTarget() { 168158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger return this->prepareToDraw(NULL, BUFFERED_DRAW, NULL); 168280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 168380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 168480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruconst GrIndexBuffer* GrContext::getQuadIndexBuffer() const { 168580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return fGpu->getQuadIndexBuffer(); 168680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 168780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 168880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querunamespace { 168980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid test_pm_conversions(GrContext* ctx, int* pmToUPMValue, int* upmToPMValue) { 169080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrConfigConversionEffect::PMConversion pmToUPM; 169180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrConfigConversionEffect::PMConversion upmToPM; 169280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrConfigConversionEffect::TestForPreservingPMConversions(ctx, &pmToUPM, &upmToPM); 169380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *pmToUPMValue = pmToUPM; 169480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *upmToPMValue = upmToPM; 169580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 169680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 169780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1698d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergerconst GrEffectRef* GrContext::createPMToUPMEffect(GrTexture* texture, 1699d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger bool swapRAndB, 1700d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger const SkMatrix& matrix) { 170180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!fDidTestPMConversions) { 170280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru test_pm_conversions(this, &fPMToUPMConversion, &fUPMToPMConversion); 170380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDidTestPMConversions = true; 170480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 170580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrConfigConversionEffect::PMConversion pmToUPM = 170680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static_cast<GrConfigConversionEffect::PMConversion>(fPMToUPMConversion); 170780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (GrConfigConversionEffect::kNone_PMConversion != pmToUPM) { 1708d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger return GrConfigConversionEffect::Create(texture, swapRAndB, pmToUPM, matrix); 170980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 1710d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger return NULL; 171180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 171280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 171380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1714d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergerconst GrEffectRef* GrContext::createUPMToPMEffect(GrTexture* texture, 1715d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger bool swapRAndB, 1716d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger const SkMatrix& matrix) { 171780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!fDidTestPMConversions) { 171880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru test_pm_conversions(this, &fPMToUPMConversion, &fUPMToPMConversion); 171980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDidTestPMConversions = true; 172080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 172180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrConfigConversionEffect::PMConversion upmToPM = 172280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static_cast<GrConfigConversionEffect::PMConversion>(fUPMToPMConversion); 172380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (GrConfigConversionEffect::kNone_PMConversion != upmToPM) { 1724d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger return GrConfigConversionEffect::Create(texture, swapRAndB, upmToPM, matrix); 172580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 1726d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger return NULL; 172780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 172880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 172980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 173080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 173180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if GR_CACHE_STATS 173280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrContext::printCacheStats() const { 173380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fTextureCache->printStats(); 173480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 173580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 1736