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