13f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
23f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com/*
33f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com * Copyright 2010 Google Inc.
43f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com *
53f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com * Use of this source code is governed by a BSD-style license that can be
63f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com * found in the LICENSE file.
73f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com */
83f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
93f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
103f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
113f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com#include "GrDrawTarget.h"
1203d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com#include "GrContext.h"
13516b4c312ba95ab60863c325482ee6c36618f706bsalomon@google.com#include "GrDrawTargetCaps.h"
14c08edffbcbe0eed40d8855f8acfe439c237c43bdbsalomon@google.com#include "GrRenderTarget.h"
153f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com#include "GrTexture.h"
163f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com#include "GrVertexBuffer.h"
173f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
185c2ee5c5d8f8593d40a2a9ffd9ca834653ee6af1sugoi@google.com#include "SkStrokeRec.h"
19290bf0ae34af76a4350a5df76ce02feb93d68196sugoi@google.com
20a2552aea03ee3cbf85c5f2c20f5b3835db5e0335reed@google.comSK_DEFINE_INST_COUNT(GrDrawTarget)
21a2552aea03ee3cbf85c5f2c20f5b3835db5e0335reed@google.com
223f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com////////////////////////////////////////////////////////////////////////////////
233f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
24c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.comGrDrawTarget::DrawInfo& GrDrawTarget::DrawInfo::operator =(const DrawInfo& di) {
25c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com    fPrimitiveType  = di.fPrimitiveType;
26c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com    fStartVertex    = di.fStartVertex;
27c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com    fStartIndex     = di.fStartIndex;
28c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com    fVertexCount    = di.fVertexCount;
29c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com    fIndexCount     = di.fIndexCount;
30c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com
31c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com    fInstanceCount          = di.fInstanceCount;
32c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com    fVerticesPerInstance    = di.fVerticesPerInstance;
33c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com    fIndicesPerInstance     = di.fIndicesPerInstance;
34c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com
35c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com    if (NULL != di.fDevBounds) {
36c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com        GrAssert(di.fDevBounds == &di.fDevBoundsStorage);
37c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com        fDevBoundsStorage = di.fDevBoundsStorage;
38c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com        fDevBounds = &fDevBoundsStorage;
39c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com    } else {
40c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com        fDevBounds = NULL;
41c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com    }
4203d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com
4303d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com    fDstCopy = di.fDstCopy;
4403d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com
45c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com    return *this;
46c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com}
47c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com
48c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com#if GR_DEBUG
49c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.combool GrDrawTarget::DrawInfo::isInstanced() const {
50c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com    if (fInstanceCount > 0) {
51c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com        GrAssert(0 == fIndexCount % fIndicesPerInstance);
52c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com        GrAssert(0 == fVertexCount % fVerticesPerInstance);
53c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com        GrAssert(fIndexCount / fIndicesPerInstance == fInstanceCount);
54c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com        GrAssert(fVertexCount / fVerticesPerInstance == fInstanceCount);
55c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com        // there is no way to specify a non-zero start index to drawIndexedInstances().
56c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com        GrAssert(0 == fStartIndex);
57c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com        return true;
58c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com    } else {
59c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com        GrAssert(!fVerticesPerInstance);
60c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com        GrAssert(!fIndicesPerInstance);
61c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com        return false;
62c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com    }
63c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com}
64c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com#endif
65c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com
66c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.comvoid GrDrawTarget::DrawInfo::adjustInstanceCount(int instanceOffset) {
67c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com    GrAssert(this->isInstanced());
68c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com    GrAssert(instanceOffset + fInstanceCount >= 0);
69c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com    fInstanceCount += instanceOffset;
70c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com    fVertexCount = fVerticesPerInstance * fInstanceCount;
71c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com    fIndexCount = fIndicesPerInstance * fInstanceCount;
72c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com}
73c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com
74c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.comvoid GrDrawTarget::DrawInfo::adjustStartVertex(int vertexOffset) {
75c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com    fStartVertex += vertexOffset;
76c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com    GrAssert(fStartVertex >= 0);
77c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com}
78c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com
79c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.comvoid GrDrawTarget::DrawInfo::adjustStartIndex(int indexOffset) {
80c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com    GrAssert(this->isIndexed());
81c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com    fStartIndex += indexOffset;
82c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com    GrAssert(fStartIndex >= 0);
83c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com}
84c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com
85c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com////////////////////////////////////////////////////////////////////////////////
86c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com
873f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com#define DEBUG_INVAL_BUFFER 0xdeadcafe
883f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com#define DEBUG_INVAL_START_IDX -1
893f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
900ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.comGrDrawTarget::GrDrawTarget(GrContext* context)
910ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.com    : fClip(NULL)
920ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.com    , fContext(context) {
930ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.com    GrAssert(NULL != context);
940ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.com
953a0ffe490df30018fb61b16519b642f3dd5b3bc1bsalomon@google.com    fDrawState = &fDefaultDrawState;
963a0ffe490df30018fb61b16519b642f3dd5b3bc1bsalomon@google.com    // We assume that fDrawState always owns a ref to the object it points at.
973a0ffe490df30018fb61b16519b642f3dd5b3bc1bsalomon@google.com    fDefaultDrawState.ref();
983f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    GeometrySrcState& geoSrc = fGeoSrcStateStack.push_back();
993f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com#if GR_DEBUG
1003f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    geoSrc.fVertexCount = DEBUG_INVAL_START_IDX;
1013f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
1023f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    geoSrc.fIndexCount = DEBUG_INVAL_START_IDX;
1033f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
1043f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com#endif
1053f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    geoSrc.fVertexSrc = kNone_GeometrySrcType;
1063f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    geoSrc.fIndexSrc  = kNone_GeometrySrcType;
1073f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com}
1083f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
1093f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comGrDrawTarget::~GrDrawTarget() {
1105bc70a7454858cbc0197d689414b98a1ae0fc50bbsalomon@google.com    GrAssert(1 == fGeoSrcStateStack.count());
111afcc161571327871da95761248abefeaafed40a4humper@google.com    SkDEBUGCODE(GeometrySrcState& geoSrc = fGeoSrcStateStack.back());
1125bc70a7454858cbc0197d689414b98a1ae0fc50bbsalomon@google.com    GrAssert(kNone_GeometrySrcType == geoSrc.fIndexSrc);
1135bc70a7454858cbc0197d689414b98a1ae0fc50bbsalomon@google.com    GrAssert(kNone_GeometrySrcType == geoSrc.fVertexSrc);
1143a0ffe490df30018fb61b16519b642f3dd5b3bc1bsalomon@google.com    fDrawState->unref();
1155bc70a7454858cbc0197d689414b98a1ae0fc50bbsalomon@google.com}
1165bc70a7454858cbc0197d689414b98a1ae0fc50bbsalomon@google.com
1175bc70a7454858cbc0197d689414b98a1ae0fc50bbsalomon@google.comvoid GrDrawTarget::releaseGeometry() {
1183f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    int popCnt = fGeoSrcStateStack.count() - 1;
1193f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    while (popCnt) {
1203f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        this->popGeometrySource();
1213f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        --popCnt;
1223f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    }
1235bc70a7454858cbc0197d689414b98a1ae0fc50bbsalomon@google.com    this->resetVertexSource();
1245bc70a7454858cbc0197d689414b98a1ae0fc50bbsalomon@google.com    this->resetIndexSource();
1253f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com}
1263f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
1278ec5ae686ce26ff7d72b8811ff6b6a3d26226bcarobertphillips@google.comvoid GrDrawTarget::setClip(const GrClipData* clip) {
1283f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    clipWillBeSet(clip);
1293f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    fClip = clip;
1303f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com}
1313f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
1328ec5ae686ce26ff7d72b8811ff6b6a3d26226bcarobertphillips@google.comconst GrClipData* GrDrawTarget::getClip() const {
1333f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    return fClip;
1343f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com}
1353f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
1363a0ffe490df30018fb61b16519b642f3dd5b3bc1bsalomon@google.comvoid GrDrawTarget::setDrawState(GrDrawState*  drawState) {
1373a0ffe490df30018fb61b16519b642f3dd5b3bc1bsalomon@google.com    GrAssert(NULL != fDrawState);
1383a0ffe490df30018fb61b16519b642f3dd5b3bc1bsalomon@google.com    if (NULL == drawState) {
1393a0ffe490df30018fb61b16519b642f3dd5b3bc1bsalomon@google.com        drawState = &fDefaultDrawState;
1403a0ffe490df30018fb61b16519b642f3dd5b3bc1bsalomon@google.com    }
1413a0ffe490df30018fb61b16519b642f3dd5b3bc1bsalomon@google.com    if (fDrawState != drawState) {
1423a0ffe490df30018fb61b16519b642f3dd5b3bc1bsalomon@google.com        fDrawState->unref();
1433a0ffe490df30018fb61b16519b642f3dd5b3bc1bsalomon@google.com        drawState->ref();
1443a0ffe490df30018fb61b16519b642f3dd5b3bc1bsalomon@google.com        fDrawState = drawState;
1453a0ffe490df30018fb61b16519b642f3dd5b3bc1bsalomon@google.com    }
1463a0ffe490df30018fb61b16519b642f3dd5b3bc1bsalomon@google.com}
1473a0ffe490df30018fb61b16519b642f3dd5b3bc1bsalomon@google.com
1489d8e4b7e65a6b644564e2f2b94730f74b88941e5jvanverth@google.combool GrDrawTarget::reserveVertexSpace(size_t vertexSize,
1493f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com                                      int vertexCount,
1503f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com                                      void** vertices) {
1513f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
1523f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    bool acquired = false;
1533f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    if (vertexCount > 0) {
1543f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        GrAssert(NULL != vertices);
1553f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        this->releasePreviousVertexSource();
1563f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        geoSrc.fVertexSrc = kNone_GeometrySrcType;
1573f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
1589d8e4b7e65a6b644564e2f2b94730f74b88941e5jvanverth@google.com        acquired = this->onReserveVertexSpace(vertexSize,
1593f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com                                              vertexCount,
1603f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com                                              vertices);
1613f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    }
1623f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    if (acquired) {
1633f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        geoSrc.fVertexSrc = kReserved_GeometrySrcType;
1643f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        geoSrc.fVertexCount = vertexCount;
1659d8e4b7e65a6b644564e2f2b94730f74b88941e5jvanverth@google.com        geoSrc.fVertexSize = vertexSize;
1663f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    } else if (NULL != vertices) {
1673f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        *vertices = NULL;
1683f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    }
1693f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    return acquired;
1703f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com}
1713f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
1723f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.combool GrDrawTarget::reserveIndexSpace(int indexCount,
1733f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com                                     void** indices) {
1743f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
1753f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    bool acquired = false;
1763f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    if (indexCount > 0) {
1773f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        GrAssert(NULL != indices);
1783f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        this->releasePreviousIndexSource();
1793f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        geoSrc.fIndexSrc = kNone_GeometrySrcType;
180dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com
1813f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        acquired = this->onReserveIndexSpace(indexCount, indices);
1823f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    }
1833f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    if (acquired) {
1843f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        geoSrc.fIndexSrc = kReserved_GeometrySrcType;
1853f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        geoSrc.fIndexCount = indexCount;
1863f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    } else if (NULL != indices) {
1873f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        *indices = NULL;
1883f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    }
1893f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    return acquired;
190dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com
1913f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com}
1923f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
1939d8e4b7e65a6b644564e2f2b94730f74b88941e5jvanverth@google.combool GrDrawTarget::reserveVertexAndIndexSpace(int vertexCount,
194c17542bbc94bd2772a2b60f9e178117f0b9840e4bsalomon@google.com                                              int indexCount,
195c17542bbc94bd2772a2b60f9e178117f0b9840e4bsalomon@google.com                                              void** vertices,
196c17542bbc94bd2772a2b60f9e178117f0b9840e4bsalomon@google.com                                              void** indices) {
1979d8e4b7e65a6b644564e2f2b94730f74b88941e5jvanverth@google.com    size_t vertexSize = this->drawState()->getVertexSize();
1989d8e4b7e65a6b644564e2f2b94730f74b88941e5jvanverth@google.com    this->willReserveVertexAndIndexSpace(vertexCount, indexCount);
199c17542bbc94bd2772a2b60f9e178117f0b9840e4bsalomon@google.com    if (vertexCount) {
2009d8e4b7e65a6b644564e2f2b94730f74b88941e5jvanverth@google.com        if (!this->reserveVertexSpace(vertexSize, vertexCount, vertices)) {
201c17542bbc94bd2772a2b60f9e178117f0b9840e4bsalomon@google.com            if (indexCount) {
202c17542bbc94bd2772a2b60f9e178117f0b9840e4bsalomon@google.com                this->resetIndexSource();
203c17542bbc94bd2772a2b60f9e178117f0b9840e4bsalomon@google.com            }
204c17542bbc94bd2772a2b60f9e178117f0b9840e4bsalomon@google.com            return false;
205c17542bbc94bd2772a2b60f9e178117f0b9840e4bsalomon@google.com        }
206c17542bbc94bd2772a2b60f9e178117f0b9840e4bsalomon@google.com    }
207c17542bbc94bd2772a2b60f9e178117f0b9840e4bsalomon@google.com    if (indexCount) {
208c17542bbc94bd2772a2b60f9e178117f0b9840e4bsalomon@google.com        if (!this->reserveIndexSpace(indexCount, indices)) {
209c17542bbc94bd2772a2b60f9e178117f0b9840e4bsalomon@google.com            if (vertexCount) {
210c17542bbc94bd2772a2b60f9e178117f0b9840e4bsalomon@google.com                this->resetVertexSource();
211c17542bbc94bd2772a2b60f9e178117f0b9840e4bsalomon@google.com            }
212c17542bbc94bd2772a2b60f9e178117f0b9840e4bsalomon@google.com            return false;
213c17542bbc94bd2772a2b60f9e178117f0b9840e4bsalomon@google.com        }
214c17542bbc94bd2772a2b60f9e178117f0b9840e4bsalomon@google.com    }
215c17542bbc94bd2772a2b60f9e178117f0b9840e4bsalomon@google.com    return true;
216c17542bbc94bd2772a2b60f9e178117f0b9840e4bsalomon@google.com}
217c17542bbc94bd2772a2b60f9e178117f0b9840e4bsalomon@google.com
2189d8e4b7e65a6b644564e2f2b94730f74b88941e5jvanverth@google.combool GrDrawTarget::geometryHints(int32_t* vertexCount,
2193f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com                                 int32_t* indexCount) const {
2203f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    if (NULL != vertexCount) {
2213f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        *vertexCount = -1;
2223f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    }
2233f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    if (NULL != indexCount) {
2243f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        *indexCount = -1;
2253f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    }
2263f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    return false;
2273f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com}
2283f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
2293f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comvoid GrDrawTarget::releasePreviousVertexSource() {
2303f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
2313f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    switch (geoSrc.fVertexSrc) {
2323f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        case kNone_GeometrySrcType:
2333f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com            break;
2343f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        case kArray_GeometrySrcType:
2353f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com            this->releaseVertexArray();
2363f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com            break;
2373f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        case kReserved_GeometrySrcType:
2383f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com            this->releaseReservedVertexSpace();
2393f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com            break;
2403f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        case kBuffer_GeometrySrcType:
2413f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com            geoSrc.fVertexBuffer->unref();
2423f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com#if GR_DEBUG
2433f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com            geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
2443f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com#endif
2453f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com            break;
2463f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        default:
2473f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com            GrCrash("Unknown Vertex Source Type.");
2483f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com            break;
2493f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    }
2503f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com}
2513f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
2523f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comvoid GrDrawTarget::releasePreviousIndexSource() {
2533f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
2543f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    switch (geoSrc.fIndexSrc) {
2553f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        case kNone_GeometrySrcType:   // these two don't require
2563f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com            break;
2573f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        case kArray_GeometrySrcType:
2583f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com            this->releaseIndexArray();
2593f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com            break;
2603f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        case kReserved_GeometrySrcType:
2613f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com            this->releaseReservedIndexSpace();
2623f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com            break;
2633f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        case kBuffer_GeometrySrcType:
2643f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com            geoSrc.fIndexBuffer->unref();
2653f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com#if GR_DEBUG
2663f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com            geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
2673f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com#endif
2683f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com            break;
2693f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        default:
2703f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com            GrCrash("Unknown Index Source Type.");
2713f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com            break;
2723f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    }
2733f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com}
2743f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
2759d8e4b7e65a6b644564e2f2b94730f74b88941e5jvanverth@google.comvoid GrDrawTarget::setVertexSourceToArray(const void* vertexArray,
2763f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com                                          int vertexCount) {
2773f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    this->releasePreviousVertexSource();
2783f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
2793f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    geoSrc.fVertexSrc = kArray_GeometrySrcType;
2809d8e4b7e65a6b644564e2f2b94730f74b88941e5jvanverth@google.com    geoSrc.fVertexSize = this->drawState()->getVertexSize();
2813f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    geoSrc.fVertexCount = vertexCount;
2823f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    this->onSetVertexSourceToArray(vertexArray, vertexCount);
2833f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com}
2843f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
2853f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comvoid GrDrawTarget::setIndexSourceToArray(const void* indexArray,
2863f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com                                         int indexCount) {
2873f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    this->releasePreviousIndexSource();
2883f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
2893f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    geoSrc.fIndexSrc = kArray_GeometrySrcType;
2903f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    geoSrc.fIndexCount = indexCount;
2913f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    this->onSetIndexSourceToArray(indexArray, indexCount);
2923f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com}
2933f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
2949d8e4b7e65a6b644564e2f2b94730f74b88941e5jvanverth@google.comvoid GrDrawTarget::setVertexSourceToBuffer(const GrVertexBuffer* buffer) {
2953f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    this->releasePreviousVertexSource();
2963f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
2973f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    geoSrc.fVertexSrc    = kBuffer_GeometrySrcType;
2983f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    geoSrc.fVertexBuffer = buffer;
2993f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    buffer->ref();
3009d8e4b7e65a6b644564e2f2b94730f74b88941e5jvanverth@google.com    geoSrc.fVertexSize = this->drawState()->getVertexSize();
3013f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com}
3023f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
3033f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comvoid GrDrawTarget::setIndexSourceToBuffer(const GrIndexBuffer* buffer) {
3043f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    this->releasePreviousIndexSource();
3053f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
3063f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    geoSrc.fIndexSrc     = kBuffer_GeometrySrcType;
3073f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    geoSrc.fIndexBuffer  = buffer;
3083f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    buffer->ref();
3093f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com}
3103f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
3113f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comvoid GrDrawTarget::resetVertexSource() {
3123f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    this->releasePreviousVertexSource();
3133f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
3143f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    geoSrc.fVertexSrc = kNone_GeometrySrcType;
3153f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com}
3163f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
3173f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comvoid GrDrawTarget::resetIndexSource() {
3183f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    this->releasePreviousIndexSource();
3193f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
3203f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    geoSrc.fIndexSrc = kNone_GeometrySrcType;
3213f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com}
3223f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
3233f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comvoid GrDrawTarget::pushGeometrySource() {
3243f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    this->geometrySourceWillPush();
3253f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    GeometrySrcState& newState = fGeoSrcStateStack.push_back();
3263f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    newState.fIndexSrc = kNone_GeometrySrcType;
3273f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    newState.fVertexSrc = kNone_GeometrySrcType;
3283f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com#if GR_DEBUG
3293f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    newState.fVertexCount  = ~0;
3303f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    newState.fVertexBuffer = (GrVertexBuffer*)~0;
3313f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    newState.fIndexCount   = ~0;
3323f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    newState.fIndexBuffer = (GrIndexBuffer*)~0;
3333f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com#endif
3343f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com}
3353f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
3363f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comvoid GrDrawTarget::popGeometrySource() {
3373f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    // if popping last element then pops are unbalanced with pushes
3383f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    GrAssert(fGeoSrcStateStack.count() > 1);
339dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com
3403f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    this->geometrySourceWillPop(fGeoSrcStateStack.fromBack(1));
3413f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    this->releasePreviousVertexSource();
3423f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    this->releasePreviousIndexSource();
3433f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    fGeoSrcStateStack.pop_back();
3443f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com}
3453f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
3463f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com////////////////////////////////////////////////////////////////////////////////
3473f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
348e5ed67c41692afaf23cdc5eded8c7d3e754de1e0bsalomon@google.combool GrDrawTarget::checkDraw(GrPrimitiveType type, int startVertex,
349e5ed67c41692afaf23cdc5eded8c7d3e754de1e0bsalomon@google.com                             int startIndex, int vertexCount,
350e5ed67c41692afaf23cdc5eded8c7d3e754de1e0bsalomon@google.com                             int indexCount) const {
35173d295e91f8e05caaad4c0895704cb9bd52d5322bsalomon@google.com    const GrDrawState& drawState = this->getDrawState();
3523f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com#if GR_DEBUG
353e5ed67c41692afaf23cdc5eded8c7d3e754de1e0bsalomon@google.com    const GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
3543f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    int maxVertex = startVertex + vertexCount;
3553f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    int maxValidVertex;
3563f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    switch (geoSrc.fVertexSrc) {
3573f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        case kNone_GeometrySrcType:
358e5ed67c41692afaf23cdc5eded8c7d3e754de1e0bsalomon@google.com            GrCrash("Attempting to draw without vertex src.");
3593f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        case kReserved_GeometrySrcType: // fallthrough
3603f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        case kArray_GeometrySrcType:
3613f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com            maxValidVertex = geoSrc.fVertexCount;
3623f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com            break;
3633f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        case kBuffer_GeometrySrcType:
3649d8e4b7e65a6b644564e2f2b94730f74b88941e5jvanverth@google.com            maxValidVertex = geoSrc.fVertexBuffer->sizeInBytes() / geoSrc.fVertexSize;
3653f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com            break;
3663f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    }
3673f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    if (maxVertex > maxValidVertex) {
368e5ed67c41692afaf23cdc5eded8c7d3e754de1e0bsalomon@google.com        GrCrash("Drawing outside valid vertex range.");
3693f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    }
370e5ed67c41692afaf23cdc5eded8c7d3e754de1e0bsalomon@google.com    if (indexCount > 0) {
371e5ed67c41692afaf23cdc5eded8c7d3e754de1e0bsalomon@google.com        int maxIndex = startIndex + indexCount;
372e5ed67c41692afaf23cdc5eded8c7d3e754de1e0bsalomon@google.com        int maxValidIndex;
373e5ed67c41692afaf23cdc5eded8c7d3e754de1e0bsalomon@google.com        switch (geoSrc.fIndexSrc) {
374e5ed67c41692afaf23cdc5eded8c7d3e754de1e0bsalomon@google.com            case kNone_GeometrySrcType:
375e5ed67c41692afaf23cdc5eded8c7d3e754de1e0bsalomon@google.com                GrCrash("Attempting to draw indexed geom without index src.");
376e5ed67c41692afaf23cdc5eded8c7d3e754de1e0bsalomon@google.com            case kReserved_GeometrySrcType: // fallthrough
377e5ed67c41692afaf23cdc5eded8c7d3e754de1e0bsalomon@google.com            case kArray_GeometrySrcType:
378e5ed67c41692afaf23cdc5eded8c7d3e754de1e0bsalomon@google.com                maxValidIndex = geoSrc.fIndexCount;
379e5ed67c41692afaf23cdc5eded8c7d3e754de1e0bsalomon@google.com                break;
380e5ed67c41692afaf23cdc5eded8c7d3e754de1e0bsalomon@google.com            case kBuffer_GeometrySrcType:
381e5ed67c41692afaf23cdc5eded8c7d3e754de1e0bsalomon@google.com                maxValidIndex = geoSrc.fIndexBuffer->sizeInBytes() / sizeof(uint16_t);
382e5ed67c41692afaf23cdc5eded8c7d3e754de1e0bsalomon@google.com                break;
383e5ed67c41692afaf23cdc5eded8c7d3e754de1e0bsalomon@google.com        }
384e5ed67c41692afaf23cdc5eded8c7d3e754de1e0bsalomon@google.com        if (maxIndex > maxValidIndex) {
385e5ed67c41692afaf23cdc5eded8c7d3e754de1e0bsalomon@google.com            GrCrash("Index reads outside valid index range.");
386e5ed67c41692afaf23cdc5eded8c7d3e754de1e0bsalomon@google.com        }
3873f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    }
3887c0a72b7f61bb7fde063e2ddfc9a3d66b52f2fddbsalomon@google.com
38973d295e91f8e05caaad4c0895704cb9bd52d5322bsalomon@google.com    GrAssert(NULL != drawState.getRenderTarget());
390860912a0affd82bc6b30ad9006658df856ca1d17bsalomon@google.com
391860912a0affd82bc6b30ad9006658df856ca1d17bsalomon@google.com    for (int s = 0; s < drawState.numColorStages(); ++s) {
392860912a0affd82bc6b30ad9006658df856ca1d17bsalomon@google.com        const GrEffectRef& effect = *drawState.getColorStage(s).getEffect();
393860912a0affd82bc6b30ad9006658df856ca1d17bsalomon@google.com        int numTextures = effect->numTextures();
394860912a0affd82bc6b30ad9006658df856ca1d17bsalomon@google.com        for (int t = 0; t < numTextures; ++t) {
395860912a0affd82bc6b30ad9006658df856ca1d17bsalomon@google.com            GrTexture* texture = effect->texture(t);
396860912a0affd82bc6b30ad9006658df856ca1d17bsalomon@google.com            GrAssert(texture->asRenderTarget() != drawState.getRenderTarget());
397860912a0affd82bc6b30ad9006658df856ca1d17bsalomon@google.com        }
398860912a0affd82bc6b30ad9006658df856ca1d17bsalomon@google.com    }
399860912a0affd82bc6b30ad9006658df856ca1d17bsalomon@google.com    for (int s = 0; s < drawState.numCoverageStages(); ++s) {
400860912a0affd82bc6b30ad9006658df856ca1d17bsalomon@google.com        const GrEffectRef& effect = *drawState.getCoverageStage(s).getEffect();
401860912a0affd82bc6b30ad9006658df856ca1d17bsalomon@google.com        int numTextures = effect->numTextures();
402860912a0affd82bc6b30ad9006658df856ca1d17bsalomon@google.com        for (int t = 0; t < numTextures; ++t) {
403860912a0affd82bc6b30ad9006658df856ca1d17bsalomon@google.com            GrTexture* texture = effect->texture(t);
404860912a0affd82bc6b30ad9006658df856ca1d17bsalomon@google.com            GrAssert(texture->asRenderTarget() != drawState.getRenderTarget());
4057c0a72b7f61bb7fde063e2ddfc9a3d66b52f2fddbsalomon@google.com        }
4067c0a72b7f61bb7fde063e2ddfc9a3d66b52f2fddbsalomon@google.com    }
407f7c3ed0aee438c87cdfd7fcd09e558d96f507cc0commit-bot@chromium.org
408f7c3ed0aee438c87cdfd7fcd09e558d96f507cc0commit-bot@chromium.org    GrAssert(drawState.validateVertexAttribs());
4093f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com#endif
410c08edffbcbe0eed40d8855f8acfe439c237c43bdbsalomon@google.com    if (NULL == drawState.getRenderTarget()) {
411198bfc0b2c5d812022dd2f3bc409d538f415b5f2bsalomon@google.com        return false;
412198bfc0b2c5d812022dd2f3bc409d538f415b5f2bsalomon@google.com    }
413e5ed67c41692afaf23cdc5eded8c7d3e754de1e0bsalomon@google.com    return true;
414e5ed67c41692afaf23cdc5eded8c7d3e754de1e0bsalomon@google.com}
415e5ed67c41692afaf23cdc5eded8c7d3e754de1e0bsalomon@google.com
41603d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.combool GrDrawTarget::setupDstReadIfNecessary(DrawInfo* info) {
417034620a763fbd2e2deb16aa502b257e980b3f62ebsalomon@google.com    if (this->caps()->dstReadInShaderSupport() || !this->getDrawState().willEffectReadDstColor()) {
41803d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com        return true;
41903d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com    }
42003d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com    GrRenderTarget* rt = this->drawState()->getRenderTarget();
42103d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com
4225b77be19f1b0ba0eadc3825605fdd0b3150db63ecommit-bot@chromium.org    const GrClipData* clip = this->getClip();
423a8cbc57c2d74f8024d149370377bd7dcbd8d204ccommit-bot@chromium.org    SkIRect copyRect;
4245b77be19f1b0ba0eadc3825605fdd0b3150db63ecommit-bot@chromium.org    clip->getConservativeBounds(this->getDrawState().getRenderTarget(), &copyRect);
4255b77be19f1b0ba0eadc3825605fdd0b3150db63ecommit-bot@chromium.org    SkIRect drawIBounds;
4265b77be19f1b0ba0eadc3825605fdd0b3150db63ecommit-bot@chromium.org    if (info->getDevIBounds(&drawIBounds)) {
4275b77be19f1b0ba0eadc3825605fdd0b3150db63ecommit-bot@chromium.org        if (!copyRect.intersect(drawIBounds)) {
4285b77be19f1b0ba0eadc3825605fdd0b3150db63ecommit-bot@chromium.org#if GR_DEBUG
4295b77be19f1b0ba0eadc3825605fdd0b3150db63ecommit-bot@chromium.org            GrPrintf("Missed an early reject. Bailing on draw from setupDstReadIfNecessary.\n");
4305b77be19f1b0ba0eadc3825605fdd0b3150db63ecommit-bot@chromium.org#endif
4315b77be19f1b0ba0eadc3825605fdd0b3150db63ecommit-bot@chromium.org            return false;
4325b77be19f1b0ba0eadc3825605fdd0b3150db63ecommit-bot@chromium.org        }
4335b77be19f1b0ba0eadc3825605fdd0b3150db63ecommit-bot@chromium.org    } else {
4345b77be19f1b0ba0eadc3825605fdd0b3150db63ecommit-bot@chromium.org#if GR_DEBUG
4355b77be19f1b0ba0eadc3825605fdd0b3150db63ecommit-bot@chromium.org        //GrPrintf("No dev bounds when dst copy is made.\n");
4365b77be19f1b0ba0eadc3825605fdd0b3150db63ecommit-bot@chromium.org#endif
4375b77be19f1b0ba0eadc3825605fdd0b3150db63ecommit-bot@chromium.org    }
4382c3b0650210f7d163690ecf77e8769d82ecfe7b3skia.committer@gmail.com
439d01e6903daf87726990f8fe48b1d765cfea04799commit-bot@chromium.org    // MSAA consideration: When there is support for reading MSAA samples in the shader we could
440d01e6903daf87726990f8fe48b1d765cfea04799commit-bot@chromium.org    // have per-sample dst values by making the copy multisampled.
44103d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com    GrTextureDesc desc;
442b1bfcd3243f88510896951871c2d846d74a79205bsalomon@google.com    this->initCopySurfaceDstDesc(rt, &desc);
4435b77be19f1b0ba0eadc3825605fdd0b3150db63ecommit-bot@chromium.org    desc.fWidth = copyRect.width();
4445b77be19f1b0ba0eadc3825605fdd0b3150db63ecommit-bot@chromium.org    desc.fHeight = copyRect.height();
44503d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com
44603d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com    GrAutoScratchTexture ast(fContext, desc, GrContext::kApprox_ScratchTexMatch);
44703d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com
44803d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com    if (NULL == ast.texture()) {
44903d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com        GrPrintf("Failed to create temporary copy of destination texture.\n");
45003d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com        return false;
45103d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com    }
452b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com    SkIPoint dstPoint = {0, 0};
453b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com    if (this->copySurface(ast.texture(), rt, copyRect, dstPoint)) {
454b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com        info->fDstCopy.setTexture(ast.texture());
455c513a51f3f26bbde4bd015a57761d1743df31e2fskia.committer@gmail.com        info->fDstCopy.setOffset(copyRect.fLeft, copyRect.fTop);
456b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com        return true;
457b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com    } else {
458b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com        return false;
459b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com    }
46003d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com}
46103d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com
462c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.comvoid GrDrawTarget::drawIndexed(GrPrimitiveType type,
463c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com                               int startVertex,
464c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com                               int startIndex,
465c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com                               int vertexCount,
466c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com                               int indexCount,
467c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com                               const SkRect* devBounds) {
46852ea95b527d20df23da16f28b7db7de981fcd83bbsalomon@google.com    if (indexCount > 0 && this->checkDraw(type, startVertex, startIndex, vertexCount, indexCount)) {
46952ea95b527d20df23da16f28b7db7de981fcd83bbsalomon@google.com        DrawInfo info;
47052ea95b527d20df23da16f28b7db7de981fcd83bbsalomon@google.com        info.fPrimitiveType = type;
47152ea95b527d20df23da16f28b7db7de981fcd83bbsalomon@google.com        info.fStartVertex   = startVertex;
47252ea95b527d20df23da16f28b7db7de981fcd83bbsalomon@google.com        info.fStartIndex    = startIndex;
47352ea95b527d20df23da16f28b7db7de981fcd83bbsalomon@google.com        info.fVertexCount   = vertexCount;
47452ea95b527d20df23da16f28b7db7de981fcd83bbsalomon@google.com        info.fIndexCount    = indexCount;
475c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com
476c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com        info.fInstanceCount         = 0;
477c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com        info.fVerticesPerInstance   = 0;
478c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com        info.fIndicesPerInstance    = 0;
479c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com
480c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com        if (NULL != devBounds) {
481c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com            info.setDevBounds(*devBounds);
482c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com        }
48303d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com        // TODO: We should continue with incorrect blending.
48403d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com        if (!this->setupDstReadIfNecessary(&info)) {
48503d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com            return;
48603d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com        }
48752ea95b527d20df23da16f28b7db7de981fcd83bbsalomon@google.com        this->onDraw(info);
4883f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    }
4893f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com}
4903f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
4913f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comvoid GrDrawTarget::drawNonIndexed(GrPrimitiveType type,
4923f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com                                  int startVertex,
493c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com                                  int vertexCount,
494c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com                                  const SkRect* devBounds) {
49552ea95b527d20df23da16f28b7db7de981fcd83bbsalomon@google.com    if (vertexCount > 0 && this->checkDraw(type, startVertex, -1, vertexCount, -1)) {
49652ea95b527d20df23da16f28b7db7de981fcd83bbsalomon@google.com        DrawInfo info;
49752ea95b527d20df23da16f28b7db7de981fcd83bbsalomon@google.com        info.fPrimitiveType = type;
49852ea95b527d20df23da16f28b7db7de981fcd83bbsalomon@google.com        info.fStartVertex   = startVertex;
49952ea95b527d20df23da16f28b7db7de981fcd83bbsalomon@google.com        info.fStartIndex    = 0;
50052ea95b527d20df23da16f28b7db7de981fcd83bbsalomon@google.com        info.fVertexCount   = vertexCount;
50152ea95b527d20df23da16f28b7db7de981fcd83bbsalomon@google.com        info.fIndexCount    = 0;
502c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com
503c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com        info.fInstanceCount         = 0;
504c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com        info.fVerticesPerInstance   = 0;
505c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com        info.fIndicesPerInstance    = 0;
506c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com
507c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com        if (NULL != devBounds) {
508c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com            info.setDevBounds(*devBounds);
509c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com        }
51003d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com        // TODO: We should continue with incorrect blending.
51103d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com        if (!this->setupDstReadIfNecessary(&info)) {
51203d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com            return;
51303d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com        }
51452ea95b527d20df23da16f28b7db7de981fcd83bbsalomon@google.com        this->onDraw(info);
5153f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    }
5163f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com}
5173f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
5185c2ee5c5d8f8593d40a2a9ffd9ca834653ee6af1sugoi@google.comvoid GrDrawTarget::stencilPath(const GrPath* path, const SkStrokeRec& stroke, SkPath::FillType fill) {
51929a68d041dbf2f117fdb3205e923676ab375ab26bsalomon@google.com    // TODO: extract portions of checkDraw that are relevant to path stenciling.
5208dc33d06f5759d2e587dbd266226fc0fe0c1562bbsalomon@google.com    GrAssert(NULL != path);
52159831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com    GrAssert(this->caps()->pathStencilingSupport());
5225c2ee5c5d8f8593d40a2a9ffd9ca834653ee6af1sugoi@google.com    GrAssert(!stroke.isHairlineStyle());
5235c2ee5c5d8f8593d40a2a9ffd9ca834653ee6af1sugoi@google.com    GrAssert(!SkPath::IsInverseFillType(fill));
524290bf0ae34af76a4350a5df76ce02feb93d68196sugoi@google.com    this->onStencilPath(path, stroke, fill);
52529a68d041dbf2f117fdb3205e923676ab375ab26bsalomon@google.com}
52629a68d041dbf2f117fdb3205e923676ab375ab26bsalomon@google.com
5273f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com////////////////////////////////////////////////////////////////////////////////
5283f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
5293f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.combool GrDrawTarget::willUseHWAALines() const {
530f1a7c7962e72d83a3bf733d2c39571b513b2df32bsalomon@google.com    // There is a conflict between using smooth lines and our use of premultiplied alpha. Smooth
531f1a7c7962e72d83a3bf733d2c39571b513b2df32bsalomon@google.com    // lines tweak the incoming alpha value but not in a premul-alpha way. So we only use them when
532f1a7c7962e72d83a3bf733d2c39571b513b2df32bsalomon@google.com    // our alpha is 0xff and tweaking the color for partial coverage is OK
53359831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com    if (!this->caps()->hwAALineSupport() ||
534c08edffbcbe0eed40d8855f8acfe439c237c43bdbsalomon@google.com        !this->getDrawState().isHWAntialiasState()) {
5353f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        return false;
5363f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    }
537f1a7c7962e72d83a3bf733d2c39571b513b2df32bsalomon@google.com    GrDrawState::BlendOptFlags opts = this->getDrawState().getBlendOpts();
538f1a7c7962e72d83a3bf733d2c39571b513b2df32bsalomon@google.com    return (GrDrawState::kDisableBlend_BlendOptFlag & opts) &&
539f1a7c7962e72d83a3bf733d2c39571b513b2df32bsalomon@google.com           (GrDrawState::kCoverageAsAlpha_BlendOptFlag & opts);
5403f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com}
5413f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
5423f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.combool GrDrawTarget::canApplyCoverage() const {
5433f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    // we can correctly apply coverage if a) we have dual source blending
5443f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    // or b) one of our blend optimizations applies.
54559831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com    return this->caps()->dualSourceBlendingSupport() ||
546f1a7c7962e72d83a3bf733d2c39571b513b2df32bsalomon@google.com           GrDrawState::kNone_BlendOpt != this->getDrawState().getBlendOpts(true);
5473f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com}
5483f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
5493c5b8bcef7b768756d74a0343d44f494797e3ba7bsalomon@google.com////////////////////////////////////////////////////////////////////////////////
5503c5b8bcef7b768756d74a0343d44f494797e3ba7bsalomon@google.com
5513c5b8bcef7b768756d74a0343d44f494797e3ba7bsalomon@google.comvoid GrDrawTarget::drawIndexedInstances(GrPrimitiveType type,
5523c5b8bcef7b768756d74a0343d44f494797e3ba7bsalomon@google.com                                        int instanceCount,
5533c5b8bcef7b768756d74a0343d44f494797e3ba7bsalomon@google.com                                        int verticesPerInstance,
554c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com                                        int indicesPerInstance,
555c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com                                        const SkRect* devBounds) {
5563c5b8bcef7b768756d74a0343d44f494797e3ba7bsalomon@google.com    if (!verticesPerInstance || !indicesPerInstance) {
5573c5b8bcef7b768756d74a0343d44f494797e3ba7bsalomon@google.com        return;
5583c5b8bcef7b768756d74a0343d44f494797e3ba7bsalomon@google.com    }
5593c5b8bcef7b768756d74a0343d44f494797e3ba7bsalomon@google.com
560c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com    int maxInstancesPerDraw = this->indexCountInCurrentSource() / indicesPerInstance;
561c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com    if (!maxInstancesPerDraw) {
5623c5b8bcef7b768756d74a0343d44f494797e3ba7bsalomon@google.com        return;
5633c5b8bcef7b768756d74a0343d44f494797e3ba7bsalomon@google.com    }
5643c5b8bcef7b768756d74a0343d44f494797e3ba7bsalomon@google.com
565c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com    DrawInfo info;
566c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com    info.fPrimitiveType = type;
567c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com    info.fStartIndex = 0;
568c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com    info.fStartVertex = 0;
569c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com    info.fIndicesPerInstance = indicesPerInstance;
570c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com    info.fVerticesPerInstance = verticesPerInstance;
571c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com
572c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com    // Set the same bounds for all the draws.
573c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com    if (NULL != devBounds) {
574c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com        info.setDevBounds(*devBounds);
575c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com    }
57603d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com    // TODO: We should continue with incorrect blending.
57703d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com    if (!this->setupDstReadIfNecessary(&info)) {
57803d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com        return;
57903d5ebc1af70a1c30c7b0ac72e7f0d3311f0e97dbsalomon@google.com    }
580c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com
5813c5b8bcef7b768756d74a0343d44f494797e3ba7bsalomon@google.com    while (instanceCount) {
582c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com        info.fInstanceCount = GrMin(instanceCount, maxInstancesPerDraw);
583c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com        info.fVertexCount = info.fInstanceCount * verticesPerInstance;
584c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com        info.fIndexCount = info.fInstanceCount * indicesPerInstance;
585c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com
586c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com        if (this->checkDraw(type,
587c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com                            info.fStartVertex,
588c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com                            info.fStartIndex,
589c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com                            info.fVertexCount,
590c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com                            info.fIndexCount)) {
591c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com            this->onDraw(info);
592c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com        }
593c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com        info.fStartVertex += info.fVertexCount;
594c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com        instanceCount -= info.fInstanceCount;
5953c5b8bcef7b768756d74a0343d44f494797e3ba7bsalomon@google.com    }
5963c5b8bcef7b768756d74a0343d44f494797e3ba7bsalomon@google.com}
597f513f109816dcc0a9b9a32facd3409873a99d119bsalomon@google.com
5983f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com////////////////////////////////////////////////////////////////////////////////
5993f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
600a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.comnamespace {
601a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com
602a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com// position + (optional) texture coord
603a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.comextern const GrVertexAttrib gBWRectPosUVAttribs[] = {
604a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com    {kVec2f_GrVertexAttribType, 0,               kPosition_GrVertexAttribBinding},
605a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com    {kVec2f_GrVertexAttribType, sizeof(GrPoint), kLocalCoord_GrVertexAttribBinding}
606a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com};
607a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com
608a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.comvoid set_vertex_attributes(GrDrawState* drawState, bool hasUVs) {
609a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com    if (hasUVs) {
610a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com        drawState->setVertexAttribs<gBWRectPosUVAttribs>(2);
611a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com    } else {
612a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com        drawState->setVertexAttribs<gBWRectPosUVAttribs>(1);
613a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com    }
614a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com}
615a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com
616a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com};
617a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com
618a8cbc57c2d74f8024d149370377bd7dcbd8d204ccommit-bot@chromium.orgvoid GrDrawTarget::onDrawRect(const SkRect& rect,
619bfed24f7c476f19f4ca358e41901ff3a35872d99bsalomon@google.com                              const SkMatrix* matrix,
620a8cbc57c2d74f8024d149370377bd7dcbd8d204ccommit-bot@chromium.org                              const SkRect* localRect,
621bfed24f7c476f19f4ca358e41901ff3a35872d99bsalomon@google.com                              const SkMatrix* localMatrix) {
6223f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
623c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com    GrDrawState::AutoViewMatrixRestore avmr;
624c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com    if (NULL != matrix) {
6258bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com        avmr.set(this->drawState(), *matrix);
6263f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    }
6273f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
628a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com    set_vertex_attributes(this->drawState(), NULL != localRect);
629a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com
6309d8e4b7e65a6b644564e2f2b94730f74b88941e5jvanverth@google.com    AutoReleaseGeometry geo(this, 4, 0);
631c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com    if (!geo.succeeded()) {
632c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com        GrPrintf("Failed to get space for vertices!\n");
633c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com        return;
6343f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    }
6353f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
636768cceef720ead8767ded5f384d880fc9905dc14jvanverth@google.com    size_t vsize = this->drawState()->getVertexSize();
637c8616f5fae91282ee8607ad060ab1605a538fc53bsalomon@google.com    geo.positions()->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, vsize);
6388bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com    if (NULL != localRect) {
639768cceef720ead8767ded5f384d880fc9905dc14jvanverth@google.com        GrPoint* coords = GrTCast<GrPoint*>(GrTCast<intptr_t>(geo.vertices()) +
640a9f1f61795e9d9019fa13e5ff1f339fc58eb84fdrobertphillips@google.com                                            sizeof(GrPoint));
6418bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com        coords->setRectFan(localRect->fLeft, localRect->fTop,
6428bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com                           localRect->fRight, localRect->fBottom,
6438bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com                           vsize);
6448bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com        if (NULL != localMatrix) {
6458bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com            localMatrix->mapPointsWithStride(coords, vsize, 4);
6463f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        }
6473f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    }
6485b77be19f1b0ba0eadc3825605fdd0b3150db63ecommit-bot@chromium.org    SkTLazy<SkRect> bounds;
649034620a763fbd2e2deb16aa502b257e980b3f62ebsalomon@google.com    if (this->getDrawState().willEffectReadDstColor()) {
6505b77be19f1b0ba0eadc3825605fdd0b3150db63ecommit-bot@chromium.org        bounds.init();
6515b77be19f1b0ba0eadc3825605fdd0b3150db63ecommit-bot@chromium.org        this->getDrawState().getViewMatrix().mapRect(bounds.get(), rect);
6525b77be19f1b0ba0eadc3825605fdd0b3150db63ecommit-bot@chromium.org    }
653dcb8988a427b49b41313aa012399f8a0fbaa41d7robertphillips@google.com
6545b77be19f1b0ba0eadc3825605fdd0b3150db63ecommit-bot@chromium.org    this->drawNonIndexed(kTriangleFan_GrPrimitiveType, 0, 4, bounds.getMaybeNull());
6553f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com}
6563f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
6578b62219b7c4b5c543eb9cdb7da38184232c59812bsalomon@google.comvoid GrDrawTarget::clipWillBeSet(const GrClipData* clipData) {
6588b62219b7c4b5c543eb9cdb7da38184232c59812bsalomon@google.com}
6598b62219b7c4b5c543eb9cdb7da38184232c59812bsalomon@google.com
6603f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com////////////////////////////////////////////////////////////////////////////////
6613f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
6623f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comGrDrawTarget::AutoStateRestore::AutoStateRestore() {
6633f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    fDrawTarget = NULL;
6643f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com}
6653f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
666bfc805bb10f955661ff7641e44c1f6d5be9dd545bsalomon@google.comGrDrawTarget::AutoStateRestore::AutoStateRestore(GrDrawTarget* target,
667fbf9f30e11f6dfae9203b152092125fe9b47adb8bsalomon@google.com                                                 ASRInit init,
668fbf9f30e11f6dfae9203b152092125fe9b47adb8bsalomon@google.com                                                 const SkMatrix* vm) {
669bfc805bb10f955661ff7641e44c1f6d5be9dd545bsalomon@google.com    fDrawTarget = NULL;
670fbf9f30e11f6dfae9203b152092125fe9b47adb8bsalomon@google.com    this->set(target, init, vm);
6713f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com}
6723f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
6733f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comGrDrawTarget::AutoStateRestore::~AutoStateRestore() {
6743f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    if (NULL != fDrawTarget) {
675bfc805bb10f955661ff7641e44c1f6d5be9dd545bsalomon@google.com        fDrawTarget->setDrawState(fSavedState);
676bfc805bb10f955661ff7641e44c1f6d5be9dd545bsalomon@google.com        fSavedState->unref();
6773f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    }
6783f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com}
6793f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
680fbf9f30e11f6dfae9203b152092125fe9b47adb8bsalomon@google.comvoid GrDrawTarget::AutoStateRestore::set(GrDrawTarget* target, ASRInit init, const SkMatrix* vm) {
681fbf9f30e11f6dfae9203b152092125fe9b47adb8bsalomon@google.com    GrAssert(NULL == fDrawTarget);
682fbf9f30e11f6dfae9203b152092125fe9b47adb8bsalomon@google.com    fDrawTarget = target;
683fbf9f30e11f6dfae9203b152092125fe9b47adb8bsalomon@google.com    fSavedState = target->drawState();
684fbf9f30e11f6dfae9203b152092125fe9b47adb8bsalomon@google.com    GrAssert(fSavedState);
685fbf9f30e11f6dfae9203b152092125fe9b47adb8bsalomon@google.com    fSavedState->ref();
686fbf9f30e11f6dfae9203b152092125fe9b47adb8bsalomon@google.com    if (kReset_ASRInit == init) {
687fbf9f30e11f6dfae9203b152092125fe9b47adb8bsalomon@google.com        if (NULL == vm) {
688fbf9f30e11f6dfae9203b152092125fe9b47adb8bsalomon@google.com            // calls the default cons
689fbf9f30e11f6dfae9203b152092125fe9b47adb8bsalomon@google.com            fTempState.init();
690fbf9f30e11f6dfae9203b152092125fe9b47adb8bsalomon@google.com        } else {
691fbf9f30e11f6dfae9203b152092125fe9b47adb8bsalomon@google.com            SkNEW_IN_TLAZY(&fTempState, GrDrawState, (*vm));
692fbf9f30e11f6dfae9203b152092125fe9b47adb8bsalomon@google.com        }
693fbf9f30e11f6dfae9203b152092125fe9b47adb8bsalomon@google.com    } else {
694fbf9f30e11f6dfae9203b152092125fe9b47adb8bsalomon@google.com        GrAssert(kPreserve_ASRInit == init);
695fbf9f30e11f6dfae9203b152092125fe9b47adb8bsalomon@google.com        if (NULL == vm) {
696fbf9f30e11f6dfae9203b152092125fe9b47adb8bsalomon@google.com            fTempState.set(*fSavedState);
697fbf9f30e11f6dfae9203b152092125fe9b47adb8bsalomon@google.com        } else {
698fbf9f30e11f6dfae9203b152092125fe9b47adb8bsalomon@google.com            SkNEW_IN_TLAZY(&fTempState, GrDrawState, (*fSavedState, *vm));
699fbf9f30e11f6dfae9203b152092125fe9b47adb8bsalomon@google.com        }
700fbf9f30e11f6dfae9203b152092125fe9b47adb8bsalomon@google.com    }
701fbf9f30e11f6dfae9203b152092125fe9b47adb8bsalomon@google.com    target->setDrawState(fTempState.get());
702fbf9f30e11f6dfae9203b152092125fe9b47adb8bsalomon@google.com}
703fbf9f30e11f6dfae9203b152092125fe9b47adb8bsalomon@google.com
704fbf9f30e11f6dfae9203b152092125fe9b47adb8bsalomon@google.combool GrDrawTarget::AutoStateRestore::setIdentity(GrDrawTarget* target, ASRInit init) {
705bfc805bb10f955661ff7641e44c1f6d5be9dd545bsalomon@google.com    GrAssert(NULL == fDrawTarget);
706bfc805bb10f955661ff7641e44c1f6d5be9dd545bsalomon@google.com    fDrawTarget = target;
707bfc805bb10f955661ff7641e44c1f6d5be9dd545bsalomon@google.com    fSavedState = target->drawState();
708bfc805bb10f955661ff7641e44c1f6d5be9dd545bsalomon@google.com    GrAssert(fSavedState);
709bfc805bb10f955661ff7641e44c1f6d5be9dd545bsalomon@google.com    fSavedState->ref();
710bfc805bb10f955661ff7641e44c1f6d5be9dd545bsalomon@google.com    if (kReset_ASRInit == init) {
711bfc805bb10f955661ff7641e44c1f6d5be9dd545bsalomon@google.com        // calls the default cons
712bfc805bb10f955661ff7641e44c1f6d5be9dd545bsalomon@google.com        fTempState.init();
713bfc805bb10f955661ff7641e44c1f6d5be9dd545bsalomon@google.com    } else {
714bfc805bb10f955661ff7641e44c1f6d5be9dd545bsalomon@google.com        GrAssert(kPreserve_ASRInit == init);
715bfc805bb10f955661ff7641e44c1f6d5be9dd545bsalomon@google.com        // calls the copy cons
716bfc805bb10f955661ff7641e44c1f6d5be9dd545bsalomon@google.com        fTempState.set(*fSavedState);
717fbf9f30e11f6dfae9203b152092125fe9b47adb8bsalomon@google.com        if (!fTempState.get()->setIdentityViewMatrix()) {
718fbf9f30e11f6dfae9203b152092125fe9b47adb8bsalomon@google.com            // let go of any resources held by the temp
719fbf9f30e11f6dfae9203b152092125fe9b47adb8bsalomon@google.com            fTempState.get()->reset();
720fbf9f30e11f6dfae9203b152092125fe9b47adb8bsalomon@google.com            fDrawTarget = NULL;
721fbf9f30e11f6dfae9203b152092125fe9b47adb8bsalomon@google.com            fSavedState->unref();
722fbf9f30e11f6dfae9203b152092125fe9b47adb8bsalomon@google.com            fSavedState = NULL;
723fbf9f30e11f6dfae9203b152092125fe9b47adb8bsalomon@google.com            return false;
724fbf9f30e11f6dfae9203b152092125fe9b47adb8bsalomon@google.com        }
7253f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    }
726bfc805bb10f955661ff7641e44c1f6d5be9dd545bsalomon@google.com    target->setDrawState(fTempState.get());
727fbf9f30e11f6dfae9203b152092125fe9b47adb8bsalomon@google.com    return true;
7283f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com}
7293f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
7303f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com////////////////////////////////////////////////////////////////////////////////
7313f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
7323f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comGrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry(
7333f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com                                         GrDrawTarget*  target,
7343f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com                                         int vertexCount,
7353f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com                                         int indexCount) {
7363f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    fTarget = NULL;
7379d8e4b7e65a6b644564e2f2b94730f74b88941e5jvanverth@google.com    this->set(target, vertexCount, indexCount);
7383f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com}
739dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com
7403f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comGrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry() {
7413f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    fTarget = NULL;
7423f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com}
7433f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
7443f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comGrDrawTarget::AutoReleaseGeometry::~AutoReleaseGeometry() {
7453f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    this->reset();
7463f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com}
7473f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
7483f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.combool GrDrawTarget::AutoReleaseGeometry::set(GrDrawTarget*  target,
7493f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com                                            int vertexCount,
7503f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com                                            int indexCount) {
7513f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    this->reset();
7523f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    fTarget = target;
7533f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    bool success = true;
7543f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    if (NULL != fTarget) {
7553f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        fTarget = target;
7569d8e4b7e65a6b644564e2f2b94730f74b88941e5jvanverth@google.com        success = target->reserveVertexAndIndexSpace(vertexCount,
757c17542bbc94bd2772a2b60f9e178117f0b9840e4bsalomon@google.com                                                     indexCount,
758c17542bbc94bd2772a2b60f9e178117f0b9840e4bsalomon@google.com                                                     &fVertices,
759c17542bbc94bd2772a2b60f9e178117f0b9840e4bsalomon@google.com                                                     &fIndices);
760c17542bbc94bd2772a2b60f9e178117f0b9840e4bsalomon@google.com        if (!success) {
761c17542bbc94bd2772a2b60f9e178117f0b9840e4bsalomon@google.com            fTarget = NULL;
762c17542bbc94bd2772a2b60f9e178117f0b9840e4bsalomon@google.com            this->reset();
7633f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        }
7643f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    }
7653f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    GrAssert(success == (NULL != fTarget));
7663f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    return success;
7673f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com}
7683f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
7693f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.comvoid GrDrawTarget::AutoReleaseGeometry::reset() {
7703f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    if (NULL != fTarget) {
7713f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        if (NULL != fVertices) {
7723f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com            fTarget->resetVertexSource();
7733f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        }
7743f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        if (NULL != fIndices) {
7753f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com            fTarget->resetIndexSource();
7763f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        }
7773f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        fTarget = NULL;
7783f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    }
7793f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    fVertices = NULL;
7803f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    fIndices = NULL;
7813f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com}
7823f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
783ab3f6ac819d71e8f9eb518454e2706a34b343054bsalomon@google.comGrDrawTarget::AutoClipRestore::AutoClipRestore(GrDrawTarget* target, const SkIRect& newClip) {
784ab3f6ac819d71e8f9eb518454e2706a34b343054bsalomon@google.com    fTarget = target;
785ab3f6ac819d71e8f9eb518454e2706a34b343054bsalomon@google.com    fClip = fTarget->getClip();
786ab3f6ac819d71e8f9eb518454e2706a34b343054bsalomon@google.com    fStack.init();
787ab3f6ac819d71e8f9eb518454e2706a34b343054bsalomon@google.com    fStack.get()->clipDevRect(newClip, SkRegion::kReplace_Op);
788ab3f6ac819d71e8f9eb518454e2706a34b343054bsalomon@google.com    fReplacementClip.fClipStack = fStack.get();
789ab3f6ac819d71e8f9eb518454e2706a34b343054bsalomon@google.com    target->setClip(&fReplacementClip);
790ab3f6ac819d71e8f9eb518454e2706a34b343054bsalomon@google.com}
791ab3f6ac819d71e8f9eb518454e2706a34b343054bsalomon@google.com
79241fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.comnamespace {
79341fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com// returns true if the read/written rect intersects the src/dst and false if not.
79441fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.combool clip_srcrect_and_dstpoint(const GrSurface* dst,
79541fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com                               const GrSurface* src,
796b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com                               const SkIRect& srcRect,
79741fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com                               const SkIPoint& dstPoint,
79841fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com                               SkIRect* clippedSrcRect,
79941fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com                               SkIPoint* clippedDstPoint) {
80041fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com    *clippedSrcRect = srcRect;
80141fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com    *clippedDstPoint = dstPoint;
802c98e389e021a9636542ad3e8751c6ca251e34104skia.committer@gmail.com
80341fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com    // clip the left edge to src and dst bounds, adjusting dstPoint if necessary
80441fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com    if (clippedSrcRect->fLeft < 0) {
80541fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com        clippedDstPoint->fX -= clippedSrcRect->fLeft;
80641fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com        clippedSrcRect->fLeft = 0;
807b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com    }
80841fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com    if (clippedDstPoint->fX < 0) {
80941fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com        clippedSrcRect->fLeft -= clippedDstPoint->fX;
81041fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com        clippedDstPoint->fX = 0;
811b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com    }
812b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com
81341fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com    // clip the top edge to src and dst bounds, adjusting dstPoint if necessary
81441fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com    if (clippedSrcRect->fTop < 0) {
81541fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com        clippedDstPoint->fY -= clippedSrcRect->fTop;
81641fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com        clippedSrcRect->fTop = 0;
817b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com    }
81841fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com    if (clippedDstPoint->fY < 0) {
81941fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com        clippedSrcRect->fTop -= clippedDstPoint->fY;
82041fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com        clippedDstPoint->fY = 0;
821b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com    }
822c98e389e021a9636542ad3e8751c6ca251e34104skia.committer@gmail.com
823b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com    // clip the right edge to the src and dst bounds.
82441fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com    if (clippedSrcRect->fRight > src->width()) {
82541fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com        clippedSrcRect->fRight = src->width();
826b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com    }
82741fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com    if (clippedDstPoint->fX + clippedSrcRect->width() > dst->width()) {
82841fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com        clippedSrcRect->fRight = clippedSrcRect->fLeft + dst->width() - clippedDstPoint->fX;
829b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com    }
830b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com
831b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com    // clip the bottom edge to the src and dst bounds.
83241fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com    if (clippedSrcRect->fBottom > src->height()) {
83341fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com        clippedSrcRect->fBottom = src->height();
834b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com    }
83541fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com    if (clippedDstPoint->fY + clippedSrcRect->height() > dst->height()) {
83641fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com        clippedSrcRect->fBottom = clippedSrcRect->fTop + dst->height() - clippedDstPoint->fY;
837b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com    }
838c98e389e021a9636542ad3e8751c6ca251e34104skia.committer@gmail.com
839b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com    // The above clipping steps may have inverted the rect if it didn't intersect either the src or
840b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com    // dst bounds.
84141fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com    return !clippedSrcRect->isEmpty();
84241fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com}
84341fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com}
84441fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com
84541fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.combool GrDrawTarget::copySurface(GrSurface* dst,
84641fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com                               GrSurface* src,
84741fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com                               const SkIRect& srcRect,
84841fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com                               const SkIPoint& dstPoint) {
84941fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com    GrAssert(NULL != dst);
85041fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com    GrAssert(NULL != src);
85141fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com
85241fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com    SkIRect clippedSrcRect;
85341fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com    SkIPoint clippedDstPoint;
85441fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com    // If the rect is outside the src or dst then we've already succeeded.
85541fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com    if (!clip_srcrect_and_dstpoint(dst,
85641fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com                                   src,
85741fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com                                   srcRect,
85841fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com                                   dstPoint,
85941fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com                                   &clippedSrcRect,
86041fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com                                   &clippedDstPoint)) {
86141fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com        GrAssert(this->canCopySurface(dst, src, srcRect, dstPoint));
862b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com        return true;
863b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com    }
864b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com
865b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com    bool result = this->onCopySurface(dst, src, clippedSrcRect, clippedDstPoint);
866b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com    GrAssert(result == this->canCopySurface(dst, src, clippedSrcRect, clippedDstPoint));
867b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com    return result;
868b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com}
869b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com
870b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.combool GrDrawTarget::canCopySurface(GrSurface* dst,
871b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com                                  GrSurface* src,
872b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com                                  const SkIRect& srcRect,
873b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com                                  const SkIPoint& dstPoint) {
87441fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com    GrAssert(NULL != dst);
87541fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com    GrAssert(NULL != src);
87641fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com
87741fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com    SkIRect clippedSrcRect;
87841fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com    SkIPoint clippedDstPoint;
87941fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com    // If the rect is outside the src or dst then we're guaranteed success
88041fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com    if (!clip_srcrect_and_dstpoint(dst,
88141fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com                                   src,
88241fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com                                   srcRect,
88341fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com                                   dstPoint,
88441fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com                                   &clippedSrcRect,
88541fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com                                   &clippedDstPoint)) {
88641fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com        return true;
88741fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com    }
88841fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com    return this->onCanCopySurface(dst, src, clippedSrcRect, clippedDstPoint);
88941fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com}
89041fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com
89141fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.combool GrDrawTarget::onCanCopySurface(GrSurface* dst,
89241fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com                                    GrSurface* src,
89341fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com                                    const SkIRect& srcRect,
89441fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com                                    const SkIPoint& dstPoint) {
895b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com    // Check that the read/write rects are contained within the src/dst bounds.
896b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com    GrAssert(!srcRect.isEmpty());
897b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com    GrAssert(SkIRect::MakeWH(src->width(), src->height()).contains(srcRect));
898b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com    GrAssert(dstPoint.fX >= 0 && dstPoint.fY >= 0);
899b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com    GrAssert(dstPoint.fX + srcRect.width() <= dst->width() &&
900b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com             dstPoint.fY + srcRect.height() <= dst->height());
901b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com
90241fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com    return !dst->isSameAs(src) && NULL != dst->asRenderTarget() && NULL != src->asTexture();
903b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com}
904b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com
905b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.combool GrDrawTarget::onCopySurface(GrSurface* dst,
906b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com                                 GrSurface* src,
907b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com                                 const SkIRect& srcRect,
908b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com                                 const SkIPoint& dstPoint) {
90941fa4107119cf477b9e014d1f657fcf98164dd8cbsalomon@google.com    if (!GrDrawTarget::onCanCopySurface(dst, src, srcRect, dstPoint)) {
910b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com        return false;
911b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com    }
912b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com
913b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com    GrRenderTarget* rt = dst->asRenderTarget();
914b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com    GrTexture* tex = src->asTexture();
915b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com
916b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com    GrDrawTarget::AutoStateRestore asr(this, kReset_ASRInit);
917b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com    this->drawState()->setRenderTarget(rt);
918b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com    SkMatrix matrix;
919b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com    matrix.setTranslate(SkIntToScalar(srcRect.fLeft - dstPoint.fX),
920b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com                        SkIntToScalar(srcRect.fTop - dstPoint.fY));
921b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com    matrix.postIDiv(tex->width(), tex->height());
922860912a0affd82bc6b30ad9006658df856ca1d17bsalomon@google.com    this->drawState()->addColorTextureEffect(tex, matrix);
923b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com    SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX,
924b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com                                        dstPoint.fY,
925b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com                                        srcRect.width(),
926b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com                                        srcRect.height());
927b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com    this->drawSimpleRect(dstRect);
928b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com    return true;
929b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com}
930b9caacef9583386aecd28188b1dda5aa09dd9e26bsalomon@google.com
931b1bfcd3243f88510896951871c2d846d74a79205bsalomon@google.comvoid GrDrawTarget::initCopySurfaceDstDesc(const GrSurface* src, GrTextureDesc* desc) {
932b1bfcd3243f88510896951871c2d846d74a79205bsalomon@google.com    // Make the dst of the copy be a render target because the default copySurface draws to the dst.
933b1bfcd3243f88510896951871c2d846d74a79205bsalomon@google.com    desc->fOrigin = kDefault_GrSurfaceOrigin;
934b1bfcd3243f88510896951871c2d846d74a79205bsalomon@google.com    desc->fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit;
935b1bfcd3243f88510896951871c2d846d74a79205bsalomon@google.com    desc->fConfig = src->config();
936b1bfcd3243f88510896951871c2d846d74a79205bsalomon@google.com}
937b1bfcd3243f88510896951871c2d846d74a79205bsalomon@google.com
93859831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com///////////////////////////////////////////////////////////////////////////////
93959831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com
940516b4c312ba95ab60863c325482ee6c36618f706bsalomon@google.comSK_DEFINE_INST_COUNT(GrDrawTargetCaps)
94159831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com
942516b4c312ba95ab60863c325482ee6c36618f706bsalomon@google.comvoid GrDrawTargetCaps::reset() {
94359831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com    f8BitPaletteSupport = false;
94459831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com    fNPOTTextureTileSupport = false;
94559831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com    fTwoSidedStencilSupport = false;
94659831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com    fStencilWrapOpsSupport = false;
94759831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com    fHWAALineSupport = false;
94859831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com    fShaderDerivativeSupport = false;
94959831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com    fGeometryShaderSupport = false;
950b691cc7b343bbe193c11aa423f95783c073bef6dskia.committer@gmail.com    fDualSourceBlendingSupport = false;
95159831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com    fBufferLockSupport = false;
95259831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com    fPathStencilingSupport = false;
9530ab0c0141b2da04fe38039410b5f75ef9f90660bcommit-bot@chromium.org    fDstReadInShaderSupport = false;
9540ab0c0141b2da04fe38039410b5f75ef9f90660bcommit-bot@chromium.org    fReuseScratchTextures = true;
95559831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com
95659831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com    fMaxRenderTargetSize = 0;
95759831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com    fMaxTextureSize = 0;
95859831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com    fMaxSampleCount = 0;
95959831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com}
96059831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com
961516b4c312ba95ab60863c325482ee6c36618f706bsalomon@google.comGrDrawTargetCaps& GrDrawTargetCaps::operator=(const GrDrawTargetCaps& other) {
96259831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com    f8BitPaletteSupport = other.f8BitPaletteSupport;
96359831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com    fNPOTTextureTileSupport = other.fNPOTTextureTileSupport;
96459831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com    fTwoSidedStencilSupport = other.fTwoSidedStencilSupport;
96559831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com    fStencilWrapOpsSupport = other.fStencilWrapOpsSupport;
96659831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com    fHWAALineSupport = other.fHWAALineSupport;
96759831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com    fShaderDerivativeSupport = other.fShaderDerivativeSupport;
96859831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com    fGeometryShaderSupport = other.fGeometryShaderSupport;
96959831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com    fDualSourceBlendingSupport = other.fDualSourceBlendingSupport;
97059831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com    fBufferLockSupport = other.fBufferLockSupport;
97159831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com    fPathStencilingSupport = other.fPathStencilingSupport;
9720ab0c0141b2da04fe38039410b5f75ef9f90660bcommit-bot@chromium.org    fDstReadInShaderSupport = other.fDstReadInShaderSupport;
9730ab0c0141b2da04fe38039410b5f75ef9f90660bcommit-bot@chromium.org    fReuseScratchTextures = other.fReuseScratchTextures;
97459831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com
97559831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com    fMaxRenderTargetSize = other.fMaxRenderTargetSize;
97659831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com    fMaxTextureSize = other.fMaxTextureSize;
97759831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com    fMaxSampleCount = other.fMaxSampleCount;
97859831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com
97959831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com    return *this;
98059831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com}
98159831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com
982516b4c312ba95ab60863c325482ee6c36618f706bsalomon@google.comvoid GrDrawTargetCaps::print() const {
9833f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    static const char* gNY[] = {"NO", "YES"};
98459831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com    GrPrintf("8 Bit Palette Support       : %s\n", gNY[f8BitPaletteSupport]);
98559831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com    GrPrintf("NPOT Texture Tile Support   : %s\n", gNY[fNPOTTextureTileSupport]);
98659831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com    GrPrintf("Two Sided Stencil Support   : %s\n", gNY[fTwoSidedStencilSupport]);
98759831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com    GrPrintf("Stencil Wrap Ops  Support   : %s\n", gNY[fStencilWrapOpsSupport]);
98859831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com    GrPrintf("HW AA Lines Support         : %s\n", gNY[fHWAALineSupport]);
98959831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com    GrPrintf("Shader Derivative Support   : %s\n", gNY[fShaderDerivativeSupport]);
99059831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com    GrPrintf("Geometry Shader Support     : %s\n", gNY[fGeometryShaderSupport]);
99159831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com    GrPrintf("Dual Source Blending Support: %s\n", gNY[fDualSourceBlendingSupport]);
99259831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com    GrPrintf("Buffer Lock Support         : %s\n", gNY[fBufferLockSupport]);
99359831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com    GrPrintf("Path Stenciling Support     : %s\n", gNY[fPathStencilingSupport]);
994a54574529842df79f5c41d903cfade74fc7ca5d1bsalomon@google.com    GrPrintf("Dst Read In Shader Support  : %s\n", gNY[fDstReadInShaderSupport]);
9950ab0c0141b2da04fe38039410b5f75ef9f90660bcommit-bot@chromium.org    GrPrintf("Reuse Scratch Textures      : %s\n", gNY[fReuseScratchTextures]);
99659831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com    GrPrintf("Max Texture Size            : %d\n", fMaxTextureSize);
99759831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com    GrPrintf("Max Render Target Size      : %d\n", fMaxRenderTargetSize);
99859831d70980761e3d9403a122c46e996a5d32543bsalomon@google.com    GrPrintf("Max Sample Count            : %d\n", fMaxSampleCount);
9993f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com}
1000