GrDrawTarget.cpp revision e4617bf6d45cdde07f89e341ebf5c485916bf0b2
1ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2010 Google Inc.
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
7ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com */
8ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
9ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
10ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
11ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#include "GrDrawTarget.h"
1226e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com#include "GrContext.h"
13c26d94fd7dc0b00cd6d0e42d28285f4a38aff021bsalomon@google.com#include "GrDrawTargetCaps.h"
148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com#include "GrRenderTarget.h"
1586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com#include "GrTexture.h"
1625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#include "GrVertexBuffer.h"
17ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
185f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com#include "SkStrokeRec.h"
1912b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com
20fa35e3ddcc9d130ce87c927218bdf27879c38711reed@google.comSK_DEFINE_INST_COUNT(GrDrawTarget)
21fa35e3ddcc9d130ce87c927218bdf27879c38711reed@google.com
22ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com////////////////////////////////////////////////////////////////////////////////
23ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
24d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.comGrDrawTarget::DrawInfo& GrDrawTarget::DrawInfo::operator =(const DrawInfo& di) {
25d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    fPrimitiveType  = di.fPrimitiveType;
26d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    fStartVertex    = di.fStartVertex;
27d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    fStartIndex     = di.fStartIndex;
28d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    fVertexCount    = di.fVertexCount;
29d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    fIndexCount     = di.fIndexCount;
30d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com
31d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    fInstanceCount          = di.fInstanceCount;
32d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    fVerticesPerInstance    = di.fVerticesPerInstance;
33d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    fIndicesPerInstance     = di.fIndicesPerInstance;
34d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com
35d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    if (NULL != di.fDevBounds) {
36d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        GrAssert(di.fDevBounds == &di.fDevBoundsStorage);
37d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        fDevBoundsStorage = di.fDevBoundsStorage;
38d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        fDevBounds = &fDevBoundsStorage;
39d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    } else {
40d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        fDevBounds = NULL;
41d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    }
4226e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com
4326e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    fDstCopy = di.fDstCopy;
4426e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com
45d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    return *this;
46d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com}
47d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com
48d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com#if GR_DEBUG
49d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.combool GrDrawTarget::DrawInfo::isInstanced() const {
50d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    if (fInstanceCount > 0) {
51d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        GrAssert(0 == fIndexCount % fIndicesPerInstance);
52d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        GrAssert(0 == fVertexCount % fVerticesPerInstance);
53d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        GrAssert(fIndexCount / fIndicesPerInstance == fInstanceCount);
54d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        GrAssert(fVertexCount / fVerticesPerInstance == fInstanceCount);
55d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        // there is no way to specify a non-zero start index to drawIndexedInstances().
56d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        GrAssert(0 == fStartIndex);
57d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        return true;
58d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    } else {
59d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        GrAssert(!fVerticesPerInstance);
60d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        GrAssert(!fIndicesPerInstance);
61d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        return false;
62d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    }
63d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com}
64d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com#endif
65d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com
66d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.comvoid GrDrawTarget::DrawInfo::adjustInstanceCount(int instanceOffset) {
67d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    GrAssert(this->isInstanced());
68d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    GrAssert(instanceOffset + fInstanceCount >= 0);
69d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    fInstanceCount += instanceOffset;
70d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    fVertexCount = fVerticesPerInstance * fInstanceCount;
71d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    fIndexCount = fIndicesPerInstance * fInstanceCount;
72d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com}
73d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com
74d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.comvoid GrDrawTarget::DrawInfo::adjustStartVertex(int vertexOffset) {
75d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    fStartVertex += vertexOffset;
76d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    GrAssert(fStartVertex >= 0);
77d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com}
78d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com
79d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.comvoid GrDrawTarget::DrawInfo::adjustStartIndex(int indexOffset) {
80d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    GrAssert(this->isIndexed());
81d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    fStartIndex += indexOffset;
82d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    GrAssert(fStartIndex >= 0);
83d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com}
84d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com
85d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com////////////////////////////////////////////////////////////////////////////////
86d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com
8725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#define DEBUG_INVAL_BUFFER 0xdeadcafe
8825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#define DEBUG_INVAL_START_IDX -1
8925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
906e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.comGrDrawTarget::GrDrawTarget(GrContext* context)
916e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com    : fClip(NULL)
926e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com    , fContext(context) {
936e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com    GrAssert(NULL != context);
946e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com
95a5d056ae0b04021dfb44c2c7a3d6a34e060261b8bsalomon@google.com    fDrawState = &fDefaultDrawState;
96a5d056ae0b04021dfb44c2c7a3d6a34e060261b8bsalomon@google.com    // We assume that fDrawState always owns a ref to the object it points at.
97a5d056ae0b04021dfb44c2c7a3d6a34e060261b8bsalomon@google.com    fDefaultDrawState.ref();
9825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometrySrcState& geoSrc = fGeoSrcStateStack.push_back();
99ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#if GR_DEBUG
10025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fVertexCount = DEBUG_INVAL_START_IDX;
10125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
10225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fIndexCount = DEBUG_INVAL_START_IDX;
10325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
104ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#endif
10525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fVertexSrc = kNone_GeometrySrcType;
10625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fIndexSrc  = kNone_GeometrySrcType;
10725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
10825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
10925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comGrDrawTarget::~GrDrawTarget() {
1104a018bb20bf969a38ec11d9506843f06366dfa7cbsalomon@google.com    GrAssert(1 == fGeoSrcStateStack.count());
1110e51577a14f903ffeafa117a75954baeb173ffb9humper@google.com    SkDEBUGCODE(GeometrySrcState& geoSrc = fGeoSrcStateStack.back());
1124a018bb20bf969a38ec11d9506843f06366dfa7cbsalomon@google.com    GrAssert(kNone_GeometrySrcType == geoSrc.fIndexSrc);
1134a018bb20bf969a38ec11d9506843f06366dfa7cbsalomon@google.com    GrAssert(kNone_GeometrySrcType == geoSrc.fVertexSrc);
114a5d056ae0b04021dfb44c2c7a3d6a34e060261b8bsalomon@google.com    fDrawState->unref();
1154a018bb20bf969a38ec11d9506843f06366dfa7cbsalomon@google.com}
1164a018bb20bf969a38ec11d9506843f06366dfa7cbsalomon@google.com
1174a018bb20bf969a38ec11d9506843f06366dfa7cbsalomon@google.comvoid GrDrawTarget::releaseGeometry() {
11825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    int popCnt = fGeoSrcStateStack.count() - 1;
11925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    while (popCnt) {
12025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        this->popGeometrySource();
12125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        --popCnt;
12225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
1234a018bb20bf969a38ec11d9506843f06366dfa7cbsalomon@google.com    this->resetVertexSource();
1244a018bb20bf969a38ec11d9506843f06366dfa7cbsalomon@google.com    this->resetIndexSource();
125ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
126ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
127beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.comvoid GrDrawTarget::setClip(const GrClipData* clip) {
12886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    clipWillBeSet(clip);
129ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fClip = clip;
130ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
131ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
132beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.comconst GrClipData* GrDrawTarget::getClip() const {
133ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    return fClip;
134ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
135ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
136a5d056ae0b04021dfb44c2c7a3d6a34e060261b8bsalomon@google.comvoid GrDrawTarget::setDrawState(GrDrawState*  drawState) {
137a5d056ae0b04021dfb44c2c7a3d6a34e060261b8bsalomon@google.com    GrAssert(NULL != fDrawState);
138a5d056ae0b04021dfb44c2c7a3d6a34e060261b8bsalomon@google.com    if (NULL == drawState) {
139a5d056ae0b04021dfb44c2c7a3d6a34e060261b8bsalomon@google.com        drawState = &fDefaultDrawState;
140a5d056ae0b04021dfb44c2c7a3d6a34e060261b8bsalomon@google.com    }
141a5d056ae0b04021dfb44c2c7a3d6a34e060261b8bsalomon@google.com    if (fDrawState != drawState) {
142a5d056ae0b04021dfb44c2c7a3d6a34e060261b8bsalomon@google.com        fDrawState->unref();
143a5d056ae0b04021dfb44c2c7a3d6a34e060261b8bsalomon@google.com        drawState->ref();
144a5d056ae0b04021dfb44c2c7a3d6a34e060261b8bsalomon@google.com        fDrawState = drawState;
145a5d056ae0b04021dfb44c2c7a3d6a34e060261b8bsalomon@google.com    }
146a5d056ae0b04021dfb44c2c7a3d6a34e060261b8bsalomon@google.com}
147a5d056ae0b04021dfb44c2c7a3d6a34e060261b8bsalomon@google.com
148b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.combool GrDrawTarget::reserveVertexSpace(size_t vertexSize,
14925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                      int vertexCount,
15025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                      void** vertices) {
15125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
15225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    bool acquired = false;
15325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    if (vertexCount > 0) {
15425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        GrAssert(NULL != vertices);
15525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        this->releasePreviousVertexSource();
15625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        geoSrc.fVertexSrc = kNone_GeometrySrcType;
157ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
158b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com        acquired = this->onReserveVertexSpace(vertexSize,
15925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                              vertexCount,
16025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                              vertices);
16125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
16225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    if (acquired) {
16325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        geoSrc.fVertexSrc = kReserved_GeometrySrcType;
16425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        geoSrc.fVertexCount = vertexCount;
165b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com        geoSrc.fVertexSize = vertexSize;
16625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    } else if (NULL != vertices) {
16725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        *vertices = NULL;
16825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
16925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    return acquired;
17025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
17125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
17225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.combool GrDrawTarget::reserveIndexSpace(int indexCount,
17325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                     void** indices) {
17425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
17525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    bool acquired = false;
17625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    if (indexCount > 0) {
17725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        GrAssert(NULL != indices);
17825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        this->releasePreviousIndexSource();
17925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        geoSrc.fIndexSrc = kNone_GeometrySrcType;
180d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
18125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        acquired = this->onReserveIndexSpace(indexCount, indices);
182ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
18325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    if (acquired) {
18425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        geoSrc.fIndexSrc = kReserved_GeometrySrcType;
18525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        geoSrc.fIndexCount = indexCount;
18625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    } else if (NULL != indices) {
18725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        *indices = NULL;
18825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
18925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    return acquired;
190d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
191ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
192ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
193b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.combool GrDrawTarget::reserveVertexAndIndexSpace(int vertexCount,
194e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com                                              int indexCount,
195e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com                                              void** vertices,
196e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com                                              void** indices) {
197b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com    size_t vertexSize = this->drawState()->getVertexSize();
198b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com    this->willReserveVertexAndIndexSpace(vertexCount, indexCount);
199e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com    if (vertexCount) {
200b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com        if (!this->reserveVertexSpace(vertexSize, vertexCount, vertices)) {
201e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com            if (indexCount) {
202e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com                this->resetIndexSource();
203e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com            }
204e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com            return false;
205e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com        }
206e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com    }
207e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com    if (indexCount) {
208e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com        if (!this->reserveIndexSpace(indexCount, indices)) {
209e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com            if (vertexCount) {
210e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com                this->resetVertexSource();
211e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com            }
212e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com            return false;
213e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com        }
214e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com    }
215e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com    return true;
216e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com}
217e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com
218b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.combool GrDrawTarget::geometryHints(int32_t* vertexCount,
219ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com                                 int32_t* indexCount) const {
220ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    if (NULL != vertexCount) {
221ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        *vertexCount = -1;
222ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
223ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    if (NULL != indexCount) {
224ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        *indexCount = -1;
225ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
226ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    return false;
227ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
228ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
22925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrDrawTarget::releasePreviousVertexSource() {
23025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
23125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    switch (geoSrc.fVertexSrc) {
23225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        case kNone_GeometrySrcType:
23325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            break;
23425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        case kArray_GeometrySrcType:
23525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            this->releaseVertexArray();
23625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            break;
23725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        case kReserved_GeometrySrcType:
23825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            this->releaseReservedVertexSpace();
23925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            break;
24025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        case kBuffer_GeometrySrcType:
24125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            geoSrc.fVertexBuffer->unref();
24225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#if GR_DEBUG
24325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
24425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#endif
24525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            break;
24625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        default:
24725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            GrCrash("Unknown Vertex Source Type.");
24825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            break;
24925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
25025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
25125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
25225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrDrawTarget::releasePreviousIndexSource() {
25325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
25425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    switch (geoSrc.fIndexSrc) {
25525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        case kNone_GeometrySrcType:   // these two don't require
25625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            break;
25725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        case kArray_GeometrySrcType:
25825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            this->releaseIndexArray();
25925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            break;
26025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        case kReserved_GeometrySrcType:
26125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            this->releaseReservedIndexSpace();
26225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            break;
26325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        case kBuffer_GeometrySrcType:
26425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            geoSrc.fIndexBuffer->unref();
26525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#if GR_DEBUG
26625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
26725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#endif
26825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            break;
26925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        default:
27025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            GrCrash("Unknown Index Source Type.");
27125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            break;
27225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
273ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
274ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
275b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.comvoid GrDrawTarget::setVertexSourceToArray(const void* vertexArray,
2761c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com                                          int vertexCount) {
27725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    this->releasePreviousVertexSource();
27825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
27925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fVertexSrc = kArray_GeometrySrcType;
280b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com    geoSrc.fVertexSize = this->drawState()->getVertexSize();
28125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fVertexCount = vertexCount;
282bcdbbe61e1a3f89545b2c1461164f0f8bf5f0797bsalomon@google.com    this->onSetVertexSourceToArray(vertexArray, vertexCount);
283ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
284ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
2851c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.comvoid GrDrawTarget::setIndexSourceToArray(const void* indexArray,
2861c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com                                         int indexCount) {
28725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    this->releasePreviousIndexSource();
28825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
28925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fIndexSrc = kArray_GeometrySrcType;
29025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fIndexCount = indexCount;
291bcdbbe61e1a3f89545b2c1461164f0f8bf5f0797bsalomon@google.com    this->onSetIndexSourceToArray(indexArray, indexCount);
292ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
293ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
294b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.comvoid GrDrawTarget::setVertexSourceToBuffer(const GrVertexBuffer* buffer) {
29525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    this->releasePreviousVertexSource();
29625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
29725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fVertexSrc    = kBuffer_GeometrySrcType;
29825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fVertexBuffer = buffer;
29925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    buffer->ref();
300b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com    geoSrc.fVertexSize = this->drawState()->getVertexSize();
301ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
302ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
303ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrDrawTarget::setIndexSourceToBuffer(const GrIndexBuffer* buffer) {
30425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    this->releasePreviousIndexSource();
30525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
30625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fIndexSrc     = kBuffer_GeometrySrcType;
30725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fIndexBuffer  = buffer;
30825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    buffer->ref();
309ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
310ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
31125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrDrawTarget::resetVertexSource() {
31225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    this->releasePreviousVertexSource();
31325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
31425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fVertexSrc = kNone_GeometrySrcType;
31525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
31625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
31725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrDrawTarget::resetIndexSource() {
31825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    this->releasePreviousIndexSource();
31925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
32025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fIndexSrc = kNone_GeometrySrcType;
32125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
32225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
32325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrDrawTarget::pushGeometrySource() {
32425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    this->geometrySourceWillPush();
32525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometrySrcState& newState = fGeoSrcStateStack.push_back();
32625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    newState.fIndexSrc = kNone_GeometrySrcType;
32725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    newState.fVertexSrc = kNone_GeometrySrcType;
32825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#if GR_DEBUG
32925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    newState.fVertexCount  = ~0;
33025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    newState.fVertexBuffer = (GrVertexBuffer*)~0;
33125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    newState.fIndexCount   = ~0;
33225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    newState.fIndexBuffer = (GrIndexBuffer*)~0;
33325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#endif
33425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
33525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
33625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrDrawTarget::popGeometrySource() {
33725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    // if popping last element then pops are unbalanced with pushes
33825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(fGeoSrcStateStack.count() > 1);
339d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
34025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    this->geometrySourceWillPop(fGeoSrcStateStack.fromBack(1));
34125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    this->releasePreviousVertexSource();
34225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    this->releasePreviousIndexSource();
34325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    fGeoSrcStateStack.pop_back();
34425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
34525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
34625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com////////////////////////////////////////////////////////////////////////////////
34725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
348e826262939dac3e67cb5ce66d4b9faeb8e2538e6bsalomon@google.combool GrDrawTarget::checkDraw(GrPrimitiveType type, int startVertex,
349e826262939dac3e67cb5ce66d4b9faeb8e2538e6bsalomon@google.com                             int startIndex, int vertexCount,
350e826262939dac3e67cb5ce66d4b9faeb8e2538e6bsalomon@google.com                             int indexCount) const {
351cddaf340f1474cc1ff429b8ef9bc8739c72f80babsalomon@google.com    const GrDrawState& drawState = this->getDrawState();
35225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#if GR_DEBUG
353e826262939dac3e67cb5ce66d4b9faeb8e2538e6bsalomon@google.com    const GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
35425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    int maxVertex = startVertex + vertexCount;
35525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    int maxValidVertex;
35625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    switch (geoSrc.fVertexSrc) {
35725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        case kNone_GeometrySrcType:
358e826262939dac3e67cb5ce66d4b9faeb8e2538e6bsalomon@google.com            GrCrash("Attempting to draw without vertex src.");
35925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        case kReserved_GeometrySrcType: // fallthrough
36025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        case kArray_GeometrySrcType:
36125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            maxValidVertex = geoSrc.fVertexCount;
36225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            break;
36325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        case kBuffer_GeometrySrcType:
364b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com            maxValidVertex = geoSrc.fVertexBuffer->sizeInBytes() / geoSrc.fVertexSize;
36525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            break;
36625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
36725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    if (maxVertex > maxValidVertex) {
368e826262939dac3e67cb5ce66d4b9faeb8e2538e6bsalomon@google.com        GrCrash("Drawing outside valid vertex range.");
36925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
370e826262939dac3e67cb5ce66d4b9faeb8e2538e6bsalomon@google.com    if (indexCount > 0) {
371e826262939dac3e67cb5ce66d4b9faeb8e2538e6bsalomon@google.com        int maxIndex = startIndex + indexCount;
372e826262939dac3e67cb5ce66d4b9faeb8e2538e6bsalomon@google.com        int maxValidIndex;
373e826262939dac3e67cb5ce66d4b9faeb8e2538e6bsalomon@google.com        switch (geoSrc.fIndexSrc) {
374e826262939dac3e67cb5ce66d4b9faeb8e2538e6bsalomon@google.com            case kNone_GeometrySrcType:
375e826262939dac3e67cb5ce66d4b9faeb8e2538e6bsalomon@google.com                GrCrash("Attempting to draw indexed geom without index src.");
376e826262939dac3e67cb5ce66d4b9faeb8e2538e6bsalomon@google.com            case kReserved_GeometrySrcType: // fallthrough
377e826262939dac3e67cb5ce66d4b9faeb8e2538e6bsalomon@google.com            case kArray_GeometrySrcType:
378e826262939dac3e67cb5ce66d4b9faeb8e2538e6bsalomon@google.com                maxValidIndex = geoSrc.fIndexCount;
379e826262939dac3e67cb5ce66d4b9faeb8e2538e6bsalomon@google.com                break;
380e826262939dac3e67cb5ce66d4b9faeb8e2538e6bsalomon@google.com            case kBuffer_GeometrySrcType:
381e826262939dac3e67cb5ce66d4b9faeb8e2538e6bsalomon@google.com                maxValidIndex = geoSrc.fIndexBuffer->sizeInBytes() / sizeof(uint16_t);
382e826262939dac3e67cb5ce66d4b9faeb8e2538e6bsalomon@google.com                break;
383e826262939dac3e67cb5ce66d4b9faeb8e2538e6bsalomon@google.com        }
384e826262939dac3e67cb5ce66d4b9faeb8e2538e6bsalomon@google.com        if (maxIndex > maxValidIndex) {
385e826262939dac3e67cb5ce66d4b9faeb8e2538e6bsalomon@google.com            GrCrash("Index reads outside valid index range.");
386e826262939dac3e67cb5ce66d4b9faeb8e2538e6bsalomon@google.com        }
38725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
388b4725b4ee617a6a2524765f79310714a5dad4b6absalomon@google.com
389cddaf340f1474cc1ff429b8ef9bc8739c72f80babsalomon@google.com    GrAssert(NULL != drawState.getRenderTarget());
390cddaf340f1474cc1ff429b8ef9bc8739c72f80babsalomon@google.com    for (int s = 0; s < GrDrawState::kNumStages; ++s) {
391cddaf340f1474cc1ff429b8ef9bc8739c72f80babsalomon@google.com        if (drawState.isStageEnabled(s)) {
3926340a41108633ac1ce5941e5cd30538630c4c55bbsalomon@google.com            const GrEffectRef& effect = *drawState.getStage(s).getEffect();
393021fc736f89fddac4f26b3f32f50263ff8fe3279bsalomon@google.com            int numTextures = effect->numTextures();
394cddaf340f1474cc1ff429b8ef9bc8739c72f80babsalomon@google.com            for (int t = 0; t < numTextures; ++t) {
395021fc736f89fddac4f26b3f32f50263ff8fe3279bsalomon@google.com                GrTexture* texture = effect->texture(t);
396cddaf340f1474cc1ff429b8ef9bc8739c72f80babsalomon@google.com                GrAssert(texture->asRenderTarget() != drawState.getRenderTarget());
397cddaf340f1474cc1ff429b8ef9bc8739c72f80babsalomon@google.com            }
398b4725b4ee617a6a2524765f79310714a5dad4b6absalomon@google.com        }
399b4725b4ee617a6a2524765f79310714a5dad4b6absalomon@google.com    }
400ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org
401ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org    GrAssert(drawState.validateVertexAttribs());
40225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#endif
4038f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    if (NULL == drawState.getRenderTarget()) {
4040ba52fcf93d52a3f230d1f185eea0c8719c176fbbsalomon@google.com        return false;
4050ba52fcf93d52a3f230d1f185eea0c8719c176fbbsalomon@google.com    }
406e826262939dac3e67cb5ce66d4b9faeb8e2538e6bsalomon@google.com    return true;
407e826262939dac3e67cb5ce66d4b9faeb8e2538e6bsalomon@google.com}
408e826262939dac3e67cb5ce66d4b9faeb8e2538e6bsalomon@google.com
40926e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.combool GrDrawTarget::setupDstReadIfNecessary(DrawInfo* info) {
410bb5c46591c50d05418467cd1c4e927ceb85c2ba9commit-bot@chromium.org    if (!this->getDrawState().willEffectReadDst()) {
41126e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com        return true;
41226e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    }
41326e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    GrRenderTarget* rt = this->drawState()->getRenderTarget();
41426e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    // If the dst is not a texture then we don't currently have a way of copying the
415e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    // texture. TODO: API-specific impl of onCopySurface that can handle more cases.
41626e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    if (NULL == rt->asTexture()) {
41726e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com        GrPrintf("Reading Dst of non-texture render target is not currently supported.\n");
41826e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com        return false;
41926e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    }
42026e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com
421bb5c46591c50d05418467cd1c4e927ceb85c2ba9commit-bot@chromium.org    const GrClipData* clip = this->getClip();
422bb5c46591c50d05418467cd1c4e927ceb85c2ba9commit-bot@chromium.org    GrIRect copyRect;
423bb5c46591c50d05418467cd1c4e927ceb85c2ba9commit-bot@chromium.org    clip->getConservativeBounds(this->getDrawState().getRenderTarget(), &copyRect);
424bb5c46591c50d05418467cd1c4e927ceb85c2ba9commit-bot@chromium.org    SkIRect drawIBounds;
425bb5c46591c50d05418467cd1c4e927ceb85c2ba9commit-bot@chromium.org    if (info->getDevIBounds(&drawIBounds)) {
426bb5c46591c50d05418467cd1c4e927ceb85c2ba9commit-bot@chromium.org        if (!copyRect.intersect(drawIBounds)) {
427bb5c46591c50d05418467cd1c4e927ceb85c2ba9commit-bot@chromium.org#if GR_DEBUG
428bb5c46591c50d05418467cd1c4e927ceb85c2ba9commit-bot@chromium.org            GrPrintf("Missed an early reject. Bailing on draw from setupDstReadIfNecessary.\n");
429bb5c46591c50d05418467cd1c4e927ceb85c2ba9commit-bot@chromium.org#endif
430bb5c46591c50d05418467cd1c4e927ceb85c2ba9commit-bot@chromium.org            return false;
431bb5c46591c50d05418467cd1c4e927ceb85c2ba9commit-bot@chromium.org        }
432bb5c46591c50d05418467cd1c4e927ceb85c2ba9commit-bot@chromium.org    } else {
433bb5c46591c50d05418467cd1c4e927ceb85c2ba9commit-bot@chromium.org#if GR_DEBUG
434bb5c46591c50d05418467cd1c4e927ceb85c2ba9commit-bot@chromium.org        //GrPrintf("No dev bounds when dst copy is made.\n");
435bb5c46591c50d05418467cd1c4e927ceb85c2ba9commit-bot@chromium.org#endif
436bb5c46591c50d05418467cd1c4e927ceb85c2ba9commit-bot@chromium.org    }
43705a2ee052c9ef4c781b7b590b00b3d2da3b3449askia.committer@gmail.com
43826e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    // The draw will resolve dst if it has MSAA. Two things to consider in the future:
43926e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    // 1) to make the dst values be pre-resolve we'd need to be able to copy to MSAA
44026e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    // texture and sample it correctly in the shader. 2) If 1 isn't available then we
44126e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    // should just resolve and use the resolved texture directly rather than making a
44226e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    // copy of it.
44326e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    GrTextureDesc desc;
44426e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit;
445bb5c46591c50d05418467cd1c4e927ceb85c2ba9commit-bot@chromium.org    desc.fWidth = copyRect.width();
446bb5c46591c50d05418467cd1c4e927ceb85c2ba9commit-bot@chromium.org    desc.fHeight = copyRect.height();
44726e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    desc.fSampleCnt = 0;
44826e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    desc.fConfig = rt->config();
44926e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com
45026e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    GrAutoScratchTexture ast(fContext, desc, GrContext::kApprox_ScratchTexMatch);
45126e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com
45226e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    if (NULL == ast.texture()) {
45326e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com        GrPrintf("Failed to create temporary copy of destination texture.\n");
45426e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com        return false;
45526e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    }
456e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    SkIPoint dstPoint = {0, 0};
457e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    if (this->copySurface(ast.texture(), rt, copyRect, dstPoint)) {
458e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com        info->fDstCopy.setTexture(ast.texture());
459e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com        info->fDstCopy.setOffset(copyRect.fLeft, copyRect.fTop);
460e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com        return true;
461e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    } else {
462e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com        return false;
463e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    }
46426e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com}
46526e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com
466d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.comvoid GrDrawTarget::drawIndexed(GrPrimitiveType type,
467d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com                               int startVertex,
468d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com                               int startIndex,
469d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com                               int vertexCount,
470d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com                               int indexCount,
471d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com                               const SkRect* devBounds) {
47274749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com    if (indexCount > 0 && this->checkDraw(type, startVertex, startIndex, vertexCount, indexCount)) {
47374749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com        DrawInfo info;
47474749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com        info.fPrimitiveType = type;
47574749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com        info.fStartVertex   = startVertex;
47674749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com        info.fStartIndex    = startIndex;
47774749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com        info.fVertexCount   = vertexCount;
47874749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com        info.fIndexCount    = indexCount;
479d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com
480d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        info.fInstanceCount         = 0;
481d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        info.fVerticesPerInstance   = 0;
482d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        info.fIndicesPerInstance    = 0;
483d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com
484d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        if (NULL != devBounds) {
485d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com            info.setDevBounds(*devBounds);
486d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        }
48726e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com        // TODO: We should continue with incorrect blending.
48826e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com        if (!this->setupDstReadIfNecessary(&info)) {
48926e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com            return;
49026e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com        }
49174749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com        this->onDraw(info);
4928214587a79c0a4398664289c4d1ce2c0bf542b42bsalomon@google.com    }
49325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
49425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
49525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrDrawTarget::drawNonIndexed(GrPrimitiveType type,
49625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                  int startVertex,
497d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com                                  int vertexCount,
498d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com                                  const SkRect* devBounds) {
49974749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com    if (vertexCount > 0 && this->checkDraw(type, startVertex, -1, vertexCount, -1)) {
50074749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com        DrawInfo info;
50174749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com        info.fPrimitiveType = type;
50274749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com        info.fStartVertex   = startVertex;
50374749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com        info.fStartIndex    = 0;
50474749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com        info.fVertexCount   = vertexCount;
50574749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com        info.fIndexCount    = 0;
506d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com
507d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        info.fInstanceCount         = 0;
508d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        info.fVerticesPerInstance   = 0;
509d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        info.fIndicesPerInstance    = 0;
510d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com
511d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        if (NULL != devBounds) {
512d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com            info.setDevBounds(*devBounds);
513d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        }
51426e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com        // TODO: We should continue with incorrect blending.
51526e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com        if (!this->setupDstReadIfNecessary(&info)) {
51626e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com            return;
51726e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com        }
51874749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com        this->onDraw(info);
5198214587a79c0a4398664289c4d1ce2c0bf542b42bsalomon@google.com    }
52025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
52125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
5225f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.comvoid GrDrawTarget::stencilPath(const GrPath* path, const SkStrokeRec& stroke, SkPath::FillType fill) {
52364aef2bacd1f5c25ffd9347aabd6265c9b60c0f4bsalomon@google.com    // TODO: extract portions of checkDraw that are relevant to path stenciling.
524ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    GrAssert(NULL != path);
525bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    GrAssert(this->caps()->pathStencilingSupport());
5265f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com    GrAssert(!stroke.isHairlineStyle());
5275f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com    GrAssert(!SkPath::IsInverseFillType(fill));
52812b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com    this->onStencilPath(path, stroke, fill);
52964aef2bacd1f5c25ffd9347aabd6265c9b60c0f4bsalomon@google.com}
53064aef2bacd1f5c25ffd9347aabd6265c9b60c0f4bsalomon@google.com
53125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com////////////////////////////////////////////////////////////////////////////////
53286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
53386c1f71625970610e768d3bf26c933db2cd685babsalomon@google.combool GrDrawTarget::willUseHWAALines() const {
5342b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com    // There is a conflict between using smooth lines and our use of premultiplied alpha. Smooth
5352b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com    // lines tweak the incoming alpha value but not in a premul-alpha way. So we only use them when
5362b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com    // our alpha is 0xff and tweaking the color for partial coverage is OK
537bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    if (!this->caps()->hwAALineSupport() ||
5388f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        !this->getDrawState().isHWAntialiasState()) {
53986c1f71625970610e768d3bf26c933db2cd685babsalomon@google.com        return false;
54086c1f71625970610e768d3bf26c933db2cd685babsalomon@google.com    }
5412b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com    GrDrawState::BlendOptFlags opts = this->getDrawState().getBlendOpts();
5422b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com    return (GrDrawState::kDisableBlend_BlendOptFlag & opts) &&
5432b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com           (GrDrawState::kCoverageAsAlpha_BlendOptFlag & opts);
544d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com}
545d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com
546d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.combool GrDrawTarget::canApplyCoverage() const {
54786c1f71625970610e768d3bf26c933db2cd685babsalomon@google.com    // we can correctly apply coverage if a) we have dual source blending
54886c1f71625970610e768d3bf26c933db2cd685babsalomon@google.com    // or b) one of our blend optimizations applies.
549bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    return this->caps()->dualSourceBlendingSupport() ||
5502b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com           GrDrawState::kNone_BlendOpt != this->getDrawState().getBlendOpts(true);
551471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com}
552471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com
553934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com////////////////////////////////////////////////////////////////////////////////
554934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com
555934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.comvoid GrDrawTarget::drawIndexedInstances(GrPrimitiveType type,
556934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com                                        int instanceCount,
557934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com                                        int verticesPerInstance,
558d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com                                        int indicesPerInstance,
559d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com                                        const SkRect* devBounds) {
560934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com    if (!verticesPerInstance || !indicesPerInstance) {
561934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        return;
562934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com    }
563934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com
564d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    int maxInstancesPerDraw = this->indexCountInCurrentSource() / indicesPerInstance;
565d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    if (!maxInstancesPerDraw) {
566934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        return;
567934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com    }
568934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com
569d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    DrawInfo info;
570d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    info.fPrimitiveType = type;
571d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    info.fStartIndex = 0;
572d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    info.fStartVertex = 0;
573d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    info.fIndicesPerInstance = indicesPerInstance;
574d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    info.fVerticesPerInstance = verticesPerInstance;
575d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com
576d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    // Set the same bounds for all the draws.
577d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    if (NULL != devBounds) {
578d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        info.setDevBounds(*devBounds);
579d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    }
58026e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    // TODO: We should continue with incorrect blending.
58126e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    if (!this->setupDstReadIfNecessary(&info)) {
58226e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com        return;
58326e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    }
584d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com
585934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com    while (instanceCount) {
586d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        info.fInstanceCount = GrMin(instanceCount, maxInstancesPerDraw);
587d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        info.fVertexCount = info.fInstanceCount * verticesPerInstance;
588d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        info.fIndexCount = info.fInstanceCount * indicesPerInstance;
589d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com
590d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        if (this->checkDraw(type,
591d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com                            info.fStartVertex,
592d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com                            info.fStartIndex,
593d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com                            info.fVertexCount,
594d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com                            info.fIndexCount)) {
595d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com            this->onDraw(info);
596d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        }
597d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        info.fStartVertex += info.fVertexCount;
598d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        instanceCount -= info.fInstanceCount;
599934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com    }
600934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com}
6013d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com
60225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com////////////////////////////////////////////////////////////////////////////////
60325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
6040406b9e1faee06c6ecb2732a1bcf3b0e53104e07bsalomon@google.comvoid GrDrawTarget::onDrawRect(const GrRect& rect,
6050406b9e1faee06c6ecb2732a1bcf3b0e53104e07bsalomon@google.com                              const SkMatrix* matrix,
6060406b9e1faee06c6ecb2732a1bcf3b0e53104e07bsalomon@google.com                              const GrRect* localRect,
6070406b9e1faee06c6ecb2732a1bcf3b0e53104e07bsalomon@google.com                              const SkMatrix* localMatrix) {
6089b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    // position + (optional) texture coord
6099b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    static const GrVertexAttrib kAttribs[] = {
610054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com        {kVec2f_GrVertexAttribType, 0,               kPosition_GrVertexAttribBinding},
611054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com        {kVec2f_GrVertexAttribType, sizeof(GrPoint), kLocalCoord_GrVertexAttribBinding}
6129b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    };
6139b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    int attribCount = 1;
614d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com
615c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com    if (NULL != localRect) {
6169b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        attribCount = 2;
61786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    }
618dea2f8d86378b791a2de94384a18e29f13f65a3ebsalomon@google.com
619d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    GrDrawState::AutoViewMatrixRestore avmr;
620d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    if (NULL != matrix) {
621c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        avmr.set(this->drawState(), *matrix);
62286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    }
623a31082685544d0ae4c0b203d7f5ff960640ed8dfbsalomon@google.com
6249b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    this->drawState()->setVertexAttribs(kAttribs, attribCount);
625b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com    AutoReleaseGeometry geo(this, 4, 0);
626d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    if (!geo.succeeded()) {
627d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        GrPrintf("Failed to get space for vertices!\n");
628d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        return;
62986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    }
63086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
6319b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    size_t vsize = this->drawState()->getVertexSize();
632d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    geo.positions()->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, vsize);
633c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com    if (NULL != localRect) {
6349b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        GrAssert(attribCount == 2);
6359b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        GrPoint* coords = GrTCast<GrPoint*>(GrTCast<intptr_t>(geo.vertices()) +
6369b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com                                            kAttribs[1].fOffset);
637c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        coords->setRectFan(localRect->fLeft, localRect->fTop,
638c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com                           localRect->fRight, localRect->fBottom,
639c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com                           vsize);
640c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        if (NULL != localMatrix) {
641c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com            localMatrix->mapPointsWithStride(coords, vsize, 4);
64286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        }
64386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    }
644bb5c46591c50d05418467cd1c4e927ceb85c2ba9commit-bot@chromium.org    SkTLazy<SkRect> bounds;
645bb5c46591c50d05418467cd1c4e927ceb85c2ba9commit-bot@chromium.org    if (this->getDrawState().willEffectReadDst()) {
646bb5c46591c50d05418467cd1c4e927ceb85c2ba9commit-bot@chromium.org        bounds.init();
647bb5c46591c50d05418467cd1c4e927ceb85c2ba9commit-bot@chromium.org        this->getDrawState().getViewMatrix().mapRect(bounds.get(), rect);
648bb5c46591c50d05418467cd1c4e927ceb85c2ba9commit-bot@chromium.org    }
6498b129aa3379ece6c43d9ce2ad0cdeafb089b7eb5robertphillips@google.com
650bb5c46591c50d05418467cd1c4e927ceb85c2ba9commit-bot@chromium.org    this->drawNonIndexed(kTriangleFan_GrPrimitiveType, 0, 4, bounds.getMaybeNull());
65186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com}
65286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
65302ddc8b85ace91b15feb329a6a1d5d62b2b846c6bsalomon@google.comvoid GrDrawTarget::clipWillBeSet(const GrClipData* clipData) {
65402ddc8b85ace91b15feb329a6a1d5d62b2b846c6bsalomon@google.com}
65502ddc8b85ace91b15feb329a6a1d5d62b2b846c6bsalomon@google.com
65625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com////////////////////////////////////////////////////////////////////////////////
6577ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com
65806afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.comGrDrawTarget::AutoStateRestore::AutoStateRestore() {
65906afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com    fDrawTarget = NULL;
66006afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com}
661ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
662873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.comGrDrawTarget::AutoStateRestore::AutoStateRestore(GrDrawTarget* target,
663873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com                                                 ASRInit init) {
664873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com    fDrawTarget = NULL;
665873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com    this->set(target, init);
666ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
667ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
668ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrDrawTarget::AutoStateRestore::~AutoStateRestore() {
6697d34d2eecc40d150d867e37d5160a1bc3cfccbdebsalomon@google.com    if (NULL != fDrawTarget) {
670873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com        fDrawTarget->setDrawState(fSavedState);
671873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com        fSavedState->unref();
6727d34d2eecc40d150d867e37d5160a1bc3cfccbdebsalomon@google.com    }
673ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
6747d34d2eecc40d150d867e37d5160a1bc3cfccbdebsalomon@google.com
675873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.comvoid GrDrawTarget::AutoStateRestore::set(GrDrawTarget* target, ASRInit init) {
676873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com    GrAssert(NULL == fDrawTarget);
677873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com    fDrawTarget = target;
678873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com    fSavedState = target->drawState();
679873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com    GrAssert(fSavedState);
680873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com    fSavedState->ref();
681873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com    if (kReset_ASRInit == init) {
682873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com        // calls the default cons
683873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com        fTempState.init();
684873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com    } else {
685873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com        GrAssert(kPreserve_ASRInit == init);
686873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com        // calls the copy cons
687873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com        fTempState.set(*fSavedState);
68806afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com    }
689873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com    target->setDrawState(fTempState.get());
69006afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com}
6917ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com
69225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com////////////////////////////////////////////////////////////////////////////////
69325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
69425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comGrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry(
69525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                         GrDrawTarget*  target,
69625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                         int vertexCount,
69725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                         int indexCount) {
69825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    fTarget = NULL;
699b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com    this->set(target, vertexCount, indexCount);
70025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
701d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
70225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comGrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry() {
70325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    fTarget = NULL;
70425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
70525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
70625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comGrDrawTarget::AutoReleaseGeometry::~AutoReleaseGeometry() {
70725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    this->reset();
70825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
70925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
71025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.combool GrDrawTarget::AutoReleaseGeometry::set(GrDrawTarget*  target,
71125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                            int vertexCount,
71225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                            int indexCount) {
71325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    this->reset();
71425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    fTarget = target;
71525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    bool success = true;
71625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    if (NULL != fTarget) {
71725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        fTarget = target;
718b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com        success = target->reserveVertexAndIndexSpace(vertexCount,
719e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com                                                     indexCount,
720e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com                                                     &fVertices,
721e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com                                                     &fIndices);
722e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com        if (!success) {
723e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com            fTarget = NULL;
724e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com            this->reset();
72525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        }
72625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
72725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(success == (NULL != fTarget));
72825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    return success;
72925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
73025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
73125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrDrawTarget::AutoReleaseGeometry::reset() {
73225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    if (NULL != fTarget) {
73325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        if (NULL != fVertices) {
73425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            fTarget->resetVertexSource();
73525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        }
73625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        if (NULL != fIndices) {
73725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            fTarget->resetIndexSource();
73825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        }
73925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        fTarget = NULL;
74025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
741cb0c5ab54d69f813f4faf4c7ac2092358bc663aabsalomon@google.com    fVertices = NULL;
742cb0c5ab54d69f813f4faf4c7ac2092358bc663aabsalomon@google.com    fIndices = NULL;
74325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
74425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
7458d67c0711b52226db59158a0cfce09f35badd96absalomon@google.comGrDrawTarget::AutoClipRestore::AutoClipRestore(GrDrawTarget* target, const SkIRect& newClip) {
7468d67c0711b52226db59158a0cfce09f35badd96absalomon@google.com    fTarget = target;
7478d67c0711b52226db59158a0cfce09f35badd96absalomon@google.com    fClip = fTarget->getClip();
7488d67c0711b52226db59158a0cfce09f35badd96absalomon@google.com    fStack.init();
7498d67c0711b52226db59158a0cfce09f35badd96absalomon@google.com    fStack.get()->clipDevRect(newClip, SkRegion::kReplace_Op);
7508d67c0711b52226db59158a0cfce09f35badd96absalomon@google.com    fReplacementClip.fClipStack = fStack.get();
7518d67c0711b52226db59158a0cfce09f35badd96absalomon@google.com    target->setClip(&fReplacementClip);
7528d67c0711b52226db59158a0cfce09f35badd96absalomon@google.com}
7538d67c0711b52226db59158a0cfce09f35badd96absalomon@google.com
754e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.combool GrDrawTarget::copySurface(GrSurface* dst,
755e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com                               GrSurface* src,
756e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com                               const SkIRect& srcRect,
757e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com                               const SkIPoint& dstPoint) {
758e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    SkIRect clippedSrcRect(srcRect);
759e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    SkIPoint clippedDstPoint(dstPoint);
760e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com
761e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    // clip the left edge to src and dst bounds, adjusting dstPoint if neceessary
762e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    if (clippedSrcRect.fLeft < 0) {
763e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com        clippedDstPoint.fX -= clippedSrcRect.fLeft;
764e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com        clippedSrcRect.fLeft = 0;
765e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    }
766e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    if (clippedDstPoint.fX < 0) {
767e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com        clippedSrcRect.fLeft -= clippedDstPoint.fX;
768e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com        clippedDstPoint.fX = 0;
769e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    }
770e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com
771e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    // clip the top edge to src and dst bounds, adjusting dstPoint if neceessary
772e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    if (clippedSrcRect.fTop < 0) {
773e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com        clippedDstPoint.fY -= clippedSrcRect.fTop;
774e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com        clippedSrcRect.fTop = 0;
775e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    }
776e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    if (clippedDstPoint.fY < 0) {
777e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com        clippedSrcRect.fTop -= clippedDstPoint.fY;
778e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com        clippedDstPoint.fY = 0;
779e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    }
780e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com
781e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    // clip the right edge to the src and dst bounds.
782e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    if (clippedSrcRect.fRight > src->width()) {
783e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com        clippedSrcRect.fRight = src->width();
784e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    }
785e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    if (clippedDstPoint.fX + clippedSrcRect.width() > dst->width()) {
786e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com        clippedSrcRect.fRight = clippedSrcRect.fLeft + dst->width() - clippedDstPoint.fX;
787e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    }
788e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com
789e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    // clip the bottom edge to the src and dst bounds.
790e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    if (clippedSrcRect.fBottom > src->height()) {
791e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com        clippedSrcRect.fBottom = src->height();
792e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    }
793e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    if (clippedDstPoint.fY + clippedSrcRect.height() > dst->height()) {
794e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com        clippedSrcRect.fBottom = clippedSrcRect.fTop + dst->height() - clippedDstPoint.fY;
795e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    }
796e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com
797e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    // The above clipping steps may have inverted the rect if it didn't intersect either the src or
798e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    // dst bounds.
799e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    if (clippedSrcRect.isEmpty()) {
800e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com        return true;
801e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    }
802e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com
803e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    bool result = this->onCopySurface(dst, src, clippedSrcRect, clippedDstPoint);
804e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    GrAssert(result == this->canCopySurface(dst, src, clippedSrcRect, clippedDstPoint));
805e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    return result;
806e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com}
807e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com
808e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.combool GrDrawTarget::canCopySurface(GrSurface* dst,
809e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com                                  GrSurface* src,
810e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com                                  const SkIRect& srcRect,
811e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com                                  const SkIPoint& dstPoint) {
812e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    // Check that the read/write rects are contained within the src/dst bounds.
813e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    GrAssert(!srcRect.isEmpty());
814e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    GrAssert(SkIRect::MakeWH(src->width(), src->height()).contains(srcRect));
815e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    GrAssert(dstPoint.fX >= 0 && dstPoint.fY >= 0);
816e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    GrAssert(dstPoint.fX + srcRect.width() <= dst->width() &&
817e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com             dstPoint.fY + srcRect.height() <= dst->height());
818e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com
819e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    return NULL != dst->asRenderTarget() && NULL != src->asTexture();
820e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com}
821e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com
822e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.combool GrDrawTarget::onCopySurface(GrSurface* dst,
823e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com                                 GrSurface* src,
824e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com                                 const SkIRect& srcRect,
825e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com                                 const SkIPoint& dstPoint) {
826e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    if (!GrDrawTarget::canCopySurface(dst, src, srcRect, dstPoint)) {
827e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com        return false;
828e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    }
829e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com
830e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    GrRenderTarget* rt = dst->asRenderTarget();
831e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    GrTexture* tex = src->asTexture();
832e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com
833e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    GrDrawTarget::AutoStateRestore asr(this, kReset_ASRInit);
834e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    this->drawState()->setRenderTarget(rt);
835e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    SkMatrix matrix;
836e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    matrix.setTranslate(SkIntToScalar(srcRect.fLeft - dstPoint.fX),
837e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com                        SkIntToScalar(srcRect.fTop - dstPoint.fY));
838e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    matrix.postIDiv(tex->width(), tex->height());
839e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    this->drawState()->createTextureEffect(0, tex, matrix);
840e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX,
841e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com                                        dstPoint.fY,
842e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com                                        srcRect.width(),
843e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com                                        srcRect.height());
844e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    this->drawSimpleRect(dstRect);
845e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    return true;
846e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com}
847e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com
848bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com///////////////////////////////////////////////////////////////////////////////
849bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com
850c26d94fd7dc0b00cd6d0e42d28285f4a38aff021bsalomon@google.comSK_DEFINE_INST_COUNT(GrDrawTargetCaps)
851bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com
852c26d94fd7dc0b00cd6d0e42d28285f4a38aff021bsalomon@google.comvoid GrDrawTargetCaps::reset() {
853bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    f8BitPaletteSupport = false;
854bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    fNPOTTextureTileSupport = false;
855bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    fTwoSidedStencilSupport = false;
856bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    fStencilWrapOpsSupport = false;
857bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    fHWAALineSupport = false;
858bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    fShaderDerivativeSupport = false;
859bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    fGeometryShaderSupport = false;
860e60ed08a3568b5e253dfb5dec2b52d13a16fff1cskia.committer@gmail.com    fDualSourceBlendingSupport = false;
861bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    fBufferLockSupport = false;
862bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    fPathStencilingSupport = false;
863bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com
864bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    fMaxRenderTargetSize = 0;
865bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    fMaxTextureSize = 0;
866bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    fMaxSampleCount = 0;
867bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com}
868bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com
869c26d94fd7dc0b00cd6d0e42d28285f4a38aff021bsalomon@google.comGrDrawTargetCaps& GrDrawTargetCaps::operator=(const GrDrawTargetCaps& other) {
870bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    f8BitPaletteSupport = other.f8BitPaletteSupport;
871bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    fNPOTTextureTileSupport = other.fNPOTTextureTileSupport;
872bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    fTwoSidedStencilSupport = other.fTwoSidedStencilSupport;
873bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    fStencilWrapOpsSupport = other.fStencilWrapOpsSupport;
874bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    fHWAALineSupport = other.fHWAALineSupport;
875bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    fShaderDerivativeSupport = other.fShaderDerivativeSupport;
876bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    fGeometryShaderSupport = other.fGeometryShaderSupport;
877bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    fDualSourceBlendingSupport = other.fDualSourceBlendingSupport;
878bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    fBufferLockSupport = other.fBufferLockSupport;
879bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    fPathStencilingSupport = other.fPathStencilingSupport;
880bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com
881bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    fMaxRenderTargetSize = other.fMaxRenderTargetSize;
882bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    fMaxTextureSize = other.fMaxTextureSize;
883bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    fMaxSampleCount = other.fMaxSampleCount;
884bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com
885bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    return *this;
886bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com}
887bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com
888c26d94fd7dc0b00cd6d0e42d28285f4a38aff021bsalomon@google.comvoid GrDrawTargetCaps::print() const {
88918c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com    static const char* gNY[] = {"NO", "YES"};
890bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    GrPrintf("8 Bit Palette Support       : %s\n", gNY[f8BitPaletteSupport]);
891bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    GrPrintf("NPOT Texture Tile Support   : %s\n", gNY[fNPOTTextureTileSupport]);
892bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    GrPrintf("Two Sided Stencil Support   : %s\n", gNY[fTwoSidedStencilSupport]);
893bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    GrPrintf("Stencil Wrap Ops  Support   : %s\n", gNY[fStencilWrapOpsSupport]);
894bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    GrPrintf("HW AA Lines Support         : %s\n", gNY[fHWAALineSupport]);
895bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    GrPrintf("Shader Derivative Support   : %s\n", gNY[fShaderDerivativeSupport]);
896bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    GrPrintf("Geometry Shader Support     : %s\n", gNY[fGeometryShaderSupport]);
897bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    GrPrintf("Dual Source Blending Support: %s\n", gNY[fDualSourceBlendingSupport]);
898bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    GrPrintf("Buffer Lock Support         : %s\n", gNY[fBufferLockSupport]);
899bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    GrPrintf("Path Stenciling Support     : %s\n", gNY[fPathStencilingSupport]);
900bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    GrPrintf("Max Texture Size            : %d\n", fMaxTextureSize);
901bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    GrPrintf("Max Render Target Size      : %d\n", fMaxRenderTargetSize);
902bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    GrPrintf("Max Sample Count            : %d\n", fMaxSampleCount);
90318c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com}
904