GrContext.cpp revision d686ac77c2c485c4a3302eda9c1de597a6f8c568
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/GrConvolutionEffect.h" 1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "effects/GrSingleTextureEffect.h" 1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "effects/GrConfigConversionEffect.h" 1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "GrBufferAllocPool.h" 1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "GrGpu.h" 1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "GrIndexBuffer.h" 1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "GrInOrderDrawBuffer.h" 2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "GrPathRenderer.h" 2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "GrPathUtils.h" 2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "GrResourceCache.h" 2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "GrSoftwarePathRenderer.h" 2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "GrStencilBuffer.h" 2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "GrTextStrike.h" 26363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#include "SkStrokeRec.h" 2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkTLazy.h" 2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkTLS.h" 2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkTrace.h" 3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSK_DEFINE_INST_COUNT(GrContext) 3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSK_DEFINE_INST_COUNT(GrDrawState) 3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// It can be useful to set this to kNo_BufferedDraw to test whether a bug is caused by using the 3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// InOrderDrawBuffer, to compare performance of using/not using InOrderDrawBuffer, or to make 3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// debugging easier. 3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define DEFAULT_BUFFERING (GR_DISABLE_DRAW_BUFFERING ? kNo_BufferedDraw : kYes_BufferedDraw) 3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define MAX_BLUR_SIGMA 4.0f 4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// When we're using coverage AA but the blend is incompatible (given gpu 4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// limitations) should we disable AA or draw wrong? 4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define DISABLE_COVERAGE_AA_FOR_BLEND 1 4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if GR_DEBUG 4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // change this to a 1 to see notifications when partial coverage fails 4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru #define GR_DEBUG_PARTIAL_COVERAGE_CHECK 0 4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#else 4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru #define GR_DEBUG_PARTIAL_COVERAGE_CHECK 0 5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 52363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerstatic const size_t MAX_TEXTURE_CACHE_COUNT = 2048; 53363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerstatic const size_t MAX_TEXTURE_CACHE_BYTES = GR_DEFAULT_TEXTURE_CACHE_MB_LIMIT * 1024 * 1024; 5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic const size_t DRAW_BUFFER_VBPOOL_BUFFER_SIZE = 1 << 15; 5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic const int DRAW_BUFFER_VBPOOL_PREALLOC_BUFFERS = 4; 5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic const size_t DRAW_BUFFER_IBPOOL_BUFFER_SIZE = 1 << 11; 5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic const int DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS = 4; 6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define ASSERT_OWNED_RESOURCE(R) GrAssert(!(R) || (R)->getContext() == this) 6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 63363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek SollenbergerGrContext* GrContext::Create(GrBackend backend, GrBackendContext context) { 6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrContext* ctx = NULL; 65363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger GrGpu* fGpu = GrGpu::Create(backend, context); 6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL != fGpu) { 6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ctx = SkNEW_ARGS(GrContext, (fGpu)); 6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fGpu->unref(); 6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return ctx; 7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querunamespace { 7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid* CreateThreadInstanceCount() { 7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkNEW_ARGS(int, (0)); 7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid DeleteThreadInstanceCount(void* v) { 7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru delete reinterpret_cast<int*>(v); 7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define THREAD_INSTANCE_COUNT \ 8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru (*reinterpret_cast<int*>(SkTLS::Get(CreateThreadInstanceCount, \ 8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru DeleteThreadInstanceCount))) 8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruint GrContext::GetThreadInstanceCount() { 8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return THREAD_INSTANCE_COUNT; 8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruGrContext::~GrContext() { 9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = 0; i < fCleanUpData.count(); ++i) { 9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru (*fCleanUpData[i].fFunc)(this, fCleanUpData[i].fInfo); 9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->flush(); 9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Since the gpu can hold scratch textures, give it a chance to let go 9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // of them before freeing the texture cache 9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fGpu->purgeResources(); 10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru delete fTextureCache; 10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fTextureCache = NULL; 10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru delete fFontCache; 10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru delete fDrawBuffer; 10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru delete fDrawBufferVBAllocPool; 10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru delete fDrawBufferIBAllocPool; 10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fAARectRenderer->unref(); 10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fGpu->unref(); 11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrSafeUnref(fPathRendererChain); 11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrSafeUnref(fSoftwarePathRenderer); 11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDrawState->unref(); 11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru --THREAD_INSTANCE_COUNT; 11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrContext::contextLost() { 11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru contextDestroyed(); 12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->setupDrawBuffer(); 12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrContext::contextDestroyed() { 12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // abandon first to so destructors 12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // don't try to free the resources in the API. 12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fGpu->abandonResources(); 12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // a path renderer may be holding onto resources that 12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // are now unusable 13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrSafeSetNull(fPathRendererChain); 13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrSafeSetNull(fSoftwarePathRenderer); 13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru delete fDrawBuffer; 13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDrawBuffer = NULL; 13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru delete fDrawBufferVBAllocPool; 13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDrawBufferVBAllocPool = NULL; 13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru delete fDrawBufferIBAllocPool; 14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDrawBufferIBAllocPool = NULL; 14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fAARectRenderer->reset(); 14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fTextureCache->purgeAllUnlocked(); 14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fFontCache->freeAll(); 14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fGpu->markContextDirty(); 14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrContext::resetContext() { 15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fGpu->markContextDirty(); 15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrContext::freeGpuResources() { 15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->flush(); 15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fGpu->purgeResources(); 15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fAARectRenderer->reset(); 15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 16080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fTextureCache->purgeAllUnlocked(); 16180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fFontCache->freeAll(); 16280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // a path renderer may be holding onto resources 16380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrSafeSetNull(fPathRendererChain); 16480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrSafeSetNull(fSoftwarePathRenderer); 16580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 16680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 16780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querusize_t GrContext::getGpuTextureCacheBytes() const { 16880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return fTextureCache->getCachedResourceBytes(); 16980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 17180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//////////////////////////////////////////////////////////////////////////////// 17280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 17380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querunamespace { 17480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 17580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid scale_rect(SkRect* rect, float xScale, float yScale) { 17680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru rect->fLeft = SkScalarMul(rect->fLeft, SkFloatToScalar(xScale)); 17780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru rect->fTop = SkScalarMul(rect->fTop, SkFloatToScalar(yScale)); 17880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru rect->fRight = SkScalarMul(rect->fRight, SkFloatToScalar(xScale)); 17980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru rect->fBottom = SkScalarMul(rect->fBottom, SkFloatToScalar(yScale)); 18080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 18180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 18280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querufloat adjust_sigma(float sigma, int *scaleFactor, int *radius) { 18380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *scaleFactor = 1; 18480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru while (sigma > MAX_BLUR_SIGMA) { 18580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *scaleFactor *= 2; 18680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru sigma *= 0.5f; 18780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 18880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *radius = static_cast<int>(ceilf(sigma * 3.0f)); 18980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(*radius <= GrConvolutionEffect::kMaxKernelRadius); 19080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return sigma; 19180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 19280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 19380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid convolve_gaussian(GrDrawTarget* target, 19480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrTexture* texture, 19580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkRect& rect, 19680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru float sigma, 19780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int radius, 19880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Gr1DKernelEffect::Direction direction) { 19980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrRenderTarget* rt = target->drawState()->getRenderTarget(); 20080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrDrawTarget::AutoStateRestore asr(target, GrDrawTarget::kReset_ASRInit); 20180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrDrawState* drawState = target->drawState(); 20280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru drawState->setRenderTarget(rt); 203d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkAutoTUnref<GrEffectRef> conv(GrConvolutionEffect::CreateGaussian(texture, 204d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger direction, 205d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger radius, 206d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger sigma)); 207d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger drawState->setEffect(0, conv); 20880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru target->drawSimpleRect(rect, NULL); 20980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 21080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 21180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 21280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 213d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger//////////////////////////////////////////////////////////////////////////////// 214d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 215d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek SollenbergerGrTexture* GrContext::findAndRefTexture(const GrTextureDesc& desc, 216d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger const GrCacheID& cacheID, 217d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger const GrTextureParams* params) { 218d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrResourceKey resourceKey = GrTexture::ComputeKey(fGpu, params, desc, cacheID); 21980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrResource* resource = fTextureCache->find(resourceKey); 220d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkSafeRef(resource); 22180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return static_cast<GrTexture*>(resource); 22280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 22380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 22480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool GrContext::isTextureInCache(const GrTextureDesc& desc, 225d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger const GrCacheID& cacheID, 22680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const GrTextureParams* params) const { 227d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrResourceKey resourceKey = GrTexture::ComputeKey(fGpu, params, desc, cacheID); 22880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return fTextureCache->hasKey(resourceKey); 22980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 23080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 23180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrContext::addStencilBuffer(GrStencilBuffer* sb) { 23280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ASSERT_OWNED_RESOURCE(sb); 23380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 23480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrResourceKey resourceKey = GrStencilBuffer::ComputeKey(sb->width(), 23580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru sb->height(), 23680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru sb->numSamples()); 237363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fTextureCache->addResource(resourceKey, sb); 23880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 23980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 24080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruGrStencilBuffer* GrContext::findStencilBuffer(int width, int height, 24180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int sampleCnt) { 24280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrResourceKey resourceKey = GrStencilBuffer::ComputeKey(width, 24380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru height, 24480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru sampleCnt); 24580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrResource* resource = fTextureCache->find(resourceKey); 24680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return static_cast<GrStencilBuffer*>(resource); 24780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 24880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 24980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void stretchImage(void* dst, 25080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int dstW, 25180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int dstH, 25280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void* src, 25380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int srcW, 25480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int srcH, 25580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int bpp) { 25680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrFixed dx = (srcW << 16) / dstW; 25780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrFixed dy = (srcH << 16) / dstH; 25880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 25980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrFixed y = dy >> 1; 26080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 26180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int dstXLimit = dstW*bpp; 26280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int j = 0; j < dstH; ++j) { 26380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrFixed x = dx >> 1; 26480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void* srcRow = (uint8_t*)src + (y>>16)*srcW*bpp; 26580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void* dstRow = (uint8_t*)dst + j*dstW*bpp; 26680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = 0; i < dstXLimit; i += bpp) { 26780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru memcpy((uint8_t*) dstRow + i, 26880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru (uint8_t*) srcRow + (x>>16)*bpp, 26980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bpp); 27080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru x += dx; 27180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 27280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru y += dy; 27380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 27480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 27580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 27680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// The desired texture is NPOT and tiled but that isn't supported by 27780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// the current hardware. Resize the texture to be a POT 27880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruGrTexture* GrContext::createResizedTexture(const GrTextureDesc& desc, 279d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger const GrCacheID& cacheID, 28080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void* srcData, 28180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t rowBytes, 28280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool needsFiltering) { 283d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkAutoTUnref<GrTexture> clampedTexture(this->findAndRefTexture(desc, cacheID, NULL)); 28480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == clampedTexture) { 285d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger clampedTexture.reset(this->createTexture(NULL, desc, cacheID, srcData, rowBytes)); 28680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 28780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == clampedTexture) { 28880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return NULL; 28980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 29080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 29180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 29280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrTextureDesc rtDesc = desc; 29380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru rtDesc.fFlags = rtDesc.fFlags | 29480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kRenderTarget_GrTextureFlagBit | 29580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kNoStencil_GrTextureFlagBit; 29680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru rtDesc.fWidth = GrNextPow2(GrMax(desc.fWidth, 64)); 29780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru rtDesc.fHeight = GrNextPow2(GrMax(desc.fHeight, 64)); 29880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 29980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrTexture* texture = fGpu->createTexture(rtDesc, NULL, 0); 30080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 30180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL != texture) { 30280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrDrawTarget::AutoStateRestore asr(fGpu, GrDrawTarget::kReset_ASRInit); 30380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrDrawState* drawState = fGpu->drawState(); 30480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru drawState->setRenderTarget(texture->asRenderTarget()); 30580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 30680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // if filtering is not desired then we want to ensure all 30780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // texels in the resampled image are copies of texels from 30880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // the original. 30980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrTextureParams params(SkShader::kClamp_TileMode, needsFiltering); 310363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger drawState->createTextureEffect(0, clampedTexture, SkMatrix::I(), params); 31180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 312d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger static const GrVertexLayout layout = GrDrawState::StageTexCoordVertexLayoutBit(0,0); 31380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrDrawTarget::AutoReleaseGeometry arg(fGpu, layout, 4, 0); 31480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 31580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (arg.succeeded()) { 31680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPoint* verts = (GrPoint*) arg.vertices(); 317d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger verts[0].setIRectFan(0, 0, texture->width(), texture->height(), 2 * sizeof(GrPoint)); 318d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger verts[1].setIRectFan(0, 0, 1, 1, 2 * sizeof(GrPoint)); 319d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger fGpu->drawNonIndexed(kTriangleFan_GrPrimitiveType, 0, 4); 32080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 32180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru texture->releaseRenderTarget(); 32280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 32380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // TODO: Our CPU stretch doesn't filter. But we create separate 324363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // stretched textures when the texture params is either filtered or 32580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // not. Either implement filtered stretch blit on CPU or just create 32680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // one when FBO case fails. 32780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 32880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru rtDesc.fFlags = kNone_GrTextureFlags; 32980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // no longer need to clamp at min RT size. 33080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru rtDesc.fWidth = GrNextPow2(desc.fWidth); 33180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru rtDesc.fHeight = GrNextPow2(desc.fHeight); 33280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int bpp = GrBytesPerPixel(desc.fConfig); 333363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkAutoSMalloc<128*128*4> stretchedPixels(bpp * rtDesc.fWidth * rtDesc.fHeight); 33480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru stretchImage(stretchedPixels.get(), rtDesc.fWidth, rtDesc.fHeight, 335363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger srcData, desc.fWidth, desc.fHeight, bpp); 33680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 33780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t stretchedRowBytes = rtDesc.fWidth * bpp; 33880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 339d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkDEBUGCODE(GrTexture* texture = )fGpu->createTexture(rtDesc, stretchedPixels.get(), stretchedRowBytes); 34080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(NULL != texture); 34180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 34280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 34380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return texture; 34480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 34580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 346d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek SollenbergerGrTexture* GrContext::createTexture(const GrTextureParams* params, 347d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger const GrTextureDesc& desc, 348d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger const GrCacheID& cacheID, 349d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger void* srcData, 350d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger size_t rowBytes) { 351d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SK_TRACE_EVENT0("GrContext::createTexture"); 35280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 35380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if GR_DUMP_TEXTURE_UPLOAD 354d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrPrintf("GrContext::createTexture[%d %d]\n", desc.fWidth, desc.fHeight); 35580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 35680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 357d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrResourceKey resourceKey = GrTexture::ComputeKey(fGpu, params, desc, cacheID); 35880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 359d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrTexture* texture; 36080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (GrTexture::NeedsResizing(resourceKey)) { 361d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger texture = this->createResizedTexture(desc, cacheID, 36280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru srcData, rowBytes, 363d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrTexture::NeedsFiltering(resourceKey)); 36480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 365d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger texture= fGpu->createTexture(desc, srcData, rowBytes); 36680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 36780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 36880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL != texture) { 369363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fTextureCache->addResource(resourceKey, texture); 37080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 37180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 37280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return texture; 37380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 37480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 375d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek SollenbergerGrTexture* GrContext::lockAndRefScratchTexture(const GrTextureDesc& inDesc, ScratchTexMatch match) { 37680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrTextureDesc desc = inDesc; 37780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 37880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert((desc.fFlags & kRenderTarget_GrTextureFlagBit) || 37980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru !(desc.fFlags & kNoStencil_GrTextureFlagBit)); 38080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 381d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (kApprox_ScratchTexMatch == match) { 38280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // bin by pow2 with a reasonable min 38380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static const int MIN_SIZE = 256; 38480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fWidth = GrMax(MIN_SIZE, GrNextPow2(desc.fWidth)); 38580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fHeight = GrMax(MIN_SIZE, GrNextPow2(desc.fHeight)); 38680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 38780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 38880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrResource* resource = NULL; 38980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int origWidth = desc.fWidth; 39080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int origHeight = desc.fHeight; 39180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool doubledW = false; 39280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool doubledH = false; 39380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 39480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru do { 395d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrResourceKey key = GrTexture::ComputeScratchKey(desc); 396363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // Ensure we have exclusive access to the texture so future 'find' calls don't return it 397363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger resource = fTextureCache->find(key, GrResourceCache::kHide_OwnershipFlag); 398d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (NULL != resource) { 399d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger resource->ref(); 40080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 40180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 402d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (kExact_ScratchTexMatch == match) { 403d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger break; 404d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } 405d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger // We had a cache miss and we are in approx mode, relax the fit of the flags... then try 406d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger // doubling width... then the height. 407d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 40880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // We no longer try to reuse textures that were previously used as render targets in 40980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // situations where no RT is needed; doing otherwise can confuse the video driver and 41080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // cause significant performance problems in some cases. 41180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (desc.fFlags & kNoStencil_GrTextureFlagBit) { 41280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fFlags = desc.fFlags & ~kNoStencil_GrTextureFlagBit; 41380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else if (!doubledW) { 41480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fFlags = inDesc.fFlags; 41580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fWidth *= 2; 41680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru doubledW = true; 41780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else if (!doubledH) { 41880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fFlags = inDesc.fFlags; 41980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fWidth = origWidth; 42080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fHeight *= 2; 42180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru doubledH = true; 42280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 42380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 42480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 42580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 42680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } while (true); 42780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 42880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == resource) { 42980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fFlags = inDesc.fFlags; 43080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fWidth = origWidth; 43180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fHeight = origHeight; 432d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrTexture* texture = fGpu->createTexture(desc, NULL, 0); 43380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL != texture) { 434d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrResourceKey key = GrTexture::ComputeScratchKey(texture->desc()); 435363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // Make the resource exclusive so future 'find' calls don't return it 436363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fTextureCache->addResource(key, texture, GrResourceCache::kHide_OwnershipFlag); 43780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru resource = texture; 43880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 43980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 44080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 44180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return static_cast<GrTexture*>(resource); 44280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 44380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 44480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrContext::addExistingTextureToCache(GrTexture* texture) { 44580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 44680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == texture) { 44780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 44880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 44980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 45080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // This texture should already have a cache entry since it was once 45180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // attached 45280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(NULL != texture->getCacheEntry()); 45380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 45480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Conceptually, the cache entry is going to assume responsibility 45580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // for the creation ref. 45680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(1 == texture->getRefCnt()); 45780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 45880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Since this texture came from an AutoScratchTexture it should 45980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // still be in the exclusive pile 46080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fTextureCache->makeNonExclusive(texture->getCacheEntry()); 46180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 46280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->purgeCache(); 46380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 46480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 46580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 46680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrContext::unlockScratchTexture(GrTexture* texture) { 46780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ASSERT_OWNED_RESOURCE(texture); 46880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(NULL != texture->getCacheEntry()); 46980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 47080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // If this is a scratch texture we detached it from the cache 47180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // while it was locked (to avoid two callers simultaneously getting 47280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // the same texture). 473d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (texture->getCacheEntry()->key().isScratch()) { 47480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fTextureCache->makeNonExclusive(texture->getCacheEntry()); 47580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 47680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 47780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->purgeCache(); 47880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 47980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 48080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrContext::purgeCache() { 48180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL != fTextureCache) { 48280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fTextureCache->purgeAsNeeded(); 48380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 48480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 48580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 48680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruGrTexture* GrContext::createUncachedTexture(const GrTextureDesc& descIn, 48780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void* srcData, 48880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t rowBytes) { 48980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrTextureDesc descCopy = descIn; 49080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return fGpu->createTexture(descCopy, srcData, rowBytes); 49180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 49280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 49380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrContext::getTextureCacheLimits(int* maxTextures, 49480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t* maxTextureBytes) const { 49580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fTextureCache->getLimits(maxTextures, maxTextureBytes); 49680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 49780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 49880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrContext::setTextureCacheLimits(int maxTextures, size_t maxTextureBytes) { 49980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fTextureCache->setLimits(maxTextures, maxTextureBytes); 50080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 50180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 50280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruint GrContext::getMaxTextureSize() const { 50380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return fGpu->getCaps().maxTextureSize(); 50480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 50580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 50680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruint GrContext::getMaxRenderTargetSize() const { 50780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return fGpu->getCaps().maxRenderTargetSize(); 50880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 50980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 51080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 51180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 512363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek SollenbergerGrTexture* GrContext::wrapBackendTexture(const GrBackendTextureDesc& desc) { 513363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return fGpu->wrapBackendTexture(desc); 51480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 51580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 516363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek SollenbergerGrRenderTarget* GrContext::wrapBackendRenderTarget(const GrBackendRenderTargetDesc& desc) { 517363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return fGpu->wrapBackendRenderTarget(desc); 51880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 51980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 52080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 52180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 52280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool GrContext::supportsIndex8PixelConfig(const GrTextureParams* params, 52380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int width, int height) const { 52480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const GrDrawTarget::Caps& caps = fGpu->getCaps(); 52580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!caps.eightBitPaletteSupport()) { 52680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 52780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 52880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 52980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool isPow2 = GrIsPow2(width) && GrIsPow2(height); 53080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 53180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!isPow2) { 53280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool tiled = NULL != params && params->isTiled(); 53380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (tiled && !caps.npotTextureTileSupport()) { 53480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 53580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 53680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 53780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 53880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 53980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 54080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//////////////////////////////////////////////////////////////////////////////// 54180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 54280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruconst GrClipData* GrContext::getClip() const { 54380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return fGpu->getClip(); 54480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 54580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 54680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrContext::setClip(const GrClipData* clipData) { 54780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fGpu->setClip(clipData); 54880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 54980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDrawState->setState(GrDrawState::kClip_StateBit, 550363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger clipData && clipData->fClipStack && !clipData->fClipStack->isWideOpen()); 55180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 55280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 55380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//////////////////////////////////////////////////////////////////////////////// 55480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 55580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrContext::clear(const GrIRect* rect, 55680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const GrColor color, 55780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrRenderTarget* target) { 55880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->prepareToDraw(NULL, DEFAULT_BUFFERING)->clear(rect, color, target); 55980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 56080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 56180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrContext::drawPaint(const GrPaint& origPaint) { 56280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // set rect to be big enough to fill the space, but not super-huge, so we 56380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // don't overflow fixed-point implementations 56480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrRect r; 56580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru r.setLTRB(0, 0, 566363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkIntToScalar(getRenderTarget()->width()), 567363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkIntToScalar(getRenderTarget()->height())); 568363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkMatrix inverse; 56980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkTCopyOnFirstWrite<GrPaint> paint(origPaint); 57080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru AutoMatrix am; 57180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 57280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // We attempt to map r by the inverse matrix and draw that. mapRect will 57380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // map the four corners and bound them with a new rect. This will not 57480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // produce a correct result for some perspective matrices. 57580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!this->getMatrix().hasPerspective()) { 57680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!fDrawState->getViewInverse(&inverse)) { 57780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPrintf("Could not invert matrix\n"); 57880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 57980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 58080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru inverse.mapRect(&r); 58180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 58280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!am.setIdentity(this, paint.writable())) { 58380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPrintf("Could not invert matrix\n"); 58480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 58580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 58680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 58780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // by definition this fills the entire clip, no need for AA 58880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (paint->isAntiAlias()) { 58980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru paint.writable()->setAntiAlias(false); 59080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 59180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->drawRect(*paint, r); 59280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 59380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 59480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//////////////////////////////////////////////////////////////////////////////// 59580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 59680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querunamespace { 59780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruinline bool disable_coverage_aa_for_blend(GrDrawTarget* target) { 59880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return DISABLE_COVERAGE_AA_FOR_BLEND && !target->canApplyCoverage(); 59980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 60080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 60180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 60280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//////////////////////////////////////////////////////////////////////////////// 60380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 60480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* create a triangle strip that strokes the specified triangle. There are 8 60580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unique vertices, but we repreat the last 2 to close up. Alternatively we 60680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru could use an indices array, and then only send 8 verts, but not sure that 60780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru would be faster. 60880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 60980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void setStrokeRectStrip(GrPoint verts[10], GrRect rect, 610363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkScalar width) { 611363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const SkScalar rad = SkScalarHalf(width); 61280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru rect.sort(); 61380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 61480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru verts[0].set(rect.fLeft + rad, rect.fTop + rad); 61580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru verts[1].set(rect.fLeft - rad, rect.fTop - rad); 61680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru verts[2].set(rect.fRight - rad, rect.fTop + rad); 61780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru verts[3].set(rect.fRight + rad, rect.fTop - rad); 61880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru verts[4].set(rect.fRight - rad, rect.fBottom - rad); 61980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru verts[5].set(rect.fRight + rad, rect.fBottom + rad); 62080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru verts[6].set(rect.fLeft + rad, rect.fBottom - rad); 62180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru verts[7].set(rect.fLeft - rad, rect.fBottom + rad); 62280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru verts[8] = verts[0]; 62380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru verts[9] = verts[1]; 62480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 62580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 62680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/** 62780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Returns true if the rects edges are integer-aligned. 62880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 62980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic bool isIRect(const GrRect& r) { 630363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return SkScalarIsInt(r.fLeft) && SkScalarIsInt(r.fTop) && 631363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkScalarIsInt(r.fRight) && SkScalarIsInt(r.fBottom); 63280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 63380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 63480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic bool apply_aa_to_rect(GrDrawTarget* target, 63580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const GrRect& rect, 636363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkScalar width, 637363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const SkMatrix* matrix, 638363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkMatrix* combinedMatrix, 63980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrRect* devRect, 64080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool* useVertexCoverage) { 64180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // we use a simple coverage ramp to do aa on axis-aligned rects 64280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // we check if the rect will be axis-aligned, and the rect won't land on 64380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // integer coords. 64480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 64580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // we are keeping around the "tweak the alpha" trick because 64680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // it is our only hope for the fixed-pipe implementation. 64780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // In a shader implementation we can give a separate coverage input 64880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // TODO: remove this ugliness when we drop the fixed-pipe impl 64980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *useVertexCoverage = false; 65080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!target->canTweakAlphaForCoverage()) { 65180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (disable_coverage_aa_for_blend(target)) { 65280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if GR_DEBUG 65380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru //GrPrintf("Turning off AA to correctly apply blend.\n"); 65480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 65580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 65680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 65780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *useVertexCoverage = true; 65880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 65980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 66080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const GrDrawState& drawState = target->getDrawState(); 66180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (drawState.getRenderTarget()->isMultisampled()) { 66280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 66380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 66480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 66580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (0 == width && target->willUseHWAALines()) { 66680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 66780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 66880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 66980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!drawState.getViewMatrix().preservesAxisAlignment()) { 67080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 67180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 67280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 67380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL != matrix && 67480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru !matrix->preservesAxisAlignment()) { 67580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 67680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 67780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 67880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *combinedMatrix = drawState.getViewMatrix(); 67980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL != matrix) { 68080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru combinedMatrix->preConcat(*matrix); 68180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(combinedMatrix->preservesAxisAlignment()); 68280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 68380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 68480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru combinedMatrix->mapRect(devRect, rect); 68580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru devRect->sort(); 68680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 68780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (width < 0) { 68880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return !isIRect(*devRect); 68980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 69080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 69180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 69280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 69380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 69480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrContext::drawRect(const GrPaint& paint, 69580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const GrRect& rect, 696363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkScalar width, 697363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const SkMatrix* matrix) { 69880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_TRACE_EVENT0("GrContext::drawRect"); 69980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 70080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrDrawTarget* target = this->prepareToDraw(&paint, DEFAULT_BUFFERING); 70180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrDrawState::AutoStageDisable atr(fDrawState); 70280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 70380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrRect devRect = rect; 704363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkMatrix combinedMatrix; 70580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool useVertexCoverage; 70680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool needAA = paint.isAntiAlias() && 70780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru !this->getRenderTarget()->isMultisampled(); 70880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool doAA = needAA && apply_aa_to_rect(target, rect, width, matrix, 70980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru &combinedMatrix, &devRect, 71080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru &useVertexCoverage); 71180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 71280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (doAA) { 71380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrDrawState::AutoDeviceCoordDraw adcd(target->drawState()); 71480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!adcd.succeeded()) { 71580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 71680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 71780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (width >= 0) { 718363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger GrVec strokeSize; 71980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (width > 0) { 72080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru strokeSize.set(width, width); 72180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru combinedMatrix.mapVectors(&strokeSize, 1); 72280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru strokeSize.setAbs(strokeSize); 72380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 724363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger strokeSize.set(SK_Scalar1, SK_Scalar1); 72580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 72680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fAARectRenderer->strokeAARect(this->getGpu(), target, devRect, 72780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru strokeSize, useVertexCoverage); 72880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 72980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fAARectRenderer->fillAARect(this->getGpu(), target, 73080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru devRect, useVertexCoverage); 73180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 73280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 73380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 73480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 73580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (width >= 0) { 73680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // TODO: consider making static vertex buffers for these cases. 73780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Hairline could be done by just adding closing vertex to 73880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // unitSquareVertexBuffer() 73980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 74080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static const int worstCaseVertCount = 10; 74180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrDrawTarget::AutoReleaseGeometry geo(target, 0, worstCaseVertCount, 0); 74280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 74380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!geo.succeeded()) { 74480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPrintf("Failed to get space for vertices!\n"); 74580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 74680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 74780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 74880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPrimitiveType primType; 74980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int vertCount; 75080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPoint* vertex = geo.positions(); 75180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 75280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (width > 0) { 75380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru vertCount = 10; 75480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru primType = kTriangleStrip_GrPrimitiveType; 75580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru setStrokeRectStrip(vertex, rect, width); 75680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 75780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // hairline 75880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru vertCount = 5; 75980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru primType = kLineStrip_GrPrimitiveType; 76080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru vertex[0].set(rect.fLeft, rect.fTop); 76180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru vertex[1].set(rect.fRight, rect.fTop); 76280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru vertex[2].set(rect.fRight, rect.fBottom); 76380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru vertex[3].set(rect.fLeft, rect.fBottom); 76480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru vertex[4].set(rect.fLeft, rect.fTop); 76580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 76680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 76780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrDrawState::AutoViewMatrixRestore avmr; 76880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL != matrix) { 76980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrDrawState* drawState = target->drawState(); 77080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru avmr.set(drawState, *matrix); 77180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 77280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 77380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru target->drawNonIndexed(primType, 0, vertCount); 77480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 77580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if GR_STATIC_RECT_VB 77680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const GrVertexBuffer* sqVB = fGpu->getUnitSquareVertexBuffer(); 77780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == sqVB) { 77880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPrintf("Failed to create static rect vb.\n"); 77980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 78080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 78180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru target->setVertexSourceToBuffer(0, sqVB); 78280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrDrawState* drawState = target->drawState(); 783363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkMatrix m; 78480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru m.setAll(rect.width(), 0, rect.fLeft, 78580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 0, rect.height(), rect.fTop, 786363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 0, 0, SkMatrix::I()[8]); 78780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 78880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL != matrix) { 78980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru m.postConcat(*matrix); 79080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 79180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrDrawState::AutoViewMatrixRestore avmr(drawState, m); 79280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 79380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru target->drawNonIndexed(kTriangleFan_GrPrimitiveType, 0, 4); 79480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#else 79580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru target->drawSimpleRect(rect, matrix); 79680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 79780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 79880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 79980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 80080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrContext::drawRectToRect(const GrPaint& paint, 80180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const GrRect& dstRect, 80280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const GrRect& srcRect, 803363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const SkMatrix* dstMatrix, 804363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const SkMatrix* srcMatrix) { 80580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_TRACE_EVENT0("GrContext::drawRectToRect"); 80680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 80780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // srcRect refers to paint's first color stage 80880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!paint.isColorStageEnabled(0)) { 80980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru drawRect(paint, dstRect, -1, dstMatrix); 81080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 81180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 81280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 81380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrDrawTarget* target = this->prepareToDraw(&paint, DEFAULT_BUFFERING); 81480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 81580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if GR_STATIC_RECT_VB 81680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrDrawState::AutoStageDisable atr(fDrawState); 81780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrDrawState* drawState = target->drawState(); 81880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 819363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkMatrix m; 82080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 82180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru m.setAll(dstRect.width(), 0, dstRect.fLeft, 82280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 0, dstRect.height(), dstRect.fTop, 823363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 0, 0, SkMatrix::I()[8]); 82480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL != dstMatrix) { 82580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru m.postConcat(*dstMatrix); 82680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 82780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 82880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // The first color stage's coords come from srcRect rather than applying a matrix to dstRect. 82980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // We explicitly compute a matrix for that stage below, no need to adjust here. 83080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static const uint32_t kExplicitCoordMask = 1 << GrPaint::kFirstColorStage; 83180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrDrawState::AutoViewMatrixRestore avmr(drawState, m, kExplicitCoordMask); 83280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 83380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru m.setAll(srcRect.width(), 0, srcRect.fLeft, 83480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 0, srcRect.height(), srcRect.fTop, 835363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 0, 0, SkMatrix::I()[8]); 83680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL != srcMatrix) { 83780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru m.postConcat(*srcMatrix); 83880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 839363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 840d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger drawState->preConcatStageMatrices(kExplicitCoordMask, m); 84180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 84280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const GrVertexBuffer* sqVB = fGpu->getUnitSquareVertexBuffer(); 84380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == sqVB) { 84480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPrintf("Failed to create static rect vb.\n"); 84580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 84680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 84780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru target->setVertexSourceToBuffer(0, sqVB); 84880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru target->drawNonIndexed(kTriangleFan_GrPrimitiveType, 0, 4); 84980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#else 85080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrDrawState::AutoStageDisable atr(fDrawState); 85180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 85280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const GrRect* srcRects[GrDrawState::kNumStages] = {NULL}; 853363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const SkMatrix* srcMatrices[GrDrawState::kNumStages] = {NULL}; 85480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru srcRects[0] = &srcRect; 85580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru srcMatrices[0] = srcMatrix; 85680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 85780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru target->drawRect(dstRect, dstMatrix, srcRects, srcMatrices); 85880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 85980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 86080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 86180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrContext::drawVertices(const GrPaint& paint, 86280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPrimitiveType primitiveType, 86380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int vertexCount, 86480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const GrPoint positions[], 86580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const GrPoint texCoords[], 86680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const GrColor colors[], 86780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const uint16_t indices[], 86880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int indexCount) { 86980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_TRACE_EVENT0("GrContext::drawVertices"); 87080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 87180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrDrawTarget::AutoReleaseGeometry geo; 87280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 87380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrDrawTarget* target = this->prepareToDraw(&paint, DEFAULT_BUFFERING); 87480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrDrawState::AutoStageDisable atr(fDrawState); 87580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 87680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrVertexLayout layout = 0; 87780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL != texCoords) { 878d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger layout |= GrDrawState::StageTexCoordVertexLayoutBit(0, 0); 87980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 88080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL != colors) { 881d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger layout |= GrDrawState::kColor_VertexLayoutBit; 88280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 883d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger int vertexSize = GrDrawState::VertexSize(layout); 88480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 88580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (sizeof(GrPoint) != vertexSize) { 88680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!geo.set(target, layout, vertexCount, 0)) { 88780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPrintf("Failed to get space for vertices!\n"); 88880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 88980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 89080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int texOffsets[GrDrawState::kMaxTexCoords]; 89180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int colorOffset; 892d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrDrawState::VertexSizeAndOffsetsByIdx(layout, 89380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru texOffsets, 89480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru &colorOffset, 89580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru NULL, 89680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru NULL); 89780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void* curVertex = geo.vertices(); 89880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 89980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = 0; i < vertexCount; ++i) { 90080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *((GrPoint*)curVertex) = positions[i]; 90180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 90280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (texOffsets[0] > 0) { 90380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *(GrPoint*)((intptr_t)curVertex + texOffsets[0]) = texCoords[i]; 90480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 90580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (colorOffset > 0) { 90680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *(GrColor*)((intptr_t)curVertex + colorOffset) = colors[i]; 90780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 90880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru curVertex = (void*)((intptr_t)curVertex + vertexSize); 90980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 91080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 91180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru target->setVertexSourceToArray(layout, positions, vertexCount); 91280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 91380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 91480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // we don't currently apply offscreen AA to this path. Need improved 91580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // management of GrDrawTarget's geometry to avoid copying points per-tile. 91680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 91780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL != indices) { 91880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru target->setIndexSourceToArray(indices, indexCount); 91980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru target->drawIndexed(primitiveType, 0, 0, vertexCount, indexCount); 92080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 92180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru target->drawNonIndexed(primitiveType, 0, vertexCount); 92280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 92380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 92480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 92580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 92680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querunamespace { 92780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 92880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustruct CircleVertex { 92980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPoint fPos; 93080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPoint fCenter; 931363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkScalar fOuterRadius; 932363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkScalar fInnerRadius; 93380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 93480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 935d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergerinline bool circleStaysCircle(const SkMatrix& m) { 936d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger return m.isSimilarity(); 937d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger} 938d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 939d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger} 940d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 941d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergervoid GrContext::drawOval(const GrPaint& paint, 942d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger const GrRect& oval, 943d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger const SkStrokeRec& stroke) { 944d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 945d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (!canDrawOval(paint, oval, stroke)) { 946d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkPath path; 947d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger path.addOval(oval); 948d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger this->drawPath(paint, path, stroke); 949d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger return; 95080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 95180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 952d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger internalDrawOval(paint, oval, stroke); 953d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger} 95480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 955d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergerbool GrContext::canDrawOval(const GrPaint& paint, const GrRect& oval, const SkStrokeRec& stroke) const { 956d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 957d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (!paint.isAntiAlias()) { 95880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 95980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 96080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 961d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger // we can draw circles in any style 962d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger bool isCircle = SkScalarNearlyEqual(oval.width(), oval.height()) 963d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger && circleStaysCircle(this->getMatrix()); 964d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger // and for now, axis-aligned ellipses only with fill or stroke-and-fill 965d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkStrokeRec::Style style = stroke.getStyle(); 966d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger bool isStroke = (style == SkStrokeRec::kStroke_Style || style == SkStrokeRec::kHairline_Style); 967d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger bool isFilledAxisAlignedEllipse = this->getMatrix().rectStaysRect() && !isStroke; 96880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 969d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger return isCircle || isFilledAxisAlignedEllipse; 97080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 97180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 972d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergervoid GrContext::internalDrawOval(const GrPaint& paint, 973d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger const GrRect& oval, 974d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger const SkStrokeRec& stroke) { 97580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 976d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkScalar xRadius = SkScalarHalf(oval.width()); 977d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkScalar yRadius = SkScalarHalf(oval.height()); 978d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 979d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkScalar strokeWidth = stroke.getWidth(); 980d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkStrokeRec::Style style = stroke.getStyle(); 981d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 982d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger bool isCircle = SkScalarNearlyEqual(xRadius, yRadius) && circleStaysCircle(this->getMatrix()); 983d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#ifdef SK_DEBUG 984d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger { 985d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger // we should have checked for this previously 986d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger bool isStroke = (style == SkStrokeRec::kStroke_Style || style == SkStrokeRec::kHairline_Style); 987d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger bool isFilledAxisAlignedEllipse = this->getMatrix().rectStaysRect() && !isStroke; 988d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkASSERT(paint.isAntiAlias() && (isCircle || isFilledAxisAlignedEllipse)); 98980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 990d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#endif 99180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 99280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrDrawTarget* target = this->prepareToDraw(&paint, DEFAULT_BUFFERING); 99380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 99480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrDrawState* drawState = target->drawState(); 99580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrDrawState::AutoStageDisable atr(fDrawState); 996363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const SkMatrix vm = drawState->getViewMatrix(); 99780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 99880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const GrRenderTarget* rt = drawState->getRenderTarget(); 99980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == rt) { 100080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 100180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 100280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 100380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrDrawState::AutoDeviceCoordDraw adcd(drawState); 100480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!adcd.succeeded()) { 100580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 100680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 100780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1008d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrVertexLayout layout = GrDrawState::kEdge_VertexLayoutBit; 1009d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrAssert(sizeof(CircleVertex) == GrDrawState::VertexSize(layout)); 101080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 101180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrDrawTarget::AutoReleaseGeometry geo(target, layout, 4, 0); 101280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!geo.succeeded()) { 101380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPrintf("Failed to get space for vertices!\n"); 101480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 101580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 101680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 101780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru CircleVertex* verts = reinterpret_cast<CircleVertex*>(geo.vertices()); 101880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1019d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrPoint center = GrPoint::Make(oval.centerX(), oval.centerY()); 1020d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger vm.mapPoints(¢er, 1); 1021d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 1022d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkScalar L; 1023d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkScalar R; 1024d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkScalar T; 1025d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkScalar B; 1026d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 1027d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (isCircle) { 1028d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger drawState->setVertexEdgeType(GrDrawState::kCircle_EdgeType); 1029d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 1030d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger xRadius = vm.mapRadius(xRadius); 1031d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 1032d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkScalar outerRadius = xRadius; 1033d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkScalar innerRadius = 0; 1034d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkScalar halfWidth = 0; 1035d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (style != SkStrokeRec::kFill_Style) { 1036d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger strokeWidth = vm.mapRadius(strokeWidth); 1037d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (SkScalarNearlyZero(strokeWidth)) { 1038d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger halfWidth = SK_ScalarHalf; 1039d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } else { 1040d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger halfWidth = SkScalarHalf(strokeWidth); 1041d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } 1042d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 1043d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger outerRadius += halfWidth; 1044d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (style == SkStrokeRec::kStroke_Style || style == SkStrokeRec::kHairline_Style) { 1045d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger innerRadius = SkMaxScalar(0, xRadius - halfWidth); 1046d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } 1047d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } 1048d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 1049d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger for (int i = 0; i < 4; ++i) { 1050d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger verts[i].fCenter = center; 1051d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger verts[i].fOuterRadius = outerRadius; 1052d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger verts[i].fInnerRadius = innerRadius; 1053d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } 1054d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 1055d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger L = -outerRadius; 1056d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger R = +outerRadius; 1057d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger T = -outerRadius; 1058d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger B = +outerRadius; 1059d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } else { // is axis-aligned ellipse 1060d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger drawState->setVertexEdgeType(GrDrawState::kEllipse_EdgeType); 1061d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 1062d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkRect xformedRect; 1063d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger vm.mapRect(&xformedRect, oval); 1064d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 1065d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger xRadius = SkScalarHalf(xformedRect.width()); 1066d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger yRadius = SkScalarHalf(xformedRect.height()); 1067d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 1068d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (style == SkStrokeRec::kStrokeAndFill_Style && strokeWidth > 0.0f) { 1069d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkScalar halfWidth = SkScalarHalf(strokeWidth); 1070d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger // do (potentially) anisotropic mapping 1071d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkVector scaledStroke; 1072d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger scaledStroke.set(halfWidth, halfWidth); 1073d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger vm.mapVectors(&scaledStroke, 1); 1074d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger // this is legit only if scale & translation (which should be the case at the moment) 1075d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger xRadius += scaledStroke.fX; 1076d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger yRadius += scaledStroke.fY; 1077d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } 1078d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 1079d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkScalar ratio = SkScalarDiv(xRadius, yRadius); 1080d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 1081d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger for (int i = 0; i < 4; ++i) { 1082d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger verts[i].fCenter = center; 1083d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger verts[i].fOuterRadius = xRadius; 1084d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger verts[i].fInnerRadius = ratio; 1085d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } 1086d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 1087d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger L = -xRadius; 1088d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger R = +xRadius; 1089d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger T = -yRadius; 1090d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger B = +yRadius; 1091d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } 1092d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 109380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // The fragment shader will extend the radius out half a pixel 109480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // to antialias. Expand the drawn rect here so all the pixels 109580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // will be captured. 1096d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger L += center.fX - SK_ScalarHalf; 1097d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger R += center.fX + SK_ScalarHalf; 1098d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger T += center.fY - SK_ScalarHalf; 1099d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger B += center.fY + SK_ScalarHalf; 110080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 110180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru verts[0].fPos = SkPoint::Make(L, T); 110280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru verts[1].fPos = SkPoint::Make(R, T); 110380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru verts[2].fPos = SkPoint::Make(L, B); 110480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru verts[3].fPos = SkPoint::Make(R, B); 110580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 110680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru target->drawNonIndexed(kTriangleStrip_GrPrimitiveType, 0, 4); 110780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 110880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1109363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergervoid GrContext::drawPath(const GrPaint& paint, const SkPath& path, const SkStrokeRec& stroke) { 111080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 111180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (path.isEmpty()) { 1112363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (path.isInverseFillType()) { 111380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->drawPaint(paint); 111480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 111580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 111680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 111780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 111880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkRect ovalRect; 1119d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger bool isOval = path.isOval(&ovalRect); 1120d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 1121d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (isOval && !path.isInverseFillType() && this->canDrawOval(paint, ovalRect, stroke)) { 1122d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger this->drawOval(paint, ovalRect, stroke); 112380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 112480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 112580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1126d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger this->internalDrawPath(paint, path, stroke); 112780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 112880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1129363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergervoid GrContext::internalDrawPath(const GrPaint& paint, const SkPath& path, const SkStrokeRec& stroke) { 113080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 113180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Note that below we may sw-rasterize the path into a scratch texture. 113280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Scratch textures can be recycled after they are returned to the texture 113380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // cache. This presents a potential hazard for buffered drawing. However, 113480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // the writePixels that uploads to the scratch will perform a flush so we're 113580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // OK. 113680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrDrawTarget* target = this->prepareToDraw(&paint, DEFAULT_BUFFERING); 113780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrDrawState::AutoStageDisable atr(fDrawState); 113880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 113980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool prAA = paint.isAntiAlias() && !this->getRenderTarget()->isMultisampled(); 114080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 114180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // An Assumption here is that path renderer would use some form of tweaking 114280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // the src color (either the input alpha or in the frag shader) to implement 114380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // aa. If we have some future driver-mojo path AA that can do the right 114480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // thing WRT to the blend then we'll need some query on the PR. 114580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (disable_coverage_aa_for_blend(target)) { 114680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if GR_DEBUG 114780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru //GrPrintf("Turning off AA to correctly apply blend.\n"); 114880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 114980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru prAA = false; 115080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 115180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1152363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger GrPathRendererChain::DrawType type = prAA ? GrPathRendererChain::kColorAntiAlias_DrawType : 1153363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger GrPathRendererChain::kColor_DrawType; 1154363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 1155d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger const SkPath* pathPtr = &path; 1156d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkPath tmpPath; 1157d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkStrokeRec strokeRec(stroke); 1158d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 1159d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger // Try a 1st time without stroking the path and without allowing the SW renderer 1160d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrPathRenderer* pr = this->getPathRenderer(*pathPtr, strokeRec, target, false, type); 1161d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 1162d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (NULL == pr) { 1163d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (!strokeRec.isHairlineStyle()) { 1164d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger // It didn't work the 1st time, so try again with the stroked path 1165d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (strokeRec.applyToPath(&tmpPath, *pathPtr)) { 1166d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger pathPtr = &tmpPath; 1167d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger strokeRec.setFillStyle(); 1168d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } 1169d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } 1170d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger // This time, allow SW renderer 1171d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger pr = this->getPathRenderer(*pathPtr, strokeRec, target, true, type); 1172d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } 1173d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 117480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == pr) { 117580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if GR_DEBUG 117680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPrintf("Unable to find path renderer compatible with path.\n"); 117780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 117880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 117980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 118080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1181d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger pr->drawPath(*pathPtr, strokeRec, target, prAA); 118280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 118380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 118480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//////////////////////////////////////////////////////////////////////////////// 118580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 118680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrContext::flush(int flagsBitfield) { 118780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (kDiscard_FlushBit & flagsBitfield) { 118880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDrawBuffer->reset(); 118980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 119080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->flushDrawBuffer(); 119180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 119280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (kForceCurrentRenderTarget_FlushBit & flagsBitfield) { 119380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fGpu->forceRenderTargetFlush(); 119480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 119580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 119680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 119780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrContext::flushDrawBuffer() { 119880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (fDrawBuffer) { 119980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // With addition of the AA clip path, flushing the draw buffer can 120080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // result in the generation of an AA clip mask. During this 120180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // process the SW path renderer may be invoked which recusively 120280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // calls this method (via internalWriteTexturePixels) creating 120380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // infinite recursion 120480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrInOrderDrawBuffer* temp = fDrawBuffer; 120580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDrawBuffer = NULL; 120680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 120780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru temp->flushTo(fGpu); 120880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 120980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDrawBuffer = temp; 121080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 121180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 121280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 121380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrContext::writeTexturePixels(GrTexture* texture, 121480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int left, int top, int width, int height, 121580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPixelConfig config, const void* buffer, size_t rowBytes, 121680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru uint32_t flags) { 121780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_TRACE_EVENT0("GrContext::writeTexturePixels"); 121880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ASSERT_OWNED_RESOURCE(texture); 121980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 122080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // TODO: use scratch texture to perform conversion 122180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (kUnpremul_PixelOpsFlag & flags) { 122280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 122380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 122480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!(kDontFlush_PixelOpsFlag & flags)) { 122580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->flush(); 122680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 122780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 122880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fGpu->writeTexturePixels(texture, left, top, width, height, 122980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru config, buffer, rowBytes); 123080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 123180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 123280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool GrContext::readTexturePixels(GrTexture* texture, 123380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int left, int top, int width, int height, 123480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPixelConfig config, void* buffer, size_t rowBytes, 123580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru uint32_t flags) { 123680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_TRACE_EVENT0("GrContext::readTexturePixels"); 123780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ASSERT_OWNED_RESOURCE(texture); 123880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 123980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // TODO: code read pixels for textures that aren't also rendertargets 124080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrRenderTarget* target = texture->asRenderTarget(); 124180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL != target) { 124280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return this->readRenderTargetPixels(target, 124380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru left, top, width, height, 124480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru config, buffer, rowBytes, 124580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru flags); 124680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 124780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 124880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 124980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 125080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 125180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkConfig8888.h" 125280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 125380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querunamespace { 125480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/** 125580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Converts a GrPixelConfig to a SkCanvas::Config8888. Only byte-per-channel 125680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * formats are representable as Config8888 and so the function returns false 125780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * if the GrPixelConfig has no equivalent Config8888. 125880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 125980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool grconfig_to_config8888(GrPixelConfig config, 126080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool unpremul, 126180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkCanvas::Config8888* config8888) { 126280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru switch (config) { 126380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case kRGBA_8888_GrPixelConfig: 126480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (unpremul) { 126580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *config8888 = SkCanvas::kRGBA_Unpremul_Config8888; 126680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 126780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *config8888 = SkCanvas::kRGBA_Premul_Config8888; 126880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 126980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 127080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case kBGRA_8888_GrPixelConfig: 127180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (unpremul) { 127280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *config8888 = SkCanvas::kBGRA_Unpremul_Config8888; 127380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 127480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *config8888 = SkCanvas::kBGRA_Premul_Config8888; 127580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 127680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 127780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru default: 127880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 127980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 128080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 128180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 128280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// It returns a configuration with where the byte position of the R & B components are swapped in 128380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// relation to the input config. This should only be called with the result of 128480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// grconfig_to_config8888 as it will fail for other configs. 128580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkCanvas::Config8888 swap_config8888_red_and_blue(SkCanvas::Config8888 config8888) { 128680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru switch (config8888) { 128780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case SkCanvas::kBGRA_Premul_Config8888: 128880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkCanvas::kRGBA_Premul_Config8888; 128980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case SkCanvas::kBGRA_Unpremul_Config8888: 129080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkCanvas::kRGBA_Unpremul_Config8888; 129180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case SkCanvas::kRGBA_Premul_Config8888: 129280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkCanvas::kBGRA_Premul_Config8888; 129380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case SkCanvas::kRGBA_Unpremul_Config8888: 129480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkCanvas::kBGRA_Unpremul_Config8888; 129580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru default: 129680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrCrash("Unexpected input"); 129780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkCanvas::kBGRA_Unpremul_Config8888;; 129880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 129980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 130080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 130180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 130280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool GrContext::readRenderTargetPixels(GrRenderTarget* target, 130380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int left, int top, int width, int height, 130480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPixelConfig config, void* buffer, size_t rowBytes, 130580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru uint32_t flags) { 130680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_TRACE_EVENT0("GrContext::readRenderTargetPixels"); 130780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ASSERT_OWNED_RESOURCE(target); 130880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 130980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == target) { 131080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru target = fDrawState->getRenderTarget(); 131180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == target) { 131280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 131380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 131480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 131580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 131680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!(kDontFlush_PixelOpsFlag & flags)) { 131780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->flush(); 131880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 131980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 132080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Determine which conversions have to be applied: flipY, swapRAnd, and/or unpremul. 132180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 132280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // If fGpu->readPixels would incur a y-flip cost then we will read the pixels upside down. We'll 132380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // either do the flipY by drawing into a scratch with a matrix or on the cpu after the read. 132480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool flipY = fGpu->readPixelsWillPayForYFlip(target, left, top, 132580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru width, height, config, 132680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru rowBytes); 132780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool swapRAndB = fGpu->preferredReadPixelsConfig(config) == GrPixelConfigSwapRAndB(config); 132880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 132980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool unpremul = SkToBool(kUnpremul_PixelOpsFlag & flags); 133080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 133180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // flipY will get set to false when it is handled below using a scratch. However, in that case 133280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // we still want to do the read upside down. 133380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool readUpsideDown = flipY; 133480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 133580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (unpremul && kRGBA_8888_GrPixelConfig != config && kBGRA_8888_GrPixelConfig != config) { 133680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // The unpremul flag is only allowed for these two configs. 133780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 133880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 133980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 134080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPixelConfig readConfig; 134180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (swapRAndB) { 134280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru readConfig = GrPixelConfigSwapRAndB(config); 134380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(kUnknown_GrPixelConfig != config); 134480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 134580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru readConfig = config; 134680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 134780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 134880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // If the src is a texture and we would have to do conversions after read pixels, we instead 134980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // do the conversions by drawing the src to a scratch texture. If we handle any of the 135080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // conversions in the draw we set the corresponding bool to false so that we don't reapply it 135180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // on the read back pixels. 135280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrTexture* src = target->asTexture(); 135380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAutoScratchTexture ast; 135480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL != src && (swapRAndB || unpremul || flipY)) { 135580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Make the scratch a render target because we don't have a robust readTexturePixels as of 135680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // yet. It calls this function. 135780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrTextureDesc desc; 135880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fFlags = kRenderTarget_GrTextureFlagBit; 135980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fWidth = width; 136080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fHeight = height; 136180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fConfig = readConfig; 136280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 136380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // When a full readback is faster than a partial we could always make the scratch exactly 136480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // match the passed rect. However, if we see many different size rectangles we will trash 136580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // our texture cache and pay the cost of creating and destroying many textures. So, we only 136680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // request an exact match when the caller is reading an entire RT. 136780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ScratchTexMatch match = kApprox_ScratchTexMatch; 136880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (0 == left && 136980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 0 == top && 137080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru target->width() == width && 137180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru target->height() == height && 137280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fGpu->fullReadPixelsIsFasterThanPartial()) { 137380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru match = kExact_ScratchTexMatch; 137480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 137580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ast.set(this, desc, match); 137680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrTexture* texture = ast.texture(); 137780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (texture) { 1378363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // compute a matrix to perform the draw 1379363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkMatrix textureMatrix; 1380363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (flipY) { 1381363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger textureMatrix.setTranslate(SK_Scalar1 * left, 1382363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SK_Scalar1 * (top + height)); 1383363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger textureMatrix.set(SkMatrix::kMScaleY, -SK_Scalar1); 1384363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } else { 1385363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger textureMatrix.setTranslate(SK_Scalar1 *left, SK_Scalar1 *top); 1386363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 1387363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger textureMatrix.postIDiv(src->width(), src->height()); 1388363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 1389d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkAutoTUnref<const GrEffectRef> effect; 139080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (unpremul) { 1391d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger effect.reset(this->createPMToUPMEffect(src, swapRAndB, textureMatrix)); 1392d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (NULL != effect) { 1393363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger unpremul = false; // we no longer need to do this on CPU after the readback. 1394363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 139580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 139680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // If we failed to create a PM->UPM effect and have no other conversions to perform then 139780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // there is no longer any point to using the scratch. 1398d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (NULL != effect || flipY || swapRAndB) { 1399d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (!effect) { 1400d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger effect.reset(GrConfigConversionEffect::Create( 1401d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger src, 1402d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger swapRAndB, 1403d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrConfigConversionEffect::kNone_PMConversion, 1404d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger textureMatrix)); 140580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 140680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru swapRAndB = false; // we will handle the swap in the draw. 1407363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger flipY = false; // we already incorporated the y flip in the matrix 140880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 140980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrDrawTarget::AutoStateRestore asr(fGpu, GrDrawTarget::kReset_ASRInit); 141080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrDrawState* drawState = fGpu->drawState(); 1411d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrAssert(effect); 1412d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger drawState->setEffect(0, effect); 1413363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 141480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru drawState->setRenderTarget(texture->asRenderTarget()); 1415363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger GrRect rect = GrRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height)); 141680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fGpu->drawSimpleRect(rect, NULL); 141780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // we want to read back from the scratch's origin 141880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru left = 0; 141980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru top = 0; 142080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru target = texture->asRenderTarget(); 142180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 142280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 142380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 142480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!fGpu->readPixels(target, 142580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru left, top, width, height, 142680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru readConfig, buffer, rowBytes, readUpsideDown)) { 142780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 142880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 1429363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // Perform any conversions we weren't able to perform using a scratch texture. 143080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (unpremul || swapRAndB || flipY) { 143180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // These are initialized to suppress a warning 143280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkCanvas::Config8888 srcC8888 = SkCanvas::kNative_Premul_Config8888; 143380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkCanvas::Config8888 dstC8888 = SkCanvas::kNative_Premul_Config8888; 143480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 143580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool c8888IsValid = grconfig_to_config8888(config, false, &srcC8888); 143680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru grconfig_to_config8888(config, unpremul, &dstC8888); 143780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 143880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (swapRAndB) { 143980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(c8888IsValid); // we should only do r/b swap on 8888 configs 144080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru srcC8888 = swap_config8888_red_and_blue(srcC8888); 144180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 144280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (flipY) { 144380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t tightRB = width * GrBytesPerPixel(config); 144480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (0 == rowBytes) { 144580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru rowBytes = tightRB; 144680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 144780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkAutoSTMalloc<256, uint8_t> tempRow(tightRB); 144880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru intptr_t top = reinterpret_cast<intptr_t>(buffer); 144980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru intptr_t bot = top + (height - 1) * rowBytes; 145080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru while (top < bot) { 145180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru uint32_t* t = reinterpret_cast<uint32_t*>(top); 145280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru uint32_t* b = reinterpret_cast<uint32_t*>(bot); 145380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru uint32_t* temp = reinterpret_cast<uint32_t*>(tempRow.get()); 145480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru memcpy(temp, t, tightRB); 145580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (c8888IsValid) { 145680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkConvertConfig8888Pixels(t, tightRB, dstC8888, 145780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru b, tightRB, srcC8888, 145880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru width, 1); 145980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkConvertConfig8888Pixels(b, tightRB, dstC8888, 146080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru temp, tightRB, srcC8888, 146180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru width, 1); 146280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 146380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru memcpy(t, b, tightRB); 146480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru memcpy(b, temp, tightRB); 146580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 146680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru top += rowBytes; 146780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bot -= rowBytes; 146880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 146980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // The above loop does nothing on the middle row when height is odd. 147080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (top == bot && c8888IsValid && dstC8888 != srcC8888) { 147180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru uint32_t* mid = reinterpret_cast<uint32_t*>(top); 147280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkConvertConfig8888Pixels(mid, tightRB, dstC8888, mid, tightRB, srcC8888, width, 1); 147380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 147480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 147580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // if we aren't flipping Y then we have no reason to be here other than doing 147680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // conversions for 8888 (r/b swap or upm). 147780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(c8888IsValid); 147880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru uint32_t* b32 = reinterpret_cast<uint32_t*>(buffer); 147980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkConvertConfig8888Pixels(b32, rowBytes, dstC8888, 148080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru b32, rowBytes, srcC8888, 148180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru width, height); 148280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 148380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 148480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 148580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 148680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 148780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrContext::resolveRenderTarget(GrRenderTarget* target) { 148880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(target); 148980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ASSERT_OWNED_RESOURCE(target); 149080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // In the future we may track whether there are any pending draws to this 149180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // target. We don't today so we always perform a flush. We don't promise 149280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // this to our clients, though. 149380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->flush(); 149480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fGpu->resolveRenderTarget(target); 149580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 149680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1497363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergervoid GrContext::copyTexture(GrTexture* src, GrRenderTarget* dst, const SkIPoint* topLeft) { 149880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == src || NULL == dst) { 149980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 150080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 150180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ASSERT_OWNED_RESOURCE(src); 150280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 150380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Writes pending to the source texture are not tracked, so a flush 150480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // is required to ensure that the copy captures the most recent contents 1505d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger // of the source texture. See similar behavior in 150680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // GrContext::resolveRenderTarget. 150780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->flush(); 150880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 150980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrDrawTarget::AutoStateRestore asr(fGpu, GrDrawTarget::kReset_ASRInit); 151080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrDrawState* drawState = fGpu->drawState(); 151180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru drawState->setRenderTarget(dst); 1512363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkMatrix sampleM; 151380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru sampleM.setIDiv(src->width(), src->height()); 1514363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkIRect srcRect = SkIRect::MakeWH(dst->width(), dst->height()); 1515363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (NULL != topLeft) { 1516363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger srcRect.offset(*topLeft); 1517363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 1518363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkIRect srcBounds = SkIRect::MakeWH(src->width(), src->height()); 1519363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (!srcRect.intersect(srcBounds)) { 1520363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return; 1521363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 1522363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger sampleM.preTranslate(SkIntToScalar(srcRect.fLeft), SkIntToScalar(srcRect.fTop)); 152380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru drawState->createTextureEffect(0, src, sampleM); 1524363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkRect dstR = SkRect::MakeWH(SkIntToScalar(srcRect.width()), SkIntToScalar(srcRect.height())); 1525363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fGpu->drawSimpleRect(dstR, NULL); 152680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 152780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 152880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrContext::writeRenderTargetPixels(GrRenderTarget* target, 152980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int left, int top, int width, int height, 153080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPixelConfig config, 153180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const void* buffer, 153280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t rowBytes, 153380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru uint32_t flags) { 153480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_TRACE_EVENT0("GrContext::writeRenderTargetPixels"); 153580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ASSERT_OWNED_RESOURCE(target); 153680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 153780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == target) { 153880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru target = fDrawState->getRenderTarget(); 153980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == target) { 154080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 154180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 154280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 154380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 154480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // TODO: when underlying api has a direct way to do this we should use it (e.g. glDrawPixels on 154580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // desktop GL). 154680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 154780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // We will always call some form of writeTexturePixels and we will pass our flags on to it. 154880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Thus, we don't perform a flush here since that call will do it (if the kNoFlush flag isn't 154980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // set.) 155080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 155180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // If the RT is also a texture and we don't have to premultiply then take the texture path. 155280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // We expect to be at least as fast or faster since it doesn't use an intermediate texture as 155380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // we do below. 155480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 155580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if !GR_MAC_BUILD 155680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // At least some drivers on the Mac get confused when glTexImage2D is called on a texture 155780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // attached to an FBO. The FBO still sees the old image. TODO: determine what OS versions and/or 155880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // HW is affected. 155980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL != target->asTexture() && !(kUnpremul_PixelOpsFlag & flags)) { 156080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->writeTexturePixels(target->asTexture(), 156180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru left, top, width, height, 156280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru config, buffer, rowBytes, flags); 156380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 156480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 156580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 1566363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 156780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool swapRAndB = (fGpu->preferredReadPixelsConfig(config) == GrPixelConfigSwapRAndB(config)); 156880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 156980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPixelConfig textureConfig; 157080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (swapRAndB) { 157180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru textureConfig = GrPixelConfigSwapRAndB(config); 157280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 157380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru textureConfig = config; 157480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 157580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 157680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrTextureDesc desc; 157780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fWidth = width; 157880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fHeight = height; 157980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fConfig = textureConfig; 158080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAutoScratchTexture ast(this, desc); 158180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrTexture* texture = ast.texture(); 158280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == texture) { 158380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 158480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 1585363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 1586d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkAutoTUnref<const GrEffectRef> effect; 1587363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkMatrix textureMatrix; 1588363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger textureMatrix.setIDiv(texture->width(), texture->height()); 1589363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 159080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // allocate a tmp buffer and sw convert the pixels to premul 159180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkAutoSTMalloc<128 * 128, uint32_t> tmpPixels(0); 159280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 159380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (kUnpremul_PixelOpsFlag & flags) { 159480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (kRGBA_8888_GrPixelConfig != config && kBGRA_8888_GrPixelConfig != config) { 159580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 159680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 1597d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger effect.reset(this->createUPMToPMEffect(texture, swapRAndB, textureMatrix)); 1598d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (NULL == effect) { 159980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkCanvas::Config8888 srcConfig8888, dstConfig8888; 160080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GR_DEBUGCODE(bool success = ) 160180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru grconfig_to_config8888(config, true, &srcConfig8888); 160280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(success); 160380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GR_DEBUGCODE(success = ) 160480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru grconfig_to_config8888(config, false, &dstConfig8888); 160580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(success); 160680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const uint32_t* src = reinterpret_cast<const uint32_t*>(buffer); 160780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tmpPixels.reset(width * height); 160880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkConvertConfig8888Pixels(tmpPixels.get(), 4 * width, dstConfig8888, 160980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru src, rowBytes, srcConfig8888, 161080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru width, height); 161180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru buffer = tmpPixels.get(); 161280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru rowBytes = 4 * width; 161380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 161480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 1615d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (NULL == effect) { 1616d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger effect.reset(GrConfigConversionEffect::Create(texture, 1617d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger swapRAndB, 1618d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrConfigConversionEffect::kNone_PMConversion, 1619d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger textureMatrix)); 162080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 162180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 162280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->writeTexturePixels(texture, 162380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 0, 0, width, height, 162480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru textureConfig, buffer, rowBytes, 162580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru flags & ~kUnpremul_PixelOpsFlag); 162680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 162780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrDrawTarget::AutoStateRestore asr(fGpu, GrDrawTarget::kReset_ASRInit); 162880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrDrawState* drawState = fGpu->drawState(); 1629d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrAssert(effect); 1630d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger drawState->setEffect(0, effect); 163180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1632363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkMatrix matrix; 1633363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger matrix.setTranslate(SkIntToScalar(left), SkIntToScalar(top)); 163480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru drawState->setViewMatrix(matrix); 163580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru drawState->setRenderTarget(target); 163680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 163780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fGpu->drawSimpleRect(GrRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height)), NULL); 163880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 163980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//////////////////////////////////////////////////////////////////////////////// 164080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 164180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruGrDrawTarget* GrContext::prepareToDraw(const GrPaint* paint, BufferedDraw buffered) { 164280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (kNo_BufferedDraw == buffered && kYes_BufferedDraw == fLastDrawWasBuffered) { 164380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->flushDrawBuffer(); 164480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fLastDrawWasBuffered = kNo_BufferedDraw; 164580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 164680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL != paint) { 164780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(fDrawState->stagesDisabled()); 164880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDrawState->setFromPaint(*paint); 164980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if GR_DEBUG_PARTIAL_COVERAGE_CHECK 165080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if ((paint->hasMask() || 0xff != paint->fCoverage) && 165180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru !fGpu->canApplyCoverage()) { 165280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPrintf("Partial pixel coverage will be incorrectly blended.\n"); 165380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 165480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 165580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 165680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (kYes_BufferedDraw == buffered) { 165780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDrawBuffer->setClip(fGpu->getClip()); 165880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fLastDrawWasBuffered = kYes_BufferedDraw; 165980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return fDrawBuffer; 166080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 166180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(kNo_BufferedDraw == buffered); 166280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return fGpu; 166380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 166480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 166580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 166680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* 166780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * This method finds a path renderer that can draw the specified path on 166880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * the provided target. 166980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Due to its expense, the software path renderer has split out so it can 167080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * can be individually allowed/disallowed via the "allowSW" boolean. 167180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 167280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruGrPathRenderer* GrContext::getPathRenderer(const SkPath& path, 1673363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const SkStrokeRec& stroke, 167480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const GrDrawTarget* target, 1675363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger bool allowSW, 1676363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger GrPathRendererChain::DrawType drawType, 1677363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger GrPathRendererChain::StencilSupport* stencilSupport) { 1678363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 167980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == fPathRendererChain) { 1680363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fPathRendererChain = SkNEW_ARGS(GrPathRendererChain, (this)); 168180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 168280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1683363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger GrPathRenderer* pr = fPathRendererChain->getPathRenderer(path, 1684363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger stroke, 168580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru target, 1686363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger drawType, 1687363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger stencilSupport); 168880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 168980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == pr && allowSW) { 169080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == fSoftwarePathRenderer) { 169180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fSoftwarePathRenderer = SkNEW_ARGS(GrSoftwarePathRenderer, (this)); 169280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 169380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru pr = fSoftwarePathRenderer; 169480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 169580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 169680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return pr; 169780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 169880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 169980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//////////////////////////////////////////////////////////////////////////////// 170080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 170180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrContext::setRenderTarget(GrRenderTarget* target) { 170280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ASSERT_OWNED_RESOURCE(target); 170380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDrawState->setRenderTarget(target); 170480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 170580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 170680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruGrRenderTarget* GrContext::getRenderTarget() { 170780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return fDrawState->getRenderTarget(); 170880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 170980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 171080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruconst GrRenderTarget* GrContext::getRenderTarget() const { 171180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return fDrawState->getRenderTarget(); 171280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 171380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 171480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool GrContext::isConfigRenderable(GrPixelConfig config) const { 171580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return fGpu->isConfigRenderable(config); 171680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 171780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1718363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerconst SkMatrix& GrContext::getMatrix() const { 171980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return fDrawState->getViewMatrix(); 172080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 172180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1722363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergervoid GrContext::setMatrix(const SkMatrix& m) { 172380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDrawState->setViewMatrix(m); 172480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 172580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 172680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrContext::setIdentityMatrix() { 172780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDrawState->viewMatrix()->reset(); 172880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 172980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1730363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergervoid GrContext::concatMatrix(const SkMatrix& m) const { 173180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDrawState->preConcatViewMatrix(m); 173280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 173380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 173480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline intptr_t setOrClear(intptr_t bits, int shift, intptr_t pred) { 173580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru intptr_t mask = 1 << shift; 173680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (pred) { 173780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bits |= mask; 173880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 173980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bits &= ~mask; 174080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 174180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return bits; 174280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 174380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 174480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruGrContext::GrContext(GrGpu* gpu) { 174580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ++THREAD_INSTANCE_COUNT; 174680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 174780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fGpu = gpu; 174880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fGpu->ref(); 174980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fGpu->setContext(this); 175080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 175180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDrawState = SkNEW(GrDrawState); 175280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fGpu->setDrawState(fDrawState); 175380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 175480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fPathRendererChain = NULL; 175580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fSoftwarePathRenderer = NULL; 175680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 175780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fTextureCache = SkNEW_ARGS(GrResourceCache, 175880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru (MAX_TEXTURE_CACHE_COUNT, 175980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru MAX_TEXTURE_CACHE_BYTES)); 176080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fFontCache = SkNEW_ARGS(GrFontCache, (fGpu)); 176180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 176280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fLastDrawWasBuffered = kNo_BufferedDraw; 176380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 176480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDrawBuffer = NULL; 176580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDrawBufferVBAllocPool = NULL; 176680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDrawBufferIBAllocPool = NULL; 176780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 176880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fAARectRenderer = SkNEW(GrAARectRenderer); 176980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 177080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDidTestPMConversions = false; 177180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 177280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->setupDrawBuffer(); 177380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 177480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 177580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrContext::setupDrawBuffer() { 177680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 177780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(NULL == fDrawBuffer); 177880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(NULL == fDrawBufferVBAllocPool); 177980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(NULL == fDrawBufferIBAllocPool); 178080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 178180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDrawBufferVBAllocPool = 178280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkNEW_ARGS(GrVertexBufferAllocPool, (fGpu, false, 178380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru DRAW_BUFFER_VBPOOL_BUFFER_SIZE, 178480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru DRAW_BUFFER_VBPOOL_PREALLOC_BUFFERS)); 178580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDrawBufferIBAllocPool = 178680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkNEW_ARGS(GrIndexBufferAllocPool, (fGpu, false, 178780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru DRAW_BUFFER_IBPOOL_BUFFER_SIZE, 178880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS)); 178980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 179080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDrawBuffer = SkNEW_ARGS(GrInOrderDrawBuffer, (fGpu, 179180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDrawBufferVBAllocPool, 179280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDrawBufferIBAllocPool)); 179380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 179480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (fDrawBuffer) { 179580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDrawBuffer->setAutoFlushTarget(fGpu); 179680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDrawBuffer->setDrawState(fDrawState); 179780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 179880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 179980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 180080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruGrDrawTarget* GrContext::getTextTarget(const GrPaint& paint) { 180180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return prepareToDraw(&paint, DEFAULT_BUFFERING); 180280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 180380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 180480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruconst GrIndexBuffer* GrContext::getQuadIndexBuffer() const { 180580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return fGpu->getQuadIndexBuffer(); 180680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 180780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 180880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querunamespace { 180980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid test_pm_conversions(GrContext* ctx, int* pmToUPMValue, int* upmToPMValue) { 181080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrConfigConversionEffect::PMConversion pmToUPM; 181180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrConfigConversionEffect::PMConversion upmToPM; 181280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrConfigConversionEffect::TestForPreservingPMConversions(ctx, &pmToUPM, &upmToPM); 181380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *pmToUPMValue = pmToUPM; 181480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *upmToPMValue = upmToPM; 181580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 181680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 181780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1818d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergerconst GrEffectRef* GrContext::createPMToUPMEffect(GrTexture* texture, 1819d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger bool swapRAndB, 1820d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger const SkMatrix& matrix) { 182180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!fDidTestPMConversions) { 182280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru test_pm_conversions(this, &fPMToUPMConversion, &fUPMToPMConversion); 182380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDidTestPMConversions = true; 182480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 182580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrConfigConversionEffect::PMConversion pmToUPM = 182680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static_cast<GrConfigConversionEffect::PMConversion>(fPMToUPMConversion); 182780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (GrConfigConversionEffect::kNone_PMConversion != pmToUPM) { 1828d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger return GrConfigConversionEffect::Create(texture, swapRAndB, pmToUPM, matrix); 182980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 1830d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger return NULL; 183180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 183280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 183380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1834d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergerconst GrEffectRef* GrContext::createUPMToPMEffect(GrTexture* texture, 1835d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger bool swapRAndB, 1836d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger const SkMatrix& matrix) { 183780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!fDidTestPMConversions) { 183880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru test_pm_conversions(this, &fPMToUPMConversion, &fUPMToPMConversion); 183980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDidTestPMConversions = true; 184080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 184180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrConfigConversionEffect::PMConversion upmToPM = 184280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static_cast<GrConfigConversionEffect::PMConversion>(fUPMToPMConversion); 184380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (GrConfigConversionEffect::kNone_PMConversion != upmToPM) { 1844d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger return GrConfigConversionEffect::Create(texture, swapRAndB, upmToPM, matrix); 184580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 1846d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger return NULL; 184780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 184880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 184980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 185080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruGrTexture* GrContext::gaussianBlur(GrTexture* srcTexture, 185180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool canClobberSrc, 185280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkRect& rect, 185380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru float sigmaX, float sigmaY) { 185480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ASSERT_OWNED_RESOURCE(srcTexture); 185580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 185680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru AutoRenderTarget art(this); 185780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 185880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru AutoMatrix am; 185980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru am.setIdentity(this); 186080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 186180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkIRect clearRect; 186280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int scaleFactorX, radiusX; 186380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int scaleFactorY, radiusY; 186480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru sigmaX = adjust_sigma(sigmaX, &scaleFactorX, &radiusX); 186580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru sigmaY = adjust_sigma(sigmaY, &scaleFactorY, &radiusY); 186680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 186780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkRect srcRect(rect); 186880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru scale_rect(&srcRect, 1.0f / scaleFactorX, 1.0f / scaleFactorY); 186980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru srcRect.roundOut(); 187080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru scale_rect(&srcRect, static_cast<float>(scaleFactorX), 187180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static_cast<float>(scaleFactorY)); 187280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 187380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru AutoClip acs(this, srcRect); 187480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 187580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(kBGRA_8888_GrPixelConfig == srcTexture->config() || 187680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kRGBA_8888_GrPixelConfig == srcTexture->config() || 187780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kAlpha_8_GrPixelConfig == srcTexture->config()); 187880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 187980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrTextureDesc desc; 188080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit; 188180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fWidth = SkScalarFloorToInt(srcRect.width()); 188280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fHeight = SkScalarFloorToInt(srcRect.height()); 188380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru desc.fConfig = srcTexture->config(); 188480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 188580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAutoScratchTexture temp1, temp2; 188680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrTexture* dstTexture = temp1.set(this, desc); 188780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrTexture* tempTexture = canClobberSrc ? srcTexture : temp2.set(this, desc); 1888363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (NULL == dstTexture || NULL == tempTexture) { 1889363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return NULL; 1890363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 189180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 189280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPaint paint; 189380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru paint.reset(); 189480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 189580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = 1; i < scaleFactorX || i < scaleFactorY; i *= 2) { 1896363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkMatrix matrix; 189780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru matrix.setIDiv(srcTexture->width(), srcTexture->height()); 189880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->setRenderTarget(dstTexture->asRenderTarget()); 189980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkRect dstRect(srcRect); 190080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru scale_rect(&dstRect, i < scaleFactorX ? 0.5f : 1.0f, 190180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru i < scaleFactorY ? 0.5f : 1.0f); 190280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1903d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger paint.colorStage(0)->setEffect(GrSimpleTextureEffect::Create(srcTexture, 1904d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger matrix, 1905d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger true))->unref(); 190680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->drawRectToRect(paint, dstRect, srcRect); 190780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru srcRect = dstRect; 190880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru srcTexture = dstTexture; 190980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkTSwap(dstTexture, tempTexture); 191080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 191180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 191280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkIRect srcIRect; 191380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru srcRect.roundOut(&srcIRect); 191480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 191580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (sigmaX > 0.0f) { 191680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (scaleFactorX > 1) { 191780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Clear out a radius to the right of the srcRect to prevent the 191880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // X convolution from reading garbage. 191980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop, 192080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru radiusX, srcIRect.height()); 192180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->clear(&clearRect, 0x0); 192280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 192380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 192480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->setRenderTarget(dstTexture->asRenderTarget()); 192580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrDrawTarget* target = this->prepareToDraw(NULL, DEFAULT_BUFFERING); 192680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru convolve_gaussian(target, srcTexture, srcRect, sigmaX, radiusX, 192780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Gr1DKernelEffect::kX_Direction); 192880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru srcTexture = dstTexture; 192980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkTSwap(dstTexture, tempTexture); 193080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 193180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 193280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (sigmaY > 0.0f) { 193380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (scaleFactorY > 1 || sigmaX > 0.0f) { 193480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Clear out a radius below the srcRect to prevent the Y 193580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // convolution from reading garbage. 193680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom, 193780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru srcIRect.width(), radiusY); 193880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->clear(&clearRect, 0x0); 193980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 194080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 194180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->setRenderTarget(dstTexture->asRenderTarget()); 194280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrDrawTarget* target = this->prepareToDraw(NULL, DEFAULT_BUFFERING); 194380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru convolve_gaussian(target, srcTexture, srcRect, sigmaY, radiusY, 194480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Gr1DKernelEffect::kY_Direction); 194580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru srcTexture = dstTexture; 194680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkTSwap(dstTexture, tempTexture); 194780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 194880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 194980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (scaleFactorX > 1 || scaleFactorY > 1) { 195080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Clear one pixel to the right and below, to accommodate bilinear 195180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // upsampling. 195280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom, 195380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru srcIRect.width() + 1, 1); 195480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->clear(&clearRect, 0x0); 195580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop, 195680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1, srcIRect.height()); 195780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->clear(&clearRect, 0x0); 1958363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkMatrix matrix; 195980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // FIXME: This should be mitchell, not bilinear. 196080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru matrix.setIDiv(srcTexture->width(), srcTexture->height()); 196180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->setRenderTarget(dstTexture->asRenderTarget()); 1962d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger paint.colorStage(0)->setEffect(GrSimpleTextureEffect::Create(srcTexture, 1963d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger matrix, 1964d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger true))->unref(); 196580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkRect dstRect(srcRect); 196680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru scale_rect(&dstRect, (float) scaleFactorX, (float) scaleFactorY); 196780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->drawRectToRect(paint, dstRect, srcRect); 196880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru srcRect = dstRect; 196980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru srcTexture = dstTexture; 197080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkTSwap(dstTexture, tempTexture); 197180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 197280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (srcTexture == temp1.texture()) { 197380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return temp1.detach(); 197480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else if (srcTexture == temp2.texture()) { 197580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return temp2.detach(); 197680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 197780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru srcTexture->ref(); 197880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return srcTexture; 197980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 198080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 198180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 198280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 198380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if GR_CACHE_STATS 198480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrContext::printCacheStats() const { 198580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fTextureCache->printStats(); 198680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 198780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 1988