GrContext.cpp revision 1cab2921ab279367f8206cdadc9259d12e603548
11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/*
31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2011 Google Inc.
41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *
51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be
61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file.
71cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */
81cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
91cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "GrContext.h"
111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "GrBufferAllocPool.h"
131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "GrClipIterator.h"
141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "GrGpu.h"
151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "GrIndexBuffer.h"
161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "GrInOrderDrawBuffer.h"
171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "GrPathRenderer.h"
181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "GrPathUtils.h"
191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "GrResourceCache.h"
201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "GrStencilBuffer.h"
211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "GrTextStrike.h"
221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkTLazy.h"
231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkTrace.h"
241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// Using MSAA seems to be slower for some yet unknown reason.
261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#define PREFER_MSAA_OFFSCREEN_AA 0
271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#define OFFSCREEN_SSAA_SCALE 4 // super sample at 4x4
281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#define DEFER_TEXT_RENDERING 1
301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#define BATCH_RECT_TO_RECT (1 && !GR_STATIC_RECT_VB)
321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// When we're using coverage AA but the blend is incompatible (given gpu
341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// limitations) should we disable AA or draw wrong?
351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#define DISABLE_COVERAGE_AA_FOR_BLEND 1
361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic const size_t MAX_TEXTURE_CACHE_COUNT = 256;
381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic const size_t MAX_TEXTURE_CACHE_BYTES = 16 * 1024 * 1024;
391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic const size_t DRAW_BUFFER_VBPOOL_BUFFER_SIZE = 1 << 18;
411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic const int DRAW_BUFFER_VBPOOL_PREALLOC_BUFFERS = 4;
421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// We are currently only batching Text and drawRectToRect, both
441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// of which use the quad index buffer.
451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic const size_t DRAW_BUFFER_IBPOOL_BUFFER_SIZE = 0;
461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic const int DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS = 0;
471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#define ASSERT_OWNED_RESOURCE(R) GrAssert(!(R) || (R)->getContext() == this)
491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
501cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerGrContext* GrContext::Create(GrEngine engine,
511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                             GrPlatform3DContext context3D) {
521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrContext* ctx = NULL;
531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrGpu* fGpu = GrGpu::Create(engine, context3D);
541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (NULL != fGpu) {
551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        ctx = new GrContext(fGpu);
561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fGpu->unref();
571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return ctx;
591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
611cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerGrContext::~GrContext() {
621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    this->flush();
631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    delete fTextureCache;
641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    delete fFontCache;
651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    delete fDrawBuffer;
661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    delete fDrawBufferVBAllocPool;
671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    delete fDrawBufferIBAllocPool;
681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrSafeUnref(fAAFillRectIndexBuffer);
701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrSafeUnref(fAAStrokeRectIndexBuffer);
711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fGpu->unref();
721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrSafeUnref(fPathRendererChain);
731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::contextLost() {
761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    contextDestroyed();
771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    this->setupDrawBuffer();
781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::contextDestroyed() {
811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // abandon first to so destructors
821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // don't try to free the resources in the API.
831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fGpu->abandonResources();
841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // a path renderer may be holding onto resources that
861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // are now unusable
871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrSafeSetNull(fPathRendererChain);
881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    delete fDrawBuffer;
901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fDrawBuffer = NULL;
911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    delete fDrawBufferVBAllocPool;
931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fDrawBufferVBAllocPool = NULL;
941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    delete fDrawBufferIBAllocPool;
961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fDrawBufferIBAllocPool = NULL;
971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrSafeSetNull(fAAFillRectIndexBuffer);
991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrSafeSetNull(fAAStrokeRectIndexBuffer);
1001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fTextureCache->removeAll();
1021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fFontCache->freeAll();
1031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fGpu->markContextDirty();
1041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
1051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::resetContext() {
1071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fGpu->markContextDirty();
1081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
1091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::freeGpuResources() {
1111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    this->flush();
1121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fTextureCache->removeAll();
1131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fFontCache->freeAll();
1141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // a path renderer may be holding onto resources
1151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrSafeSetNull(fPathRendererChain);
1161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
1171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger////////////////////////////////////////////////////////////////////////////////
1191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerint GrContext::PaintStageVertexLayoutBits(
1211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                            const GrPaint& paint,
1221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                            const bool hasTexCoords[GrPaint::kTotalStages]) {
1231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int stageMask = paint.getActiveStageMask();
1241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int layout = 0;
1251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    for (int i = 0; i < GrPaint::kTotalStages; ++i) {
1261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if ((1 << i) & stageMask) {
1271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            if (NULL != hasTexCoords && hasTexCoords[i]) {
1281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                layout |= GrDrawTarget::StageTexCoordVertexLayoutBit(i, i);
1291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            } else {
1301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                layout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(i);
1311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
1321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
1331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
1341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return layout;
1351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
1361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger////////////////////////////////////////////////////////////////////////////////
1391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerenum {
1411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // flags for textures
1421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    kNPOTBit            = 0x1,
1431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    kFilterBit          = 0x2,
1441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    kScratchBit         = 0x4,
1451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // resource type
1471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    kTextureBit         = 0x8,
1481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    kStencilBufferBit   = 0x10
1491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger};
1501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1511cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerGrTexture* GrContext::TextureCacheEntry::texture() const {
1521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (NULL == fEntry) {
1531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return NULL;
1541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else {
1551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return (GrTexture*) fEntry->resource();
1561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
1571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
1581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergernamespace {
1601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// returns true if this is a "special" texture because of gpu NPOT limitations
1611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool gen_texture_key_values(const GrGpu* gpu,
1621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                            const GrSamplerState* sampler,
1631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                            GrContext::TextureKey clientKey,
1641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                            int width,
1651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                            int height,
1661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                            bool scratch,
1671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                            uint32_t v[4]) {
1681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GR_STATIC_ASSERT(sizeof(GrContext::TextureKey) == sizeof(uint64_t));
1691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // we assume we only need 16 bits of width and height
1701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // assert that texture creation will fail anyway if this assumption
1711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // would cause key collisions.
1721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrAssert(gpu->getCaps().fMaxTextureSize <= SK_MaxU16);
1731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    v[0] = clientKey & 0xffffffffUL;
1741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    v[1] = (clientKey >> 32) & 0xffffffffUL;
1751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    v[2] = width | (height << 16);
1761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    v[3] = 0;
1781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (!gpu->getCaps().fNPOTTextureTileSupport) {
1791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        bool isPow2 = GrIsPow2(width) && GrIsPow2(height);
1801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        bool tiled = NULL != sampler &&
1821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                     ((sampler->getWrapX() != GrSamplerState::kClamp_WrapMode) ||
1831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                      (sampler->getWrapY() != GrSamplerState::kClamp_WrapMode));
1841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (tiled && !isPow2) {
1861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            v[3] |= kNPOTBit;
1871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            if (GrSamplerState::kNearest_Filter != sampler->getFilter()) {
1881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                v[3] |= kFilterBit;
1891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
1901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
1911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
1921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (scratch) {
1941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        v[3] |= kScratchBit;
1951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
1961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    v[3] |= kTextureBit;
1981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return v[3] & kNPOTBit;
2001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
2011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// we should never have more than one stencil buffer with same combo of
2031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// (width,height,samplecount)
2041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid gen_stencil_key_values(int width, int height,
2051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                            int sampleCnt, uint32_t v[4]) {
2061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    v[0] = width;
2071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    v[1] = height;
2081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    v[2] = sampleCnt;
2091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    v[3] = kStencilBufferBit;
2101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
2111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid gen_stencil_key_values(const GrStencilBuffer* sb,
2131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                            uint32_t v[4]) {
2141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    gen_stencil_key_values(sb->width(), sb->height(),
2151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                           sb->numSamples(), v);
2161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
2171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// This should be subsumed by a future version of GrDrawState
2191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// It does not reset stage textures/samplers or per-vertex-edge-aa state since
2201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// they aren't used unless the vertex layout references them.
2211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// It also doesn't set the render target.
2221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid reset_draw_state(GrDrawState* drawState){
2231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        drawState->setViewMatrix(GrMatrix::I());
2251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        drawState->setColorFilter(0, SkXfermode::kDst_Mode);
2261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        drawState->resetStateFlags();
2271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        drawState->setEdgeAAData(NULL, 0);
2281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        drawState->disableStencil();
2291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        drawState->setAlpha(0xFF);
2301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        drawState->setBlendFunc(kOne_BlendCoeff,
2311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                           kZero_BlendCoeff);
2321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        drawState->setFirstCoverageStage(GrDrawState::kNumStages);
2331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        drawState->setDrawFace(GrDrawState::kBoth_DrawFace);
2341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
2351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
2361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2371cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerGrContext::TextureCacheEntry GrContext::findAndLockTexture(
2381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        TextureKey key,
2391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        int width,
2401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        int height,
2411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        const GrSamplerState* sampler) {
2421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    uint32_t v[4];
2431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    gen_texture_key_values(fGpu, sampler, key, width, height, false, v);
2441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrResourceKey resourceKey(v);
2451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return TextureCacheEntry(fTextureCache->findAndLock(resourceKey,
2461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                            GrResourceCache::kNested_LockType));
2471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
2481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool GrContext::isTextureInCache(TextureKey key,
2501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                 int width,
2511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                 int height,
2521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                 const GrSamplerState* sampler) const {
2531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    uint32_t v[4];
2541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    gen_texture_key_values(fGpu, sampler, key, width, height, false, v);
2551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrResourceKey resourceKey(v);
2561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return fTextureCache->hasKey(resourceKey);
2571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
2581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2591cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerGrResourceEntry* GrContext::addAndLockStencilBuffer(GrStencilBuffer* sb) {
2601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    ASSERT_OWNED_RESOURCE(sb);
2611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    uint32_t v[4];
2621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    gen_stencil_key_values(sb, v);
2631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrResourceKey resourceKey(v);
2641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return fTextureCache->createAndLock(resourceKey, sb);
2651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
2661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2671cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerGrStencilBuffer* GrContext::findStencilBuffer(int width, int height,
2681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                              int sampleCnt) {
2691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    uint32_t v[4];
2701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    gen_stencil_key_values(width, height, sampleCnt, v);
2711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrResourceKey resourceKey(v);
2721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrResourceEntry* entry = fTextureCache->findAndLock(resourceKey,
2731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                            GrResourceCache::kSingle_LockType);
2741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (NULL != entry) {
2751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrStencilBuffer* sb = (GrStencilBuffer*) entry->resource();
2761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return sb;
2771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else {
2781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return NULL;
2791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
2801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
2811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::unlockStencilBuffer(GrResourceEntry* sbEntry) {
2831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    ASSERT_OWNED_RESOURCE(sbEntry->resource());
2841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fTextureCache->unlock(sbEntry);
2851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
2861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void stretchImage(void* dst,
2881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                         int dstW,
2891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                         int dstH,
2901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                         void* src,
2911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                         int srcW,
2921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                         int srcH,
2931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                         int bpp) {
2941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrFixed dx = (srcW << 16) / dstW;
2951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrFixed dy = (srcH << 16) / dstH;
2961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrFixed y = dy >> 1;
2981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int dstXLimit = dstW*bpp;
3001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    for (int j = 0; j < dstH; ++j) {
3011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrFixed x = dx >> 1;
3021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        void* srcRow = (uint8_t*)src + (y>>16)*srcW*bpp;
3031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        void* dstRow = (uint8_t*)dst + j*dstW*bpp;
3041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        for (int i = 0; i < dstXLimit; i += bpp) {
3051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            memcpy((uint8_t*) dstRow + i,
3061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                   (uint8_t*) srcRow + (x>>16)*bpp,
3071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                   bpp);
3081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            x += dx;
3091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
3101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        y += dy;
3111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
3121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
3131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3141cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerGrContext::TextureCacheEntry GrContext::createAndLockTexture(
3151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        TextureKey key,
3161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        const GrSamplerState* sampler,
3171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        const GrTextureDesc& desc,
3181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        void* srcData,
3191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        size_t rowBytes) {
3201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SK_TRACE_EVENT0("GrContext::createAndLockTexture");
3211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if GR_DUMP_TEXTURE_UPLOAD
3231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrPrintf("GrContext::createAndLockTexture [%d %d]\n", desc.fWidth, desc.fHeight);
3241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif
3251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    TextureCacheEntry entry;
3271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    uint32_t v[4];
3281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bool special = gen_texture_key_values(fGpu, sampler, key,
3291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                          desc.fWidth, desc.fHeight, false, v);
3301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrResourceKey resourceKey(v);
3311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (special) {
3331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrAssert(NULL != sampler);
3341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        TextureCacheEntry clampEntry = this->findAndLockTexture(key,
3351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                                desc.fWidth,
3361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                                desc.fHeight,
3371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                                NULL);
3381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (NULL == clampEntry.texture()) {
3401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            clampEntry = this->createAndLockTexture(key, NULL, desc,
3411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                    srcData, rowBytes);
3421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrAssert(NULL != clampEntry.texture());
3431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            if (NULL == clampEntry.texture()) {
3441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                return entry;
3451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
3461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
3471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrTextureDesc rtDesc = desc;
3481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        rtDesc.fFlags =  rtDesc.fFlags |
3491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                         kRenderTarget_GrTextureFlagBit |
3501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                         kNoStencil_GrTextureFlagBit;
3511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        rtDesc.fWidth  = GrNextPow2(GrMax(desc.fWidth, 64));
3521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        rtDesc.fHeight = GrNextPow2(GrMax(desc.fHeight, 64));
3531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrTexture* texture = fGpu->createTexture(rtDesc, NULL, 0);
3551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (NULL != texture) {
3571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrDrawTarget::AutoStateRestore asr(fGpu);
3581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrDrawState* drawState = fGpu->drawState();
3591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            reset_draw_state(drawState);
3601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            drawState->setRenderTarget(texture->asRenderTarget());
3611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            drawState->setTexture(0, clampEntry.texture());
3621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrSamplerState::Filter filter;
3641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            // if filtering is not desired then we want to ensure all
3651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            // texels in the resampled image are copies of texels from
3661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            // the original.
3671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            if (GrSamplerState::kNearest_Filter == sampler->getFilter()) {
3681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                filter = GrSamplerState::kNearest_Filter;
3691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            } else {
3701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                filter = GrSamplerState::kBilinear_Filter;
3711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
3721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            drawState->sampler(0)->reset(GrSamplerState::kClamp_WrapMode,
3731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                         filter);
3741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            static const GrVertexLayout layout =
3761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                GrDrawTarget::StageTexCoordVertexLayoutBit(0,0);
3771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrDrawTarget::AutoReleaseGeometry arg(fGpu, layout, 4, 0);
3781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            if (arg.succeeded()) {
3801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                GrPoint* verts = (GrPoint*) arg.vertices();
3811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                verts[0].setIRectFan(0, 0,
3821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                     texture->width(),
3831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                     texture->height(),
3841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                     2*sizeof(GrPoint));
3851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                verts[1].setIRectFan(0, 0, 1, 1, 2*sizeof(GrPoint));
3861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                fGpu->drawNonIndexed(kTriangleFan_PrimitiveType,
3871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                     0, 4);
3881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                entry.set(fTextureCache->createAndLock(resourceKey, texture));
3891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
3901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            texture->releaseRenderTarget();
3911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        } else {
3921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            // TODO: Our CPU stretch doesn't filter. But we create separate
3931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            // stretched textures when the sampler state is either filtered or
3941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            // not. Either implement filtered stretch blit on CPU or just create
3951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            // one when FBO case fails.
3961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
3971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            rtDesc.fFlags = kNone_GrTextureFlags;
3981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            // no longer need to clamp at min RT size.
3991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            rtDesc.fWidth  = GrNextPow2(desc.fWidth);
4001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            rtDesc.fHeight = GrNextPow2(desc.fHeight);
4011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            int bpp = GrBytesPerPixel(desc.fConfig);
4021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            SkAutoSMalloc<128*128*4> stretchedPixels(bpp *
4031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                     rtDesc.fWidth *
4041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                     rtDesc.fHeight);
4051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            stretchImage(stretchedPixels.get(), rtDesc.fWidth, rtDesc.fHeight,
4061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                         srcData, desc.fWidth, desc.fHeight, bpp);
4071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
4081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            size_t stretchedRowBytes = rtDesc.fWidth * bpp;
4091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
4101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrTexture* texture = fGpu->createTexture(rtDesc,
4111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                     stretchedPixels.get(),
4121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                     stretchedRowBytes);
4131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrAssert(NULL != texture);
4141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            entry.set(fTextureCache->createAndLock(resourceKey, texture));
4151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
4161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fTextureCache->unlock(clampEntry.cacheEntry());
4171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
4181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else {
4191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrTexture* texture = fGpu->createTexture(desc, srcData, rowBytes);
4201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (NULL != texture) {
4211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            entry.set(fTextureCache->createAndLock(resourceKey, texture));
4221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
4231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
4241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return entry;
4251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
4261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
4271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergernamespace {
4281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerinline void gen_scratch_tex_key_values(const GrGpu* gpu,
4291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                       const GrTextureDesc& desc,
4301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                       uint32_t v[4]) {
4311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // Instead of a client-provided key of the texture contents
4321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // we create a key of from the descriptor.
4331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrContext::TextureKey descKey = desc.fAALevel |
4341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                    (desc.fFlags << 8) |
4351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                    ((uint64_t) desc.fConfig << 32);
4361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // this code path isn't friendly to tiling with NPOT restricitons
4371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // We just pass ClampNoFilter()
4381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    gen_texture_key_values(gpu, NULL, descKey, desc.fWidth,
4391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                           desc.fHeight, true, v);
4401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
4411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
4421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
4431cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerGrContext::TextureCacheEntry GrContext::lockScratchTexture(
4441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                const GrTextureDesc& inDesc,
4451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                ScratchTexMatch match) {
4461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
4471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrTextureDesc desc = inDesc;
4481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (kExact_ScratchTexMatch != match) {
4491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // bin by pow2 with a reasonable min
4501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        static const int MIN_SIZE = 256;
4511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        desc.fWidth  = GrMax(MIN_SIZE, GrNextPow2(desc.fWidth));
4521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        desc.fHeight = GrMax(MIN_SIZE, GrNextPow2(desc.fHeight));
4531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
4541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
4551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    uint32_t p0 = desc.fConfig;
4561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    uint32_t p1 = (desc.fAALevel << 16) | desc.fFlags;
4571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
4581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrResourceEntry* entry;
4591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int origWidth = desc.fWidth;
4601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int origHeight = desc.fHeight;
4611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bool doubledW = false;
4621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bool doubledH = false;
4631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
4641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    do {
4651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        uint32_t v[4];
4661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        gen_scratch_tex_key_values(fGpu, desc, v);
4671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrResourceKey key(v);
4681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        entry = fTextureCache->findAndLock(key,
4691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                           GrResourceCache::kNested_LockType);
4701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // if we miss, relax the fit of the flags...
4711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // then try doubling width... then height.
4721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (NULL != entry || kExact_ScratchTexMatch == match) {
4731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            break;
4741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
4751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (!(desc.fFlags & kRenderTarget_GrTextureFlagBit)) {
4761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            desc.fFlags = desc.fFlags | kRenderTarget_GrTextureFlagBit;
4771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        } else if (desc.fFlags & kNoStencil_GrTextureFlagBit) {
4781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            desc.fFlags = desc.fFlags & ~kNoStencil_GrTextureFlagBit;
4791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        } else if (!doubledW) {
4801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            desc.fFlags = inDesc.fFlags;
4811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            desc.fWidth *= 2;
4821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            doubledW = true;
4831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        } else if (!doubledH) {
4841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            desc.fFlags = inDesc.fFlags;
4851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            desc.fWidth = origWidth;
4861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            desc.fHeight *= 2;
4871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            doubledH = true;
4881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        } else {
4891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            break;
4901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
4911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
4921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } while (true);
4931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
4941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (NULL == entry) {
4951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        desc.fFlags = inDesc.fFlags;
4961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        desc.fWidth = origWidth;
4971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        desc.fHeight = origHeight;
4981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrTexture* texture = fGpu->createTexture(desc, NULL, 0);
4991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (NULL != texture) {
5001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            uint32_t v[4];
5011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            gen_scratch_tex_key_values(fGpu, desc, v);
5021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrResourceKey key(v);
5031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            entry = fTextureCache->createAndLock(key, texture);
5041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
5051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
5061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
5071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // If the caller gives us the same desc/sampler twice we don't want
5081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // to return the same texture the second time (unless it was previously
5091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // released). So we detach the entry from the cache and reattach at release.
5101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (NULL != entry) {
5111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fTextureCache->detach(entry);
5121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
5131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return TextureCacheEntry(entry);
5141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
5151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
5161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::unlockTexture(TextureCacheEntry entry) {
5171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    ASSERT_OWNED_RESOURCE(entry.texture());
5181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // If this is a scratch texture we detached it from the cache
5191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // while it was locked (to avoid two callers simultaneously getting
5201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // the same texture).
5211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (kScratchBit & entry.cacheEntry()->key().getValue32(3)) {
5221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fTextureCache->reattachAndUnlock(entry.cacheEntry());
5231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else {
5241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fTextureCache->unlock(entry.cacheEntry());
5251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
5261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
5271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
5281cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerGrTexture* GrContext::createUncachedTexture(const GrTextureDesc& desc,
5291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                            void* srcData,
5301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                            size_t rowBytes) {
5311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return fGpu->createTexture(desc, srcData, rowBytes);
5321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
5331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
5341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::getTextureCacheLimits(int* maxTextures,
5351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                      size_t* maxTextureBytes) const {
5361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fTextureCache->getLimits(maxTextures, maxTextureBytes);
5371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
5381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
5391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::setTextureCacheLimits(int maxTextures, size_t maxTextureBytes) {
5401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fTextureCache->setLimits(maxTextures, maxTextureBytes);
5411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
5421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
5431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerint GrContext::getMaxTextureSize() const {
5441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return fGpu->getCaps().fMaxTextureSize;
5451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
5461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
5471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerint GrContext::getMaxRenderTargetSize() const {
5481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return fGpu->getCaps().fMaxRenderTargetSize;
5491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
5501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
5511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
5521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
5531cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerGrTexture* GrContext::createPlatformTexture(const GrPlatformTextureDesc& desc) {
5541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return fGpu->createPlatformTexture(desc);
5551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
5561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
5571cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerGrRenderTarget* GrContext::createPlatformRenderTarget(const GrPlatformRenderTargetDesc& desc) {
5581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return fGpu->createPlatformRenderTarget(desc);
5591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
5601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
5611cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerGrResource* GrContext::createPlatformSurface(const GrPlatformSurfaceDesc& desc) {
5621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // validate flags here so that GrGpu subclasses don't have to check
5631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (kTexture_GrPlatformSurfaceType == desc.fSurfaceType &&
5641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        0 != desc.fRenderTargetFlags) {
5651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return NULL;
5661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
5671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (desc.fSampleCnt &&
5681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        (kGrCanResolve_GrPlatformRenderTargetFlagBit & desc.fRenderTargetFlags)) {
5691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return NULL;
5701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
5711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (kTextureRenderTarget_GrPlatformSurfaceType == desc.fSurfaceType &&
5721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        desc.fSampleCnt &&
5731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        !(kGrCanResolve_GrPlatformRenderTargetFlagBit & desc.fRenderTargetFlags)) {
5741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return NULL;
5751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
5761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return fGpu->createPlatformSurface(desc);
5771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
5781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
5791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
5801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
5811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool GrContext::supportsIndex8PixelConfig(const GrSamplerState* sampler,
5821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                          int width, int height) const {
5831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    const GrDrawTarget::Caps& caps = fGpu->getCaps();
5841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (!caps.f8BitPaletteSupport) {
5851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return false;
5861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
5871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
5881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bool isPow2 = GrIsPow2(width) && GrIsPow2(height);
5891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
5901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (!isPow2) {
5911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        bool tiled = NULL != sampler &&
5921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                     (sampler->getWrapX() != GrSamplerState::kClamp_WrapMode ||
5931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                      sampler->getWrapY() != GrSamplerState::kClamp_WrapMode);
5941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (tiled && !caps.fNPOTTextureTileSupport) {
5951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            return false;
5961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
5971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
5981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return true;
5991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
6001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
6011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger////////////////////////////////////////////////////////////////////////////////
6021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
6031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerconst GrClip& GrContext::getClip() const { return fGpu->getClip(); }
6041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
6051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::setClip(const GrClip& clip) {
6061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fGpu->setClip(clip);
6071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fGpu->drawState()->enableState(GrDrawState::kClip_StateBit);
6081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
6091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
6101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::setClip(const GrIRect& rect) {
6111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrClip clip;
6121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    clip.setFromIRect(rect);
6131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fGpu->setClip(clip);
6141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
6151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
6161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger////////////////////////////////////////////////////////////////////////////////
6171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
6181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::clear(const GrIRect* rect, const GrColor color) {
6191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    this->flush();
6201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fGpu->clear(rect, color);
6211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
6221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
6231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::drawPaint(const GrPaint& paint) {
6241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // set rect to be big enough to fill the space, but not super-huge, so we
6251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // don't overflow fixed-point implementations
6261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrRect r;
6271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    r.setLTRB(0, 0,
6281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger              GrIntToScalar(getRenderTarget()->width()),
6291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger              GrIntToScalar(getRenderTarget()->height()));
6301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrMatrix inverse;
6311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkTLazy<GrPaint> tmpPaint;
6321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    const GrPaint* p = &paint;
6331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrDrawState* drawState = fGpu->drawState();
6341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrAutoMatrix am;
6351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
6361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // We attempt to map r by the inverse matrix and draw that. mapRect will
6371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // map the four corners and bound them with a new rect. This will not
6381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // produce a correct result for some perspective matrices.
6391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (!this->getMatrix().hasPerspective()) {
6401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (!drawState->getViewInverse(&inverse)) {
6411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrPrintf("Could not invert matrix");
6421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            return;
6431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
6441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        inverse.mapRect(&r);
6451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else {
6461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (paint.getActiveMaskStageMask() || paint.getActiveStageMask()) {
6471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            if (!drawState->getViewInverse(&inverse)) {
6481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                GrPrintf("Could not invert matrix");
6491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                return;
6501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
6511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            tmpPaint.set(paint);
6521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            tmpPaint.get()->preConcatActiveSamplerMatrices(inverse);
6531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            p = tmpPaint.get();
6541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
6551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        am.set(this, GrMatrix::I());
6561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
6571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // by definition this fills the entire clip, no need for AA
6581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (paint.fAntiAlias) {
6591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (!tmpPaint.isValid()) {
6601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            tmpPaint.set(paint);
6611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            p = tmpPaint.get();
6621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
6631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrAssert(p == tmpPaint.get());
6641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        tmpPaint.get()->fAntiAlias = false;
6651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
6661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    this->drawRect(*p, r);
6671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
6681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
6691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger////////////////////////////////////////////////////////////////////////////////
6701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
6711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergernamespace {
6721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerinline bool disable_coverage_aa_for_blend(GrDrawTarget* target) {
6731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return DISABLE_COVERAGE_AA_FOR_BLEND && !target->canApplyCoverage();
6741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
6751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
6761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
6771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstruct GrContext::OffscreenRecord {
6781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    enum Downsample {
6791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        k4x4SinglePass_Downsample,
6801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        kFSAA_Downsample
6811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }                              fDownsample;
6821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int                            fTileSizeX;
6831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int                            fTileSizeY;
6841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int                            fTileCountX;
6851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int                            fTileCountY;
6861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int                            fScale;
6871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrAutoScratchTexture           fOffscreen;
6881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrDrawTarget::SavedDrawState   fSavedState;
6891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrClip                         fClip;
6901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger};
6911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
6921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool GrContext::doOffscreenAA(GrDrawTarget* target,
6931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                              bool isHairLines) const {
6941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if !GR_USE_OFFSCREEN_AA
6951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return false;
6961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#else
6971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // Line primitves are always rasterized as 1 pixel wide.
6981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // Super-sampling would make them too thin but MSAA would be OK.
6991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (isHairLines &&
7001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        (!PREFER_MSAA_OFFSCREEN_AA || !fGpu->getCaps().fFSAASupport)) {
7011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return false;
7021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
7031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (target->getDrawState().getRenderTarget()->isMultisampled()) {
7041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return false;
7051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
7061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (disable_coverage_aa_for_blend(target)) {
7071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if GR_DEBUG
7081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        //GrPrintf("Turning off AA to correctly apply blend.\n");
7091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif
7101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return false;
7111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
7121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return true;
7131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif
7141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
7151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
7161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool GrContext::prepareForOffscreenAA(GrDrawTarget* target,
7171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                      bool requireStencil,
7181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                      const GrIRect& boundRect,
7191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                      GrPathRenderer* pr,
7201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                      OffscreenRecord* record) {
7211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
7221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrAssert(GR_USE_OFFSCREEN_AA);
7231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
7241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrAssert(NULL == record->fOffscreen.texture());
7251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrAssert(!boundRect.isEmpty());
7261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
7271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int boundW = boundRect.width();
7281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int boundH = boundRect.height();
7291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
7301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrTextureDesc desc;
7311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
7321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    desc.fWidth  = GrMin(fMaxOffscreenAASize, boundW);
7331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    desc.fHeight = GrMin(fMaxOffscreenAASize, boundH);
7341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
7351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (requireStencil) {
7361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        desc.fFlags = kRenderTarget_GrTextureFlagBit;
7371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else {
7381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        desc.fFlags = kRenderTarget_GrTextureFlagBit |
7391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                      kNoStencil_GrTextureFlagBit;
7401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
7411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
7421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    desc.fConfig = kRGBA_8888_PM_GrPixelConfig;
7431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
7441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (PREFER_MSAA_OFFSCREEN_AA && fGpu->getCaps().fFSAASupport) {
7451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        record->fDownsample = OffscreenRecord::kFSAA_Downsample;
7461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        record->fScale = 1;
7471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        desc.fAALevel = kMed_GrAALevel;
7481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else {
7491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        record->fDownsample = OffscreenRecord::k4x4SinglePass_Downsample;
7501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        record->fScale = OFFSCREEN_SSAA_SCALE;
7511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // both downsample paths assume this
7521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GR_STATIC_ASSERT(4 == OFFSCREEN_SSAA_SCALE);
7531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        desc.fAALevel = kNone_GrAALevel;
7541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
7551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
7561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    desc.fWidth *= record->fScale;
7571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    desc.fHeight *= record->fScale;
7581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    record->fOffscreen.set(this, desc);
7591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (NULL == record->fOffscreen.texture()) {
7601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return false;
7611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
7621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // the approximate lookup might have given us some slop space, might as well
7631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // use it when computing the tiles size.
7641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // these are scale values, will adjust after considering
7651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // the possible second offscreen.
7661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    record->fTileSizeX = record->fOffscreen.texture()->width();
7671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    record->fTileSizeY = record->fOffscreen.texture()->height();
7681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
7691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    record->fTileSizeX /= record->fScale;
7701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    record->fTileSizeY /= record->fScale;
7711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
7721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    record->fTileCountX = GrIDivRoundUp(boundW, record->fTileSizeX);
7731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    record->fTileCountY = GrIDivRoundUp(boundH, record->fTileSizeY);
7741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
7751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    record->fClip = target->getClip();
7761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
7771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    target->saveCurrentDrawState(&record->fSavedState);
7781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return true;
7791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
7801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
7811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::setupOffscreenAAPass1(GrDrawTarget* target,
7821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                      const GrIRect& boundRect,
7831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                      int tileX, int tileY,
7841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                      OffscreenRecord* record) {
7851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
7861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrRenderTarget* offRT = record->fOffscreen.texture()->asRenderTarget();
7871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrAssert(NULL != offRT);
7881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
7891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrPaint tempPaint;
7901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    tempPaint.reset();
7911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    this->setPaint(tempPaint, target);
7921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrDrawState* drawState = target->drawState();
7931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    drawState->setRenderTarget(offRT);
7941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if PREFER_MSAA_OFFSCREEN_AA
7951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    drawState->enableState(GrDrawState::kHWAntialias_StateBit);
7961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif
7971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
7981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrMatrix transM;
7991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int left = boundRect.fLeft + tileX * record->fTileSizeX;
8001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int top =  boundRect.fTop  + tileY * record->fTileSizeY;
8011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    transM.setTranslate(-left * GR_Scalar1, -top * GR_Scalar1);
8021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    drawState->viewMatrix()->postConcat(transM);
8031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrMatrix scaleM;
8041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    scaleM.setScale(record->fScale * GR_Scalar1, record->fScale * GR_Scalar1);
8051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    drawState->viewMatrix()->postConcat(scaleM);
8061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int w = (tileX == record->fTileCountX-1) ? boundRect.fRight - left :
8081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                               record->fTileSizeX;
8091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int h = (tileY == record->fTileCountY-1) ? boundRect.fBottom - top :
8101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                               record->fTileSizeY;
8111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrIRect clear = SkIRect::MakeWH(record->fScale * w,
8121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                    record->fScale * h);
8131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    target->setClip(GrClip(clear));
8141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if 0
8151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // visualize tile boundaries by setting edges of offscreen to white
8161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // and interior to tranparent. black.
8171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    target->clear(&clear, 0xffffffff);
8181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static const int gOffset = 2;
8201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrIRect clear2 = SkIRect::MakeLTRB(gOffset, gOffset,
8211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                       record->fScale * w - gOffset,
8221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                       record->fScale * h - gOffset);
8231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    target->clear(&clear2, 0x0);
8241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#else
8251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    target->clear(&clear, 0x0);
8261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif
8271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
8281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::doOffscreenAAPass2(GrDrawTarget* target,
8301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                 const GrPaint& paint,
8311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                 const GrIRect& boundRect,
8321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                 int tileX, int tileY,
8331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                 OffscreenRecord* record) {
8341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SK_TRACE_EVENT0("GrContext::doOffscreenAAPass2");
8351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrAssert(NULL != record->fOffscreen.texture());
8361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrDrawTarget::AutoGeometryPush agp(target);
8371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrIRect tileRect;
8381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    tileRect.fLeft = boundRect.fLeft + tileX * record->fTileSizeX;
8391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    tileRect.fTop  = boundRect.fTop  + tileY * record->fTileSizeY,
8401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    tileRect.fRight = (tileX == record->fTileCountX-1) ?
8411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                        boundRect.fRight :
8421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                        tileRect.fLeft + record->fTileSizeX;
8431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    tileRect.fBottom = (tileY == record->fTileCountY-1) ?
8441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                        boundRect.fBottom :
8451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                        tileRect.fTop + record->fTileSizeY;
8461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrSamplerState::Filter filter;
8481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (OffscreenRecord::k4x4SinglePass_Downsample == record->fDownsample) {
8491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        filter = GrSamplerState::k4x4Downsample_Filter;
8501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else {
8511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        filter = GrSamplerState::kBilinear_Filter;
8521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
8531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrTexture* src = record->fOffscreen.texture();
8551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int scale;
8561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    enum {
8581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        kOffscreenStage = GrPaint::kTotalStages,
8591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    };
8601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrDrawState* drawState = target->drawState();
8621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (OffscreenRecord::kFSAA_Downsample == record->fDownsample) {
8641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        scale = 1;
8651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrIRect rect = SkIRect::MakeWH(tileRect.width(), tileRect.height());
8661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        src->asRenderTarget()->overrideResolveRect(rect);
8671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else {
8681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrAssert(OffscreenRecord::k4x4SinglePass_Downsample ==
8691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                 record->fDownsample);
8701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        scale = 4;
8711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
8721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // setup for draw back to main RT, we use the original
8741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // draw state setup by the caller plus an additional coverage
8751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // stage to handle the AA resolve. Also, we use an identity
8761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // view matrix and so pre-concat sampler matrices with view inv.
8771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int stageMask = paint.getActiveStageMask();
8781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    target->restoreDrawState(record->fSavedState);
8801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    target->setClip(record->fClip);
8811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (stageMask) {
8831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrMatrix invVM;
8841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (drawState->getViewInverse(&invVM)) {
8851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            drawState->preConcatSamplerMatrices(stageMask, invVM);
8861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
8871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
8881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // This is important when tiling, otherwise second tile's
8891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // pass 1 view matrix will be incorrect.
8901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrDrawState::AutoViewMatrixRestore avmr(drawState, GrMatrix::I());
8911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    drawState->setTexture(kOffscreenStage, src);
8931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrSamplerState* sampler = drawState->sampler(kOffscreenStage);
8941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    sampler->reset(GrSamplerState::kClamp_WrapMode, filter);
8951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    sampler->matrix()->setScale(scale * GR_Scalar1 / src->width(),
8961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                scale * GR_Scalar1 / src->height());
8971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    sampler->matrix()->preTranslate(SkIntToScalar(-tileRect.fLeft),
8981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                    SkIntToScalar(-tileRect.fTop));
8991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
9001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrRect dstRect;
9011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int stages = (1 << kOffscreenStage) | stageMask;
9021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    dstRect.set(tileRect);
9031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    target->drawSimpleRect(dstRect, NULL, stages);
9041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
9051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
9061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::cleanupOffscreenAA(GrDrawTarget* target,
9071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                   GrPathRenderer* pr,
9081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                   OffscreenRecord* record) {
9091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    target->restoreDrawState(record->fSavedState);
9101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
9111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
9121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger////////////////////////////////////////////////////////////////////////////////
9131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
9141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/*  create a triangle strip that strokes the specified triangle. There are 8
9151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger unique vertices, but we repreat the last 2 to close up. Alternatively we
9161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger could use an indices array, and then only send 8 verts, but not sure that
9171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger would be faster.
9181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */
9191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void setStrokeRectStrip(GrPoint verts[10], GrRect rect,
9201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                               GrScalar width) {
9211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    const GrScalar rad = GrScalarHalf(width);
9221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    rect.sort();
9231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
9241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    verts[0].set(rect.fLeft + rad, rect.fTop + rad);
9251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    verts[1].set(rect.fLeft - rad, rect.fTop - rad);
9261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    verts[2].set(rect.fRight - rad, rect.fTop + rad);
9271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    verts[3].set(rect.fRight + rad, rect.fTop - rad);
9281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    verts[4].set(rect.fRight - rad, rect.fBottom - rad);
9291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    verts[5].set(rect.fRight + rad, rect.fBottom + rad);
9301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    verts[6].set(rect.fLeft + rad, rect.fBottom - rad);
9311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    verts[7].set(rect.fLeft - rad, rect.fBottom + rad);
9321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    verts[8] = verts[0];
9331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    verts[9] = verts[1];
9341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
9351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
9361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void setInsetFan(GrPoint* pts, size_t stride,
9371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                        const GrRect& r, GrScalar dx, GrScalar dy) {
9381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    pts->setRectFan(r.fLeft + dx, r.fTop + dy, r.fRight - dx, r.fBottom - dy, stride);
9391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
9401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
9411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic const uint16_t gFillAARectIdx[] = {
9421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    0, 1, 5, 5, 4, 0,
9431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    1, 2, 6, 6, 5, 1,
9441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    2, 3, 7, 7, 6, 2,
9451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    3, 0, 4, 4, 7, 3,
9461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    4, 5, 6, 6, 7, 4,
9471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger};
9481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
9491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerint GrContext::aaFillRectIndexCount() const {
9501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return GR_ARRAY_COUNT(gFillAARectIdx);
9511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
9521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
9531cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerGrIndexBuffer* GrContext::aaFillRectIndexBuffer() {
9541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (NULL == fAAFillRectIndexBuffer) {
9551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fAAFillRectIndexBuffer = fGpu->createIndexBuffer(sizeof(gFillAARectIdx),
9561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                         false);
9571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (NULL != fAAFillRectIndexBuffer) {
9581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    #if GR_DEBUG
9591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            bool updated =
9601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    #endif
9611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            fAAFillRectIndexBuffer->updateData(gFillAARectIdx,
9621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                               sizeof(gFillAARectIdx));
9631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GR_DEBUGASSERT(updated);
9641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
9651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
9661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return fAAFillRectIndexBuffer;
9671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
9681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
9691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic const uint16_t gStrokeAARectIdx[] = {
9701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    0 + 0, 1 + 0, 5 + 0, 5 + 0, 4 + 0, 0 + 0,
9711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    1 + 0, 2 + 0, 6 + 0, 6 + 0, 5 + 0, 1 + 0,
9721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    2 + 0, 3 + 0, 7 + 0, 7 + 0, 6 + 0, 2 + 0,
9731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    3 + 0, 0 + 0, 4 + 0, 4 + 0, 7 + 0, 3 + 0,
9741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
9751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    0 + 4, 1 + 4, 5 + 4, 5 + 4, 4 + 4, 0 + 4,
9761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    1 + 4, 2 + 4, 6 + 4, 6 + 4, 5 + 4, 1 + 4,
9771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    2 + 4, 3 + 4, 7 + 4, 7 + 4, 6 + 4, 2 + 4,
9781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    3 + 4, 0 + 4, 4 + 4, 4 + 4, 7 + 4, 3 + 4,
9791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
9801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    0 + 8, 1 + 8, 5 + 8, 5 + 8, 4 + 8, 0 + 8,
9811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    1 + 8, 2 + 8, 6 + 8, 6 + 8, 5 + 8, 1 + 8,
9821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    2 + 8, 3 + 8, 7 + 8, 7 + 8, 6 + 8, 2 + 8,
9831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    3 + 8, 0 + 8, 4 + 8, 4 + 8, 7 + 8, 3 + 8,
9841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger};
9851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
9861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerint GrContext::aaStrokeRectIndexCount() const {
9871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return GR_ARRAY_COUNT(gStrokeAARectIdx);
9881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
9891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
9901cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerGrIndexBuffer* GrContext::aaStrokeRectIndexBuffer() {
9911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (NULL == fAAStrokeRectIndexBuffer) {
9921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fAAStrokeRectIndexBuffer = fGpu->createIndexBuffer(sizeof(gStrokeAARectIdx),
9931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                           false);
9941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (NULL != fAAStrokeRectIndexBuffer) {
9951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    #if GR_DEBUG
9961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            bool updated =
9971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    #endif
9981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            fAAStrokeRectIndexBuffer->updateData(gStrokeAARectIdx,
9991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                 sizeof(gStrokeAARectIdx));
10001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GR_DEBUGASSERT(updated);
10011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
10021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
10031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return fAAStrokeRectIndexBuffer;
10041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
10051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
10061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic GrVertexLayout aa_rect_layout(const GrDrawTarget* target,
10071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                     bool useCoverage) {
10081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrVertexLayout layout = 0;
10091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    for (int s = 0; s < GrDrawState::kNumStages; ++s) {
10101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (NULL != target->getDrawState().getTexture(s)) {
10111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            layout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(s);
10121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
10131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
10141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (useCoverage) {
10151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        layout |= GrDrawTarget::kCoverage_VertexLayoutBit;
10161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else {
10171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        layout |= GrDrawTarget::kColor_VertexLayoutBit;
10181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
10191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return layout;
10201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
10211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
10221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::fillAARect(GrDrawTarget* target,
10231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                           const GrRect& devRect,
10241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                           bool useVertexCoverage) {
10251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrVertexLayout layout = aa_rect_layout(target, useVertexCoverage);
10261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
10271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    size_t vsize = GrDrawTarget::VertexSize(layout);
10281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
10291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrDrawTarget::AutoReleaseGeometry geo(target, layout, 8, 0);
10301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (!geo.succeeded()) {
10311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrPrintf("Failed to get space for vertices!\n");
10321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return;
10331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
10341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrIndexBuffer* indexBuffer = this->aaFillRectIndexBuffer();
10351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (NULL == indexBuffer) {
10361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrPrintf("Failed to create index buffer!\n");
10371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return;
10381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
10391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
10401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    intptr_t verts = reinterpret_cast<intptr_t>(geo.vertices());
10411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
10421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrPoint* fan0Pos = reinterpret_cast<GrPoint*>(verts);
10431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrPoint* fan1Pos = reinterpret_cast<GrPoint*>(verts + 4 * vsize);
10441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
10451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    setInsetFan(fan0Pos, vsize, devRect, -GR_ScalarHalf, -GR_ScalarHalf);
10461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    setInsetFan(fan1Pos, vsize, devRect,  GR_ScalarHalf,  GR_ScalarHalf);
10471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
10481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    verts += sizeof(GrPoint);
10491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    for (int i = 0; i < 4; ++i) {
10501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        *reinterpret_cast<GrColor*>(verts + i * vsize) = 0;
10511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
10521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
10531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrColor innerColor;
10541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (useVertexCoverage) {
10551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        innerColor = 0xffffffff;
10561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else {
10571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        innerColor = target->getDrawState().getColor();
10581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
10591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
10601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    verts += 4 * vsize;
10611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    for (int i = 0; i < 4; ++i) {
10621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        *reinterpret_cast<GrColor*>(verts + i * vsize) = innerColor;
10631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
10641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
10651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    target->setIndexSourceToBuffer(indexBuffer);
10661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
10671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    target->drawIndexed(kTriangles_PrimitiveType, 0,
10681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                         0, 8, this->aaFillRectIndexCount());
10691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
10701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
10711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::strokeAARect(GrDrawTarget* target,
10721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                             const GrRect& devRect,
10731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                             const GrVec& devStrokeSize,
10741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                             bool useVertexCoverage) {
10751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    const GrScalar& dx = devStrokeSize.fX;
10761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    const GrScalar& dy = devStrokeSize.fY;
10771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    const GrScalar rx = GrMul(dx, GR_ScalarHalf);
10781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    const GrScalar ry = GrMul(dy, GR_ScalarHalf);
10791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
10801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrScalar spare;
10811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    {
10821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrScalar w = devRect.width() - dx;
10831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrScalar h = devRect.height() - dy;
10841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        spare = GrMin(w, h);
10851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
10861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
10871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (spare <= 0) {
10881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrRect r(devRect);
10891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        r.inset(-rx, -ry);
10901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fillAARect(target, r, useVertexCoverage);
10911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return;
10921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
10931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrVertexLayout layout = aa_rect_layout(target, useVertexCoverage);
10941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    size_t vsize = GrDrawTarget::VertexSize(layout);
10951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
10961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrDrawTarget::AutoReleaseGeometry geo(target, layout, 16, 0);
10971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (!geo.succeeded()) {
10981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrPrintf("Failed to get space for vertices!\n");
10991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return;
11001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
11011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrIndexBuffer* indexBuffer = this->aaStrokeRectIndexBuffer();
11021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (NULL == indexBuffer) {
11031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrPrintf("Failed to create index buffer!\n");
11041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return;
11051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
11061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
11071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    intptr_t verts = reinterpret_cast<intptr_t>(geo.vertices());
11081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
11091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrPoint* fan0Pos = reinterpret_cast<GrPoint*>(verts);
11101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrPoint* fan1Pos = reinterpret_cast<GrPoint*>(verts + 4 * vsize);
11111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrPoint* fan2Pos = reinterpret_cast<GrPoint*>(verts + 8 * vsize);
11121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrPoint* fan3Pos = reinterpret_cast<GrPoint*>(verts + 12 * vsize);
11131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
11141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    setInsetFan(fan0Pos, vsize, devRect, -rx - GR_ScalarHalf, -ry - GR_ScalarHalf);
11151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    setInsetFan(fan1Pos, vsize, devRect, -rx + GR_ScalarHalf, -ry + GR_ScalarHalf);
11161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    setInsetFan(fan2Pos, vsize, devRect,  rx - GR_ScalarHalf,  ry - GR_ScalarHalf);
11171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    setInsetFan(fan3Pos, vsize, devRect,  rx + GR_ScalarHalf,  ry + GR_ScalarHalf);
11181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
11191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    verts += sizeof(GrPoint);
11201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    for (int i = 0; i < 4; ++i) {
11211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        *reinterpret_cast<GrColor*>(verts + i * vsize) = 0;
11221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
11231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
11241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrColor innerColor;
11251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (useVertexCoverage) {
11261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        innerColor = 0xffffffff;
11271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else {
11281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        innerColor = target->getDrawState().getColor();
11291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
11301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    verts += 4 * vsize;
11311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    for (int i = 0; i < 8; ++i) {
11321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        *reinterpret_cast<GrColor*>(verts + i * vsize) = innerColor;
11331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
11341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
11351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    verts += 8 * vsize;
11361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    for (int i = 0; i < 8; ++i) {
11371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        *reinterpret_cast<GrColor*>(verts + i * vsize) = 0;
11381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
11391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
11401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    target->setIndexSourceToBuffer(indexBuffer);
11411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    target->drawIndexed(kTriangles_PrimitiveType,
11421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                        0, 0, 16, aaStrokeRectIndexCount());
11431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
11441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
11451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/**
11461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Returns true if the rects edges are integer-aligned.
11471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */
11481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic bool isIRect(const GrRect& r) {
11491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return GrScalarIsInt(r.fLeft) && GrScalarIsInt(r.fTop) &&
11501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger           GrScalarIsInt(r.fRight) && GrScalarIsInt(r.fBottom);
11511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
11521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
11531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic bool apply_aa_to_rect(GrDrawTarget* target,
11541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                             const GrRect& rect,
11551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                             GrScalar width,
11561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                             const GrMatrix* matrix,
11571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                             GrMatrix* combinedMatrix,
11581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                             GrRect* devRect,
11591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                             bool* useVertexCoverage) {
11601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // we use a simple alpha ramp to do aa on axis-aligned rects
11611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // do AA with alpha ramp if the caller requested AA, the rect
11621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // will be axis-aligned, and the rect won't land on integer coords.
11631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
11641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // we are keeping around the "tweak the alpha" trick because
11651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // it is our only hope for the fixed-pipe implementation.
11661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // In a shader implementation we can give a separate coverage input
11671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // TODO: remove this ugliness when we drop the fixed-pipe impl
11681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    *useVertexCoverage = false;
11691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (!target->canTweakAlphaForCoverage()) {
11701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (target->getCaps().fSupportPerVertexCoverage) {
11711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            if (disable_coverage_aa_for_blend(target)) {
11721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if GR_DEBUG
11731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                //GrPrintf("Turning off AA to correctly apply blend.\n");
11741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif
11751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                return false;
11761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            } else {
11771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                *useVertexCoverage = true;
11781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
11791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        } else {
11801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrPrintf("Rect AA dropped because no support for coverage.\n");
11811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            return false;
11821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
11831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
11841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    const GrDrawState& drawState = target->getDrawState();
11851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (drawState.getRenderTarget()->isMultisampled()) {
11861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return false;
11871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
11881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
11891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (0 == width && target->willUseHWAALines()) {
11901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return false;
11911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
11921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
11931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (!drawState.getViewMatrix().preservesAxisAlignment()) {
11941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return false;
11951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
11961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
11971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (NULL != matrix &&
11981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        !matrix->preservesAxisAlignment()) {
11991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return false;
12001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
12011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
12021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    *combinedMatrix = drawState.getViewMatrix();
12031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (NULL != matrix) {
12041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        combinedMatrix->preConcat(*matrix);
12051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrAssert(combinedMatrix->preservesAxisAlignment());
12061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
12071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
12081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    combinedMatrix->mapRect(devRect, rect);
12091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    devRect->sort();
12101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
12111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (width < 0) {
12121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return !isIRect(*devRect);
12131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else {
12141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return true;
12151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
12161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
12171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
12181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::drawRect(const GrPaint& paint,
12191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                         const GrRect& rect,
12201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                         GrScalar width,
12211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                         const GrMatrix* matrix) {
12221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SK_TRACE_EVENT0("GrContext::drawRect");
12231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
12241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);
12251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int stageMask = paint.getActiveStageMask();
12261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
12271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrRect devRect = rect;
12281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrMatrix combinedMatrix;
12291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bool useVertexCoverage;
12301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bool needAA = paint.fAntiAlias &&
12311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                  !this->getRenderTarget()->isMultisampled();
12321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bool doAA = needAA && apply_aa_to_rect(target, rect, width, matrix,
12331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                           &combinedMatrix, &devRect,
12341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                           &useVertexCoverage);
12351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
12361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (doAA) {
12371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrDrawTarget::AutoDeviceCoordDraw adcd(target, stageMask);
12381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (width >= 0) {
12391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrVec strokeSize;;
12401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            if (width > 0) {
12411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                strokeSize.set(width, width);
12421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                combinedMatrix.mapVectors(&strokeSize, 1);
12431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                strokeSize.setAbs(strokeSize);
12441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            } else {
12451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                strokeSize.set(GR_Scalar1, GR_Scalar1);
12461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
12471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            strokeAARect(target, devRect, strokeSize, useVertexCoverage);
12481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        } else {
12491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            fillAARect(target, devRect, useVertexCoverage);
12501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
12511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return;
12521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
12531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
12541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (width >= 0) {
12551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // TODO: consider making static vertex buffers for these cases.
12561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // Hairline could be done by just adding closing vertex to
12571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // unitSquareVertexBuffer()
12581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrVertexLayout layout =  PaintStageVertexLayoutBits(paint, NULL);
12591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
12601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        static const int worstCaseVertCount = 10;
12611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrDrawTarget::AutoReleaseGeometry geo(target, layout, worstCaseVertCount, 0);
12621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
12631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (!geo.succeeded()) {
12641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrPrintf("Failed to get space for vertices!\n");
12651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            return;
12661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
12671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
12681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrPrimitiveType primType;
12691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        int vertCount;
12701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrPoint* vertex = geo.positions();
12711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
12721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (width > 0) {
12731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            vertCount = 10;
12741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            primType = kTriangleStrip_PrimitiveType;
12751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            setStrokeRectStrip(vertex, rect, width);
12761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        } else {
12771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            // hairline
12781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            vertCount = 5;
12791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            primType = kLineStrip_PrimitiveType;
12801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            vertex[0].set(rect.fLeft, rect.fTop);
12811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            vertex[1].set(rect.fRight, rect.fTop);
12821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            vertex[2].set(rect.fRight, rect.fBottom);
12831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            vertex[3].set(rect.fLeft, rect.fBottom);
12841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            vertex[4].set(rect.fLeft, rect.fTop);
12851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
12861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
12871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrDrawState::AutoViewMatrixRestore avmr;
12881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (NULL != matrix) {
12891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrDrawState* drawState = target->drawState();
12901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            avmr.set(drawState);
12911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            drawState->preConcatViewMatrix(*matrix);
12921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            drawState->preConcatSamplerMatrices(stageMask, *matrix);
12931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
12941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
12951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        target->drawNonIndexed(primType, 0, vertCount);
12961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else {
12971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if GR_STATIC_RECT_VB
12981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrVertexLayout layout = PaintStageVertexLayoutBits(paint, NULL);
12991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            const GrVertexBuffer* sqVB = fGpu->getUnitSquareVertexBuffer();
13001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            if (NULL == sqVB) {
13011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                GrPrintf("Failed to create static rect vb.\n");
13021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                return;
13031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
13041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            target->setVertexSourceToBuffer(layout, sqVB);
13051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrDrawState* drawState = target->drawState();
13061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrDrawState::AutoViewMatrixRestore avmr(drawState);
13071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrMatrix m;
13081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            m.setAll(rect.width(),    0,             rect.fLeft,
13091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                        0,            rect.height(), rect.fTop,
13101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                        0,            0,             GrMatrix::I()[8]);
13111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
13121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            if (NULL != matrix) {
13131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                m.postConcat(*matrix);
13141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
13151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            drawState->preConcatViewMatrix(m);
13161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            drawState->preConcatSamplerMatrices(stageMask, m);
13171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
13181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            target->drawNonIndexed(kTriangleFan_PrimitiveType, 0, 4);
13191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#else
13201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            target->drawSimpleRect(rect, matrix, stageMask);
13211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif
13221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
13231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
13241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
13251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::drawRectToRect(const GrPaint& paint,
13261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                               const GrRect& dstRect,
13271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                               const GrRect& srcRect,
13281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                               const GrMatrix* dstMatrix,
13291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                               const GrMatrix* srcMatrix) {
13301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SK_TRACE_EVENT0("GrContext::drawRectToRect");
13311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
13321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // srcRect refers to paint's first texture
13331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (NULL == paint.getTexture(0)) {
13341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        drawRect(paint, dstRect, -1, dstMatrix);
13351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return;
13361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
13371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
13381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GR_STATIC_ASSERT(!BATCH_RECT_TO_RECT || !GR_STATIC_RECT_VB);
13391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
13401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if GR_STATIC_RECT_VB
13411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);
13421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrDrawState* drawState = target->drawState();
13431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrVertexLayout layout = PaintStageVertexLayoutBits(paint, NULL);
13441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrDrawState::AutoViewMatrixRestore avmr(drawState);
13451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
13461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrMatrix m;
13471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
13481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    m.setAll(dstRect.width(), 0,                dstRect.fLeft,
13491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger             0,               dstRect.height(), dstRect.fTop,
13501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger             0,               0,                GrMatrix::I()[8]);
13511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (NULL != dstMatrix) {
13521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        m.postConcat(*dstMatrix);
13531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
13541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    drawState->preConcatViewMatrix(m);
13551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
13561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // srcRect refers to first stage
13571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int otherStageMask = paint.getActiveStageMask() &
13581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                         (~(1 << GrPaint::kFirstTextureStage));
13591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (otherStageMask) {
13601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        drawState->preConcatSamplerMatrices(otherStageMask, m);
13611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
13621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
13631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    m.setAll(srcRect.width(), 0,                srcRect.fLeft,
13641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger             0,               srcRect.height(), srcRect.fTop,
13651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger             0,               0,                GrMatrix::I()[8]);
13661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (NULL != srcMatrix) {
13671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        m.postConcat(*srcMatrix);
13681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
13691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    drawState->sampler(GrPaint::kFirstTextureStage)->preConcatMatrix(m);
13701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
13711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    const GrVertexBuffer* sqVB = fGpu->getUnitSquareVertexBuffer();
13721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (NULL == sqVB) {
13731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrPrintf("Failed to create static rect vb.\n");
13741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return;
13751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
13761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    target->setVertexSourceToBuffer(layout, sqVB);
13771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    target->drawNonIndexed(kTriangleFan_PrimitiveType, 0, 4);
13781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#else
13791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
13801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrDrawTarget* target;
13811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if BATCH_RECT_TO_RECT
13821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    target = this->prepareToDraw(paint, kBuffered_DrawCategory);
13831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#else
13841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);
13851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif
13861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
13871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    const GrRect* srcRects[GrDrawState::kNumStages] = {NULL};
13881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    const GrMatrix* srcMatrices[GrDrawState::kNumStages] = {NULL};
13891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    srcRects[0] = &srcRect;
13901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    srcMatrices[0] = srcMatrix;
13911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
13921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    target->drawRect(dstRect, dstMatrix, 1, srcRects, srcMatrices);
13931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif
13941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
13951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
13961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::drawVertices(const GrPaint& paint,
13971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                             GrPrimitiveType primitiveType,
13981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                             int vertexCount,
13991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                             const GrPoint positions[],
14001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                             const GrPoint texCoords[],
14011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                             const GrColor colors[],
14021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                             const uint16_t indices[],
14031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                             int indexCount) {
14041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SK_TRACE_EVENT0("GrContext::drawVertices");
14051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
14061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrDrawTarget::AutoReleaseGeometry geo;
14071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
14081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);
14091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
14101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bool hasTexCoords[GrPaint::kTotalStages] = {
14111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        NULL != texCoords,   // texCoordSrc provides explicit stage 0 coords
14121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        0                    // remaining stages use positions
14131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    };
14141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
14151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrVertexLayout layout = PaintStageVertexLayoutBits(paint, hasTexCoords);
14161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
14171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (NULL != colors) {
14181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        layout |= GrDrawTarget::kColor_VertexLayoutBit;
14191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
14201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int vertexSize = GrDrawTarget::VertexSize(layout);
14211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
14221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (sizeof(GrPoint) != vertexSize) {
14231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (!geo.set(target, layout, vertexCount, 0)) {
14241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrPrintf("Failed to get space for vertices!\n");
14251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            return;
14261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
14271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        int texOffsets[GrDrawState::kMaxTexCoords];
14281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        int colorOffset;
14291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrDrawTarget::VertexSizeAndOffsetsByIdx(layout,
14301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                texOffsets,
14311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                &colorOffset,
14321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                NULL,
14331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                NULL);
14341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        void* curVertex = geo.vertices();
14351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
14361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        for (int i = 0; i < vertexCount; ++i) {
14371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            *((GrPoint*)curVertex) = positions[i];
14381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
14391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            if (texOffsets[0] > 0) {
14401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                *(GrPoint*)((intptr_t)curVertex + texOffsets[0]) = texCoords[i];
14411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
14421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            if (colorOffset > 0) {
14431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                *(GrColor*)((intptr_t)curVertex + colorOffset) = colors[i];
14441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
14451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            curVertex = (void*)((intptr_t)curVertex + vertexSize);
14461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
14471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else {
14481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        target->setVertexSourceToArray(layout, positions, vertexCount);
14491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
14501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
14511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // we don't currently apply offscreen AA to this path. Need improved
14521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // management of GrDrawTarget's geometry to avoid copying points per-tile.
14531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
14541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (NULL != indices) {
14551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        target->setIndexSourceToArray(indices, indexCount);
14561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        target->drawIndexed(primitiveType, 0, 0, vertexCount, indexCount);
14571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else {
14581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        target->drawNonIndexed(primitiveType, 0, vertexCount);
14591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
14601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
14611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
14621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
14631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
14641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::drawPath(const GrPaint& paint, const GrPath& path,
14651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                         GrPathFill fill, const GrPoint* translate) {
14661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
14671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (path.isEmpty()) {
14681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger       if (GrIsFillInverted(fill)) {
14691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger           this->drawPaint(paint);
14701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger       }
14711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger       return;
14721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
14731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
14741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);
14751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
14761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bool prAA = paint.fAntiAlias && !this->getRenderTarget()->isMultisampled();
14771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
14781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // An Assumption here is that path renderer would use some form of tweaking
14791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // the src color (either the input alpha or in the frag shader) to implement
14801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // aa. If we have some future driver-mojo path AA that can do the right
14811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // thing WRT to the blend then we'll need some query on the PR.
14821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (disable_coverage_aa_for_blend(target)) {
14831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if GR_DEBUG
14841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        //GrPrintf("Turning off AA to correctly apply blend.\n");
14851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif
14861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        prAA = false;
14871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
14881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
14891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bool doOSAA = false;
14901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrPathRenderer* pr = NULL;
14911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (prAA) {
14921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        pr = this->getPathRenderer(path, fill, true);
14931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (NULL == pr) {
14941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            prAA = false;
14951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            doOSAA = this->doOffscreenAA(target, kHairLine_PathFill == fill);
14961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            pr = this->getPathRenderer(path, fill, false);
14971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
14981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else {
14991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        pr = this->getPathRenderer(path, fill, false);
15001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
15011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
15021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (NULL == pr) {
15031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if GR_DEBUG
15041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrPrintf("Unable to find path renderer compatible with path.\n");
15051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif
15061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return;
15071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
15081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
15091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrPathRenderer::AutoClearPath arp(pr, target, &path, fill, prAA, translate);
15101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrDrawState::StageMask stageMask = paint.getActiveStageMask();
15111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
15121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (doOSAA) {
15131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        bool needsStencil = pr->requiresStencilPass(target, path, fill);
15141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        const GrRenderTarget* rt = target->getDrawState().getRenderTarget();
15151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // compute bounds as intersection of rt size, clip, and path
15161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrIRect bound = SkIRect::MakeWH(rt->width(), rt->height());
15171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrIRect clipIBounds;
15181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (target->getClip().hasConservativeBounds()) {
15191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            target->getClip().getConservativeBounds().roundOut(&clipIBounds);
15201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            if (!bound.intersect(clipIBounds)) {
15211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                return;
15221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
15231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
15241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrRect pathBounds = path.getBounds();
15251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (!pathBounds.isEmpty()) {
15261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            if (NULL != translate) {
15271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                pathBounds.offset(*translate);
15281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
15291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            target->getDrawState().getViewMatrix().mapRect(&pathBounds,
15301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                           pathBounds);
15311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrIRect pathIBounds;
15321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            pathBounds.roundOut(&pathIBounds);
15331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            if (!bound.intersect(pathIBounds)) {
15341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                return;
15351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
15361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
15371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        OffscreenRecord record;
15381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (this->prepareForOffscreenAA(target, needsStencil, bound,
15391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                        pr, &record)) {
15401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            for (int tx = 0; tx < record.fTileCountX; ++tx) {
15411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                for (int ty = 0; ty < record.fTileCountY; ++ty) {
15421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    this->setupOffscreenAAPass1(target, bound, tx, ty, &record);
15431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    pr->drawPath(0);
15441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    this->doOffscreenAAPass2(target, paint, bound, tx, ty, &record);
15451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                }
15461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
15471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            this->cleanupOffscreenAA(target, pr, &record);
15481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            if (GrIsFillInverted(fill) && bound != clipIBounds) {
15491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                GrDrawTarget::AutoDeviceCoordDraw adcd(target, stageMask);
15501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                GrRect rect;
15511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                if (clipIBounds.fTop < bound.fTop) {
15521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    rect.iset(clipIBounds.fLeft, clipIBounds.fTop,
15531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                              clipIBounds.fRight, bound.fTop);
15541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    target->drawSimpleRect(rect, NULL, stageMask);
15551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                }
15561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                if (clipIBounds.fLeft < bound.fLeft) {
15571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    rect.iset(clipIBounds.fLeft, bound.fTop,
15581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                              bound.fLeft, bound.fBottom);
15591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    target->drawSimpleRect(rect, NULL, stageMask);
15601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                }
15611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                if (clipIBounds.fRight > bound.fRight) {
15621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    rect.iset(bound.fRight, bound.fTop,
15631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                              clipIBounds.fRight, bound.fBottom);
15641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    target->drawSimpleRect(rect, NULL, stageMask);
15651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                }
15661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                if (clipIBounds.fBottom > bound.fBottom) {
15671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    rect.iset(clipIBounds.fLeft, bound.fBottom,
15681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                              clipIBounds.fRight, clipIBounds.fBottom);
15691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    target->drawSimpleRect(rect, NULL, stageMask);
15701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                }
15711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            }
15721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            return;
15731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
15741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
15751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    pr->drawPath(stageMask);
15761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
15771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
15781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger////////////////////////////////////////////////////////////////////////////////
15791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
15801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::flush(int flagsBitfield) {
15811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (kDiscard_FlushBit & flagsBitfield) {
15821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fDrawBuffer->reset();
15831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else {
15841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        this->flushDrawBuffer();
15851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
15861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (kForceCurrentRenderTarget_FlushBit & flagsBitfield) {
15871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fGpu->forceRenderTargetFlush();
15881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
15891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
15901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
15911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::flushText() {
15921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (kText_DrawCategory == fLastDrawCategory) {
15931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        flushDrawBuffer();
15941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
15951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
15961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
15971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::flushDrawBuffer() {
15981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if BATCH_RECT_TO_RECT || DEFER_TEXT_RENDERING
15991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (fDrawBuffer) {
16001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fDrawBuffer->playback(fGpu);
16011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fDrawBuffer->reset();
16021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
16031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif
16041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
16051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
16061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::internalWriteTexturePixels(GrTexture* texture,
16071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                           int left, int top,
16081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                           int width, int height,
16091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                           GrPixelConfig config,
16101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                           const void* buffer,
16111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                           size_t rowBytes,
16121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                           uint32_t flags) {
16131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SK_TRACE_EVENT0("GrContext::writeTexturePixels");
16141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    ASSERT_OWNED_RESOURCE(texture);
16151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
16161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (!(kDontFlush_PixelOpsFlag & flags)) {
16171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        this->flush();
16181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
16191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // TODO: use scratch texture to perform conversion
16201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (GrPixelConfigIsUnpremultiplied(texture->config()) !=
16211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrPixelConfigIsUnpremultiplied(config)) {
16221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return;
16231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
16241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
16251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fGpu->writeTexturePixels(texture, left, top, width, height,
16261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                             config, buffer, rowBytes);
16271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
16281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
16291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool GrContext::internalReadTexturePixels(GrTexture* texture,
16301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                          int left, int top,
16311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                          int width, int height,
16321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                          GrPixelConfig config,
16331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                          void* buffer,
16341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                          size_t rowBytes,
16351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                          uint32_t flags) {
16361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SK_TRACE_EVENT0("GrContext::readTexturePixels");
16371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    ASSERT_OWNED_RESOURCE(texture);
16381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
16391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // TODO: code read pixels for textures that aren't also rendertargets
16401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrRenderTarget* target = texture->asRenderTarget();
16411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (NULL != target) {
16421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return this->internalReadRenderTargetPixels(target,
16431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                    left, top, width, height,
16441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                    config, buffer, rowBytes,
16451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                    flags);
16461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else {
16471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return false;
16481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
16491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
16501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
16511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool GrContext::internalReadRenderTargetPixels(GrRenderTarget* target,
16521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                               int left, int top,
16531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                               int width, int height,
16541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                               GrPixelConfig config,
16551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                               void* buffer,
16561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                               size_t rowBytes,
16571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                               uint32_t flags) {
16581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SK_TRACE_EVENT0("GrContext::readRenderTargetPixels");
16591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    ASSERT_OWNED_RESOURCE(target);
16601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
16611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (NULL == target) {
16621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        target = fGpu->drawState()->getRenderTarget();
16631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (NULL == target) {
16641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            return false;
16651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
16661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
16671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
16681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // PM <-> UPM conversion requires a draw. Currently we only support drawing
16691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // into a UPM target, not reading from a UPM texture. Thus, UPM->PM is not
16701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // not supported at this time.
16711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (GrPixelConfigIsUnpremultiplied(target->config()) &&
16721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        !GrPixelConfigIsUnpremultiplied(config)) {
16731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return false;
16741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
16751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
16761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (!(kDontFlush_PixelOpsFlag & flags)) {
16771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        this->flush();
16781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
16791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
16801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrTexture* src = target->asTexture();
16811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bool swapRAndB = NULL != src &&
16821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                     fGpu->preferredReadPixelsConfig(config) ==
16831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                     GrPixelConfigSwapRAndB(config);
16841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
16851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bool flipY = NULL != src &&
16861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                 fGpu->readPixelsWillPayForYFlip(target, left, top,
16871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                 width, height, config,
16881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                 rowBytes);
16891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bool alphaConversion = (!GrPixelConfigIsUnpremultiplied(target->config()) &&
16901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                             GrPixelConfigIsUnpremultiplied(config));
16911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
16921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (NULL == src && alphaConversion) {
16931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // we should fallback to cpu conversion here. This could happen when
16941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // we were given an external render target by the client that is not
16951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // also a texture (e.g. FBO 0 in GL)
16961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return false;
16971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
16981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // we draw to a scratch texture if any of these conversion are applied
16991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrAutoScratchTexture ast;
17001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (flipY || swapRAndB || alphaConversion) {
17011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrAssert(NULL != src);
17021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (swapRAndB) {
17031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            config = GrPixelConfigSwapRAndB(config);
17041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            GrAssert(kUnknown_GrPixelConfig != config);
17051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
17061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // Make the scratch a render target because we don't have a robust
17071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // readTexturePixels as of yet (it calls this function).
17081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        const GrTextureDesc desc = {
17091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            kRenderTarget_GrTextureFlagBit,
17101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            kNone_GrAALevel,
17111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            width, height,
17121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            config
17131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        };
17141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
17151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // When a full readback is faster than a partial we could always make
17161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // the scratch exactly match the passed rect. However, if we see many
17171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // different size rectangles we will trash our texture cache and pay the
17181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // cost of creating and destroying many textures. So, we only request
17191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // an exact match when the caller is reading an entire RT.
17201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        ScratchTexMatch match = kApprox_ScratchTexMatch;
17211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (0 == left &&
17221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            0 == top &&
17231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            target->width() == width &&
17241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            target->height() == height &&
17251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            fGpu->fullReadPixelsIsFasterThanPartial()) {
17261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            match = kExact_ScratchTexMatch;
17271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
17281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        ast.set(this, desc, match);
17291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrTexture* texture = ast.texture();
17301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (!texture) {
17311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            return false;
17321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
17331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        target = texture->asRenderTarget();
17341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrAssert(NULL != target);
17351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
17361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrDrawTarget::AutoStateRestore asr(fGpu);
17371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrDrawState* drawState = fGpu->drawState();
17381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        reset_draw_state(drawState);
17391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        drawState->setRenderTarget(target);
17401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
17411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrMatrix matrix;
17421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (flipY) {
17431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            matrix.setTranslate(SK_Scalar1 * left,
17441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                SK_Scalar1 * (top + height));
17451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            matrix.set(GrMatrix::kMScaleY, -GR_Scalar1);
17461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        } else {
17471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            matrix.setTranslate(SK_Scalar1 *left, SK_Scalar1 *top);
17481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
17491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        matrix.postIDiv(src->width(), src->height());
17501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        drawState->sampler(0)->reset(matrix);
17511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        drawState->sampler(0)->setRAndBSwap(swapRAndB);
17521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        drawState->setTexture(0, src);
17531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrRect rect;
17541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        rect.setXYWH(0, 0, SK_Scalar1 * width, SK_Scalar1 * height);
17551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fGpu->drawSimpleRect(rect, NULL, 0x1);
17561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        left = 0;
17571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        top = 0;
17581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
17591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return fGpu->readPixels(target,
17601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                            left, top, width, height,
17611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                            config, buffer, rowBytes, flipY);
17621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
17631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
17641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::copyTexture(GrTexture* src, GrRenderTarget* dst) {
17651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (NULL == src || NULL == dst) {
17661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return;
17671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
17681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    ASSERT_OWNED_RESOURCE(src);
17691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
17701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrDrawTarget::AutoStateRestore asr(fGpu);
17711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrDrawState* drawState = fGpu->drawState();
17721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    reset_draw_state(drawState);
17731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    drawState->setRenderTarget(dst);
17741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrMatrix sampleM;
17751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    sampleM.setIDiv(src->width(), src->height());
17761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    drawState->setTexture(0, src);
17771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    drawState->sampler(0)->reset(sampleM);
17781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkRect rect = SkRect::MakeXYWH(0, 0, src->width(), src->height());
17791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fGpu->drawSimpleRect(rect, NULL, 1 << 0);
17801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
17811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
17821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::internalWriteRenderTargetPixels(GrRenderTarget* target,
17831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                int left, int top,
17841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                int width, int height,
17851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                GrPixelConfig config,
17861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                const void* buffer,
17871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                size_t rowBytes,
17881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                uint32_t flags) {
17891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SK_TRACE_EVENT0("GrContext::writeRenderTargetPixels");
17901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    ASSERT_OWNED_RESOURCE(target);
17911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
17921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (NULL == target) {
17931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        target = fGpu->drawState()->getRenderTarget();
17941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (NULL == target) {
17951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            return;
17961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
17971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
17981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
17991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // TODO: when underlying api has a direct way to do this we should use it
18001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // (e.g. glDrawPixels on desktop GL).
18011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
18021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // If the RT is also a texture and we don't have to do PM/UPM conversion
18031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // then take the texture path, which we expect to be at least as fast or
18041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // faster since it doesn't use an intermediate texture as we do below.
18051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
18061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if !GR_MAC_BUILD
18071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // At least some drivers on the Mac get confused when glTexImage2D is called
18081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // on a texture attached to an FBO. The FBO still sees the old image. TODO:
18091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // determine what OS versions and/or HW is affected.
18101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (NULL != target->asTexture() &&
18111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrPixelConfigIsUnpremultiplied(target->config()) ==
18121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrPixelConfigIsUnpremultiplied(config)) {
18131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
18141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        this->internalWriteTexturePixels(target->asTexture(),
18151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                         left, top, width, height,
18161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                         config, buffer, rowBytes, flags);
18171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return;
18181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
18191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif
18201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
18211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bool swapRAndB = fGpu->preferredReadPixelsConfig(config) ==
18221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                     GrPixelConfigSwapRAndB(config);
18231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (swapRAndB) {
18241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        config = GrPixelConfigSwapRAndB(config);
18251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
18261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
18271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    const GrTextureDesc desc = {
18281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        kNone_GrTextureFlags, kNone_GrAALevel, width, height, config
18291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    };
18301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrAutoScratchTexture ast(this, desc);
18311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrTexture* texture = ast.texture();
18321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (NULL == texture) {
18331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return;
18341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
18351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    this->internalWriteTexturePixels(texture, 0, 0, width, height,
18361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                     config, buffer, rowBytes, flags);
18371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
18381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrDrawTarget::AutoStateRestore  asr(fGpu);
18391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrDrawState* drawState = fGpu->drawState();
18401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    reset_draw_state(drawState);
18411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
18421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrMatrix matrix;
18431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    matrix.setTranslate(GrIntToScalar(left), GrIntToScalar(top));
18441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    drawState->setViewMatrix(matrix);
18451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    drawState->setRenderTarget(target);
18461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    drawState->setTexture(0, texture);
18471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
18481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    matrix.setIDiv(texture->width(), texture->height());
18491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    drawState->sampler(0)->reset(GrSamplerState::kClamp_WrapMode,
18501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                 GrSamplerState::kNearest_Filter,
18511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                 matrix);
18521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    drawState->sampler(0)->setRAndBSwap(swapRAndB);
18531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
18541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrVertexLayout layout = GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0);
18551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    static const int VCOUNT = 4;
18561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // TODO: Use GrGpu::drawRect here
18571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrDrawTarget::AutoReleaseGeometry geo(fGpu, layout, VCOUNT, 0);
18581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (!geo.succeeded()) {
18591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrPrintf("Failed to get space for vertices!\n");
18601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return;
18611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
18621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    ((GrPoint*)geo.vertices())->setIRectFan(0, 0, width, height);
18631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fGpu->drawNonIndexed(kTriangleFan_PrimitiveType, 0, VCOUNT);
18641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
18651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger////////////////////////////////////////////////////////////////////////////////
18661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
18671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::setPaint(const GrPaint& paint, GrDrawTarget* target) {
18681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrDrawState* drawState = target->drawState();
18691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
18701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    for (int i = 0; i < GrPaint::kMaxTextures; ++i) {
18711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        int s = i + GrPaint::kFirstTextureStage;
18721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        drawState->setTexture(s, paint.getTexture(i));
18731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        ASSERT_OWNED_RESOURCE(paint.getTexture(i));
18741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (paint.getTexture(i)) {
18751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            *drawState->sampler(s) = paint.getTextureSampler(i);
18761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
18771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
18781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
18791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    drawState->setFirstCoverageStage(GrPaint::kFirstMaskStage);
18801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
18811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    for (int i = 0; i < GrPaint::kMaxMasks; ++i) {
18821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        int s = i + GrPaint::kFirstMaskStage;
18831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        drawState->setTexture(s, paint.getMask(i));
18841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        ASSERT_OWNED_RESOURCE(paint.getMask(i));
18851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (paint.getMask(i)) {
18861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            *drawState->sampler(s) = paint.getMaskSampler(i);
18871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
18881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
18891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
18901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    drawState->setColor(paint.fColor);
18911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
18921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (paint.fDither) {
18931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        drawState->enableState(GrDrawState::kDither_StateBit);
18941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else {
18951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        drawState->disableState(GrDrawState::kDither_StateBit);
18961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
18971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (paint.fAntiAlias) {
18981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        drawState->enableState(GrDrawState::kHWAntialias_StateBit);
18991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else {
19001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        drawState->disableState(GrDrawState::kHWAntialias_StateBit);
19011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
19021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (paint.fColorMatrixEnabled) {
19031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        drawState->enableState(GrDrawState::kColorMatrix_StateBit);
19041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else {
19051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        drawState->disableState(GrDrawState::kColorMatrix_StateBit);
19061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
19071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    drawState->setBlendFunc(paint.fSrcBlendCoeff, paint.fDstBlendCoeff);
19081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    drawState->setColorFilter(paint.fColorFilterColor, paint.fColorFilterXfermode);
19091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    drawState->setColorMatrix(paint.fColorMatrix);
19101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
19111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (paint.getActiveMaskStageMask() && !target->canApplyCoverage()) {
19121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        GrPrintf("Partial pixel coverage will be incorrectly blended.\n");
19131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
19141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
19151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
19161cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerGrDrawTarget* GrContext::prepareToDraw(const GrPaint& paint,
19171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                       DrawCategory category) {
19181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (category != fLastDrawCategory) {
19191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        flushDrawBuffer();
19201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fLastDrawCategory = category;
19211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
19221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    this->setPaint(paint, fGpu);
19231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrDrawTarget* target = fGpu;
19241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    switch (category) {
19251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    case kText_DrawCategory:
19261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if DEFER_TEXT_RENDERING
19271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        target = fDrawBuffer;
19281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fDrawBuffer->initializeDrawStateAndClip(*fGpu);
19291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#else
19301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        target = fGpu;
19311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif
19321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        break;
19331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    case kUnbuffered_DrawCategory:
19341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        target = fGpu;
19351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        break;
19361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    case kBuffered_DrawCategory:
19371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        target = fDrawBuffer;
19381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fDrawBuffer->initializeDrawStateAndClip(*fGpu);
19391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        break;
19401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
19411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return target;
19421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
19431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
19441cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerGrPathRenderer* GrContext::getPathRenderer(const GrPath& path,
19451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                           GrPathFill fill,
19461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                           bool antiAlias) {
19471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (NULL == fPathRendererChain) {
19481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fPathRendererChain =
19491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            new GrPathRendererChain(this, GrPathRendererChain::kNone_UsageFlag);
19501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
19511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return fPathRendererChain->getPathRenderer(fGpu->getCaps(), path,
19521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                               fill, antiAlias);
19531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
19541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
19551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger////////////////////////////////////////////////////////////////////////////////
19561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
19571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::setRenderTarget(GrRenderTarget* target) {
19581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    ASSERT_OWNED_RESOURCE(target);
19591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    this->flush(false);
19601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fGpu->drawState()->setRenderTarget(target);
19611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
19621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
19631cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerGrRenderTarget* GrContext::getRenderTarget() {
19641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return fGpu->drawState()->getRenderTarget();
19651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
19661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
19671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerconst GrRenderTarget* GrContext::getRenderTarget() const {
19681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return fGpu->getDrawState().getRenderTarget();
19691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
19701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
19711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerconst GrMatrix& GrContext::getMatrix() const {
19721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return fGpu->getDrawState().getViewMatrix();
19731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
19741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
19751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::setMatrix(const GrMatrix& m) {
19761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fGpu->drawState()->setViewMatrix(m);
19771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
19781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
19791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::concatMatrix(const GrMatrix& m) const {
19801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fGpu->drawState()->preConcatViewMatrix(m);
19811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
19821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
19831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic inline intptr_t setOrClear(intptr_t bits, int shift, intptr_t pred) {
19841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    intptr_t mask = 1 << shift;
19851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (pred) {
19861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        bits |= mask;
19871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else {
19881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        bits &= ~mask;
19891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
19901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return bits;
19911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
19921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
19931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::resetStats() {
19941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fGpu->resetStats();
19951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
19961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
19971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerconst GrGpuStats& GrContext::getStats() const {
19981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return fGpu->getStats();
19991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
20001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
20011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::printStats() const {
20021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fGpu->printStats();
20031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
20041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
20051cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerGrContext::GrContext(GrGpu* gpu) {
20061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fGpu = gpu;
20071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fGpu->ref();
20081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fGpu->setContext(this);
20091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
20101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fPathRendererChain = NULL;
20111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
20121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fTextureCache = new GrResourceCache(MAX_TEXTURE_CACHE_COUNT,
20131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                        MAX_TEXTURE_CACHE_BYTES);
20141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fFontCache = new GrFontCache(fGpu);
20151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
20161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fLastDrawCategory = kUnbuffered_DrawCategory;
20171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
20181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fDrawBuffer = NULL;
20191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fDrawBufferVBAllocPool = NULL;
20201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fDrawBufferIBAllocPool = NULL;
20211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
20221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fAAFillRectIndexBuffer = NULL;
20231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fAAStrokeRectIndexBuffer = NULL;
20241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
20251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int gpuMaxOffscreen = gpu->getCaps().fMaxRenderTargetSize;
20261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (!PREFER_MSAA_OFFSCREEN_AA || !gpu->getCaps().fFSAASupport) {
20271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        gpuMaxOffscreen /= OFFSCREEN_SSAA_SCALE;
20281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
20291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fMaxOffscreenAASize = GrMin(GR_MAX_OFFSCREEN_AA_SIZE, gpuMaxOffscreen);
20301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
20311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    this->setupDrawBuffer();
20321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
20331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
20341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::setupDrawBuffer() {
20351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
20361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrAssert(NULL == fDrawBuffer);
20371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrAssert(NULL == fDrawBufferVBAllocPool);
20381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrAssert(NULL == fDrawBufferIBAllocPool);
20391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
20401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if DEFER_TEXT_RENDERING || BATCH_RECT_TO_RECT
20411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fDrawBufferVBAllocPool =
20421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        new GrVertexBufferAllocPool(fGpu, false,
20431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                    DRAW_BUFFER_VBPOOL_BUFFER_SIZE,
20441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                    DRAW_BUFFER_VBPOOL_PREALLOC_BUFFERS);
20451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fDrawBufferIBAllocPool =
20461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        new GrIndexBufferAllocPool(fGpu, false,
20471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                   DRAW_BUFFER_IBPOOL_BUFFER_SIZE,
20481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                   DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS);
20491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
20501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fDrawBuffer = new GrInOrderDrawBuffer(fGpu,
20511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                          fDrawBufferVBAllocPool,
20521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                          fDrawBufferIBAllocPool);
20531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif
20541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
20551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if BATCH_RECT_TO_RECT
20561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fDrawBuffer->setQuadIndexBuffer(this->getQuadIndexBuffer());
20571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif
20581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
20591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
20601cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerGrDrawTarget* GrContext::getTextTarget(const GrPaint& paint) {
20611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrDrawTarget* target;
20621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if DEFER_TEXT_RENDERING
20631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    target = prepareToDraw(paint, kText_DrawCategory);
20641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#else
20651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    target = prepareToDraw(paint, kUnbuffered_DrawCategory);
20661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif
20671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    this->setPaint(paint, target);
20681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return target;
20691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
20701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
20711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerconst GrIndexBuffer* GrContext::getQuadIndexBuffer() const {
20721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return fGpu->getQuadIndexBuffer();
20731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
20741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
20751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::convolveInX(GrTexture* texture,
20761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                            const SkRect& rect,
20771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                            const float* kernel,
20781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                            int kernelWidth) {
20791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    ASSERT_OWNED_RESOURCE(texture);
20801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
20811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    float imageIncrement[2] = {1.0f / texture->width(), 0.0f};
20821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    convolve(texture, rect, imageIncrement, kernel, kernelWidth);
20831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
20841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
20851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::convolveInY(GrTexture* texture,
20861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                            const SkRect& rect,
20871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                            const float* kernel,
20881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                            int kernelWidth) {
20891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    ASSERT_OWNED_RESOURCE(texture);
20901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
20911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    float imageIncrement[2] = {0.0f, 1.0f / texture->height()};
20921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    convolve(texture, rect, imageIncrement, kernel, kernelWidth);
20931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
20941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
20951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid GrContext::convolve(GrTexture* texture,
20961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                         const SkRect& rect,
20971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                         float imageIncrement[2],
20981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                         const float* kernel,
20991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                         int kernelWidth) {
21001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    ASSERT_OWNED_RESOURCE(texture);
21011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
21021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrDrawTarget::AutoStateRestore asr(fGpu);
21031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrDrawState* drawState = fGpu->drawState();
21041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GrMatrix sampleM;
21051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    sampleM.setIDiv(texture->width(), texture->height());
21061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    drawState->sampler(0)->reset(GrSamplerState::kClamp_WrapMode,
21071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                 GrSamplerState::kConvolution_Filter,
21081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                 sampleM);
21091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    drawState->sampler(0)->setConvolutionParams(kernelWidth,
21101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                kernel,
21111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                                imageIncrement);
21121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
21131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    drawState->setViewMatrix(GrMatrix::I());
21141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    drawState->setTexture(0, texture);
21151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    drawState->setAlpha(0xFF);
21161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    drawState->setBlendFunc(kOne_BlendCoeff, kZero_BlendCoeff);
21171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fGpu->drawSimpleRect(rect, NULL, 1 << 0);
21181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
21191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
21201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
2121