GrContext.cpp revision 1e266f8ff2fb2f05f44e77e046a24410ff7b4c77
127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com */
827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
9ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
101fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com#include "GrContext.h"
111fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com
12278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com#include "GrBufferAllocPool.h"
13278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com#include "GrClipIterator.h"
1405ef510389950e1ae8dcba40e41e001db771b12dbsalomon@google.com#include "GrGpu.h"
1527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#include "GrIndexBuffer.h"
1627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#include "GrInOrderDrawBuffer.h"
1727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#include "GrPathRenderer.h"
18d22b6e4351e552a8379d7781096d9e79feeae263tomhudson@google.com#include "GrPathUtils.h"
1950398bf7f1953e640e5529616e710cf540799731bsalomon@google.com#include "GrResourceCache.h"
20558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com#include "GrStencilBuffer.h"
21278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com#include "GrTextStrike.h"
228c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com#include "SkTLazy.h"
230c8d93a94099dee2dff8da6000ded9ad59676488tomhudson@google.com#include "SkTrace.h"
2427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
25919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com// Using MSAA seems to be slower for some yet unknown reason.
26919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com#define PREFER_MSAA_OFFSCREEN_AA 0
27919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com#define OFFSCREEN_SSAA_SCALE 4 // super sample at 4x4
2806afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com
2927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#define DEFER_TEXT_RENDERING 1
3027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
3127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#define BATCH_RECT_TO_RECT (1 && !GR_STATIC_RECT_VB)
3227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
33d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com// When we're using coverage AA but the blend is incompatible (given gpu
34d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com// limitations) should we disable AA or draw wrong?
35950d7a8d8def14efc98d12d6947347fde351b737bsalomon@google.com#define DISABLE_COVERAGE_AA_FOR_BLEND 1
36d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com
378ccadddfa78adbdbbdfa724247318436465a7378bsalomon@google.comstatic const size_t MAX_TEXTURE_CACHE_COUNT = 256;
388ccadddfa78adbdbbdfa724247318436465a7378bsalomon@google.comstatic const size_t MAX_TEXTURE_CACHE_BYTES = 16 * 1024 * 1024;
3927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
4027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comstatic const size_t DRAW_BUFFER_VBPOOL_BUFFER_SIZE = 1 << 18;
4127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comstatic const int DRAW_BUFFER_VBPOOL_PREALLOC_BUFFERS = 4;
4227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
4327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com// We are currently only batching Text and drawRectToRect, both
4427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com// of which use the quad index buffer.
4527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comstatic const size_t DRAW_BUFFER_IBPOOL_BUFFER_SIZE = 0;
4627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comstatic const int DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS = 0;
4727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
48bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com#define ASSERT_OWNED_RESOURCE(R) GrAssert(!(R) || (R)->getContext() == this)
49bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com
5005ef510389950e1ae8dcba40e41e001db771b12dbsalomon@google.comGrContext* GrContext::Create(GrEngine engine,
5105ef510389950e1ae8dcba40e41e001db771b12dbsalomon@google.com                             GrPlatform3DContext context3D) {
5227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    GrContext* ctx = NULL;
5327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    GrGpu* fGpu = GrGpu::Create(engine, context3D);
5427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    if (NULL != fGpu) {
5527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        ctx = new GrContext(fGpu);
5627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        fGpu->unref();
5727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    }
5827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    return ctx;
5927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
6027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
6127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comGrContext::~GrContext() {
628fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    this->flush();
6327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    delete fTextureCache;
6427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    delete fFontCache;
6527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    delete fDrawBuffer;
6627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    delete fDrawBufferVBAllocPool;
67de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com    delete fDrawBufferIBAllocPool;
683008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com
69205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    GrSafeUnref(fAAFillRectIndexBuffer);
70205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    GrSafeUnref(fAAStrokeRectIndexBuffer);
71205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    fGpu->unref();
723008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com    GrSafeUnref(fPathRendererChain);
7327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
7427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
758fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.comvoid GrContext::contextLost() {
7653a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com    contextDestroyed();
7753a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com    this->setupDrawBuffer();
7853a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com}
7953a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com
8053a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.comvoid GrContext::contextDestroyed() {
81205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    // abandon first to so destructors
82205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    // don't try to free the resources in the API.
83205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    fGpu->abandonResources();
84205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
853008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com    // a path renderer may be holding onto resources that
863008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com    // are now unusable
873008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com    GrSafeSetNull(fPathRendererChain);
883008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com
898fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    delete fDrawBuffer;
908fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    fDrawBuffer = NULL;
91205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
928fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    delete fDrawBufferVBAllocPool;
938fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    fDrawBufferVBAllocPool = NULL;
94205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
958fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    delete fDrawBufferIBAllocPool;
968fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    fDrawBufferIBAllocPool = NULL;
978fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
98205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    GrSafeSetNull(fAAFillRectIndexBuffer);
99205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    GrSafeSetNull(fAAStrokeRectIndexBuffer);
100205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
1018fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    fTextureCache->removeAll();
1028fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    fFontCache->freeAll();
1038fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    fGpu->markContextDirty();
1048fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com}
1058fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
1068fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.comvoid GrContext::resetContext() {
1078fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    fGpu->markContextDirty();
1088fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com}
1098fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
1108fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.comvoid GrContext::freeGpuResources() {
1118fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    this->flush();
1128fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    fTextureCache->removeAll();
1138fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    fFontCache->freeAll();
1143008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com    // a path renderer may be holding onto resources
1153008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com    GrSafeSetNull(fPathRendererChain);
11627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
11727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
118fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com////////////////////////////////////////////////////////////////////////////////
119fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com
12026c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.comint GrContext::PaintStageVertexLayoutBits(
12126c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com                            const GrPaint& paint,
12226c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com                            const bool hasTexCoords[GrPaint::kTotalStages]) {
12326c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com    int stageMask = paint.getActiveStageMask();
12426c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com    int layout = 0;
12526c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com    for (int i = 0; i < GrPaint::kTotalStages; ++i) {
12626c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com        if ((1 << i) & stageMask) {
12726c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com            if (NULL != hasTexCoords && hasTexCoords[i]) {
12826c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com                layout |= GrDrawTarget::StageTexCoordVertexLayoutBit(i, i);
12926c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com            } else {
13026c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com                layout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(i);
13126c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com            }
13226c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com        }
13326c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com    }
13426c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com    return layout;
13526c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com}
13626c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com
13726c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com
13826c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com////////////////////////////////////////////////////////////////////////////////
13926c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com
140fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.comenum {
141558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com    // flags for textures
142558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com    kNPOTBit            = 0x1,
143558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com    kFilterBit          = 0x2,
144558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com    kScratchBit         = 0x4,
145558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com
146558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com    // resource type
147558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com    kTextureBit         = 0x8,
148558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com    kStencilBufferBit   = 0x10
149fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com};
150fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com
15150398bf7f1953e640e5529616e710cf540799731bsalomon@google.comGrTexture* GrContext::TextureCacheEntry::texture() const {
15250398bf7f1953e640e5529616e710cf540799731bsalomon@google.com    if (NULL == fEntry) {
15350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com        return NULL;
15450398bf7f1953e640e5529616e710cf540799731bsalomon@google.com    } else {
15550398bf7f1953e640e5529616e710cf540799731bsalomon@google.com        return (GrTexture*) fEntry->resource();
15650398bf7f1953e640e5529616e710cf540799731bsalomon@google.com    }
15750398bf7f1953e640e5529616e710cf540799731bsalomon@google.com}
15850398bf7f1953e640e5529616e710cf540799731bsalomon@google.com
15950398bf7f1953e640e5529616e710cf540799731bsalomon@google.comnamespace {
16050398bf7f1953e640e5529616e710cf540799731bsalomon@google.com// returns true if this is a "special" texture because of gpu NPOT limitations
16150398bf7f1953e640e5529616e710cf540799731bsalomon@google.combool gen_texture_key_values(const GrGpu* gpu,
1621fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com                            const GrSamplerState* sampler,
16350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com                            GrContext::TextureKey clientKey,
16450398bf7f1953e640e5529616e710cf540799731bsalomon@google.com                            int width,
16550398bf7f1953e640e5529616e710cf540799731bsalomon@google.com                            int height,
16650398bf7f1953e640e5529616e710cf540799731bsalomon@google.com                            bool scratch,
16750398bf7f1953e640e5529616e710cf540799731bsalomon@google.com                            uint32_t v[4]) {
16850398bf7f1953e640e5529616e710cf540799731bsalomon@google.com    GR_STATIC_ASSERT(sizeof(GrContext::TextureKey) == sizeof(uint64_t));
16950398bf7f1953e640e5529616e710cf540799731bsalomon@google.com    // we assume we only need 16 bits of width and height
17050398bf7f1953e640e5529616e710cf540799731bsalomon@google.com    // assert that texture creation will fail anyway if this assumption
17150398bf7f1953e640e5529616e710cf540799731bsalomon@google.com    // would cause key collisions.
17218c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com    GrAssert(gpu->getCaps().fMaxTextureSize <= SK_MaxU16);
17350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com    v[0] = clientKey & 0xffffffffUL;
17450398bf7f1953e640e5529616e710cf540799731bsalomon@google.com    v[1] = (clientKey >> 32) & 0xffffffffUL;
17550398bf7f1953e640e5529616e710cf540799731bsalomon@google.com    v[2] = width | (height << 16);
17650398bf7f1953e640e5529616e710cf540799731bsalomon@google.com
17750398bf7f1953e640e5529616e710cf540799731bsalomon@google.com    v[3] = 0;
17818c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com    if (!gpu->getCaps().fNPOTTextureTileSupport) {
179fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com        bool isPow2 = GrIsPow2(width) && GrIsPow2(height);
180fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com
1811fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com        bool tiled = NULL != sampler &&
1821fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com                     ((sampler->getWrapX() != GrSamplerState::kClamp_WrapMode) ||
1831fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com                      (sampler->getWrapY() != GrSamplerState::kClamp_WrapMode));
184fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com
185fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com        if (tiled && !isPow2) {
18650398bf7f1953e640e5529616e710cf540799731bsalomon@google.com            v[3] |= kNPOTBit;
1871fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com            if (GrSamplerState::kNearest_Filter != sampler->getFilter()) {
18850398bf7f1953e640e5529616e710cf540799731bsalomon@google.com                v[3] |= kFilterBit;
189fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com            }
190fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com        }
191fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com    }
192fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com
19350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com    if (scratch) {
19450398bf7f1953e640e5529616e710cf540799731bsalomon@google.com        v[3] |= kScratchBit;
195fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com    }
19650398bf7f1953e640e5529616e710cf540799731bsalomon@google.com
197558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com    v[3] |= kTextureBit;
198558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com
19950398bf7f1953e640e5529616e710cf540799731bsalomon@google.com    return v[3] & kNPOTBit;
20050398bf7f1953e640e5529616e710cf540799731bsalomon@google.com}
201558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com
202558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com// we should never have more than one stencil buffer with same combo of
203558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com// (width,height,samplecount)
204558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.comvoid gen_stencil_key_values(int width, int height,
205558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com                            int sampleCnt, uint32_t v[4]) {
206558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com    v[0] = width;
207558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com    v[1] = height;
208558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com    v[2] = sampleCnt;
209558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com    v[3] = kStencilBufferBit;
210558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com}
211558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com
212558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.comvoid gen_stencil_key_values(const GrStencilBuffer* sb,
213558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com                            uint32_t v[4]) {
214558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com    gen_stencil_key_values(sb->width(), sb->height(),
215558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com                           sb->numSamples(), v);
216558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com}
21782c7bd8f25682fcacfeea12ed899976504a767ffbsalomon@google.com
21882c7bd8f25682fcacfeea12ed899976504a767ffbsalomon@google.com// This should be subsumed by a future version of GrDrawState
21982c7bd8f25682fcacfeea12ed899976504a767ffbsalomon@google.com// It does not reset stage textures/samplers or per-vertex-edge-aa state since
22082c7bd8f25682fcacfeea12ed899976504a767ffbsalomon@google.com// they aren't used unless the vertex layout references them.
22182c7bd8f25682fcacfeea12ed899976504a767ffbsalomon@google.com// It also doesn't set the render target.
2226b67e21b6549598254c1ffa4243bf32615d90fb6bsalomon@google.comvoid reset_draw_state(GrDrawState* drawState){
2238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
2248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        drawState->setViewMatrix(GrMatrix::I());
2258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        drawState->setColorFilter(0, SkXfermode::kDst_Mode);
2266b67e21b6549598254c1ffa4243bf32615d90fb6bsalomon@google.com        drawState->resetStateFlags();
2278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        drawState->setEdgeAAData(NULL, 0);
2288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        drawState->disableStencil();
2298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        drawState->setAlpha(0xFF);
2306b67e21b6549598254c1ffa4243bf32615d90fb6bsalomon@google.com        drawState->setBlendFunc(kOne_BlendCoeff,
2313d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com                           kZero_BlendCoeff);
2328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        drawState->setFirstCoverageStage(GrDrawState::kNumStages);
2338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        drawState->setDrawFace(GrDrawState::kBoth_DrawFace);
23482c7bd8f25682fcacfeea12ed899976504a767ffbsalomon@google.com}
235fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com}
236fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com
2371fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.comGrContext::TextureCacheEntry GrContext::findAndLockTexture(
2381fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com        TextureKey key,
2391fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com        int width,
2401fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com        int height,
2411fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com        const GrSamplerState* sampler) {
24250398bf7f1953e640e5529616e710cf540799731bsalomon@google.com    uint32_t v[4];
24350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com    gen_texture_key_values(fGpu, sampler, key, width, height, false, v);
24450398bf7f1953e640e5529616e710cf540799731bsalomon@google.com    GrResourceKey resourceKey(v);
245558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com    return TextureCacheEntry(fTextureCache->findAndLock(resourceKey,
246558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com                                            GrResourceCache::kNested_LockType));
247558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com}
248558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com
249fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.combool GrContext::isTextureInCache(TextureKey key,
250fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com                                 int width,
251fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com                                 int height,
2521fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com                                 const GrSamplerState* sampler) const {
253fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com    uint32_t v[4];
254fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com    gen_texture_key_values(fGpu, sampler, key, width, height, false, v);
255fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com    GrResourceKey resourceKey(v);
256fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com    return fTextureCache->hasKey(resourceKey);
257fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com}
258fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com
259558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.comGrResourceEntry* GrContext::addAndLockStencilBuffer(GrStencilBuffer* sb) {
260bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com    ASSERT_OWNED_RESOURCE(sb);
261558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com    uint32_t v[4];
262558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com    gen_stencil_key_values(sb, v);
263558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com    GrResourceKey resourceKey(v);
264558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com    return fTextureCache->createAndLock(resourceKey, sb);
265558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com}
266558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com
267558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.comGrStencilBuffer* GrContext::findStencilBuffer(int width, int height,
268558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com                                              int sampleCnt) {
269558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com    uint32_t v[4];
270558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com    gen_stencil_key_values(width, height, sampleCnt, v);
271558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com    GrResourceKey resourceKey(v);
272558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com    GrResourceEntry* entry = fTextureCache->findAndLock(resourceKey,
273558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com                                            GrResourceCache::kSingle_LockType);
274558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com    if (NULL != entry) {
275558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com        GrStencilBuffer* sb = (GrStencilBuffer*) entry->resource();
276558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com        return sb;
277558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com    } else {
278558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com        return NULL;
279558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com    }
280558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com}
281558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com
282558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.comvoid GrContext::unlockStencilBuffer(GrResourceEntry* sbEntry) {
283bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com    ASSERT_OWNED_RESOURCE(sbEntry->resource());
284558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com    fTextureCache->unlock(sbEntry);
28527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
28627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
28727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comstatic void stretchImage(void* dst,
28827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                         int dstW,
28927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                         int dstH,
29027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                         void* src,
29127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                         int srcW,
29227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                         int srcH,
29327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                         int bpp) {
29427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    GrFixed dx = (srcW << 16) / dstW;
29527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    GrFixed dy = (srcH << 16) / dstH;
29627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
29727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    GrFixed y = dy >> 1;
29827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
29927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    int dstXLimit = dstW*bpp;
30027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    for (int j = 0; j < dstH; ++j) {
30127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        GrFixed x = dx >> 1;
30227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        void* srcRow = (uint8_t*)src + (y>>16)*srcW*bpp;
30327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        void* dstRow = (uint8_t*)dst + j*dstW*bpp;
30427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        for (int i = 0; i < dstXLimit; i += bpp) {
30527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com            memcpy((uint8_t*) dstRow + i,
30627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                   (uint8_t*) srcRow + (x>>16)*bpp,
30727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                   bpp);
30827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com            x += dx;
30927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        }
31027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        y += dy;
31127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    }
31227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
31327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
3141fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.comGrContext::TextureCacheEntry GrContext::createAndLockTexture(
3151fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com        TextureKey key,
3161fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com        const GrSamplerState* sampler,
3171fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com        const GrTextureDesc& desc,
3181fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com        void* srcData,
3191fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com        size_t rowBytes) {
320278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com    SK_TRACE_EVENT0("GrContext::createAndLockTexture");
32127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
32227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#if GR_DUMP_TEXTURE_UPLOAD
32327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    GrPrintf("GrContext::createAndLockTexture [%d %d]\n", desc.fWidth, desc.fHeight);
32427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#endif
32527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
32650398bf7f1953e640e5529616e710cf540799731bsalomon@google.com    TextureCacheEntry entry;
32750398bf7f1953e640e5529616e710cf540799731bsalomon@google.com    uint32_t v[4];
32850398bf7f1953e640e5529616e710cf540799731bsalomon@google.com    bool special = gen_texture_key_values(fGpu, sampler, key,
32950398bf7f1953e640e5529616e710cf540799731bsalomon@google.com                                          desc.fWidth, desc.fHeight, false, v);
33050398bf7f1953e640e5529616e710cf540799731bsalomon@google.com    GrResourceKey resourceKey(v);
33150398bf7f1953e640e5529616e710cf540799731bsalomon@google.com
33227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    if (special) {
3331fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com        GrAssert(NULL != sampler);
3341fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com        TextureCacheEntry clampEntry = this->findAndLockTexture(key,
3351fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com                                                                desc.fWidth,
3361fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com                                                                desc.fHeight,
3371fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com                                                                NULL);
33827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
33950398bf7f1953e640e5529616e710cf540799731bsalomon@google.com        if (NULL == clampEntry.texture()) {
3401fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com            clampEntry = this->createAndLockTexture(key, NULL, desc,
3411fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com                                                    srcData, rowBytes);
34250398bf7f1953e640e5529616e710cf540799731bsalomon@google.com            GrAssert(NULL != clampEntry.texture());
34350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com            if (NULL == clampEntry.texture()) {
34450398bf7f1953e640e5529616e710cf540799731bsalomon@google.com                return entry;
34527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com            }
34627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        }
347fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com        GrTextureDesc rtDesc = desc;
348fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com        rtDesc.fFlags =  rtDesc.fFlags |
349fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com                         kRenderTarget_GrTextureFlagBit |
350fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com                         kNoStencil_GrTextureFlagBit;
3519962108c400dadcae913614e8a5ab781780981d8bsalomon@google.com        rtDesc.fWidth  = GrNextPow2(GrMax(desc.fWidth, 64));
3529962108c400dadcae913614e8a5ab781780981d8bsalomon@google.com        rtDesc.fHeight = GrNextPow2(GrMax(desc.fHeight, 64));
35327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
35427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        GrTexture* texture = fGpu->createTexture(rtDesc, NULL, 0);
35527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
35627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        if (NULL != texture) {
35727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com            GrDrawTarget::AutoStateRestore asr(fGpu);
3588f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            GrDrawState* drawState = fGpu->drawState();
3596b67e21b6549598254c1ffa4243bf32615d90fb6bsalomon@google.com            reset_draw_state(drawState);
3608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            drawState->setRenderTarget(texture->asRenderTarget());
3618f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            drawState->setTexture(0, clampEntry.texture());
36282c7bd8f25682fcacfeea12ed899976504a767ffbsalomon@google.com
3636aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com            GrSamplerState::Filter filter;
3646aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com            // if filtering is not desired then we want to ensure all
3656aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com            // texels in the resampled image are copies of texels from
3666aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com            // the original.
3671fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com            if (GrSamplerState::kNearest_Filter == sampler->getFilter()) {
3686aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com                filter = GrSamplerState::kNearest_Filter;
3696aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com            } else {
3706aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com                filter = GrSamplerState::kBilinear_Filter;
3716aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com            }
3721e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com            drawState->sampler(0)->reset(GrSamplerState::kClamp_WrapMode,
3731e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com                                         filter);
37427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
37527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com            static const GrVertexLayout layout =
37627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                                GrDrawTarget::StageTexCoordVertexLayoutBit(0,0);
37727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com            GrDrawTarget::AutoReleaseGeometry arg(fGpu, layout, 4, 0);
37827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
37927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com            if (arg.succeeded()) {
38027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                GrPoint* verts = (GrPoint*) arg.vertices();
38127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                verts[0].setIRectFan(0, 0,
38227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                                     texture->width(),
38327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                                     texture->height(),
38427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                                     2*sizeof(GrPoint));
38527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                verts[1].setIRectFan(0, 0, 1, 1, 2*sizeof(GrPoint));
38627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                fGpu->drawNonIndexed(kTriangleFan_PrimitiveType,
38727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                                     0, 4);
38850398bf7f1953e640e5529616e710cf540799731bsalomon@google.com                entry.set(fTextureCache->createAndLock(resourceKey, texture));
38927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com            }
3901da0746fa155cdca982ae8deb68cc64f540c92dfbsalomon@google.com            texture->releaseRenderTarget();
39127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        } else {
39227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com            // TODO: Our CPU stretch doesn't filter. But we create separate
39327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com            // stretched textures when the sampler state is either filtered or
39427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com            // not. Either implement filtered stretch blit on CPU or just create
39527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com            // one when FBO case fails.
39627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
397fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com            rtDesc.fFlags = kNone_GrTextureFlags;
39827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com            // no longer need to clamp at min RT size.
39927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com            rtDesc.fWidth  = GrNextPow2(desc.fWidth);
40027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com            rtDesc.fHeight = GrNextPow2(desc.fHeight);
40164c4fe4113424bcfab8b3e0c7049887fda5ab4ffbsalomon@google.com            int bpp = GrBytesPerPixel(desc.fConfig);
4023582bf9e3d94feac5d4cc64fdb646dd68a3e4b18bsalomon@google.com            SkAutoSMalloc<128*128*4> stretchedPixels(bpp *
40327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                                                     rtDesc.fWidth *
40427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                                                     rtDesc.fHeight);
40527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com            stretchImage(stretchedPixels.get(), rtDesc.fWidth, rtDesc.fHeight,
40627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                         srcData, desc.fWidth, desc.fHeight, bpp);
40727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
40827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com            size_t stretchedRowBytes = rtDesc.fWidth * bpp;
40927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
41027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com            GrTexture* texture = fGpu->createTexture(rtDesc,
41127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                                                     stretchedPixels.get(),
41227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                                                     stretchedRowBytes);
41327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com            GrAssert(NULL != texture);
41450398bf7f1953e640e5529616e710cf540799731bsalomon@google.com            entry.set(fTextureCache->createAndLock(resourceKey, texture));
41527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        }
41650398bf7f1953e640e5529616e710cf540799731bsalomon@google.com        fTextureCache->unlock(clampEntry.cacheEntry());
41727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
41827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    } else {
41927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        GrTexture* texture = fGpu->createTexture(desc, srcData, rowBytes);
42027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        if (NULL != texture) {
42150398bf7f1953e640e5529616e710cf540799731bsalomon@google.com            entry.set(fTextureCache->createAndLock(resourceKey, texture));
42227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        }
42327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    }
42427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    return entry;
42527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
42627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
42750398bf7f1953e640e5529616e710cf540799731bsalomon@google.comnamespace {
42850398bf7f1953e640e5529616e710cf540799731bsalomon@google.cominline void gen_scratch_tex_key_values(const GrGpu* gpu,
42950398bf7f1953e640e5529616e710cf540799731bsalomon@google.com                                       const GrTextureDesc& desc,
43050398bf7f1953e640e5529616e710cf540799731bsalomon@google.com                                       uint32_t v[4]) {
43150398bf7f1953e640e5529616e710cf540799731bsalomon@google.com    // Instead of a client-provided key of the texture contents
43250398bf7f1953e640e5529616e710cf540799731bsalomon@google.com    // we create a key of from the descriptor.
43350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com    GrContext::TextureKey descKey = desc.fAALevel |
43450398bf7f1953e640e5529616e710cf540799731bsalomon@google.com                                    (desc.fFlags << 8) |
43564c4fe4113424bcfab8b3e0c7049887fda5ab4ffbsalomon@google.com                                    ((uint64_t) desc.fConfig << 32);
43650398bf7f1953e640e5529616e710cf540799731bsalomon@google.com    // this code path isn't friendly to tiling with NPOT restricitons
43750398bf7f1953e640e5529616e710cf540799731bsalomon@google.com    // We just pass ClampNoFilter()
4381fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com    gen_texture_key_values(gpu, NULL, descKey, desc.fWidth,
4391fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com                           desc.fHeight, true, v);
44050398bf7f1953e640e5529616e710cf540799731bsalomon@google.com}
44127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
44227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
44350398bf7f1953e640e5529616e710cf540799731bsalomon@google.comGrContext::TextureCacheEntry GrContext::lockScratchTexture(
44450398bf7f1953e640e5529616e710cf540799731bsalomon@google.com                                                const GrTextureDesc& inDesc,
44550398bf7f1953e640e5529616e710cf540799731bsalomon@google.com                                                ScratchTexMatch match) {
44650398bf7f1953e640e5529616e710cf540799731bsalomon@google.com
447b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com    GrTextureDesc desc = inDesc;
44850398bf7f1953e640e5529616e710cf540799731bsalomon@google.com    if (kExact_ScratchTexMatch != match) {
44950398bf7f1953e640e5529616e710cf540799731bsalomon@google.com        // bin by pow2 with a reasonable min
45050398bf7f1953e640e5529616e710cf540799731bsalomon@google.com        static const int MIN_SIZE = 256;
45150398bf7f1953e640e5529616e710cf540799731bsalomon@google.com        desc.fWidth  = GrMax(MIN_SIZE, GrNextPow2(desc.fWidth));
45250398bf7f1953e640e5529616e710cf540799731bsalomon@google.com        desc.fHeight = GrMax(MIN_SIZE, GrNextPow2(desc.fHeight));
45350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com    }
454b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com
45564c4fe4113424bcfab8b3e0c7049887fda5ab4ffbsalomon@google.com    uint32_t p0 = desc.fConfig;
456b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com    uint32_t p1 = (desc.fAALevel << 16) | desc.fFlags;
457b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com
45850398bf7f1953e640e5529616e710cf540799731bsalomon@google.com    GrResourceEntry* entry;
459b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com    int origWidth = desc.fWidth;
460b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com    int origHeight = desc.fHeight;
461b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com    bool doubledW = false;
462b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com    bool doubledH = false;
463b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com
464b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com    do {
46550398bf7f1953e640e5529616e710cf540799731bsalomon@google.com        uint32_t v[4];
46650398bf7f1953e640e5529616e710cf540799731bsalomon@google.com        gen_scratch_tex_key_values(fGpu, desc, v);
46750398bf7f1953e640e5529616e710cf540799731bsalomon@google.com        GrResourceKey key(v);
468558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com        entry = fTextureCache->findAndLock(key,
469558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com                                           GrResourceCache::kNested_LockType);
470b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com        // if we miss, relax the fit of the flags...
471b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com        // then try doubling width... then height.
47250398bf7f1953e640e5529616e710cf540799731bsalomon@google.com        if (NULL != entry || kExact_ScratchTexMatch == match) {
473b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com            break;
474b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com        }
475b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com        if (!(desc.fFlags & kRenderTarget_GrTextureFlagBit)) {
476b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com            desc.fFlags = desc.fFlags | kRenderTarget_GrTextureFlagBit;
477b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com        } else if (desc.fFlags & kNoStencil_GrTextureFlagBit) {
478b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com            desc.fFlags = desc.fFlags & ~kNoStencil_GrTextureFlagBit;
479b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com        } else if (!doubledW) {
480b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com            desc.fFlags = inDesc.fFlags;
481b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com            desc.fWidth *= 2;
482b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com            doubledW = true;
483b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com        } else if (!doubledH) {
484b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com            desc.fFlags = inDesc.fFlags;
485b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com            desc.fWidth = origWidth;
486b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com            desc.fHeight *= 2;
487b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com            doubledH = true;
488b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com        } else {
489b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com            break;
490b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com        }
491b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com
492b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com    } while (true);
493b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com
494b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com    if (NULL == entry) {
495b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com        desc.fFlags = inDesc.fFlags;
496b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com        desc.fWidth = origWidth;
497b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com        desc.fHeight = origHeight;
498b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com        GrTexture* texture = fGpu->createTexture(desc, NULL, 0);
499b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com        if (NULL != texture) {
50050398bf7f1953e640e5529616e710cf540799731bsalomon@google.com            uint32_t v[4];
50150398bf7f1953e640e5529616e710cf540799731bsalomon@google.com            gen_scratch_tex_key_values(fGpu, desc, v);
50250398bf7f1953e640e5529616e710cf540799731bsalomon@google.com            GrResourceKey key(v);
503b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com            entry = fTextureCache->createAndLock(key, texture);
504b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com        }
505b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com    }
506b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com
507b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com    // If the caller gives us the same desc/sampler twice we don't want
508b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com    // to return the same texture the second time (unless it was previously
509b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com    // released). So we detach the entry from the cache and reattach at release.
510b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com    if (NULL != entry) {
511b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com        fTextureCache->detach(entry);
512b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com    }
51350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com    return TextureCacheEntry(entry);
514b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com}
515b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com
51650398bf7f1953e640e5529616e710cf540799731bsalomon@google.comvoid GrContext::unlockTexture(TextureCacheEntry entry) {
517bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com    ASSERT_OWNED_RESOURCE(entry.texture());
51850398bf7f1953e640e5529616e710cf540799731bsalomon@google.com    // If this is a scratch texture we detached it from the cache
51950398bf7f1953e640e5529616e710cf540799731bsalomon@google.com    // while it was locked (to avoid two callers simultaneously getting
52050398bf7f1953e640e5529616e710cf540799731bsalomon@google.com    // the same texture).
52150398bf7f1953e640e5529616e710cf540799731bsalomon@google.com    if (kScratchBit & entry.cacheEntry()->key().getValue32(3)) {
52250398bf7f1953e640e5529616e710cf540799731bsalomon@google.com        fTextureCache->reattachAndUnlock(entry.cacheEntry());
523fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com    } else {
52450398bf7f1953e640e5529616e710cf540799731bsalomon@google.com        fTextureCache->unlock(entry.cacheEntry());
525fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com    }
52627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
52727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
528fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.comGrTexture* GrContext::createUncachedTexture(const GrTextureDesc& desc,
52927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                                            void* srcData,
53027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                                            size_t rowBytes) {
53127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    return fGpu->createTexture(desc, srcData, rowBytes);
53227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
53327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
53427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::getTextureCacheLimits(int* maxTextures,
53527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                                      size_t* maxTextureBytes) const {
53627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    fTextureCache->getLimits(maxTextures, maxTextureBytes);
53727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
53827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
53927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::setTextureCacheLimits(int maxTextures, size_t maxTextureBytes) {
54027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    fTextureCache->setLimits(maxTextures, maxTextureBytes);
54127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
54227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
543919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.comint GrContext::getMaxTextureSize() const {
54418c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com    return fGpu->getCaps().fMaxTextureSize;
545919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com}
546919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com
547919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.comint GrContext::getMaxRenderTargetSize() const {
54818c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com    return fGpu->getCaps().fMaxRenderTargetSize;
54927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
55027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
55127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com///////////////////////////////////////////////////////////////////////////////
55227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
553e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.comGrTexture* GrContext::createPlatformTexture(const GrPlatformTextureDesc& desc) {
554e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com    return fGpu->createPlatformTexture(desc);
555e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com}
556e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com
557e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.comGrRenderTarget* GrContext::createPlatformRenderTarget(const GrPlatformRenderTargetDesc& desc) {
558e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com    return fGpu->createPlatformRenderTarget(desc);
559e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com}
560e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com
5615877ffd5ea71a3ea70096d5c11c843798defa690bsalomon@google.comGrResource* GrContext::createPlatformSurface(const GrPlatformSurfaceDesc& desc) {
5625877ffd5ea71a3ea70096d5c11c843798defa690bsalomon@google.com    // validate flags here so that GrGpu subclasses don't have to check
5635877ffd5ea71a3ea70096d5c11c843798defa690bsalomon@google.com    if (kTexture_GrPlatformSurfaceType == desc.fSurfaceType &&
5645877ffd5ea71a3ea70096d5c11c843798defa690bsalomon@google.com        0 != desc.fRenderTargetFlags) {
5655877ffd5ea71a3ea70096d5c11c843798defa690bsalomon@google.com        return NULL;
5665877ffd5ea71a3ea70096d5c11c843798defa690bsalomon@google.com    }
5675bfc21761e0ce41206acac4c5008fc0f24debd44bsalomon@google.com    if (desc.fSampleCnt &&
5685bfc21761e0ce41206acac4c5008fc0f24debd44bsalomon@google.com        (kGrCanResolve_GrPlatformRenderTargetFlagBit & desc.fRenderTargetFlags)) {
569973b879dfd994fdb2d5d487edc2012ee3a81f326bsalomon@google.com        return NULL;
5705bfc21761e0ce41206acac4c5008fc0f24debd44bsalomon@google.com    }
5715bfc21761e0ce41206acac4c5008fc0f24debd44bsalomon@google.com    if (kTextureRenderTarget_GrPlatformSurfaceType == desc.fSurfaceType &&
5725bfc21761e0ce41206acac4c5008fc0f24debd44bsalomon@google.com        desc.fSampleCnt &&
5735bfc21761e0ce41206acac4c5008fc0f24debd44bsalomon@google.com        !(kGrCanResolve_GrPlatformRenderTargetFlagBit & desc.fRenderTargetFlags)) {
5745bfc21761e0ce41206acac4c5008fc0f24debd44bsalomon@google.com        return NULL;
5755bfc21761e0ce41206acac4c5008fc0f24debd44bsalomon@google.com    }
5765877ffd5ea71a3ea70096d5c11c843798defa690bsalomon@google.com    return fGpu->createPlatformSurface(desc);
57727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
57827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
5795877ffd5ea71a3ea70096d5c11c843798defa690bsalomon@google.com///////////////////////////////////////////////////////////////////////////////
5805877ffd5ea71a3ea70096d5c11c843798defa690bsalomon@google.com
5811fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.combool GrContext::supportsIndex8PixelConfig(const GrSamplerState* sampler,
5821f221a70214fa1ab87b8a32dd66facf485f318eebsalomon@google.com                                          int width, int height) const {
58318c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com    const GrDrawTarget::Caps& caps = fGpu->getCaps();
58418c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com    if (!caps.f8BitPaletteSupport) {
58527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        return false;
58627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    }
58727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
58827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    bool isPow2 = GrIsPow2(width) && GrIsPow2(height);
58927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
59027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    if (!isPow2) {
5911fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com        bool tiled = NULL != sampler &&
5921fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com                     (sampler->getWrapX() != GrSamplerState::kClamp_WrapMode ||
5931fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com                      sampler->getWrapY() != GrSamplerState::kClamp_WrapMode);
59418c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com        if (tiled && !caps.fNPOTTextureTileSupport) {
59527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com            return false;
59627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        }
59727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    }
59827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    return true;
59927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
60027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
60127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com////////////////////////////////////////////////////////////////////////////////
60227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
60305ef510389950e1ae8dcba40e41e001db771b12dbsalomon@google.comconst GrClip& GrContext::getClip() const { return fGpu->getClip(); }
60405ef510389950e1ae8dcba40e41e001db771b12dbsalomon@google.com
60527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::setClip(const GrClip& clip) {
60627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    fGpu->setClip(clip);
6078f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    fGpu->drawState()->enableState(GrDrawState::kClip_StateBit);
60827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
60927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
61027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::setClip(const GrIRect& rect) {
61127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    GrClip clip;
612d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com    clip.setFromIRect(rect);
61327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    fGpu->setClip(clip);
61427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
61527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
61627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com////////////////////////////////////////////////////////////////////////////////
61727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
6186aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.comvoid GrContext::clear(const GrIRect* rect, const GrColor color) {
619398109cc3e56b8122ad21c4d43a74a83be5b42a8bsalomon@google.com    this->flush();
6206aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com    fGpu->clear(rect, color);
62127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
62227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
62327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::drawPaint(const GrPaint& paint) {
62427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    // set rect to be big enough to fill the space, but not super-huge, so we
62527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    // don't overflow fixed-point implementations
626d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com    GrRect r;
627d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com    r.setLTRB(0, 0,
628d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com              GrIntToScalar(getRenderTarget()->width()),
629d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com              GrIntToScalar(getRenderTarget()->height()));
63027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    GrMatrix inverse;
6318c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com    SkTLazy<GrPaint> tmpPaint;
6328c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com    const GrPaint* p = &paint;
6338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrDrawState* drawState = fGpu->drawState();
6348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrAutoMatrix am;
6358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6364f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com    // We attempt to map r by the inverse matrix and draw that. mapRect will
6374f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com    // map the four corners and bound them with a new rect. This will not
6384f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com    // produce a correct result for some perspective matrices.
6398c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com    if (!this->getMatrix().hasPerspective()) {
6408f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        if (!drawState->getViewInverse(&inverse)) {
6418c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com            GrPrintf("Could not invert matrix");
6428c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com            return;
6438c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com        }
64427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        inverse.mapRect(&r);
64527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    } else {
6468c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com        if (paint.getActiveMaskStageMask() || paint.getActiveStageMask()) {
6478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            if (!drawState->getViewInverse(&inverse)) {
6488c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com                GrPrintf("Could not invert matrix");
6498c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com                return;
6508c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com            }
6518c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com            tmpPaint.set(paint);
6528c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com            tmpPaint.get()->preConcatActiveSamplerMatrices(inverse);
6538c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com            p = tmpPaint.get();
6548c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com        }
6554f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com        am.set(this, GrMatrix::I());
65627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    }
6574f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com    // by definition this fills the entire clip, no need for AA
6584f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com    if (paint.fAntiAlias) {
6598c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com        if (!tmpPaint.isValid()) {
6608c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com            tmpPaint.set(paint);
6618c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com            p = tmpPaint.get();
6628c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com        }
6638c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com        GrAssert(p == tmpPaint.get());
6648c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com        tmpPaint.get()->fAntiAlias = false;
6654f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com    }
6664f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com    this->drawRect(*p, r);
66727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
66827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
669205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com////////////////////////////////////////////////////////////////////////////////
670205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
671d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.comnamespace {
672d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.cominline bool disable_coverage_aa_for_blend(GrDrawTarget* target) {
673d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com    return DISABLE_COVERAGE_AA_FOR_BLEND && !target->canApplyCoverage();
674d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com}
675d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com}
676d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com
677919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.comstruct GrContext::OffscreenRecord {
678919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com    enum Downsample {
679919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com        k4x4TwoPass_Downsample,
680919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com        k4x4SinglePass_Downsample,
681919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com        kFSAA_Downsample
682919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com    }                              fDownsample;
683b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com    int                            fTileSizeX;
684b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com    int                            fTileSizeY;
685919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com    int                            fTileCountX;
686919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com    int                            fTileCountY;
687919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com    int                            fScale;
68850398bf7f1953e640e5529616e710cf540799731bsalomon@google.com    GrAutoScratchTexture           fOffscreen0;
68950398bf7f1953e640e5529616e710cf540799731bsalomon@google.com    GrAutoScratchTexture           fOffscreen1;
690919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com    GrDrawTarget::SavedDrawState   fSavedState;
691237a461ec96918eef9bd9f61d4d63fc43968b3e8tomhudson@google.com    GrClip                         fClip;
692919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com};
693919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com
694471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.combool GrContext::doOffscreenAA(GrDrawTarget* target,
695471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com                              bool isHairLines) const {
696919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com#if !GR_USE_OFFSCREEN_AA
6978295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com    return false;
6988295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com#else
6991f221a70214fa1ab87b8a32dd66facf485f318eebsalomon@google.com    // Line primitves are always rasterized as 1 pixel wide.
7001f221a70214fa1ab87b8a32dd66facf485f318eebsalomon@google.com    // Super-sampling would make them too thin but MSAA would be OK.
7011f221a70214fa1ab87b8a32dd66facf485f318eebsalomon@google.com    if (isHairLines &&
70218c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com        (!PREFER_MSAA_OFFSCREEN_AA || !fGpu->getCaps().fFSAASupport)) {
7038295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com        return false;
7048295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com    }
7058f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    if (target->getDrawState().getRenderTarget()->isMultisampled()) {
7068295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com        return false;
7078295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com    }
708d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com    if (disable_coverage_aa_for_blend(target)) {
7091983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#if GR_DEBUG
710979432ba2621b617f5e85a9ff48c6b6cd1504a0dbsalomon@google.com        //GrPrintf("Turning off AA to correctly apply blend.\n");
7111983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#endif
7128295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com        return false;
7138295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com    }
7148295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com    return true;
7158295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com#endif
7168295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com}
7178295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com
718919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.combool GrContext::prepareForOffscreenAA(GrDrawTarget* target,
71906afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com                                      bool requireStencil,
7208295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com                                      const GrIRect& boundRect,
721d22b6e4351e552a8379d7781096d9e79feeae263tomhudson@google.com                                      GrPathRenderer* pr,
72206afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com                                      OffscreenRecord* record) {
723919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com
724919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com    GrAssert(GR_USE_OFFSCREEN_AA);
72506afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com
72650398bf7f1953e640e5529616e710cf540799731bsalomon@google.com    GrAssert(NULL == record->fOffscreen0.texture());
72750398bf7f1953e640e5529616e710cf540799731bsalomon@google.com    GrAssert(NULL == record->fOffscreen1.texture());
728919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com    GrAssert(!boundRect.isEmpty());
72906afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com
7308295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com    int boundW = boundRect.width();
7318295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com    int boundH = boundRect.height();
732919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com
733b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com    GrTextureDesc desc;
734919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com
735b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com    desc.fWidth  = GrMin(fMaxOffscreenAASize, boundW);
736b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com    desc.fHeight = GrMin(fMaxOffscreenAASize, boundH);
73706afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com
73806afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com    if (requireStencil) {
73906afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com        desc.fFlags = kRenderTarget_GrTextureFlagBit;
74006afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com    } else {
74106afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com        desc.fFlags = kRenderTarget_GrTextureFlagBit |
74206afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com                      kNoStencil_GrTextureFlagBit;
74306afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com    }
74406afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com
745c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com    desc.fConfig = kRGBA_8888_PM_GrPixelConfig;
74606afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com
74718c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com    if (PREFER_MSAA_OFFSCREEN_AA && fGpu->getCaps().fFSAASupport) {
7486aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com        record->fDownsample = OffscreenRecord::kFSAA_Downsample;
749d22b6e4351e552a8379d7781096d9e79feeae263tomhudson@google.com        record->fScale = 1;
7508295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com        desc.fAALevel = kMed_GrAALevel;
7518295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com    } else {
75218c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com        record->fDownsample = fGpu->getCaps().fShaderSupport ?
7536aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com                                OffscreenRecord::k4x4SinglePass_Downsample :
7546aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com                                OffscreenRecord::k4x4TwoPass_Downsample;
755919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com        record->fScale = OFFSCREEN_SSAA_SCALE;
756919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com        // both downsample paths assume this
757919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com        GR_STATIC_ASSERT(4 == OFFSCREEN_SSAA_SCALE);
7588295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com        desc.fAALevel = kNone_GrAALevel;
7598295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com    }
760d22b6e4351e552a8379d7781096d9e79feeae263tomhudson@google.com
761b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com    desc.fWidth *= record->fScale;
762b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com    desc.fHeight *= record->fScale;
76350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com    record->fOffscreen0.set(this, desc);
76450398bf7f1953e640e5529616e710cf540799731bsalomon@google.com    if (NULL == record->fOffscreen0.texture()) {
76506afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com        return false;
76606afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com    }
767b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com    // the approximate lookup might have given us some slop space, might as well
768b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com    // use it when computing the tiles size.
769b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com    // these are scale values, will adjust after considering
770b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com    // the possible second offscreen.
77150398bf7f1953e640e5529616e710cf540799731bsalomon@google.com    record->fTileSizeX = record->fOffscreen0.texture()->width();
77250398bf7f1953e640e5529616e710cf540799731bsalomon@google.com    record->fTileSizeY = record->fOffscreen0.texture()->height();
7738295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com
7746aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com    if (OffscreenRecord::k4x4TwoPass_Downsample == record->fDownsample) {
7758295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com        desc.fWidth /= 2;
7768295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com        desc.fHeight /= 2;
77750398bf7f1953e640e5529616e710cf540799731bsalomon@google.com        record->fOffscreen1.set(this, desc);
77850398bf7f1953e640e5529616e710cf540799731bsalomon@google.com        if (NULL == record->fOffscreen1.texture()) {
7798295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com            return false;
7808295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com        }
781b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com        record->fTileSizeX = GrMin(record->fTileSizeX,
78250398bf7f1953e640e5529616e710cf540799731bsalomon@google.com                                   2 * record->fOffscreen0.texture()->width());
783b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com        record->fTileSizeY = GrMin(record->fTileSizeY,
78450398bf7f1953e640e5529616e710cf540799731bsalomon@google.com                                   2 * record->fOffscreen0.texture()->height());
7858295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com    }
786b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com    record->fTileSizeX /= record->fScale;
787b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com    record->fTileSizeY /= record->fScale;
788b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com
789b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com    record->fTileCountX = GrIDivRoundUp(boundW, record->fTileSizeX);
790b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com    record->fTileCountY = GrIDivRoundUp(boundH, record->fTileSizeY);
791b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com
792237a461ec96918eef9bd9f61d4d63fc43968b3e8tomhudson@google.com    record->fClip = target->getClip();
793237a461ec96918eef9bd9f61d4d63fc43968b3e8tomhudson@google.com
794919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com    target->saveCurrentDrawState(&record->fSavedState);
795919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com    return true;
796919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com}
797919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com
798919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.comvoid GrContext::setupOffscreenAAPass1(GrDrawTarget* target,
799919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com                                      const GrIRect& boundRect,
800919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com                                      int tileX, int tileY,
801919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com                                      OffscreenRecord* record) {
8028295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com
80350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com    GrRenderTarget* offRT0 = record->fOffscreen0.texture()->asRenderTarget();
8048295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com    GrAssert(NULL != offRT0);
80506afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com
80606afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com    GrPaint tempPaint;
80706afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com    tempPaint.reset();
808bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com    this->setPaint(tempPaint, target);
8098f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrDrawState* drawState = target->drawState();
8108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    drawState->setRenderTarget(offRT0);
811289533ada623f2238a83771eec977f204f75994fbsalomon@google.com#if PREFER_MSAA_OFFSCREEN_AA
8128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    target->enableState(GrDrawState::kHWAntialias_StateBit);
813289533ada623f2238a83771eec977f204f75994fbsalomon@google.com#endif
81406afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com
8153d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com    GrMatrix transM;
816b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com    int left = boundRect.fLeft + tileX * record->fTileSizeX;
817b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com    int top =  boundRect.fTop  + tileY * record->fTileSizeY;
8183d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com    transM.setTranslate(-left * GR_Scalar1, -top * GR_Scalar1);
8198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    drawState->viewMatrix()->postConcat(transM);
8203d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com    GrMatrix scaleM;
8213d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com    scaleM.setScale(record->fScale * GR_Scalar1, record->fScale * GR_Scalar1);
8228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    drawState->viewMatrix()->postConcat(scaleM);
82306afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com
824919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com    int w = (tileX == record->fTileCountX-1) ? boundRect.fRight - left :
825b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com                                               record->fTileSizeX;
826919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com    int h = (tileY == record->fTileCountY-1) ? boundRect.fBottom - top :
827b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com                                               record->fTileSizeY;
828919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com    GrIRect clear = SkIRect::MakeWH(record->fScale * w,
829919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com                                    record->fScale * h);
830237a461ec96918eef9bd9f61d4d63fc43968b3e8tomhudson@google.com    target->setClip(GrClip(clear));
831919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com#if 0
832919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com    // visualize tile boundaries by setting edges of offscreen to white
833919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com    // and interior to tranparent. black.
834919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com    target->clear(&clear, 0xffffffff);
835919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com
836919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com    static const int gOffset = 2;
837919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com    GrIRect clear2 = SkIRect::MakeLTRB(gOffset, gOffset,
838919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com                                       record->fScale * w - gOffset,
839919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com                                       record->fScale * h - gOffset);
840919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com    target->clear(&clear2, 0x0);
841919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com#else
8428295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com    target->clear(&clear, 0x0);
843919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com#endif
84406afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com}
84506afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com
846919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.comvoid GrContext::doOffscreenAAPass2(GrDrawTarget* target,
8478295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com                                 const GrPaint& paint,
8488295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com                                 const GrIRect& boundRect,
849919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com                                 int tileX, int tileY,
8508295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com                                 OffscreenRecord* record) {
851278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com    SK_TRACE_EVENT0("GrContext::doOffscreenAAPass2");
85250398bf7f1953e640e5529616e710cf540799731bsalomon@google.com    GrAssert(NULL != record->fOffscreen0.texture());
853ee435122d7dcb9cd4be4524004b0de282c42848bbsalomon@google.com    GrDrawTarget::AutoGeometryPush agp(target);
854919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com    GrIRect tileRect;
855b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com    tileRect.fLeft = boundRect.fLeft + tileX * record->fTileSizeX;
856b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com    tileRect.fTop  = boundRect.fTop  + tileY * record->fTileSizeY,
857919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com    tileRect.fRight = (tileX == record->fTileCountX-1) ?
858919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com                        boundRect.fRight :
859b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com                        tileRect.fLeft + record->fTileSizeX;
860919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com    tileRect.fBottom = (tileY == record->fTileCountY-1) ?
861919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com                        boundRect.fBottom :
862b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com                        tileRect.fTop + record->fTileSizeY;
86306afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com
8646aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com    GrSamplerState::Filter filter;
8656aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com    if (OffscreenRecord::k4x4SinglePass_Downsample == record->fDownsample) {
8666aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com        filter = GrSamplerState::k4x4Downsample_Filter;
8676aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com    } else {
8686aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com        filter = GrSamplerState::kBilinear_Filter;
8696aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com    }
8706aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com
871a47a48dca5045d71cbc5de343404045209a13e15bsalomon@google.com    GrMatrix sampleM;
8728295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com
87350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com    GrTexture* src = record->fOffscreen0.texture();
8748295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com    int scale;
8758295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com
87626c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com    enum {
87726c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com        kOffscreenStage = GrPaint::kTotalStages,
87826c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com    };
87926c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com
8808f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrDrawState* drawState = target->drawState();
8818f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
8826aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com    if (OffscreenRecord::k4x4TwoPass_Downsample == record->fDownsample) {
88350398bf7f1953e640e5529616e710cf540799731bsalomon@google.com        GrAssert(NULL != record->fOffscreen1.texture());
8848295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com        scale = 2;
88550398bf7f1953e640e5529616e710cf540799731bsalomon@google.com        GrRenderTarget* dst = record->fOffscreen1.texture()->asRenderTarget();
8868f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
8878295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com        // Do 2x2 downsample from first to second
8888f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        drawState->setTexture(kOffscreenStage, src);
8898f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        drawState->setRenderTarget(dst);
8908f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        drawState->setViewMatrix(GrMatrix::I());
8918295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com        sampleM.setScale(scale * GR_Scalar1 / src->width(),
8928295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com                         scale * GR_Scalar1 / src->height());
8931e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com        GrSamplerState* sampler = drawState->sampler(kOffscreenStage);
8941e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com        sampler->reset(GrSamplerState::kClamp_WrapMode, filter);
8951e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com        sampler->setMatrix(sampleM);
8969d12f5c11b56ef51ba2c95db721ae7e5bab27023bsalomon@google.com        GrRect rect = SkRect::MakeWH(SkIntToScalar(scale * tileRect.width()),
8979d12f5c11b56ef51ba2c95db721ae7e5bab27023bsalomon@google.com                                     SkIntToScalar(scale * tileRect.height()));
8988295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com        target->drawSimpleRect(rect, NULL, 1 << kOffscreenStage);
8998295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com
90050398bf7f1953e640e5529616e710cf540799731bsalomon@google.com        src = record->fOffscreen1.texture();
9016aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com    } else if (OffscreenRecord::kFSAA_Downsample == record->fDownsample) {
9028295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com        scale = 1;
903919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com        GrIRect rect = SkIRect::MakeWH(tileRect.width(), tileRect.height());
9048295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com        src->asRenderTarget()->overrideResolveRect(rect);
9056aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com    } else {
9066aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com        GrAssert(OffscreenRecord::k4x4SinglePass_Downsample ==
9076aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com                 record->fDownsample);
9086aef1fb4ebf8b8b2ed352eb81e961565fbbd56cbbsalomon@google.com        scale = 4;
9098295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com    }
9108295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com
911919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com    // setup for draw back to main RT, we use the original
912919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com    // draw state setup by the caller plus an additional coverage
913919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com    // stage to handle the AA resolve. Also, we use an identity
914919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com    // view matrix and so pre-concat sampler matrices with view inv.
91526c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com    int stageMask = paint.getActiveStageMask();
91626c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com
9178295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com    target->restoreDrawState(record->fSavedState);
918237a461ec96918eef9bd9f61d4d63fc43968b3e8tomhudson@google.com    target->setClip(record->fClip);
91926c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com
92026c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com    if (stageMask) {
9218295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com        GrMatrix invVM;
9228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        if (drawState->getViewInverse(&invVM)) {
9238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            drawState->preConcatSamplerMatrices(stageMask, invVM);
9248295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com        }
9258295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com    }
926919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com    // This is important when tiling, otherwise second tile's
927919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com    // pass 1 view matrix will be incorrect.
9288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrDrawState::AutoViewMatrixRestore avmr(drawState, GrMatrix::I());
9298295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com
9308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    drawState->setTexture(kOffscreenStage, src);
9311e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com    GrSamplerState* sampler = drawState->sampler(kOffscreenStage);
9321e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com    sampler->reset(GrSamplerState::kClamp_WrapMode, filter);
9338295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com    sampleM.setScale(scale * GR_Scalar1 / src->width(),
9348295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com                     scale * GR_Scalar1 / src->height());
9351e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com
9361e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com    sampler->setMatrix(sampleM);
9379d12f5c11b56ef51ba2c95db721ae7e5bab27023bsalomon@google.com    sampleM.setTranslate(SkIntToScalar(-tileRect.fLeft),
9389d12f5c11b56ef51ba2c95db721ae7e5bab27023bsalomon@google.com                         SkIntToScalar(-tileRect.fTop));
9391e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com    sampler->preConcatMatrix(sampleM);
94006afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com
94120efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com    GrRect dstRect;
94226c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com    int stages = (1 << kOffscreenStage) | stageMask;
943919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com    dstRect.set(tileRect);
9448295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com    target->drawSimpleRect(dstRect, NULL, stages);
945919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com}
94606afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com
947d22b6e4351e552a8379d7781096d9e79feeae263tomhudson@google.comvoid GrContext::cleanupOffscreenAA(GrDrawTarget* target,
948d22b6e4351e552a8379d7781096d9e79feeae263tomhudson@google.com                                   GrPathRenderer* pr,
949d22b6e4351e552a8379d7781096d9e79feeae263tomhudson@google.com                                   OffscreenRecord* record) {
9508295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com    target->restoreDrawState(record->fSavedState);
95106afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com}
95206afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com
95306afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com////////////////////////////////////////////////////////////////////////////////
95406afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com
95527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com/*  create a triangle strip that strokes the specified triangle. There are 8
95627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com unique vertices, but we repreat the last 2 to close up. Alternatively we
95727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com could use an indices array, and then only send 8 verts, but not sure that
95827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com would be faster.
95927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com */
960205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comstatic void setStrokeRectStrip(GrPoint verts[10], GrRect rect,
96127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                               GrScalar width) {
96227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    const GrScalar rad = GrScalarHalf(width);
963205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    rect.sort();
96427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
96527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    verts[0].set(rect.fLeft + rad, rect.fTop + rad);
96627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    verts[1].set(rect.fLeft - rad, rect.fTop - rad);
96727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    verts[2].set(rect.fRight - rad, rect.fTop + rad);
96827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    verts[3].set(rect.fRight + rad, rect.fTop - rad);
96927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    verts[4].set(rect.fRight - rad, rect.fBottom - rad);
97027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    verts[5].set(rect.fRight + rad, rect.fBottom + rad);
97127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    verts[6].set(rect.fLeft + rad, rect.fBottom - rad);
97227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    verts[7].set(rect.fLeft - rad, rect.fBottom + rad);
97327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    verts[8] = verts[0];
97427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    verts[9] = verts[1];
97527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
97627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
977205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comstatic void setInsetFan(GrPoint* pts, size_t stride,
978205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com                        const GrRect& r, GrScalar dx, GrScalar dy) {
979205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    pts->setRectFan(r.fLeft + dx, r.fTop + dy, r.fRight - dx, r.fBottom - dy, stride);
980205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com}
981205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
982205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comstatic const uint16_t gFillAARectIdx[] = {
983205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    0, 1, 5, 5, 4, 0,
984205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    1, 2, 6, 6, 5, 1,
985205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    2, 3, 7, 7, 6, 2,
986205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    3, 0, 4, 4, 7, 3,
987205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    4, 5, 6, 6, 7, 4,
988205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com};
989205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
990205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comint GrContext::aaFillRectIndexCount() const {
991205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    return GR_ARRAY_COUNT(gFillAARectIdx);
992205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com}
993205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
994205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comGrIndexBuffer* GrContext::aaFillRectIndexBuffer() {
995205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    if (NULL == fAAFillRectIndexBuffer) {
996205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com        fAAFillRectIndexBuffer = fGpu->createIndexBuffer(sizeof(gFillAARectIdx),
997205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com                                                         false);
9989b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com        if (NULL != fAAFillRectIndexBuffer) {
9999b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com    #if GR_DEBUG
10009b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com            bool updated =
10019b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com    #endif
10029b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com            fAAFillRectIndexBuffer->updateData(gFillAARectIdx,
10039b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com                                               sizeof(gFillAARectIdx));
10049b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com            GR_DEBUGASSERT(updated);
10059b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com        }
1006205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    }
1007205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    return fAAFillRectIndexBuffer;
1008205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com}
1009205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
1010205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comstatic const uint16_t gStrokeAARectIdx[] = {
1011205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    0 + 0, 1 + 0, 5 + 0, 5 + 0, 4 + 0, 0 + 0,
1012205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    1 + 0, 2 + 0, 6 + 0, 6 + 0, 5 + 0, 1 + 0,
1013205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    2 + 0, 3 + 0, 7 + 0, 7 + 0, 6 + 0, 2 + 0,
1014205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    3 + 0, 0 + 0, 4 + 0, 4 + 0, 7 + 0, 3 + 0,
1015205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
1016205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    0 + 4, 1 + 4, 5 + 4, 5 + 4, 4 + 4, 0 + 4,
1017205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    1 + 4, 2 + 4, 6 + 4, 6 + 4, 5 + 4, 1 + 4,
1018205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    2 + 4, 3 + 4, 7 + 4, 7 + 4, 6 + 4, 2 + 4,
1019205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    3 + 4, 0 + 4, 4 + 4, 4 + 4, 7 + 4, 3 + 4,
1020205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
1021205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    0 + 8, 1 + 8, 5 + 8, 5 + 8, 4 + 8, 0 + 8,
1022205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    1 + 8, 2 + 8, 6 + 8, 6 + 8, 5 + 8, 1 + 8,
1023205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    2 + 8, 3 + 8, 7 + 8, 7 + 8, 6 + 8, 2 + 8,
1024205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    3 + 8, 0 + 8, 4 + 8, 4 + 8, 7 + 8, 3 + 8,
1025205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com};
1026205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
1027205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comint GrContext::aaStrokeRectIndexCount() const {
1028205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    return GR_ARRAY_COUNT(gStrokeAARectIdx);
1029205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com}
1030205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
1031205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comGrIndexBuffer* GrContext::aaStrokeRectIndexBuffer() {
1032205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    if (NULL == fAAStrokeRectIndexBuffer) {
1033205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com        fAAStrokeRectIndexBuffer = fGpu->createIndexBuffer(sizeof(gStrokeAARectIdx),
1034205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com                                                           false);
10359b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com        if (NULL != fAAStrokeRectIndexBuffer) {
10369b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com    #if GR_DEBUG
10379b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com            bool updated =
10389b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com    #endif
10399b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com            fAAStrokeRectIndexBuffer->updateData(gStrokeAARectIdx,
10409b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com                                                 sizeof(gStrokeAARectIdx));
10419b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com            GR_DEBUGASSERT(updated);
10429b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com        }
1043205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    }
1044205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    return fAAStrokeRectIndexBuffer;
1045205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com}
1046205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
1047a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.comstatic GrVertexLayout aa_rect_layout(const GrDrawTarget* target,
1048a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com                                     bool useCoverage) {
1049a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com    GrVertexLayout layout = 0;
10509381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    for (int s = 0; s < GrDrawState::kNumStages; ++s) {
10518f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        if (NULL != target->getDrawState().getTexture(s)) {
1052a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com            layout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(s);
1053a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com        }
1054a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com    }
1055a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com    if (useCoverage) {
1056a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com        layout |= GrDrawTarget::kCoverage_VertexLayoutBit;
1057a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com    } else {
1058a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com        layout |= GrDrawTarget::kColor_VertexLayoutBit;
1059a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com    }
1060a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com    return layout;
1061a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com}
1062a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com
1063205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comvoid GrContext::fillAARect(GrDrawTarget* target,
1064a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com                           const GrRect& devRect,
1065a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com                           bool useVertexCoverage) {
1066a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com    GrVertexLayout layout = aa_rect_layout(target, useVertexCoverage);
1067205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
1068205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    size_t vsize = GrDrawTarget::VertexSize(layout);
1069205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
1070205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    GrDrawTarget::AutoReleaseGeometry geo(target, layout, 8, 0);
10716513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com    if (!geo.succeeded()) {
10726513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com        GrPrintf("Failed to get space for vertices!\n");
10736513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com        return;
10746513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com    }
10759b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com    GrIndexBuffer* indexBuffer = this->aaFillRectIndexBuffer();
10769b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com    if (NULL == indexBuffer) {
10779b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com        GrPrintf("Failed to create index buffer!\n");
10789b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com        return;
10799b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com    }
1080205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
1081205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    intptr_t verts = reinterpret_cast<intptr_t>(geo.vertices());
1082205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
1083205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    GrPoint* fan0Pos = reinterpret_cast<GrPoint*>(verts);
1084205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    GrPoint* fan1Pos = reinterpret_cast<GrPoint*>(verts + 4 * vsize);
1085205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
1086205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    setInsetFan(fan0Pos, vsize, devRect, -GR_ScalarHalf, -GR_ScalarHalf);
1087205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    setInsetFan(fan1Pos, vsize, devRect,  GR_ScalarHalf,  GR_ScalarHalf);
1088205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
1089205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    verts += sizeof(GrPoint);
1090205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    for (int i = 0; i < 4; ++i) {
1091205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com        *reinterpret_cast<GrColor*>(verts + i * vsize) = 0;
1092205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    }
1093205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
1094a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com    GrColor innerColor;
1095a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com    if (useVertexCoverage) {
1096e10f6fdf76fa9b627cbb8471b58b13c457af83e8bsalomon@google.com        innerColor = 0xffffffff;
1097a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com    } else {
10988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        innerColor = target->getDrawState().getColor();
1099a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com    }
1100a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com
1101205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    verts += 4 * vsize;
1102205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    for (int i = 0; i < 4; ++i) {
1103205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com        *reinterpret_cast<GrColor*>(verts + i * vsize) = innerColor;
1104205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    }
1105205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
11069b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com    target->setIndexSourceToBuffer(indexBuffer);
1107205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
1108205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    target->drawIndexed(kTriangles_PrimitiveType, 0,
1109205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com                         0, 8, this->aaFillRectIndexCount());
1110205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com}
1111205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
1112a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.comvoid GrContext::strokeAARect(GrDrawTarget* target,
1113a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com                             const GrRect& devRect,
1114a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com                             const GrVec& devStrokeSize,
1115a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com                             bool useVertexCoverage) {
1116205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    const GrScalar& dx = devStrokeSize.fX;
1117205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    const GrScalar& dy = devStrokeSize.fY;
1118205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    const GrScalar rx = GrMul(dx, GR_ScalarHalf);
1119205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    const GrScalar ry = GrMul(dy, GR_ScalarHalf);
1120205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
1121205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    GrScalar spare;
1122205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    {
1123205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com        GrScalar w = devRect.width() - dx;
1124205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com        GrScalar h = devRect.height() - dy;
1125205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com        spare = GrMin(w, h);
1126205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    }
1127205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
1128205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    if (spare <= 0) {
1129205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com        GrRect r(devRect);
1130205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com        r.inset(-rx, -ry);
1131a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com        fillAARect(target, r, useVertexCoverage);
1132205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com        return;
1133205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    }
1134a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com    GrVertexLayout layout = aa_rect_layout(target, useVertexCoverage);
1135205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    size_t vsize = GrDrawTarget::VertexSize(layout);
1136205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
1137205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    GrDrawTarget::AutoReleaseGeometry geo(target, layout, 16, 0);
11386513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com    if (!geo.succeeded()) {
11396513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com        GrPrintf("Failed to get space for vertices!\n");
11406513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com        return;
11416513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com    }
11429b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com    GrIndexBuffer* indexBuffer = this->aaStrokeRectIndexBuffer();
11439b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com    if (NULL == indexBuffer) {
11449b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com        GrPrintf("Failed to create index buffer!\n");
11459b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com        return;
11469b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com    }
1147205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
1148205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    intptr_t verts = reinterpret_cast<intptr_t>(geo.vertices());
1149205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
1150205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    GrPoint* fan0Pos = reinterpret_cast<GrPoint*>(verts);
1151205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    GrPoint* fan1Pos = reinterpret_cast<GrPoint*>(verts + 4 * vsize);
1152205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    GrPoint* fan2Pos = reinterpret_cast<GrPoint*>(verts + 8 * vsize);
1153205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    GrPoint* fan3Pos = reinterpret_cast<GrPoint*>(verts + 12 * vsize);
1154205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
1155205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    setInsetFan(fan0Pos, vsize, devRect, -rx - GR_ScalarHalf, -ry - GR_ScalarHalf);
1156205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    setInsetFan(fan1Pos, vsize, devRect, -rx + GR_ScalarHalf, -ry + GR_ScalarHalf);
1157205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    setInsetFan(fan2Pos, vsize, devRect,  rx - GR_ScalarHalf,  ry - GR_ScalarHalf);
1158205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    setInsetFan(fan3Pos, vsize, devRect,  rx + GR_ScalarHalf,  ry + GR_ScalarHalf);
1159205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
1160205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    verts += sizeof(GrPoint);
1161205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    for (int i = 0; i < 4; ++i) {
1162205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com        *reinterpret_cast<GrColor*>(verts + i * vsize) = 0;
1163205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    }
1164205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
1165a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com    GrColor innerColor;
1166a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com    if (useVertexCoverage) {
1167e10f6fdf76fa9b627cbb8471b58b13c457af83e8bsalomon@google.com        innerColor = 0xffffffff;
1168a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com    } else {
11698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        innerColor = target->getDrawState().getColor();
1170a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com    }
1171205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    verts += 4 * vsize;
1172205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    for (int i = 0; i < 8; ++i) {
1173205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com        *reinterpret_cast<GrColor*>(verts + i * vsize) = innerColor;
1174205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    }
1175205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
1176205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    verts += 8 * vsize;
1177205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    for (int i = 0; i < 8; ++i) {
1178205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com        *reinterpret_cast<GrColor*>(verts + i * vsize) = 0;
1179205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    }
1180205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
11819b09c9e91c2863d526cb05e67288c230f5ff33debsalomon@google.com    target->setIndexSourceToBuffer(indexBuffer);
1182205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    target->drawIndexed(kTriangles_PrimitiveType,
1183205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com                        0, 0, 16, aaStrokeRectIndexCount());
1184205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com}
1185205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
118620efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com/**
118720efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com * Returns true if the rects edges are integer-aligned.
118820efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com */
118920efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.comstatic bool isIRect(const GrRect& r) {
119020efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com    return GrScalarIsInt(r.fLeft) && GrScalarIsInt(r.fTop) &&
119120efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com           GrScalarIsInt(r.fRight) && GrScalarIsInt(r.fBottom);
119220efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com}
119320efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com
1194205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comstatic bool apply_aa_to_rect(GrDrawTarget* target,
1195205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com                             const GrRect& rect,
1196205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com                             GrScalar width,
1197205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com                             const GrMatrix* matrix,
1198205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com                             GrMatrix* combinedMatrix,
1199a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com                             GrRect* devRect,
1200a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com                             bool* useVertexCoverage) {
1201205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    // we use a simple alpha ramp to do aa on axis-aligned rects
1202205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    // do AA with alpha ramp if the caller requested AA, the rect
1203289533ada623f2238a83771eec977f204f75994fbsalomon@google.com    // will be axis-aligned, and the rect won't land on integer coords.
1204d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com
1205a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com    // we are keeping around the "tweak the alpha" trick because
1206a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com    // it is our only hope for the fixed-pipe implementation.
1207a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com    // In a shader implementation we can give a separate coverage input
1208289533ada623f2238a83771eec977f204f75994fbsalomon@google.com    // TODO: remove this ugliness when we drop the fixed-pipe impl
1209a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com    *useVertexCoverage = false;
1210d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com    if (!target->canTweakAlphaForCoverage()) {
1211a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com        if (target->getCaps().fSupportPerVertexCoverage) {
1212a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com            if (disable_coverage_aa_for_blend(target)) {
12131983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#if GR_DEBUG
1214979432ba2621b617f5e85a9ff48c6b6cd1504a0dbsalomon@google.com                //GrPrintf("Turning off AA to correctly apply blend.\n");
12151983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#endif
1216a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com                return false;
1217a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com            } else {
1218a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com                *useVertexCoverage = true;
1219a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com            }
1220a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com        } else {
1221a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com            GrPrintf("Rect AA dropped because no support for coverage.\n");
1222a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com            return false;
1223a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com        }
1224205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    }
12258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    const GrDrawState& drawState = target->getDrawState();
12268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    if (drawState.getRenderTarget()->isMultisampled()) {
1227205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com        return false;
1228205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    }
1229205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
1230471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com    if (0 == width && target->willUseHWAALines()) {
1231205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com        return false;
1232205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    }
1233205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
12348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    if (!drawState.getViewMatrix().preservesAxisAlignment()) {
1235205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com        return false;
1236205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    }
1237205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
1238205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    if (NULL != matrix &&
1239205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com        !matrix->preservesAxisAlignment()) {
1240205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com        return false;
1241205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    }
1242205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
12438f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    *combinedMatrix = drawState.getViewMatrix();
1244205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    if (NULL != matrix) {
1245205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com        combinedMatrix->preConcat(*matrix);
1246205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com        GrAssert(combinedMatrix->preservesAxisAlignment());
1247205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    }
1248205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
1249205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    combinedMatrix->mapRect(devRect, rect);
1250205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    devRect->sort();
1251205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
1252205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    if (width < 0) {
125320efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com        return !isIRect(*devRect);
1254205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    } else {
1255205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com        return true;
1256205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    }
1257205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com}
1258205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
125927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::drawRect(const GrPaint& paint,
126027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                         const GrRect& rect,
126127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                         GrScalar width,
126227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                         const GrMatrix* matrix) {
1263278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com    SK_TRACE_EVENT0("GrContext::drawRect");
126427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
126527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);
126626c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com    int stageMask = paint.getActiveStageMask();
126727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
1268205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    GrRect devRect = rect;
1269205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    GrMatrix combinedMatrix;
1270a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com    bool useVertexCoverage;
1271289533ada623f2238a83771eec977f204f75994fbsalomon@google.com    bool needAA = paint.fAntiAlias &&
1272289533ada623f2238a83771eec977f204f75994fbsalomon@google.com                  !this->getRenderTarget()->isMultisampled();
1273289533ada623f2238a83771eec977f204f75994fbsalomon@google.com    bool doAA = needAA && apply_aa_to_rect(target, rect, width, matrix,
1274289533ada623f2238a83771eec977f204f75994fbsalomon@google.com                                           &combinedMatrix, &devRect,
1275289533ada623f2238a83771eec977f204f75994fbsalomon@google.com                                           &useVertexCoverage);
1276205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
1277205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    if (doAA) {
12788f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrDrawTarget::AutoDeviceCoordDraw adcd(target, stageMask);
1279205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com        if (width >= 0) {
1280205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com            GrVec strokeSize;;
1281205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com            if (width > 0) {
1282205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com                strokeSize.set(width, width);
1283cc4dac3dac215dc0dd56f7b30d07cc304671b033bsalomon@google.com                combinedMatrix.mapVectors(&strokeSize, 1);
1284205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com                strokeSize.setAbs(strokeSize);
1285205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com            } else {
1286205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com                strokeSize.set(GR_Scalar1, GR_Scalar1);
1287205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com            }
1288a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com            strokeAARect(target, devRect, strokeSize, useVertexCoverage);
1289205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com        } else {
1290a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com            fillAARect(target, devRect, useVertexCoverage);
1291205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com        }
1292205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com        return;
1293205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    }
1294205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
129527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    if (width >= 0) {
129627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        // TODO: consider making static vertex buffers for these cases.
129727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        // Hairline could be done by just adding closing vertex to
129827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        // unitSquareVertexBuffer()
129926c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com        GrVertexLayout layout =  PaintStageVertexLayoutBits(paint, NULL);
130026c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com
130127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        static const int worstCaseVertCount = 10;
130227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        GrDrawTarget::AutoReleaseGeometry geo(target, layout, worstCaseVertCount, 0);
130327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
130427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        if (!geo.succeeded()) {
13056513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com            GrPrintf("Failed to get space for vertices!\n");
130627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com            return;
130727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        }
130827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
130927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        GrPrimitiveType primType;
131027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        int vertCount;
131127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        GrPoint* vertex = geo.positions();
131227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
131327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        if (width > 0) {
131427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com            vertCount = 10;
131527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com            primType = kTriangleStrip_PrimitiveType;
131627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com            setStrokeRectStrip(vertex, rect, width);
131727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        } else {
131827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com            // hairline
131927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com            vertCount = 5;
132027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com            primType = kLineStrip_PrimitiveType;
132127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com            vertex[0].set(rect.fLeft, rect.fTop);
132227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com            vertex[1].set(rect.fRight, rect.fTop);
132327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com            vertex[2].set(rect.fRight, rect.fBottom);
132427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com            vertex[3].set(rect.fLeft, rect.fBottom);
132527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com            vertex[4].set(rect.fLeft, rect.fTop);
132627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        }
132727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
13288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrDrawState::AutoViewMatrixRestore avmr;
132927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        if (NULL != matrix) {
13308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            GrDrawState* drawState = target->drawState();
13318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            avmr.set(drawState);
13328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            drawState->preConcatViewMatrix(*matrix);
13338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            drawState->preConcatSamplerMatrices(stageMask, *matrix);
133427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        }
133527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
133627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        target->drawNonIndexed(primType, 0, vertCount);
133727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    } else {
13388f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com#if GR_STATIC_RECT_VB
133926c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com            GrVertexLayout layout = PaintStageVertexLayoutBits(paint, NULL);
13406513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com            const GrVertexBuffer* sqVB = fGpu->getUnitSquareVertexBuffer();
13416513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com            if (NULL == sqVB) {
13426513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com                GrPrintf("Failed to create static rect vb.\n");
13436513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com                return;
13446513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com            }
13456513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com            target->setVertexSourceToBuffer(layout, sqVB);
13468f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            GrDrawState* drawState = target->drawState();
13478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            GrDrawState::AutoViewMatrixRestore avmr(drawState);
134827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com            GrMatrix m;
13498295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com            m.setAll(rect.width(),    0,             rect.fLeft,
1350205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com                        0,            rect.height(), rect.fTop,
1351205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com                        0,            0,             GrMatrix::I()[8]);
135227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
135327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com            if (NULL != matrix) {
135427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                m.postConcat(*matrix);
135527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com            }
13568f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            drawState->preConcatViewMatrix(m);
13578f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            drawState->preConcatSamplerMatrices(stageMask, m);
135826c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com
135927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com            target->drawNonIndexed(kTriangleFan_PrimitiveType, 0, 4);
13608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com#else
136126c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com            target->drawSimpleRect(rect, matrix, stageMask);
13628f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com#endif
136327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    }
136427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
136527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
136627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::drawRectToRect(const GrPaint& paint,
136727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                               const GrRect& dstRect,
136827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                               const GrRect& srcRect,
136927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                               const GrMatrix* dstMatrix,
137027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                               const GrMatrix* srcMatrix) {
1371278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com    SK_TRACE_EVENT0("GrContext::drawRectToRect");
137227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
137326c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com    // srcRect refers to paint's first texture
137426c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com    if (NULL == paint.getTexture(0)) {
137527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        drawRect(paint, dstRect, -1, dstMatrix);
137627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        return;
137727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    }
1378de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com
137927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    GR_STATIC_ASSERT(!BATCH_RECT_TO_RECT || !GR_STATIC_RECT_VB);
138027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
138127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#if GR_STATIC_RECT_VB
138227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);
13838f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrDrawState* drawState = target->drawState();
138426c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com    GrVertexLayout layout = PaintStageVertexLayoutBits(paint, NULL);
13858f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrDrawState::AutoViewMatrixRestore avmr(drawState);
138627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
138727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    GrMatrix m;
138827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
138927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    m.setAll(dstRect.width(), 0,                dstRect.fLeft,
139027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com             0,               dstRect.height(), dstRect.fTop,
139127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com             0,               0,                GrMatrix::I()[8]);
139227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    if (NULL != dstMatrix) {
139327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        m.postConcat(*dstMatrix);
139427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    }
13958f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    drawState->preConcatViewMatrix(m);
139627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
139726c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com    // srcRect refers to first stage
139826c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com    int otherStageMask = paint.getActiveStageMask() &
139926c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com                         (~(1 << GrPaint::kFirstTextureStage));
140026c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com    if (otherStageMask) {
14018f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        drawState->preConcatSamplerMatrices(otherStageMask, m);
140226c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com    }
140326c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com
140427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    m.setAll(srcRect.width(), 0,                srcRect.fLeft,
140527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com             0,               srcRect.height(), srcRect.fTop,
140627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com             0,               0,                GrMatrix::I()[8]);
140727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    if (NULL != srcMatrix) {
140827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        m.postConcat(*srcMatrix);
140927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    }
14108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    drawState->sampler(GrPaint::kFirstTextureStage)->preConcatMatrix(m);
141127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
14126513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com    const GrVertexBuffer* sqVB = fGpu->getUnitSquareVertexBuffer();
14136513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com    if (NULL == sqVB) {
14146513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com        GrPrintf("Failed to create static rect vb.\n");
14156513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com        return;
14166513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com    }
14176513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com    target->setVertexSourceToBuffer(layout, sqVB);
141827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    target->drawNonIndexed(kTriangleFan_PrimitiveType, 0, 4);
141927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#else
142027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
142127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    GrDrawTarget* target;
1422de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com#if BATCH_RECT_TO_RECT
142327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    target = this->prepareToDraw(paint, kBuffered_DrawCategory);
1424de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com#else
142527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);
142627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#endif
142727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
14289381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    const GrRect* srcRects[GrDrawState::kNumStages] = {NULL};
14299381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    const GrMatrix* srcMatrices[GrDrawState::kNumStages] = {NULL};
143027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    srcRects[0] = &srcRect;
143127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    srcMatrices[0] = srcMatrix;
143227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
143327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    target->drawRect(dstRect, dstMatrix, 1, srcRects, srcMatrices);
143427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#endif
143527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
143627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
143727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::drawVertices(const GrPaint& paint,
143827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                             GrPrimitiveType primitiveType,
143927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                             int vertexCount,
144027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                             const GrPoint positions[],
144127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                             const GrPoint texCoords[],
144227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                             const GrColor colors[],
144327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                             const uint16_t indices[],
144427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                             int indexCount) {
1445278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com    SK_TRACE_EVENT0("GrContext::drawVertices");
144627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
144727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    GrDrawTarget::AutoReleaseGeometry geo;
144827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
144927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);
145027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
145126c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com    bool hasTexCoords[GrPaint::kTotalStages] = {
145226c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com        NULL != texCoords,   // texCoordSrc provides explicit stage 0 coords
145326c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com        0                    // remaining stages use positions
145426c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com    };
145526c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com
145626c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com    GrVertexLayout layout = PaintStageVertexLayoutBits(paint, hasTexCoords);
145727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
145827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    if (NULL != colors) {
145927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        layout |= GrDrawTarget::kColor_VertexLayoutBit;
146027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    }
146126c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com    int vertexSize = GrDrawTarget::VertexSize(layout);
146227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
146327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    if (sizeof(GrPoint) != vertexSize) {
146427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        if (!geo.set(target, layout, vertexCount, 0)) {
14656513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com            GrPrintf("Failed to get space for vertices!\n");
146627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com            return;
146727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        }
14689381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com        int texOffsets[GrDrawState::kMaxTexCoords];
146927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        int colorOffset;
147026c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com        GrDrawTarget::VertexSizeAndOffsetsByIdx(layout,
147126c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com                                                texOffsets,
1472aeb2160b1dd34f8e640e8e56544fe407d4ff6311bsalomon@google.com                                                &colorOffset,
1473a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com                                                NULL,
1474a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com                                                NULL);
147527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        void* curVertex = geo.vertices();
147627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
147727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        for (int i = 0; i < vertexCount; ++i) {
147827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com            *((GrPoint*)curVertex) = positions[i];
147927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
148027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com            if (texOffsets[0] > 0) {
148127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                *(GrPoint*)((intptr_t)curVertex + texOffsets[0]) = texCoords[i];
148227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com            }
148327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com            if (colorOffset > 0) {
148427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                *(GrColor*)((intptr_t)curVertex + colorOffset) = colors[i];
148527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com            }
148626c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com            curVertex = (void*)((intptr_t)curVertex + vertexSize);
148727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        }
148827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    } else {
148927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        target->setVertexSourceToArray(layout, positions, vertexCount);
149027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    }
149127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
1492919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com    // we don't currently apply offscreen AA to this path. Need improved
1493919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com    // management of GrDrawTarget's geometry to avoid copying points per-tile.
1494a47a48dca5045d71cbc5de343404045209a13e15bsalomon@google.com
14958295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com    if (NULL != indices) {
1496919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com        target->setIndexSourceToArray(indices, indexCount);
14978295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com        target->drawIndexed(primitiveType, 0, 0, vertexCount, indexCount);
149827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    } else {
14998295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com        target->drawNonIndexed(primitiveType, 0, vertexCount);
15008295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com    }
150127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
150227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
150306afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com///////////////////////////////////////////////////////////////////////////////
150427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
150507f3ee10d34f09342abb93d758b5e151ff78f7a5reed@google.comvoid GrContext::drawPath(const GrPaint& paint, const GrPath& path,
150607f3ee10d34f09342abb93d758b5e151ff78f7a5reed@google.com                         GrPathFill fill, const GrPoint* translate) {
150727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
1508fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com    if (path.isEmpty()) {
1509fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com#if GR_DEBUG
1510fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com       GrPrintf("Empty path should have been caught by canvas.\n");
1511fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com#endif
1512fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com       if (GrIsFillInverted(fill)) {
1513fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com           this->drawPaint(paint);
1514fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com       }
1515fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com       return;
1516fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com    }
1517fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com
151827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);
1519d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com
1520289533ada623f2238a83771eec977f204f75994fbsalomon@google.com    bool prAA = paint.fAntiAlias && !this->getRenderTarget()->isMultisampled();
1521289533ada623f2238a83771eec977f204f75994fbsalomon@google.com
1522d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com    // An Assumption here is that path renderer would use some form of tweaking
1523d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com    // the src color (either the input alpha or in the frag shader) to implement
1524d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com    // aa. If we have some future driver-mojo path AA that can do the right
1525d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com    // thing WRT to the blend then we'll need some query on the PR.
1526d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com    if (disable_coverage_aa_for_blend(target)) {
15271983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#if GR_DEBUG
1528979432ba2621b617f5e85a9ff48c6b6cd1504a0dbsalomon@google.com        //GrPrintf("Turning off AA to correctly apply blend.\n");
15291983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#endif
1530289533ada623f2238a83771eec977f204f75994fbsalomon@google.com        prAA = false;
1531d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com    }
1532289533ada623f2238a83771eec977f204f75994fbsalomon@google.com
1533289533ada623f2238a83771eec977f204f75994fbsalomon@google.com    bool doOSAA = false;
1534289533ada623f2238a83771eec977f204f75994fbsalomon@google.com    GrPathRenderer* pr = NULL;
1535289533ada623f2238a83771eec977f204f75994fbsalomon@google.com    if (prAA) {
1536289533ada623f2238a83771eec977f204f75994fbsalomon@google.com        pr = this->getPathRenderer(path, fill, true);
1537289533ada623f2238a83771eec977f204f75994fbsalomon@google.com        if (NULL == pr) {
1538289533ada623f2238a83771eec977f204f75994fbsalomon@google.com            prAA = false;
1539289533ada623f2238a83771eec977f204f75994fbsalomon@google.com            doOSAA = this->doOffscreenAA(target, kHairLine_PathFill == fill);
1540289533ada623f2238a83771eec977f204f75994fbsalomon@google.com            pr = this->getPathRenderer(path, fill, false);
1541289533ada623f2238a83771eec977f204f75994fbsalomon@google.com        }
1542289533ada623f2238a83771eec977f204f75994fbsalomon@google.com    } else {
1543289533ada623f2238a83771eec977f204f75994fbsalomon@google.com        pr = this->getPathRenderer(path, fill, false);
1544289533ada623f2238a83771eec977f204f75994fbsalomon@google.com    }
1545289533ada623f2238a83771eec977f204f75994fbsalomon@google.com
15463008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com    if (NULL == pr) {
15471983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#if GR_DEBUG
15483008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com        GrPrintf("Unable to find path renderer compatible with path.\n");
15491983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#endif
15503008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com        return;
15513008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com    }
15523008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com
1553289533ada623f2238a83771eec977f204f75994fbsalomon@google.com    GrPathRenderer::AutoClearPath arp(pr, target, &path, fill, prAA, translate);
155439ee0ffa72fbd5df6d3ec6db4fdad0c1bc3946fdbsalomon@google.com    GrDrawState::StageMask stageMask = paint.getActiveStageMask();
155506afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com
1556289533ada623f2238a83771eec977f204f75994fbsalomon@google.com    if (doOSAA) {
15578295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com        bool needsStencil = pr->requiresStencilPass(target, path, fill);
15588f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        const GrRenderTarget* rt = target->getDrawState().getRenderTarget();
15598295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com        // compute bounds as intersection of rt size, clip, and path
15608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrIRect bound = SkIRect::MakeWH(rt->width(), rt->height());
15617ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com        GrIRect clipIBounds;
15628295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com        if (target->getClip().hasConservativeBounds()) {
15638295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com            target->getClip().getConservativeBounds().roundOut(&clipIBounds);
156420efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com            if (!bound.intersect(clipIBounds)) {
15658295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com                return;
15668295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com            }
15678295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com        }
156807f3ee10d34f09342abb93d758b5e151ff78f7a5reed@google.com        GrRect pathBounds = path.getBounds();
156907f3ee10d34f09342abb93d758b5e151ff78f7a5reed@google.com        if (!pathBounds.isEmpty()) {
15707ca72f33556e9d6c827b8c9493eb9531da5e347bbsalomon@google.com            if (NULL != translate) {
15717ca72f33556e9d6c827b8c9493eb9531da5e347bbsalomon@google.com                pathBounds.offset(*translate);
15727ca72f33556e9d6c827b8c9493eb9531da5e347bbsalomon@google.com            }
15738f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            target->getDrawState().getViewMatrix().mapRect(&pathBounds,
15748f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                                                           pathBounds);
1575919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com            GrIRect pathIBounds;
15768295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com            pathBounds.roundOut(&pathIBounds);
157720efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com            if (!bound.intersect(pathIBounds)) {
15788295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com                return;
15798295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com            }
15808295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com        }
1581919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com        OffscreenRecord record;
1582d22b6e4351e552a8379d7781096d9e79feeae263tomhudson@google.com        if (this->prepareForOffscreenAA(target, needsStencil, bound,
1583d22b6e4351e552a8379d7781096d9e79feeae263tomhudson@google.com                                        pr, &record)) {
1584919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com            for (int tx = 0; tx < record.fTileCountX; ++tx) {
1585919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com                for (int ty = 0; ty < record.fTileCountY; ++ty) {
1586919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com                    this->setupOffscreenAAPass1(target, bound, tx, ty, &record);
1587ee435122d7dcb9cd4be4524004b0de282c42848bbsalomon@google.com                    pr->drawPath(0);
1588919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com                    this->doOffscreenAAPass2(target, paint, bound, tx, ty, &record);
1589919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com                }
1590919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com            }
1591d22b6e4351e552a8379d7781096d9e79feeae263tomhudson@google.com            this->cleanupOffscreenAA(target, pr, &record);
1592fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com            if (GrIsFillInverted(fill) && bound != clipIBounds) {
15937ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com                GrDrawTarget::AutoDeviceCoordDraw adcd(target, stageMask);
15947ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com                GrRect rect;
15957ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com                if (clipIBounds.fTop < bound.fTop) {
15969d12f5c11b56ef51ba2c95db721ae7e5bab27023bsalomon@google.com                    rect.iset(clipIBounds.fLeft, clipIBounds.fTop,
15979d12f5c11b56ef51ba2c95db721ae7e5bab27023bsalomon@google.com                              clipIBounds.fRight, bound.fTop);
15987ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com                    target->drawSimpleRect(rect, NULL, stageMask);
15997ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com                }
16007ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com                if (clipIBounds.fLeft < bound.fLeft) {
16019d12f5c11b56ef51ba2c95db721ae7e5bab27023bsalomon@google.com                    rect.iset(clipIBounds.fLeft, bound.fTop,
16029d12f5c11b56ef51ba2c95db721ae7e5bab27023bsalomon@google.com                              bound.fLeft, bound.fBottom);
16037ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com                    target->drawSimpleRect(rect, NULL, stageMask);
16047ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com                }
16057ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com                if (clipIBounds.fRight > bound.fRight) {
16069d12f5c11b56ef51ba2c95db721ae7e5bab27023bsalomon@google.com                    rect.iset(bound.fRight, bound.fTop,
16079d12f5c11b56ef51ba2c95db721ae7e5bab27023bsalomon@google.com                              clipIBounds.fRight, bound.fBottom);
16087ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com                    target->drawSimpleRect(rect, NULL, stageMask);
16097ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com                }
16107ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com                if (clipIBounds.fBottom > bound.fBottom) {
16119d12f5c11b56ef51ba2c95db721ae7e5bab27023bsalomon@google.com                    rect.iset(clipIBounds.fLeft, bound.fBottom,
16129d12f5c11b56ef51ba2c95db721ae7e5bab27023bsalomon@google.com                              clipIBounds.fRight, clipIBounds.fBottom);
16137ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com                    target->drawSimpleRect(rect, NULL, stageMask);
16147ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com                }
16157ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com            }
16168295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com            return;
16178295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com        }
1618ee435122d7dcb9cd4be4524004b0de282c42848bbsalomon@google.com    }
1619ee435122d7dcb9cd4be4524004b0de282c42848bbsalomon@google.com    pr->drawPath(stageMask);
162027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
16218295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com
162227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com////////////////////////////////////////////////////////////////////////////////
162327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
16241f221a70214fa1ab87b8a32dd66facf485f318eebsalomon@google.combool GrContext::supportsShaders() const {
162518c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com    return fGpu->getCaps().fShaderSupport;
16261f221a70214fa1ab87b8a32dd66facf485f318eebsalomon@google.com}
16271f221a70214fa1ab87b8a32dd66facf485f318eebsalomon@google.com
1628a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.comvoid GrContext::flush(int flagsBitfield) {
1629a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com    if (kDiscard_FlushBit & flagsBitfield) {
1630a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com        fDrawBuffer->reset();
1631a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com    } else {
1632c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com        this->flushDrawBuffer();
1633a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com    }
1634a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com    if (kForceCurrentRenderTarget_FlushBit & flagsBitfield) {
163527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        fGpu->forceRenderTargetFlush();
163627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    }
163727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
163827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
163927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::flushText() {
164027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    if (kText_DrawCategory == fLastDrawCategory) {
164127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        flushDrawBuffer();
164227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    }
164327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
164427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
164527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::flushDrawBuffer() {
164627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#if BATCH_RECT_TO_RECT || DEFER_TEXT_RENDERING
164753a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com    if (fDrawBuffer) {
164853a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com        fDrawBuffer->playback(fGpu);
164953a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com        fDrawBuffer->reset();
165053a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com    }
165127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#endif
165227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
165327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
16546f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.comvoid GrContext::internalWriteTexturePixels(GrTexture* texture,
16556f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com                                           int left, int top,
16566f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com                                           int width, int height,
16576f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com                                           GrPixelConfig config,
16586f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com                                           const void* buffer,
16596f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com                                           size_t rowBytes,
16606f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com                                           uint32_t flags) {
16616f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com    SK_TRACE_EVENT0("GrContext::writeTexturePixels");
1662bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com    ASSERT_OWNED_RESOURCE(texture);
1663bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com
16646f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com    if (!(kDontFlush_PixelOpsFlag & flags)) {
16656f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com        this->flush();
16666f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com    }
16676f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com    // TODO: use scratch texture to perform conversion
16686f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com    if (GrPixelConfigIsUnpremultiplied(texture->config()) !=
16696f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com        GrPixelConfigIsUnpremultiplied(config)) {
16706f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com        return;
16716f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com    }
16726f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com
16736f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com    fGpu->writeTexturePixels(texture, left, top, width, height,
16746f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com                             config, buffer, rowBytes);
16756f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com}
16766f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com
16776f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.combool GrContext::internalReadTexturePixels(GrTexture* texture,
16786f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com                                          int left, int top,
16796f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com                                          int width, int height,
16806f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com                                          GrPixelConfig config,
16816f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com                                          void* buffer,
16826f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com                                          size_t rowBytes,
16836f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com                                          uint32_t flags) {
1684278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com    SK_TRACE_EVENT0("GrContext::readTexturePixels");
1685bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com    ASSERT_OWNED_RESOURCE(texture);
1686669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com
1687a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com    // TODO: code read pixels for textures that aren't also rendertargets
1688669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com    GrRenderTarget* target = texture->asRenderTarget();
1689669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com    if (NULL != target) {
16906f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com        return this->internalReadRenderTargetPixels(target,
16916f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com                                                    left, top, width, height,
16926f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com                                                    config, buffer, rowBytes,
16936f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com                                                    flags);
1694669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com    } else {
1695669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com        return false;
1696669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com    }
1697669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com}
1698669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com
16996f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.combool GrContext::internalReadRenderTargetPixels(GrRenderTarget* target,
17006f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com                                               int left, int top,
17016f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com                                               int width, int height,
17026f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com                                               GrPixelConfig config,
17036f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com                                               void* buffer,
17046f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com                                               size_t rowBytes,
17056f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com                                               uint32_t flags) {
1706278cbb452a260de1550769b168df448e0911cf3ctomhudson@google.com    SK_TRACE_EVENT0("GrContext::readRenderTargetPixels");
1707bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com    ASSERT_OWNED_RESOURCE(target);
1708bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com
1709669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com    if (NULL == target) {
17108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        target = fGpu->drawState()->getRenderTarget();
1711c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com        if (NULL == target) {
1712c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com            return false;
1713c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com        }
1714c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com    }
1715c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com
1716c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com    // PM <-> UPM conversion requires a draw. Currently we only support drawing
1717c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com    // into a UPM target, not reading from a UPM texture. Thus, UPM->PM is not
1718c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com    // not supported at this time.
1719c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com    if (GrPixelConfigIsUnpremultiplied(target->config()) &&
1720c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com        !GrPixelConfigIsUnpremultiplied(config)) {
1721c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com        return false;
1722669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com    }
1723669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com
17246f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com    if (!(kDontFlush_PixelOpsFlag & flags)) {
17256f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com        this->flush();
17266f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com    }
1727c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com
1728c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com    GrTexture* src = target->asTexture();
17290a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com    bool swapRAndB = NULL != src &&
17300a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com                     fGpu->preferredReadPixelsConfig(config) ==
17310a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com                     GrPixelConfigSwapRAndB(config);
1732c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com
1733c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com    bool flipY = NULL != src &&
1734c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com                 fGpu->readPixelsWillPayForYFlip(target, left, top,
1735c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com                                                 width, height, config,
1736c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com                                                 rowBytes);
17370a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com    bool alphaConversion = (!GrPixelConfigIsUnpremultiplied(target->config()) &&
17380a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com                             GrPixelConfigIsUnpremultiplied(config));
1739c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com
17400a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com    if (NULL == src && alphaConversion) {
17410a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com        // we should fallback to cpu conversion here. This could happen when
17420a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com        // we were given an external render target by the client that is not
17430a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com        // also a texture (e.g. FBO 0 in GL)
17440a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com        return false;
17450a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com    }
17460a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com    // we draw to a scratch texture if any of these conversion are applied
1747c4ff22a2965616629765b8ffe0e58f6d05f92fa3bsalomon@google.com    GrAutoScratchTexture ast;
17480a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com    if (flipY || swapRAndB || alphaConversion) {
17490a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com        GrAssert(NULL != src);
17500a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com        if (swapRAndB) {
17510a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com            config = GrPixelConfigSwapRAndB(config);
17520a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com            GrAssert(kUnknown_GrPixelConfig != config);
1753c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com        }
1754c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com        // Make the scratch a render target because we don't have a robust
1755c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com        // readTexturePixels as of yet (it calls this function).
1756c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com        const GrTextureDesc desc = {
1757c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com            kRenderTarget_GrTextureFlagBit,
1758c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com            kNone_GrAALevel,
1759c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com            width, height,
17605bc34f04fe70cdde702ac3bff1fea0ccb275d4a5bsalomon@google.com            config
1761c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com        };
1762c4ff22a2965616629765b8ffe0e58f6d05f92fa3bsalomon@google.com
176356d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com        // When a full readback is faster than a partial we could always make
176456d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com        // the scratch exactly match the passed rect. However, if we see many
176556d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com        // different size rectangles we will trash our texture cache and pay the
176656d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com        // cost of creating and destroying many textures. So, we only request
176756d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com        // an exact match when the caller is reading an entire RT.
176856d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com        ScratchTexMatch match = kApprox_ScratchTexMatch;
176956d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com        if (0 == left &&
177056d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com            0 == top &&
177156d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com            target->width() == width &&
177256d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com            target->height() == height &&
177356d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com            fGpu->fullReadPixelsIsFasterThanPartial()) {
177456d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com            match = kExact_ScratchTexMatch;
177556d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com        }
177656d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com        ast.set(this, desc, match);
1777c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com        GrTexture* texture = ast.texture();
1778c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com        if (!texture) {
1779c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com            return false;
1780c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com        }
1781c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com        target = texture->asRenderTarget();
1782c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com        GrAssert(NULL != target);
1783c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com
1784c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com        GrDrawTarget::AutoStateRestore asr(fGpu);
17858f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrDrawState* drawState = fGpu->drawState();
17866b67e21b6549598254c1ffa4243bf32615d90fb6bsalomon@google.com        reset_draw_state(drawState);
17878f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        drawState->setRenderTarget(target);
1788c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com
1789c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com        GrMatrix matrix;
1790c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com        if (flipY) {
1791c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com            matrix.setTranslate(SK_Scalar1 * left,
1792c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com                                SK_Scalar1 * (top + height));
1793c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com            matrix.set(GrMatrix::kMScaleY, -GR_Scalar1);
1794c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com        } else {
1795c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com            matrix.setTranslate(SK_Scalar1 *left, SK_Scalar1 *top);
1796c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com        }
1797c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com        matrix.postIDiv(src->width(), src->height());
17981e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com        drawState->sampler(0)->reset(matrix);
17991e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com        drawState->sampler(0)->setRAndBSwap(swapRAndB);
18008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        drawState->setTexture(0, src);
1801c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com        GrRect rect;
1802c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com        rect.setXYWH(0, 0, SK_Scalar1 * width, SK_Scalar1 * height);
1803c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com        fGpu->drawSimpleRect(rect, NULL, 0x1);
1804c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com        left = 0;
1805c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com        top = 0;
1806c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com    }
1807669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com    return fGpu->readPixels(target,
1808c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com                            left, top, width, height,
1809c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com                            config, buffer, rowBytes, flipY);
181027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
181127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
1812ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.orgvoid GrContext::copyTexture(GrTexture* src, GrRenderTarget* dst) {
1813ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org    if (NULL == src || NULL == dst) {
1814ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org        return;
1815ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org    }
1816ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org    ASSERT_OWNED_RESOURCE(src);
1817ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org
1818ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org    GrDrawTarget::AutoStateRestore asr(fGpu);
18198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrDrawState* drawState = fGpu->drawState();
18206b67e21b6549598254c1ffa4243bf32615d90fb6bsalomon@google.com    reset_draw_state(drawState);
18218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    drawState->setRenderTarget(dst);
1822ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org    GrMatrix sampleM;
1823ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org    sampleM.setIDiv(src->width(), src->height());
18248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    drawState->setTexture(0, src);
18251e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com    drawState->sampler(0)->reset(sampleM);
1826ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org    SkRect rect = SkRect::MakeXYWH(0, 0, src->width(), src->height());
1827ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org    fGpu->drawSimpleRect(rect, NULL, 1 << 0);
1828ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org}
1829ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org
18306f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.comvoid GrContext::internalWriteRenderTargetPixels(GrRenderTarget* target,
18316f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com                                                int left, int top,
18326f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com                                                int width, int height,
18336f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com                                                GrPixelConfig config,
18346f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com                                                const void* buffer,
18356f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com                                                size_t rowBytes,
18366f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com                                                uint32_t flags) {
18376f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com    SK_TRACE_EVENT0("GrContext::writeRenderTargetPixels");
1838bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com    ASSERT_OWNED_RESOURCE(target);
18396f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com
18406f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com    if (NULL == target) {
18418f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        target = fGpu->drawState()->getRenderTarget();
18426f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com        if (NULL == target) {
18436f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com            return;
18446f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com        }
18456f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com    }
184627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
184727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    // TODO: when underlying api has a direct way to do this we should use it
184827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    // (e.g. glDrawPixels on desktop GL).
184927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
1850a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com    // If the RT is also a texture and we don't have to do PM/UPM conversion
1851a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com    // then take the texture path, which we expect to be at least as fast or
1852a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com    // faster since it doesn't use an intermediate texture as we do below.
1853a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com
1854a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com#if !GR_MAC_BUILD
1855a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com    // At least some drivers on the Mac get confused when glTexImage2D is called
1856a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com    // on a texture attached to an FBO. The FBO still sees the old image. TODO:
1857a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com    // determine what OS versions and/or HW is affected.
1858a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com    if (NULL != target->asTexture() &&
1859a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com        GrPixelConfigIsUnpremultiplied(target->config()) ==
1860a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com        GrPixelConfigIsUnpremultiplied(config)) {
1861a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com
1862a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com        this->internalWriteTexturePixels(target->asTexture(),
1863a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com                                         left, top, width, height,
1864a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com                                         config, buffer, rowBytes, flags);
1865a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com        return;
1866a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com    }
1867a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com#endif
1868a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com
1869a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com    bool swapRAndB = fGpu->preferredReadPixelsConfig(config) ==
1870a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com                     GrPixelConfigSwapRAndB(config);
1871a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com    if (swapRAndB) {
1872a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com        config = GrPixelConfigSwapRAndB(config);
1873a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com    }
1874a85449dac125b8985010df7c057e9e6201d55112bsalomon@google.com
1875fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com    const GrTextureDesc desc = {
18765bc34f04fe70cdde702ac3bff1fea0ccb275d4a5bsalomon@google.com        kNone_GrTextureFlags, kNone_GrAALevel, width, height, config
187727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    };
187850398bf7f1953e640e5529616e710cf540799731bsalomon@google.com    GrAutoScratchTexture ast(this, desc);
187950398bf7f1953e640e5529616e710cf540799731bsalomon@google.com    GrTexture* texture = ast.texture();
188027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    if (NULL == texture) {
188127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        return;
188227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    }
18836f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com    this->internalWriteTexturePixels(texture, 0, 0, width, height,
18846f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com                                     config, buffer, rowBytes, flags);
188527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
188627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    GrDrawTarget::AutoStateRestore  asr(fGpu);
18878f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrDrawState* drawState = fGpu->drawState();
18886b67e21b6549598254c1ffa4243bf32615d90fb6bsalomon@google.com    reset_draw_state(drawState);
188927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
189027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    GrMatrix matrix;
189127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    matrix.setTranslate(GrIntToScalar(left), GrIntToScalar(top));
18928f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    drawState->setViewMatrix(matrix);
18938f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    drawState->setRenderTarget(target);
18948f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    drawState->setTexture(0, texture);
189527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
18965c63865b529eb5714e41419dfa23c70d26ff6e4ebsalomon@google.com    matrix.setIDiv(texture->width(), texture->height());
18971e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com    drawState->sampler(0)->reset(GrSamplerState::kClamp_WrapMode,
18981e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com                                 GrSamplerState::kNearest_Filter,
18991e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com                                 matrix);
19001e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com    drawState->sampler(0)->setRAndBSwap(swapRAndB);
190127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
190227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    GrVertexLayout layout = GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0);
190327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    static const int VCOUNT = 4;
19046513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com    // TODO: Use GrGpu::drawRect here
190527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    GrDrawTarget::AutoReleaseGeometry geo(fGpu, layout, VCOUNT, 0);
190627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    if (!geo.succeeded()) {
19076513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com        GrPrintf("Failed to get space for vertices!\n");
190827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        return;
190927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    }
191027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    ((GrPoint*)geo.vertices())->setIRectFan(0, 0, width, height);
191127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    fGpu->drawNonIndexed(kTriangleFan_PrimitiveType, 0, VCOUNT);
191227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
191327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com////////////////////////////////////////////////////////////////////////////////
191427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
1915bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.comvoid GrContext::setPaint(const GrPaint& paint, GrDrawTarget* target) {
19168f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrDrawState* drawState = target->drawState();
191726c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com
191826c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com    for (int i = 0; i < GrPaint::kMaxTextures; ++i) {
191926c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com        int s = i + GrPaint::kFirstTextureStage;
19208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        drawState->setTexture(s, paint.getTexture(i));
1921bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com        ASSERT_OWNED_RESOURCE(paint.getTexture(i));
19221e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com        *drawState->sampler(s) = paint.getTextureSampler(i);
192326c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com    }
192426c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com
19258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    drawState->setFirstCoverageStage(GrPaint::kFirstMaskStage);
192626c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com
192726c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com    for (int i = 0; i < GrPaint::kMaxMasks; ++i) {
192826c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com        int s = i + GrPaint::kFirstMaskStage;
19298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        drawState->setTexture(s, paint.getMask(i));
1930bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com        ASSERT_OWNED_RESOURCE(paint.getMask(i));
19311e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com        *drawState->sampler(s) = paint.getMaskSampler(i);
193226c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com    }
193326c2d0a69e66f1656d2dc23953a6f153e5d5009fbsalomon@google.com
19348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    drawState->setColor(paint.fColor);
193527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
193627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    if (paint.fDither) {
19378f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        drawState->enableState(GrDrawState::kDither_StateBit);
193827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    } else {
19398f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        drawState->disableState(GrDrawState::kDither_StateBit);
194027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    }
194127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    if (paint.fAntiAlias) {
19428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        drawState->enableState(GrDrawState::kHWAntialias_StateBit);
194327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    } else {
19448f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        drawState->disableState(GrDrawState::kHWAntialias_StateBit);
194527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    }
19466b67e21b6549598254c1ffa4243bf32615d90fb6bsalomon@google.com    drawState->setBlendFunc(paint.fSrcBlendCoeff, paint.fDstBlendCoeff);
19478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    drawState->setColorFilter(paint.fColorFilterColor, paint.fColorFilterXfermode);
1948d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com
1949d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com    if (paint.getActiveMaskStageMask() && !target->canApplyCoverage()) {
1950d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com        GrPrintf("Partial pixel coverage will be incorrectly blended.\n");
1951d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com    }
195227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
195327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
1954de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.comGrDrawTarget* GrContext::prepareToDraw(const GrPaint& paint,
195527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                                       DrawCategory category) {
195627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    if (category != fLastDrawCategory) {
195727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        flushDrawBuffer();
195827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        fLastDrawCategory = category;
195927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    }
1960bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com    this->setPaint(paint, fGpu);
196127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    GrDrawTarget* target = fGpu;
196227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    switch (category) {
196327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    case kText_DrawCategory:
196427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#if DEFER_TEXT_RENDERING
196527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        target = fDrawBuffer;
196627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        fDrawBuffer->initializeDrawStateAndClip(*fGpu);
196727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#else
196827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        target = fGpu;
196927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#endif
197027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        break;
197127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    case kUnbuffered_DrawCategory:
197227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        target = fGpu;
197327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        break;
197427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    case kBuffered_DrawCategory:
197527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        target = fDrawBuffer;
197627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        fDrawBuffer->initializeDrawStateAndClip(*fGpu);
197727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        break;
197827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    }
197927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    return target;
198027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
198127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
1982289533ada623f2238a83771eec977f204f75994fbsalomon@google.comGrPathRenderer* GrContext::getPathRenderer(const GrPath& path,
1983289533ada623f2238a83771eec977f204f75994fbsalomon@google.com                                           GrPathFill fill,
1984289533ada623f2238a83771eec977f204f75994fbsalomon@google.com                                           bool antiAlias) {
19853008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com    if (NULL == fPathRendererChain) {
19863008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com        fPathRendererChain =
19873008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com            new GrPathRendererChain(this, GrPathRendererChain::kNone_UsageFlag);
19883008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com    }
1989289533ada623f2238a83771eec977f204f75994fbsalomon@google.com    return fPathRendererChain->getPathRenderer(fGpu->getCaps(), path,
1990289533ada623f2238a83771eec977f204f75994fbsalomon@google.com                                               fill, antiAlias);
19913008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com}
19923008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com
199327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com////////////////////////////////////////////////////////////////////////////////
199427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
199527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::setRenderTarget(GrRenderTarget* target) {
1996bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com    ASSERT_OWNED_RESOURCE(target);
19978fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    this->flush(false);
19988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    fGpu->drawState()->setRenderTarget(target);
199927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
200027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
200127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comGrRenderTarget* GrContext::getRenderTarget() {
20028f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    return fGpu->drawState()->getRenderTarget();
200327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
200427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
200527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comconst GrRenderTarget* GrContext::getRenderTarget() const {
20068f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    return fGpu->getDrawState().getRenderTarget();
200727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
200827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
200927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comconst GrMatrix& GrContext::getMatrix() const {
20108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    return fGpu->getDrawState().getViewMatrix();
201127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
201227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
201327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::setMatrix(const GrMatrix& m) {
20148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    fGpu->drawState()->setViewMatrix(m);
201527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
201627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
201727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::concatMatrix(const GrMatrix& m) const {
20188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    fGpu->drawState()->preConcatViewMatrix(m);
201927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
202027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
202127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comstatic inline intptr_t setOrClear(intptr_t bits, int shift, intptr_t pred) {
202227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    intptr_t mask = 1 << shift;
202327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    if (pred) {
202427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        bits |= mask;
202527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    } else {
202627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        bits &= ~mask;
202727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    }
202827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    return bits;
202927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
203027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
203127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::resetStats() {
203227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    fGpu->resetStats();
203327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
203427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
203505ef510389950e1ae8dcba40e41e001db771b12dbsalomon@google.comconst GrGpuStats& GrContext::getStats() const {
203627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    return fGpu->getStats();
203727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
203827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
203927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comvoid GrContext::printStats() const {
204027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    fGpu->printStats();
204127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
204227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
2043583a1e38503ebd57ba9bd39a3fabe89bead8e76cbsalomon@google.comGrContext::GrContext(GrGpu* gpu) {
204427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    fGpu = gpu;
204527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    fGpu->ref();
2046669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com    fGpu->setContext(this);
20478fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
20483008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com    fPathRendererChain = NULL;
2049dfe75bcf98b0c04535efbf7fe36492a7fb53c90dbsalomon@google.com
205050398bf7f1953e640e5529616e710cf540799731bsalomon@google.com    fTextureCache = new GrResourceCache(MAX_TEXTURE_CACHE_COUNT,
205150398bf7f1953e640e5529616e710cf540799731bsalomon@google.com                                        MAX_TEXTURE_CACHE_BYTES);
205227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    fFontCache = new GrFontCache(fGpu);
205327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
205427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    fLastDrawCategory = kUnbuffered_DrawCategory;
205527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
20568fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    fDrawBuffer = NULL;
20578fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    fDrawBufferVBAllocPool = NULL;
20588fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    fDrawBufferIBAllocPool = NULL;
20598fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
2060205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    fAAFillRectIndexBuffer = NULL;
2061205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    fAAStrokeRectIndexBuffer = NULL;
2062919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com
206318c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com    int gpuMaxOffscreen = gpu->getCaps().fMaxRenderTargetSize;
206418c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com    if (!PREFER_MSAA_OFFSCREEN_AA || !gpu->getCaps().fFSAASupport) {
2065919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com        gpuMaxOffscreen /= OFFSCREEN_SSAA_SCALE;
2066919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com    }
2067919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com    fMaxOffscreenAASize = GrMin(GR_MAX_OFFSCREEN_AA_SIZE, gpuMaxOffscreen);
2068205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
20698fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    this->setupDrawBuffer();
20708fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com}
20718fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
20728fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.comvoid GrContext::setupDrawBuffer() {
20738fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
20748fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    GrAssert(NULL == fDrawBuffer);
20758fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    GrAssert(NULL == fDrawBufferVBAllocPool);
20768fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    GrAssert(NULL == fDrawBufferIBAllocPool);
20778fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
207827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#if DEFER_TEXT_RENDERING || BATCH_RECT_TO_RECT
2079de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com    fDrawBufferVBAllocPool =
20808fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com        new GrVertexBufferAllocPool(fGpu, false,
208127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                                    DRAW_BUFFER_VBPOOL_BUFFER_SIZE,
208227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                                    DRAW_BUFFER_VBPOOL_PREALLOC_BUFFERS);
2083de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com    fDrawBufferIBAllocPool =
20848fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com        new GrIndexBufferAllocPool(fGpu, false,
2085de6ac2dec54a34545dae1986cd743d24c8d655e8bsalomon@google.com                                   DRAW_BUFFER_IBPOOL_BUFFER_SIZE,
208627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                                   DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS);
208727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
2088471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com    fDrawBuffer = new GrInOrderDrawBuffer(fGpu,
2089471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com                                          fDrawBufferVBAllocPool,
209027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                                          fDrawBufferIBAllocPool);
209127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#endif
209227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
209327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#if BATCH_RECT_TO_RECT
209427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    fDrawBuffer->setQuadIndexBuffer(this->getQuadIndexBuffer());
209527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#endif
209627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
209727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
209827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comGrDrawTarget* GrContext::getTextTarget(const GrPaint& paint) {
209927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    GrDrawTarget* target;
210027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#if DEFER_TEXT_RENDERING
210127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    target = prepareToDraw(paint, kText_DrawCategory);
210227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#else
210327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    target = prepareToDraw(paint, kUnbuffered_DrawCategory);
210427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#endif
2105bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com    this->setPaint(paint, target);
210627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    return target;
210727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
210827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
210927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comconst GrIndexBuffer* GrContext::getQuadIndexBuffer() const {
211027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    return fGpu->getQuadIndexBuffer();
211127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
2112dfe75bcf98b0c04535efbf7fe36492a7fb53c90dbsalomon@google.com
2113aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.orgvoid GrContext::convolveInX(GrTexture* texture,
2114aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org                            const SkRect& rect,
2115aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org                            const float* kernel,
2116aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org                            int kernelWidth) {
2117bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com    ASSERT_OWNED_RESOURCE(texture);
2118bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com
21199962108c400dadcae913614e8a5ab781780981d8bsalomon@google.com    float imageIncrement[2] = {1.0f / texture->width(), 0.0f};
2120aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org    convolve(texture, rect, imageIncrement, kernel, kernelWidth);
2121aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org}
2122aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org
2123aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.orgvoid GrContext::convolveInY(GrTexture* texture,
2124aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org                            const SkRect& rect,
2125aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org                            const float* kernel,
2126aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org                            int kernelWidth) {
2127bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com    ASSERT_OWNED_RESOURCE(texture);
2128bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com
21299962108c400dadcae913614e8a5ab781780981d8bsalomon@google.com    float imageIncrement[2] = {0.0f, 1.0f / texture->height()};
2130aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org    convolve(texture, rect, imageIncrement, kernel, kernelWidth);
2131aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org}
2132aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org
2133aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.orgvoid GrContext::convolve(GrTexture* texture,
2134aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org                         const SkRect& rect,
2135aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org                         float imageIncrement[2],
2136aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org                         const float* kernel,
2137aadd9f8b193aa70e3dc30cbe5c4e1bc5c1d047basenorblanco@chromium.org                         int kernelWidth) {
2138bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com    ASSERT_OWNED_RESOURCE(texture);
2139bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com
2140027de5f922e8ad1acc5402829f716b8c513fdd8dsenorblanco@chromium.org    GrDrawTarget::AutoStateRestore asr(fGpu);
21411e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com    GrDrawState* drawState = fGpu->drawState();
2142027de5f922e8ad1acc5402829f716b8c513fdd8dsenorblanco@chromium.org    GrMatrix sampleM;
214360014ca38710d3fc265f4376b05c0fefd0e044cfsenorblanco@chromium.org    sampleM.setIDiv(texture->width(), texture->height());
21441e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com    drawState->sampler(0)->reset(GrSamplerState::kClamp_WrapMode,
21451e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com                                 GrSamplerState::kConvolution_Filter,
21461e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com                                 sampleM);
21471e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com    drawState->sampler(0)->setConvolutionParams(kernelWidth,
21481e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com                                                kernel,
21491e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com                                                imageIncrement);
21501e266f8ff2fb2f05f44e77e046a24410ff7b4c77bsalomon@google.com
21518f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    drawState->setViewMatrix(GrMatrix::I());
21528f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    drawState->setTexture(0, texture);
21538f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    drawState->setAlpha(0xFF);
21546b67e21b6549598254c1ffa4243bf32615d90fb6bsalomon@google.com    drawState->setBlendFunc(kOne_BlendCoeff, kZero_BlendCoeff);
2155027de5f922e8ad1acc5402829f716b8c513fdd8dsenorblanco@chromium.org    fGpu->drawSimpleRect(rect, NULL, 1 << 0);
2156027de5f922e8ad1acc5402829f716b8c513fdd8dsenorblanco@chromium.org}
2157c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com
2158c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com///////////////////////////////////////////////////////////////////////////////
2159