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"
14c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org#include "GrPath.h"
158f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com#include "GrRenderTarget.h"
1662c447d3a556e3042cdf5d23b3e2a618eaa3c100bsalomon#include "GrTemplates.h"
1786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com#include "GrTexture.h"
1825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#include "GrVertexBuffer.h"
19ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
205f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com#include "SkStrokeRec.h"
2112b4e27ae1a29460e91a59f38122483e1faec697sugoi@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
3549f085dddff10473b6ebf832a974288300224e60bsalomon    if (di.fDevBounds) {
36f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org        SkASSERT(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
48515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG
49d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.combool GrDrawTarget::DrawInfo::isInstanced() const {
50d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    if (fInstanceCount > 0) {
51f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org        SkASSERT(0 == fIndexCount % fIndicesPerInstance);
52f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org        SkASSERT(0 == fVertexCount % fVerticesPerInstance);
53f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org        SkASSERT(fIndexCount / fIndicesPerInstance == fInstanceCount);
54f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org        SkASSERT(fVertexCount / fVerticesPerInstance == fInstanceCount);
55d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        // there is no way to specify a non-zero start index to drawIndexedInstances().
56f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org        SkASSERT(0 == fStartIndex);
57d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        return true;
58d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    } else {
59f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org        SkASSERT(!fVerticesPerInstance);
60f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org        SkASSERT(!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) {
67f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(this->isInstanced());
68f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(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;
76f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(fStartVertex >= 0);
77d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com}
78d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com
79d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.comvoid GrDrawTarget::DrawInfo::adjustStartIndex(int indexOffset) {
80f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(this->isIndexed());
81d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    fStartIndex += indexOffset;
82f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(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)
92a3baf3be0e2a3128fb73bd41d40d130f75a4dc86commit-bot@chromium.org    , fContext(context)
932a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org    , fGpuTraceMarkerCount(0) {
9449f085dddff10473b6ebf832a974288300224e60bsalomon    SkASSERT(context);
956e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com
96a5d056ae0b04021dfb44c2c7a3d6a34e060261b8bsalomon@google.com    fDrawState = &fDefaultDrawState;
97a5d056ae0b04021dfb44c2c7a3d6a34e060261b8bsalomon@google.com    // We assume that fDrawState always owns a ref to the object it points at.
98a5d056ae0b04021dfb44c2c7a3d6a34e060261b8bsalomon@google.com    fDefaultDrawState.ref();
9925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometrySrcState& geoSrc = fGeoSrcStateStack.push_back();
100515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG
10125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fVertexCount = DEBUG_INVAL_START_IDX;
10225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
10325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fIndexCount = DEBUG_INVAL_START_IDX;
10425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
105ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#endif
10625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fVertexSrc = kNone_GeometrySrcType;
10725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fIndexSrc  = kNone_GeometrySrcType;
10825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
10925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
11025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comGrDrawTarget::~GrDrawTarget() {
111f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(1 == fGeoSrcStateStack.count());
1120e51577a14f903ffeafa117a75954baeb173ffb9humper@google.com    SkDEBUGCODE(GeometrySrcState& geoSrc = fGeoSrcStateStack.back());
113f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(kNone_GeometrySrcType == geoSrc.fIndexSrc);
114f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(kNone_GeometrySrcType == geoSrc.fVertexSrc);
115a5d056ae0b04021dfb44c2c7a3d6a34e060261b8bsalomon@google.com    fDrawState->unref();
1164a018bb20bf969a38ec11d9506843f06366dfa7cbsalomon@google.com}
1174a018bb20bf969a38ec11d9506843f06366dfa7cbsalomon@google.com
1184a018bb20bf969a38ec11d9506843f06366dfa7cbsalomon@google.comvoid GrDrawTarget::releaseGeometry() {
11925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    int popCnt = fGeoSrcStateStack.count() - 1;
12025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    while (popCnt) {
12125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        this->popGeometrySource();
12225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        --popCnt;
12325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
1244a018bb20bf969a38ec11d9506843f06366dfa7cbsalomon@google.com    this->resetVertexSource();
1254a018bb20bf969a38ec11d9506843f06366dfa7cbsalomon@google.com    this->resetIndexSource();
126ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
127ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
128beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.comvoid GrDrawTarget::setClip(const GrClipData* clip) {
12986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    clipWillBeSet(clip);
130ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fClip = clip;
131ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
132ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
133beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.comconst GrClipData* GrDrawTarget::getClip() const {
134ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    return fClip;
135ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
136ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
137a5d056ae0b04021dfb44c2c7a3d6a34e060261b8bsalomon@google.comvoid GrDrawTarget::setDrawState(GrDrawState*  drawState) {
13849f085dddff10473b6ebf832a974288300224e60bsalomon    SkASSERT(fDrawState);
139a5d056ae0b04021dfb44c2c7a3d6a34e060261b8bsalomon@google.com    if (NULL == drawState) {
140a5d056ae0b04021dfb44c2c7a3d6a34e060261b8bsalomon@google.com        drawState = &fDefaultDrawState;
141a5d056ae0b04021dfb44c2c7a3d6a34e060261b8bsalomon@google.com    }
142a5d056ae0b04021dfb44c2c7a3d6a34e060261b8bsalomon@google.com    if (fDrawState != drawState) {
143a5d056ae0b04021dfb44c2c7a3d6a34e060261b8bsalomon@google.com        fDrawState->unref();
144a5d056ae0b04021dfb44c2c7a3d6a34e060261b8bsalomon@google.com        drawState->ref();
145a5d056ae0b04021dfb44c2c7a3d6a34e060261b8bsalomon@google.com        fDrawState = drawState;
146a5d056ae0b04021dfb44c2c7a3d6a34e060261b8bsalomon@google.com    }
147a5d056ae0b04021dfb44c2c7a3d6a34e060261b8bsalomon@google.com}
148a5d056ae0b04021dfb44c2c7a3d6a34e060261b8bsalomon@google.com
149b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.combool GrDrawTarget::reserveVertexSpace(size_t vertexSize,
15025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                      int vertexCount,
15125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                      void** vertices) {
15225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
15325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    bool acquired = false;
15425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    if (vertexCount > 0) {
15549f085dddff10473b6ebf832a974288300224e60bsalomon        SkASSERT(vertices);
15625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        this->releasePreviousVertexSource();
15725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        geoSrc.fVertexSrc = kNone_GeometrySrcType;
158ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
159b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com        acquired = this->onReserveVertexSpace(vertexSize,
16025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                              vertexCount,
16125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                              vertices);
16225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
16325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    if (acquired) {
16425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        geoSrc.fVertexSrc = kReserved_GeometrySrcType;
16525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        geoSrc.fVertexCount = vertexCount;
166b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com        geoSrc.fVertexSize = vertexSize;
16749f085dddff10473b6ebf832a974288300224e60bsalomon    } else if (vertices) {
16825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        *vertices = NULL;
16925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
17025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    return acquired;
17125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
17225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
17325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.combool GrDrawTarget::reserveIndexSpace(int indexCount,
17425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                     void** indices) {
17525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
17625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    bool acquired = false;
17725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    if (indexCount > 0) {
17849f085dddff10473b6ebf832a974288300224e60bsalomon        SkASSERT(indices);
17925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        this->releasePreviousIndexSource();
18025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        geoSrc.fIndexSrc = kNone_GeometrySrcType;
181d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
18225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        acquired = this->onReserveIndexSpace(indexCount, indices);
183ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
18425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    if (acquired) {
18525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        geoSrc.fIndexSrc = kReserved_GeometrySrcType;
18625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        geoSrc.fIndexCount = indexCount;
18749f085dddff10473b6ebf832a974288300224e60bsalomon    } else if (indices) {
18825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        *indices = NULL;
18925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
19025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    return acquired;
191d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
192ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
193ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
194b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.combool GrDrawTarget::reserveVertexAndIndexSpace(int vertexCount,
195e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com                                              int indexCount,
196e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com                                              void** vertices,
197e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com                                              void** indices) {
1987b3d5ee72c2238aa239bce4d5b3aea98a437ca7aegdaniel    size_t vertexStride = this->drawState()->getVertexStride();
199b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com    this->willReserveVertexAndIndexSpace(vertexCount, indexCount);
200e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com    if (vertexCount) {
2017b3d5ee72c2238aa239bce4d5b3aea98a437ca7aegdaniel        if (!this->reserveVertexSpace(vertexStride, vertexCount, vertices)) {
202e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com            if (indexCount) {
203e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com                this->resetIndexSource();
204e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com            }
205e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com            return false;
206e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com        }
207e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com    }
208e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com    if (indexCount) {
209e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com        if (!this->reserveIndexSpace(indexCount, indices)) {
210e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com            if (vertexCount) {
211e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com                this->resetVertexSource();
212e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com            }
213e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com            return false;
214e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com        }
215e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com    }
216e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com    return true;
217e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com}
218e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com
219b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.combool GrDrawTarget::geometryHints(int32_t* vertexCount,
220ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com                                 int32_t* indexCount) const {
22149f085dddff10473b6ebf832a974288300224e60bsalomon    if (vertexCount) {
222ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        *vertexCount = -1;
223ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
22449f085dddff10473b6ebf832a974288300224e60bsalomon    if (indexCount) {
225ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        *indexCount = -1;
226ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
227ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    return false;
228ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
229ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
23025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrDrawTarget::releasePreviousVertexSource() {
23125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
23225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    switch (geoSrc.fVertexSrc) {
23325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        case kNone_GeometrySrcType:
23425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            break;
23525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        case kArray_GeometrySrcType:
23625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            this->releaseVertexArray();
23725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            break;
23825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        case kReserved_GeometrySrcType:
23925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            this->releaseReservedVertexSpace();
24025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            break;
24125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        case kBuffer_GeometrySrcType:
24225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            geoSrc.fVertexBuffer->unref();
243515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG
24425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
24525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#endif
24625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            break;
24725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        default:
24888cb22b6b4816c7a9ca6c5b795965b4606f9eb7bcommit-bot@chromium.org            SkFAIL("Unknown Vertex Source Type.");
24925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            break;
25025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
25125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
25225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
25325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrDrawTarget::releasePreviousIndexSource() {
25425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
25525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    switch (geoSrc.fIndexSrc) {
25625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        case kNone_GeometrySrcType:   // these two don't require
25725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            break;
25825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        case kArray_GeometrySrcType:
25925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            this->releaseIndexArray();
26025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            break;
26125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        case kReserved_GeometrySrcType:
26225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            this->releaseReservedIndexSpace();
26325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            break;
26425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        case kBuffer_GeometrySrcType:
26525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            geoSrc.fIndexBuffer->unref();
266515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG
26725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
26825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#endif
26925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            break;
27025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        default:
27188cb22b6b4816c7a9ca6c5b795965b4606f9eb7bcommit-bot@chromium.org            SkFAIL("Unknown Index Source Type.");
27225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            break;
27325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
274ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
275ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
276b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.comvoid GrDrawTarget::setVertexSourceToArray(const void* vertexArray,
2771c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com                                          int vertexCount) {
27825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    this->releasePreviousVertexSource();
27925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
28025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fVertexSrc = kArray_GeometrySrcType;
2817b3d5ee72c2238aa239bce4d5b3aea98a437ca7aegdaniel    geoSrc.fVertexSize = this->drawState()->getVertexStride();
28225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fVertexCount = vertexCount;
283bcdbbe61e1a3f89545b2c1461164f0f8bf5f0797bsalomon@google.com    this->onSetVertexSourceToArray(vertexArray, vertexCount);
284ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
285ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
2861c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.comvoid GrDrawTarget::setIndexSourceToArray(const void* indexArray,
2871c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com                                         int indexCount) {
28825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    this->releasePreviousIndexSource();
28925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
29025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fIndexSrc = kArray_GeometrySrcType;
29125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fIndexCount = indexCount;
292bcdbbe61e1a3f89545b2c1461164f0f8bf5f0797bsalomon@google.com    this->onSetIndexSourceToArray(indexArray, indexCount);
293ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
294ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
295b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.comvoid GrDrawTarget::setVertexSourceToBuffer(const GrVertexBuffer* buffer) {
29625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    this->releasePreviousVertexSource();
29725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
29825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fVertexSrc    = kBuffer_GeometrySrcType;
29925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fVertexBuffer = buffer;
30025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    buffer->ref();
3017b3d5ee72c2238aa239bce4d5b3aea98a437ca7aegdaniel    geoSrc.fVertexSize = this->drawState()->getVertexStride();
302ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
303ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
304ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrDrawTarget::setIndexSourceToBuffer(const GrIndexBuffer* buffer) {
30525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    this->releasePreviousIndexSource();
30625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
30725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fIndexSrc     = kBuffer_GeometrySrcType;
30825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fIndexBuffer  = buffer;
30925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    buffer->ref();
310ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
311ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
31225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrDrawTarget::resetVertexSource() {
31325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    this->releasePreviousVertexSource();
31425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
31525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fVertexSrc = kNone_GeometrySrcType;
31625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
31725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
31825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrDrawTarget::resetIndexSource() {
31925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    this->releasePreviousIndexSource();
32025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
32125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fIndexSrc = kNone_GeometrySrcType;
32225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
32325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
32425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrDrawTarget::pushGeometrySource() {
32525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    this->geometrySourceWillPush();
32625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometrySrcState& newState = fGeoSrcStateStack.push_back();
32725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    newState.fIndexSrc = kNone_GeometrySrcType;
32825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    newState.fVertexSrc = kNone_GeometrySrcType;
329515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG
33025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    newState.fVertexCount  = ~0;
33125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    newState.fVertexBuffer = (GrVertexBuffer*)~0;
33225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    newState.fIndexCount   = ~0;
33325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    newState.fIndexBuffer = (GrIndexBuffer*)~0;
33425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#endif
33525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
33625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
33725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrDrawTarget::popGeometrySource() {
33825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    // if popping last element then pops are unbalanced with pushes
339f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(fGeoSrcStateStack.count() > 1);
340d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
34125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    this->geometrySourceWillPop(fGeoSrcStateStack.fromBack(1));
34225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    this->releasePreviousVertexSource();
34325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    this->releasePreviousIndexSource();
34425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    fGeoSrcStateStack.pop_back();
34525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
34625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
34725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com////////////////////////////////////////////////////////////////////////////////
34825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
349e826262939dac3e67cb5ce66d4b9faeb8e2538e6bsalomon@google.combool GrDrawTarget::checkDraw(GrPrimitiveType type, int startVertex,
350e826262939dac3e67cb5ce66d4b9faeb8e2538e6bsalomon@google.com                             int startIndex, int vertexCount,
351e826262939dac3e67cb5ce66d4b9faeb8e2538e6bsalomon@google.com                             int indexCount) const {
352cddaf340f1474cc1ff429b8ef9bc8739c72f80babsalomon@google.com    const GrDrawState& drawState = this->getDrawState();
353515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG
354e826262939dac3e67cb5ce66d4b9faeb8e2538e6bsalomon@google.com    const GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
35525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    int maxVertex = startVertex + vertexCount;
35625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    int maxValidVertex;
35725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    switch (geoSrc.fVertexSrc) {
35825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        case kNone_GeometrySrcType:
35988cb22b6b4816c7a9ca6c5b795965b4606f9eb7bcommit-bot@chromium.org            SkFAIL("Attempting to draw without vertex src.");
36025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        case kReserved_GeometrySrcType: // fallthrough
36125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        case kArray_GeometrySrcType:
36225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            maxValidVertex = geoSrc.fVertexCount;
36325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            break;
36425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        case kBuffer_GeometrySrcType:
365089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org            maxValidVertex = static_cast<int>(geoSrc.fVertexBuffer->gpuMemorySize() / geoSrc.fVertexSize);
36625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            break;
36725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
36825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    if (maxVertex > maxValidVertex) {
36988cb22b6b4816c7a9ca6c5b795965b4606f9eb7bcommit-bot@chromium.org        SkFAIL("Drawing outside valid vertex range.");
37025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
371e826262939dac3e67cb5ce66d4b9faeb8e2538e6bsalomon@google.com    if (indexCount > 0) {
372e826262939dac3e67cb5ce66d4b9faeb8e2538e6bsalomon@google.com        int maxIndex = startIndex + indexCount;
373e826262939dac3e67cb5ce66d4b9faeb8e2538e6bsalomon@google.com        int maxValidIndex;
374e826262939dac3e67cb5ce66d4b9faeb8e2538e6bsalomon@google.com        switch (geoSrc.fIndexSrc) {
375e826262939dac3e67cb5ce66d4b9faeb8e2538e6bsalomon@google.com            case kNone_GeometrySrcType:
37688cb22b6b4816c7a9ca6c5b795965b4606f9eb7bcommit-bot@chromium.org                SkFAIL("Attempting to draw indexed geom without index src.");
377e826262939dac3e67cb5ce66d4b9faeb8e2538e6bsalomon@google.com            case kReserved_GeometrySrcType: // fallthrough
378e826262939dac3e67cb5ce66d4b9faeb8e2538e6bsalomon@google.com            case kArray_GeometrySrcType:
379e826262939dac3e67cb5ce66d4b9faeb8e2538e6bsalomon@google.com                maxValidIndex = geoSrc.fIndexCount;
380e826262939dac3e67cb5ce66d4b9faeb8e2538e6bsalomon@google.com                break;
381e826262939dac3e67cb5ce66d4b9faeb8e2538e6bsalomon@google.com            case kBuffer_GeometrySrcType:
382089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org                maxValidIndex = static_cast<int>(geoSrc.fIndexBuffer->gpuMemorySize() / sizeof(uint16_t));
383e826262939dac3e67cb5ce66d4b9faeb8e2538e6bsalomon@google.com                break;
384e826262939dac3e67cb5ce66d4b9faeb8e2538e6bsalomon@google.com        }
385e826262939dac3e67cb5ce66d4b9faeb8e2538e6bsalomon@google.com        if (maxIndex > maxValidIndex) {
38688cb22b6b4816c7a9ca6c5b795965b4606f9eb7bcommit-bot@chromium.org            SkFAIL("Index reads outside valid index range.");
387e826262939dac3e67cb5ce66d4b9faeb8e2538e6bsalomon@google.com        }
38825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
389b4725b4ee617a6a2524765f79310714a5dad4b6absalomon@google.com
39049f085dddff10473b6ebf832a974288300224e60bsalomon    SkASSERT(drawState.getRenderTarget());
391eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com
392bd769d0f1c8cf6ccbb2738dfad1624a4c828e4ebjoshualitt    if (drawState.hasGeometryProcessor()) {
393b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt        const GrGeometryProcessor* gp = drawState.getGeometryProcessor()->getGeometryProcessor();
394b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt        int numTextures = gp->numTextures();
395bd769d0f1c8cf6ccbb2738dfad1624a4c828e4ebjoshualitt        for (int t = 0; t < numTextures; ++t) {
396b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt            GrTexture* texture = gp->texture(t);
397bd769d0f1c8cf6ccbb2738dfad1624a4c828e4ebjoshualitt            SkASSERT(texture->asRenderTarget() != drawState.getRenderTarget());
398bd769d0f1c8cf6ccbb2738dfad1624a4c828e4ebjoshualitt        }
399bd769d0f1c8cf6ccbb2738dfad1624a4c828e4ebjoshualitt    }
400bd769d0f1c8cf6ccbb2738dfad1624a4c828e4ebjoshualitt
401eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com    for (int s = 0; s < drawState.numColorStages(); ++s) {
402b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt        const GrProcessor* effect = drawState.getColorStage(s).getProcessor();
403eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com        int numTextures = effect->numTextures();
404eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com        for (int t = 0; t < numTextures; ++t) {
405eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com            GrTexture* texture = effect->texture(t);
406f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org            SkASSERT(texture->asRenderTarget() != drawState.getRenderTarget());
407eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com        }
408eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com    }
409eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com    for (int s = 0; s < drawState.numCoverageStages(); ++s) {
410b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt        const GrProcessor* effect = drawState.getCoverageStage(s).getProcessor();
411eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com        int numTextures = effect->numTextures();
412eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com        for (int t = 0; t < numTextures; ++t) {
413eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com            GrTexture* texture = effect->texture(t);
414f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org            SkASSERT(texture->asRenderTarget() != drawState.getRenderTarget());
415b4725b4ee617a6a2524765f79310714a5dad4b6absalomon@google.com        }
416b4725b4ee617a6a2524765f79310714a5dad4b6absalomon@google.com    }
417ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org
418f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(drawState.validateVertexAttribs());
41925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#endif
4208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    if (NULL == drawState.getRenderTarget()) {
4210ba52fcf93d52a3f230d1f185eea0c8719c176fbbsalomon@google.com        return false;
4220ba52fcf93d52a3f230d1f185eea0c8719c176fbbsalomon@google.com    }
423e826262939dac3e67cb5ce66d4b9faeb8e2538e6bsalomon@google.com    return true;
424e826262939dac3e67cb5ce66d4b9faeb8e2538e6bsalomon@google.com}
425e826262939dac3e67cb5ce66d4b9faeb8e2538e6bsalomon@google.com
426c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.orgbool GrDrawTarget::setupDstReadIfNecessary(GrDeviceCoordTexture* dstCopy, const SkRect* drawBounds) {
427b515881446c303a50d9b2dd38b9163b4e5c625a2bsalomon@google.com    if (this->caps()->dstReadInShaderSupport() || !this->getDrawState().willEffectReadDstColor()) {
42826e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com        return true;
42926e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    }
43026e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    GrRenderTarget* rt = this->drawState()->getRenderTarget();
431fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org    SkIRect copyRect;
432c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org    const GrClipData* clip = this->getClip();
433c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org    clip->getConservativeBounds(rt, &copyRect);
434c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org
43549f085dddff10473b6ebf832a974288300224e60bsalomon    if (drawBounds) {
436c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org        SkIRect drawIBounds;
437c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org        drawBounds->roundOut(&drawIBounds);
438bb5c46591c50d05418467cd1c4e927ceb85c2ba9commit-bot@chromium.org        if (!copyRect.intersect(drawIBounds)) {
439515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG
440bb5c46591c50d05418467cd1c4e927ceb85c2ba9commit-bot@chromium.org            GrPrintf("Missed an early reject. Bailing on draw from setupDstReadIfNecessary.\n");
441bb5c46591c50d05418467cd1c4e927ceb85c2ba9commit-bot@chromium.org#endif
442bb5c46591c50d05418467cd1c4e927ceb85c2ba9commit-bot@chromium.org            return false;
443bb5c46591c50d05418467cd1c4e927ceb85c2ba9commit-bot@chromium.org        }
444bb5c46591c50d05418467cd1c4e927ceb85c2ba9commit-bot@chromium.org    } else {
445515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG
446bb5c46591c50d05418467cd1c4e927ceb85c2ba9commit-bot@chromium.org        //GrPrintf("No dev bounds when dst copy is made.\n");
447bb5c46591c50d05418467cd1c4e927ceb85c2ba9commit-bot@chromium.org#endif
448bb5c46591c50d05418467cd1c4e927ceb85c2ba9commit-bot@chromium.org    }
44905a2ee052c9ef4c781b7b590b00b3d2da3b3449askia.committer@gmail.com
45063150afcc0c4120370db6f5566cd404584345668commit-bot@chromium.org    // MSAA consideration: When there is support for reading MSAA samples in the shader we could
45163150afcc0c4120370db6f5566cd404584345668commit-bot@chromium.org    // have per-sample dst values by making the copy multisampled.
45226e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    GrTextureDesc desc;
453eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com    this->initCopySurfaceDstDesc(rt, &desc);
454bb5c46591c50d05418467cd1c4e927ceb85c2ba9commit-bot@chromium.org    desc.fWidth = copyRect.width();
455bb5c46591c50d05418467cd1c4e927ceb85c2ba9commit-bot@chromium.org    desc.fHeight = copyRect.height();
45626e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com
45726e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    GrAutoScratchTexture ast(fContext, desc, GrContext::kApprox_ScratchTexMatch);
45826e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com
45926e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    if (NULL == ast.texture()) {
46026e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com        GrPrintf("Failed to create temporary copy of destination texture.\n");
46126e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com        return false;
46226e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    }
463e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    SkIPoint dstPoint = {0, 0};
464e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    if (this->copySurface(ast.texture(), rt, copyRect, dstPoint)) {
465c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org        dstCopy->setTexture(ast.texture());
466c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org        dstCopy->setOffset(copyRect.fLeft, copyRect.fTop);
467e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com        return true;
468e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    } else {
469e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com        return false;
470e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    }
47126e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com}
47226e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com
473d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.comvoid GrDrawTarget::drawIndexed(GrPrimitiveType type,
474d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com                               int startVertex,
475d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com                               int startIndex,
476d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com                               int vertexCount,
477d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com                               int indexCount,
478d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com                               const SkRect* devBounds) {
47974749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com    if (indexCount > 0 && this->checkDraw(type, startVertex, startIndex, vertexCount, indexCount)) {
48074749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com        DrawInfo info;
48174749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com        info.fPrimitiveType = type;
48274749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com        info.fStartVertex   = startVertex;
48374749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com        info.fStartIndex    = startIndex;
48474749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com        info.fVertexCount   = vertexCount;
48574749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com        info.fIndexCount    = indexCount;
486d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com
487d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        info.fInstanceCount         = 0;
488d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        info.fVerticesPerInstance   = 0;
489d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        info.fIndicesPerInstance    = 0;
490d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com
49149f085dddff10473b6ebf832a974288300224e60bsalomon        if (devBounds) {
492d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com            info.setDevBounds(*devBounds);
493d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        }
49426e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com        // TODO: We should continue with incorrect blending.
49526e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com        if (!this->setupDstReadIfNecessary(&info)) {
49626e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com            return;
49726e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com        }
49874749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com        this->onDraw(info);
4998214587a79c0a4398664289c4d1ce2c0bf542b42bsalomon@google.com    }
50025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
50125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
50225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrDrawTarget::drawNonIndexed(GrPrimitiveType type,
50325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                  int startVertex,
504d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com                                  int vertexCount,
505d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com                                  const SkRect* devBounds) {
50674749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com    if (vertexCount > 0 && this->checkDraw(type, startVertex, -1, vertexCount, -1)) {
50774749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com        DrawInfo info;
50874749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com        info.fPrimitiveType = type;
50974749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com        info.fStartVertex   = startVertex;
51074749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com        info.fStartIndex    = 0;
51174749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com        info.fVertexCount   = vertexCount;
51274749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com        info.fIndexCount    = 0;
513d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com
514d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        info.fInstanceCount         = 0;
515d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        info.fVerticesPerInstance   = 0;
516d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        info.fIndicesPerInstance    = 0;
517d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com
51849f085dddff10473b6ebf832a974288300224e60bsalomon        if (devBounds) {
519d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com            info.setDevBounds(*devBounds);
520d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        }
52126e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com        // TODO: We should continue with incorrect blending.
52226e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com        if (!this->setupDstReadIfNecessary(&info)) {
52326e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com            return;
52426e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com        }
52574749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com        this->onDraw(info);
5268214587a79c0a4398664289c4d1ce2c0bf542b42bsalomon@google.com    }
52725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
52825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
52932184d81629e39809bb9e915286d8fe971a8ed68commit-bot@chromium.orgvoid GrDrawTarget::stencilPath(const GrPath* path, SkPath::FillType fill) {
53064aef2bacd1f5c25ffd9347aabd6265c9b60c0f4bsalomon@google.com    // TODO: extract portions of checkDraw that are relevant to path stenciling.
53149f085dddff10473b6ebf832a974288300224e60bsalomon    SkASSERT(path);
532c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org    SkASSERT(this->caps()->pathRenderingSupport());
533f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(!SkPath::IsInverseFillType(fill));
53432184d81629e39809bb9e915286d8fe971a8ed68commit-bot@chromium.org    this->onStencilPath(path, fill);
53564aef2bacd1f5c25ffd9347aabd6265c9b60c0f4bsalomon@google.com}
53664aef2bacd1f5c25ffd9347aabd6265c9b60c0f4bsalomon@google.com
53732184d81629e39809bb9e915286d8fe971a8ed68commit-bot@chromium.orgvoid GrDrawTarget::drawPath(const GrPath* path, SkPath::FillType fill) {
538c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org    // TODO: extract portions of checkDraw that are relevant to path rendering.
53949f085dddff10473b6ebf832a974288300224e60bsalomon    SkASSERT(path);
540c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org    SkASSERT(this->caps()->pathRenderingSupport());
541c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org    const GrDrawState* drawState = &getDrawState();
542c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org
543c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org    SkRect devBounds;
544c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org    if (SkPath::IsInverseFillType(fill)) {
545c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org        devBounds = SkRect::MakeWH(SkIntToScalar(drawState->getRenderTarget()->width()),
546c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org                                   SkIntToScalar(drawState->getRenderTarget()->height()));
547c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org    } else {
548c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org        devBounds = path->getBounds();
549c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org    }
550c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org    SkMatrix viewM = drawState->getViewMatrix();
551c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org    viewM.mapRect(&devBounds);
552c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org
553c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org    GrDeviceCoordTexture dstCopy;
554c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org    if (!this->setupDstReadIfNecessary(&dstCopy, &devBounds)) {
555c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org        return;
556c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org    }
557c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org
55832184d81629e39809bb9e915286d8fe971a8ed68commit-bot@chromium.org    this->onDrawPath(path, fill, dstCopy.texture() ? &dstCopy : NULL);
559c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org}
560c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org
561b85a0aab6905af8b329539b7573a7555b727d5e5cdaltonvoid GrDrawTarget::drawPaths(const GrPathRange* pathRange,
562b85a0aab6905af8b329539b7573a7555b727d5e5cdalton                             const uint32_t indices[], int count,
563b85a0aab6905af8b329539b7573a7555b727d5e5cdalton                             const float transforms[], PathTransformType transformsType,
564b85a0aab6905af8b329539b7573a7555b727d5e5cdalton                             SkPath::FillType fill) {
5659b62aa156bcf1db6f11af9302bf8bb8ef2567142commit-bot@chromium.org    SkASSERT(this->caps()->pathRenderingSupport());
56649f085dddff10473b6ebf832a974288300224e60bsalomon    SkASSERT(pathRange);
56749f085dddff10473b6ebf832a974288300224e60bsalomon    SkASSERT(indices);
56849f085dddff10473b6ebf832a974288300224e60bsalomon    SkASSERT(transforms);
569b85a0aab6905af8b329539b7573a7555b727d5e5cdalton
570b85a0aab6905af8b329539b7573a7555b727d5e5cdalton    // Don't compute a bounding box for setupDstReadIfNecessary(), we'll opt
571b85a0aab6905af8b329539b7573a7555b727d5e5cdalton    // instead for it to just copy the entire dst. Realistically this is a moot
572b85a0aab6905af8b329539b7573a7555b727d5e5cdalton    // point, because any context that supports NV_path_rendering will also
573b85a0aab6905af8b329539b7573a7555b727d5e5cdalton    // support NV_blend_equation_advanced.
5749b62aa156bcf1db6f11af9302bf8bb8ef2567142commit-bot@chromium.org    GrDeviceCoordTexture dstCopy;
575b85a0aab6905af8b329539b7573a7555b727d5e5cdalton    if (!this->setupDstReadIfNecessary(&dstCopy, NULL)) {
5769b62aa156bcf1db6f11af9302bf8bb8ef2567142commit-bot@chromium.org        return;
5779b62aa156bcf1db6f11af9302bf8bb8ef2567142commit-bot@chromium.org    }
5789b62aa156bcf1db6f11af9302bf8bb8ef2567142commit-bot@chromium.org
579b85a0aab6905af8b329539b7573a7555b727d5e5cdalton    this->onDrawPaths(pathRange, indices, count, transforms, transformsType, fill,
5809b62aa156bcf1db6f11af9302bf8bb8ef2567142commit-bot@chromium.org                      dstCopy.texture() ? &dstCopy : NULL);
5819b62aa156bcf1db6f11af9302bf8bb8ef2567142commit-bot@chromium.org}
5829b62aa156bcf1db6f11af9302bf8bb8ef2567142commit-bot@chromium.org
5833eee3834fba1d2e29dfb61adcb97e4624b6a3ac8egdanieltypedef GrTraceMarkerSet::Iter TMIter;
5843eee3834fba1d2e29dfb61adcb97e4624b6a3ac8egdanielvoid GrDrawTarget::saveActiveTraceMarkers() {
5853eee3834fba1d2e29dfb61adcb97e4624b6a3ac8egdaniel    if (this->caps()->gpuTracingSupport()) {
5863eee3834fba1d2e29dfb61adcb97e4624b6a3ac8egdaniel        SkASSERT(0 == fStoredTraceMarkers.count());
5873eee3834fba1d2e29dfb61adcb97e4624b6a3ac8egdaniel        fStoredTraceMarkers.addSet(fActiveTraceMarkers);
5883eee3834fba1d2e29dfb61adcb97e4624b6a3ac8egdaniel        for (TMIter iter = fStoredTraceMarkers.begin(); iter != fStoredTraceMarkers.end(); ++iter) {
5893eee3834fba1d2e29dfb61adcb97e4624b6a3ac8egdaniel            this->removeGpuTraceMarker(&(*iter));
5903eee3834fba1d2e29dfb61adcb97e4624b6a3ac8egdaniel        }
5913eee3834fba1d2e29dfb61adcb97e4624b6a3ac8egdaniel    }
5923eee3834fba1d2e29dfb61adcb97e4624b6a3ac8egdaniel}
5933eee3834fba1d2e29dfb61adcb97e4624b6a3ac8egdaniel
5943eee3834fba1d2e29dfb61adcb97e4624b6a3ac8egdanielvoid GrDrawTarget::restoreActiveTraceMarkers() {
5953eee3834fba1d2e29dfb61adcb97e4624b6a3ac8egdaniel    if (this->caps()->gpuTracingSupport()) {
5963eee3834fba1d2e29dfb61adcb97e4624b6a3ac8egdaniel        SkASSERT(0 == fActiveTraceMarkers.count());
5973eee3834fba1d2e29dfb61adcb97e4624b6a3ac8egdaniel        for (TMIter iter = fStoredTraceMarkers.begin(); iter != fStoredTraceMarkers.end(); ++iter) {
5983eee3834fba1d2e29dfb61adcb97e4624b6a3ac8egdaniel            this->addGpuTraceMarker(&(*iter));
5993eee3834fba1d2e29dfb61adcb97e4624b6a3ac8egdaniel        }
6003eee3834fba1d2e29dfb61adcb97e4624b6a3ac8egdaniel        for (TMIter iter = fActiveTraceMarkers.begin(); iter != fActiveTraceMarkers.end(); ++iter) {
6013eee3834fba1d2e29dfb61adcb97e4624b6a3ac8egdaniel            this->fStoredTraceMarkers.remove(*iter);
6023eee3834fba1d2e29dfb61adcb97e4624b6a3ac8egdaniel        }
6033eee3834fba1d2e29dfb61adcb97e4624b6a3ac8egdaniel    }
6043eee3834fba1d2e29dfb61adcb97e4624b6a3ac8egdaniel}
6053eee3834fba1d2e29dfb61adcb97e4624b6a3ac8egdaniel
6063eee3834fba1d2e29dfb61adcb97e4624b6a3ac8egdanielvoid GrDrawTarget::addGpuTraceMarker(const GrGpuTraceMarker* marker) {
607a3baf3be0e2a3128fb73bd41d40d130f75a4dc86commit-bot@chromium.org    if (this->caps()->gpuTracingSupport()) {
6082a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org        SkASSERT(fGpuTraceMarkerCount >= 0);
6092a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org        this->fActiveTraceMarkers.add(*marker);
6102a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org        this->didAddGpuTraceMarker();
6112a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org        ++fGpuTraceMarkerCount;
612a3baf3be0e2a3128fb73bd41d40d130f75a4dc86commit-bot@chromium.org    }
613a3baf3be0e2a3128fb73bd41d40d130f75a4dc86commit-bot@chromium.org}
614a3baf3be0e2a3128fb73bd41d40d130f75a4dc86commit-bot@chromium.org
6153eee3834fba1d2e29dfb61adcb97e4624b6a3ac8egdanielvoid GrDrawTarget::removeGpuTraceMarker(const GrGpuTraceMarker* marker) {
616a3baf3be0e2a3128fb73bd41d40d130f75a4dc86commit-bot@chromium.org    if (this->caps()->gpuTracingSupport()) {
6172a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org        SkASSERT(fGpuTraceMarkerCount >= 1);
6182a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org        this->fActiveTraceMarkers.remove(*marker);
6192a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org        this->didRemoveGpuTraceMarker();
6202a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org        --fGpuTraceMarkerCount;
621a3baf3be0e2a3128fb73bd41d40d130f75a4dc86commit-bot@chromium.org    }
622a3baf3be0e2a3128fb73bd41d40d130f75a4dc86commit-bot@chromium.org}
623a3baf3be0e2a3128fb73bd41d40d130f75a4dc86commit-bot@chromium.org
62425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com////////////////////////////////////////////////////////////////////////////////
62586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
626934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.comvoid GrDrawTarget::drawIndexedInstances(GrPrimitiveType type,
627934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com                                        int instanceCount,
628934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com                                        int verticesPerInstance,
629d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com                                        int indicesPerInstance,
630d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com                                        const SkRect* devBounds) {
631934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com    if (!verticesPerInstance || !indicesPerInstance) {
632934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        return;
633934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com    }
634934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com
635d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    int maxInstancesPerDraw = this->indexCountInCurrentSource() / indicesPerInstance;
636d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    if (!maxInstancesPerDraw) {
637934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        return;
638934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com    }
639934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com
640d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    DrawInfo info;
641d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    info.fPrimitiveType = type;
642d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    info.fStartIndex = 0;
643d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    info.fStartVertex = 0;
644d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    info.fIndicesPerInstance = indicesPerInstance;
645d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    info.fVerticesPerInstance = verticesPerInstance;
646d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com
647d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    // Set the same bounds for all the draws.
64849f085dddff10473b6ebf832a974288300224e60bsalomon    if (devBounds) {
649d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        info.setDevBounds(*devBounds);
650d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    }
65126e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    // TODO: We should continue with incorrect blending.
65226e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    if (!this->setupDstReadIfNecessary(&info)) {
65326e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com        return;
65426e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    }
655d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com
656934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com    while (instanceCount) {
657972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org        info.fInstanceCount = SkTMin(instanceCount, maxInstancesPerDraw);
658d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        info.fVertexCount = info.fInstanceCount * verticesPerInstance;
659d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        info.fIndexCount = info.fInstanceCount * indicesPerInstance;
660d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com
661d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        if (this->checkDraw(type,
662d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com                            info.fStartVertex,
663d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com                            info.fStartIndex,
664d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com                            info.fVertexCount,
665d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com                            info.fIndexCount)) {
666d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com            this->onDraw(info);
667d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        }
668d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        info.fStartVertex += info.fVertexCount;
669d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        instanceCount -= info.fInstanceCount;
670934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com    }
671934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com}
6723d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com
67325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com////////////////////////////////////////////////////////////////////////////////
67425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
675429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.comnamespace {
676429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com
677429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com// position + (optional) texture coord
678429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.comextern const GrVertexAttrib gBWRectPosUVAttribs[] = {
679429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com    {kVec2f_GrVertexAttribType, 0,               kPosition_GrVertexAttribBinding},
680972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org    {kVec2f_GrVertexAttribType, sizeof(SkPoint), kLocalCoord_GrVertexAttribBinding}
681429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com};
682429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com
683429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.comvoid set_vertex_attributes(GrDrawState* drawState, bool hasUVs) {
684429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com    if (hasUVs) {
6857b3d5ee72c2238aa239bce4d5b3aea98a437ca7aegdaniel        drawState->setVertexAttribs<gBWRectPosUVAttribs>(2, 2 * sizeof(SkPoint));
686429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com    } else {
6877b3d5ee72c2238aa239bce4d5b3aea98a437ca7aegdaniel        drawState->setVertexAttribs<gBWRectPosUVAttribs>(1, sizeof(SkPoint));
688429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com    }
689429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com}
690429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com
691429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com};
692429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com
693fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.orgvoid GrDrawTarget::onDrawRect(const SkRect& rect,
694fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org                              const SkRect* localRect,
6950406b9e1faee06c6ecb2732a1bcf3b0e53104e07bsalomon@google.com                              const SkMatrix* localMatrix) {
696dea2f8d86378b791a2de94384a18e29f13f65a3ebsalomon@google.com
69749f085dddff10473b6ebf832a974288300224e60bsalomon    set_vertex_attributes(this->drawState(), SkToBool(localRect));
698429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com
699b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com    AutoReleaseGeometry geo(this, 4, 0);
700d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    if (!geo.succeeded()) {
701d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        GrPrintf("Failed to get space for vertices!\n");
702d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        return;
70386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    }
70486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
7057b3d5ee72c2238aa239bce4d5b3aea98a437ca7aegdaniel    size_t vstride = this->drawState()->getVertexStride();
7067b3d5ee72c2238aa239bce4d5b3aea98a437ca7aegdaniel    geo.positions()->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, vstride);
70749f085dddff10473b6ebf832a974288300224e60bsalomon    if (localRect) {
708972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org        SkPoint* coords = GrTCast<SkPoint*>(GrTCast<intptr_t>(geo.vertices()) +
709972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org                                            sizeof(SkPoint));
710c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        coords->setRectFan(localRect->fLeft, localRect->fTop,
711c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com                           localRect->fRight, localRect->fBottom,
7127b3d5ee72c2238aa239bce4d5b3aea98a437ca7aegdaniel                           vstride);
71349f085dddff10473b6ebf832a974288300224e60bsalomon        if (localMatrix) {
7147b3d5ee72c2238aa239bce4d5b3aea98a437ca7aegdaniel            localMatrix->mapPointsWithStride(coords, vstride, 4);
71586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        }
71686afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    }
7173ae0e6c2b213d45c370846a4d4182a6754ca493ecommit-bot@chromium.org    SkRect bounds;
7183ae0e6c2b213d45c370846a4d4182a6754ca493ecommit-bot@chromium.org    this->getDrawState().getViewMatrix().mapRect(&bounds, rect);
7198b129aa3379ece6c43d9ce2ad0cdeafb089b7eb5robertphillips@google.com
7203ae0e6c2b213d45c370846a4d4182a6754ca493ecommit-bot@chromium.org    this->drawNonIndexed(kTriangleFan_GrPrimitiveType, 0, 4, &bounds);
72186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com}
72286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
72302ddc8b85ace91b15feb329a6a1d5d62b2b846c6bsalomon@google.comvoid GrDrawTarget::clipWillBeSet(const GrClipData* clipData) {
72402ddc8b85ace91b15feb329a6a1d5d62b2b846c6bsalomon@google.com}
72502ddc8b85ace91b15feb329a6a1d5d62b2b846c6bsalomon@google.com
72625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com////////////////////////////////////////////////////////////////////////////////
7277ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com
72806afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.comGrDrawTarget::AutoStateRestore::AutoStateRestore() {
72906afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com    fDrawTarget = NULL;
73006afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com}
731ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
732873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.comGrDrawTarget::AutoStateRestore::AutoStateRestore(GrDrawTarget* target,
733137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com                                                 ASRInit init,
734137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com                                                 const SkMatrix* vm) {
735873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com    fDrawTarget = NULL;
736137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com    this->set(target, init, vm);
737ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
738ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
739ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrDrawTarget::AutoStateRestore::~AutoStateRestore() {
74049f085dddff10473b6ebf832a974288300224e60bsalomon    if (fDrawTarget) {
741873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com        fDrawTarget->setDrawState(fSavedState);
742873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com        fSavedState->unref();
7437d34d2eecc40d150d867e37d5160a1bc3cfccbdebsalomon@google.com    }
744ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
7457d34d2eecc40d150d867e37d5160a1bc3cfccbdebsalomon@google.com
746137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.comvoid GrDrawTarget::AutoStateRestore::set(GrDrawTarget* target, ASRInit init, const SkMatrix* vm) {
747f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(NULL == fDrawTarget);
748137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com    fDrawTarget = target;
749137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com    fSavedState = target->drawState();
750f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(fSavedState);
751137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com    fSavedState->ref();
752137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com    if (kReset_ASRInit == init) {
753137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com        if (NULL == vm) {
754137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com            // calls the default cons
755137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com            fTempState.init();
756137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com        } else {
757137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com            SkNEW_IN_TLAZY(&fTempState, GrDrawState, (*vm));
758137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com        }
759137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com    } else {
760f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org        SkASSERT(kPreserve_ASRInit == init);
761137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com        if (NULL == vm) {
762137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com            fTempState.set(*fSavedState);
763137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com        } else {
764137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com            SkNEW_IN_TLAZY(&fTempState, GrDrawState, (*fSavedState, *vm));
765137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com        }
766137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com    }
767137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com    target->setDrawState(fTempState.get());
768137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com}
769137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com
770137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.combool GrDrawTarget::AutoStateRestore::setIdentity(GrDrawTarget* target, ASRInit init) {
771f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(NULL == fDrawTarget);
772873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com    fDrawTarget = target;
773873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com    fSavedState = target->drawState();
774f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(fSavedState);
775873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com    fSavedState->ref();
776873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com    if (kReset_ASRInit == init) {
777873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com        // calls the default cons
778873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com        fTempState.init();
779873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com    } else {
780f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org        SkASSERT(kPreserve_ASRInit == init);
781873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com        // calls the copy cons
782873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com        fTempState.set(*fSavedState);
783137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com        if (!fTempState.get()->setIdentityViewMatrix()) {
784137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com            // let go of any resources held by the temp
785137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com            fTempState.get()->reset();
786137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com            fDrawTarget = NULL;
787137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com            fSavedState->unref();
788137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com            fSavedState = NULL;
789137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com            return false;
790137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com        }
79106afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com    }
792873ea0c93f202600ec2591bc1e2e5d7a1e05f59dbsalomon@google.com    target->setDrawState(fTempState.get());
793137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com    return true;
79406afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com}
7957ac249bdc7a86bc44610e02abeeaa0c14ba8163absalomon@google.com
79625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com////////////////////////////////////////////////////////////////////////////////
79725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
79825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comGrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry(
79925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                         GrDrawTarget*  target,
80025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                         int vertexCount,
80125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                         int indexCount) {
80225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    fTarget = NULL;
803b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com    this->set(target, vertexCount, indexCount);
80425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
805d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
80625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comGrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry() {
80725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    fTarget = NULL;
80825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
80925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
81025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comGrDrawTarget::AutoReleaseGeometry::~AutoReleaseGeometry() {
81125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    this->reset();
81225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
81325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
81425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.combool GrDrawTarget::AutoReleaseGeometry::set(GrDrawTarget*  target,
81525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                            int vertexCount,
81625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                            int indexCount) {
81725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    this->reset();
81825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    fTarget = target;
81925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    bool success = true;
82049f085dddff10473b6ebf832a974288300224e60bsalomon    if (fTarget) {
821b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com        success = target->reserveVertexAndIndexSpace(vertexCount,
822e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com                                                     indexCount,
823e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com                                                     &fVertices,
824e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com                                                     &fIndices);
825e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com        if (!success) {
826e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com            fTarget = NULL;
827e3d7095c2374a423815e662020459832f389a40fbsalomon@google.com            this->reset();
82825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        }
82925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
83049f085dddff10473b6ebf832a974288300224e60bsalomon    SkASSERT(success == SkToBool(fTarget));
83125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    return success;
83225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
83325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
83425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrDrawTarget::AutoReleaseGeometry::reset() {
83549f085dddff10473b6ebf832a974288300224e60bsalomon    if (fTarget) {
83649f085dddff10473b6ebf832a974288300224e60bsalomon        if (fVertices) {
83725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            fTarget->resetVertexSource();
83825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        }
83949f085dddff10473b6ebf832a974288300224e60bsalomon        if (fIndices) {
84025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            fTarget->resetIndexSource();
84125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        }
84225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        fTarget = NULL;
84325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
844cb0c5ab54d69f813f4faf4c7ac2092358bc663aabsalomon@google.com    fVertices = NULL;
845cb0c5ab54d69f813f4faf4c7ac2092358bc663aabsalomon@google.com    fIndices = NULL;
84625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
84725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
8488d67c0711b52226db59158a0cfce09f35badd96absalomon@google.comGrDrawTarget::AutoClipRestore::AutoClipRestore(GrDrawTarget* target, const SkIRect& newClip) {
8498d67c0711b52226db59158a0cfce09f35badd96absalomon@google.com    fTarget = target;
8508d67c0711b52226db59158a0cfce09f35badd96absalomon@google.com    fClip = fTarget->getClip();
8518d67c0711b52226db59158a0cfce09f35badd96absalomon@google.com    fStack.init();
8528d67c0711b52226db59158a0cfce09f35badd96absalomon@google.com    fStack.get()->clipDevRect(newClip, SkRegion::kReplace_Op);
8538d67c0711b52226db59158a0cfce09f35badd96absalomon@google.com    fReplacementClip.fClipStack = fStack.get();
8548d67c0711b52226db59158a0cfce09f35badd96absalomon@google.com    target->setClip(&fReplacementClip);
8558d67c0711b52226db59158a0cfce09f35badd96absalomon@google.com}
8568d67c0711b52226db59158a0cfce09f35badd96absalomon@google.com
857116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.comnamespace {
858116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com// returns true if the read/written rect intersects the src/dst and false if not.
859116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.combool clip_srcrect_and_dstpoint(const GrSurface* dst,
860116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com                               const GrSurface* src,
861e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com                               const SkIRect& srcRect,
862116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com                               const SkIPoint& dstPoint,
863116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com                               SkIRect* clippedSrcRect,
864116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com                               SkIPoint* clippedDstPoint) {
865116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com    *clippedSrcRect = srcRect;
866116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com    *clippedDstPoint = dstPoint;
867a9493a3c78f6eb82635ece960b4f16918b885428skia.committer@gmail.com
868116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com    // clip the left edge to src and dst bounds, adjusting dstPoint if necessary
869116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com    if (clippedSrcRect->fLeft < 0) {
870116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com        clippedDstPoint->fX -= clippedSrcRect->fLeft;
871116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com        clippedSrcRect->fLeft = 0;
872e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    }
873116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com    if (clippedDstPoint->fX < 0) {
874116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com        clippedSrcRect->fLeft -= clippedDstPoint->fX;
875116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com        clippedDstPoint->fX = 0;
876e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    }
877e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com
878116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com    // clip the top edge to src and dst bounds, adjusting dstPoint if necessary
879116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com    if (clippedSrcRect->fTop < 0) {
880116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com        clippedDstPoint->fY -= clippedSrcRect->fTop;
881116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com        clippedSrcRect->fTop = 0;
882e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    }
883116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com    if (clippedDstPoint->fY < 0) {
884116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com        clippedSrcRect->fTop -= clippedDstPoint->fY;
885116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com        clippedDstPoint->fY = 0;
886e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    }
887a9493a3c78f6eb82635ece960b4f16918b885428skia.committer@gmail.com
888e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    // clip the right edge to the src and dst bounds.
889116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com    if (clippedSrcRect->fRight > src->width()) {
890116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com        clippedSrcRect->fRight = src->width();
891e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    }
892116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com    if (clippedDstPoint->fX + clippedSrcRect->width() > dst->width()) {
893116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com        clippedSrcRect->fRight = clippedSrcRect->fLeft + dst->width() - clippedDstPoint->fX;
894e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    }
895e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com
896e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    // clip the bottom edge to the src and dst bounds.
897116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com    if (clippedSrcRect->fBottom > src->height()) {
898116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com        clippedSrcRect->fBottom = src->height();
899e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    }
900116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com    if (clippedDstPoint->fY + clippedSrcRect->height() > dst->height()) {
901116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com        clippedSrcRect->fBottom = clippedSrcRect->fTop + dst->height() - clippedDstPoint->fY;
902e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    }
903a9493a3c78f6eb82635ece960b4f16918b885428skia.committer@gmail.com
904e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    // The above clipping steps may have inverted the rect if it didn't intersect either the src or
905e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    // dst bounds.
906116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com    return !clippedSrcRect->isEmpty();
907116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com}
908116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com}
909116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com
910116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.combool GrDrawTarget::copySurface(GrSurface* dst,
911116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com                               GrSurface* src,
912116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com                               const SkIRect& srcRect,
913116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com                               const SkIPoint& dstPoint) {
91449f085dddff10473b6ebf832a974288300224e60bsalomon    SkASSERT(dst);
91549f085dddff10473b6ebf832a974288300224e60bsalomon    SkASSERT(src);
916116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com
917116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com    SkIRect clippedSrcRect;
918116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com    SkIPoint clippedDstPoint;
919116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com    // If the rect is outside the src or dst then we've already succeeded.
920116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com    if (!clip_srcrect_and_dstpoint(dst,
921116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com                                   src,
922116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com                                   srcRect,
923116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com                                   dstPoint,
924116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com                                   &clippedSrcRect,
925116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com                                   &clippedDstPoint)) {
926f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org        SkASSERT(this->canCopySurface(dst, src, srcRect, dstPoint));
927e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com        return true;
928e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    }
929e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com
930e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    bool result = this->onCopySurface(dst, src, clippedSrcRect, clippedDstPoint);
931f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(result == this->canCopySurface(dst, src, clippedSrcRect, clippedDstPoint));
932e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    return result;
933e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com}
934e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com
935e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.combool GrDrawTarget::canCopySurface(GrSurface* dst,
936e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com                                  GrSurface* src,
937e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com                                  const SkIRect& srcRect,
938e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com                                  const SkIPoint& dstPoint) {
93949f085dddff10473b6ebf832a974288300224e60bsalomon    SkASSERT(dst);
94049f085dddff10473b6ebf832a974288300224e60bsalomon    SkASSERT(src);
941116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com
942116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com    SkIRect clippedSrcRect;
943116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com    SkIPoint clippedDstPoint;
944116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com    // If the rect is outside the src or dst then we're guaranteed success
945116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com    if (!clip_srcrect_and_dstpoint(dst,
946116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com                                   src,
947116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com                                   srcRect,
948116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com                                   dstPoint,
949116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com                                   &clippedSrcRect,
950116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com                                   &clippedDstPoint)) {
951116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com        return true;
952116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com    }
953116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com    return this->onCanCopySurface(dst, src, clippedSrcRect, clippedDstPoint);
954116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com}
955116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com
956116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.combool GrDrawTarget::onCanCopySurface(GrSurface* dst,
957116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com                                    GrSurface* src,
958116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com                                    const SkIRect& srcRect,
959116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com                                    const SkIPoint& dstPoint) {
960e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    // Check that the read/write rects are contained within the src/dst bounds.
961f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(!srcRect.isEmpty());
962f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(SkIRect::MakeWH(src->width(), src->height()).contains(srcRect));
963f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(dstPoint.fX >= 0 && dstPoint.fY >= 0);
964f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(dstPoint.fX + srcRect.width() <= dst->width() &&
965e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com             dstPoint.fY + srcRect.height() <= dst->height());
966e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com
96749f085dddff10473b6ebf832a974288300224e60bsalomon    return !dst->isSameAs(src) && dst->asRenderTarget() && src->asTexture();
968e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com}
969e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com
970e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.combool GrDrawTarget::onCopySurface(GrSurface* dst,
971e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com                                 GrSurface* src,
972e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com                                 const SkIRect& srcRect,
973e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com                                 const SkIPoint& dstPoint) {
974116ad84d3126b0db22b2312ca59ed70e5c56f6fcbsalomon@google.com    if (!GrDrawTarget::onCanCopySurface(dst, src, srcRect, dstPoint)) {
975e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com        return false;
976e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    }
977e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com
978e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    GrRenderTarget* rt = dst->asRenderTarget();
979e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    GrTexture* tex = src->asTexture();
980e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com
981e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    GrDrawTarget::AutoStateRestore asr(this, kReset_ASRInit);
982e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    this->drawState()->setRenderTarget(rt);
983e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    SkMatrix matrix;
984e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    matrix.setTranslate(SkIntToScalar(srcRect.fLeft - dstPoint.fX),
985e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com                        SkIntToScalar(srcRect.fTop - dstPoint.fY));
986e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    matrix.postIDiv(tex->width(), tex->height());
987b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt    this->drawState()->addColorTextureProcessor(tex, matrix);
988e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX,
989e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com                                        dstPoint.fY,
990e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com                                        srcRect.width(),
991e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com                                        srcRect.height());
992e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    this->drawSimpleRect(dstRect);
993e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com    return true;
994e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com}
995e4617bf6d45cdde07f89e341ebf5c485916bf0b2bsalomon@google.com
996eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.comvoid GrDrawTarget::initCopySurfaceDstDesc(const GrSurface* src, GrTextureDesc* desc) {
997eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com    // Make the dst of the copy be a render target because the default copySurface draws to the dst.
998eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com    desc->fOrigin = kDefault_GrSurfaceOrigin;
999eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com    desc->fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit;
1000eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com    desc->fConfig = src->config();
1001eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com}
1002eb85117c05471e1a55ce387cbc38279f857a4584bsalomon@google.com
1003bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com///////////////////////////////////////////////////////////////////////////////
1004bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com
1005c26d94fd7dc0b00cd6d0e42d28285f4a38aff021bsalomon@google.comvoid GrDrawTargetCaps::reset() {
10064744231c149989666d70956527495bddb2e5dd8bcommit-bot@chromium.org    fMipMapSupport = false;
1007bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    fNPOTTextureTileSupport = false;
1008bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    fTwoSidedStencilSupport = false;
1009bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    fStencilWrapOpsSupport = false;
1010bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    fHWAALineSupport = false;
1011bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    fShaderDerivativeSupport = false;
1012bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    fGeometryShaderSupport = false;
1013e60ed08a3568b5e253dfb5dec2b52d13a16fff1cskia.committer@gmail.com    fDualSourceBlendingSupport = false;
1014c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org    fPathRenderingSupport = false;
1015b835652599356556401b68ac26b57044160a7289commit-bot@chromium.org    fDstReadInShaderSupport = false;
101628361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org    fDiscardRenderTargetSupport = false;
1017b835652599356556401b68ac26b57044160a7289commit-bot@chromium.org    fReuseScratchTextures = true;
1018a3baf3be0e2a3128fb73bd41d40d130f75a4dc86commit-bot@chromium.org    fGpuTracingSupport = false;
101978697816b0a345c614071070eaa895d71f598e22krajcevski    fCompressedTexSubImageSupport = false;
1020bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com
1021160b478eed1dd4924a86a87fd60c91139e08ff71commit-bot@chromium.org    fMapBufferFlags = kNone_MapFlags;
1022160b478eed1dd4924a86a87fd60c91139e08ff71commit-bot@chromium.org
1023bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    fMaxRenderTargetSize = 0;
1024bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    fMaxTextureSize = 0;
1025bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    fMaxSampleCount = 0;
10267388051d745590d7759e7ed49c233caec6bea0f7commit-bot@chromium.org
10277388051d745590d7759e7ed49c233caec6bea0f7commit-bot@chromium.org    memset(fConfigRenderSupport, 0, sizeof(fConfigRenderSupport));
10286e7ddaae0a077a777b8b8872ec27f8faab275536commit-bot@chromium.org    memset(fConfigTextureSupport, 0, sizeof(fConfigTextureSupport));
1029bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com}
1030bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com
1031c26d94fd7dc0b00cd6d0e42d28285f4a38aff021bsalomon@google.comGrDrawTargetCaps& GrDrawTargetCaps::operator=(const GrDrawTargetCaps& other) {
10324744231c149989666d70956527495bddb2e5dd8bcommit-bot@chromium.org    fMipMapSupport = other.fMipMapSupport;
1033bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    fNPOTTextureTileSupport = other.fNPOTTextureTileSupport;
1034bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    fTwoSidedStencilSupport = other.fTwoSidedStencilSupport;
1035bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    fStencilWrapOpsSupport = other.fStencilWrapOpsSupport;
1036bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    fHWAALineSupport = other.fHWAALineSupport;
1037bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    fShaderDerivativeSupport = other.fShaderDerivativeSupport;
1038bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    fGeometryShaderSupport = other.fGeometryShaderSupport;
1039bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    fDualSourceBlendingSupport = other.fDualSourceBlendingSupport;
1040c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org    fPathRenderingSupport = other.fPathRenderingSupport;
1041b835652599356556401b68ac26b57044160a7289commit-bot@chromium.org    fDstReadInShaderSupport = other.fDstReadInShaderSupport;
104228361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org    fDiscardRenderTargetSupport = other.fDiscardRenderTargetSupport;
1043b835652599356556401b68ac26b57044160a7289commit-bot@chromium.org    fReuseScratchTextures = other.fReuseScratchTextures;
1044a3baf3be0e2a3128fb73bd41d40d130f75a4dc86commit-bot@chromium.org    fGpuTracingSupport = other.fGpuTracingSupport;
104578697816b0a345c614071070eaa895d71f598e22krajcevski    fCompressedTexSubImageSupport = other.fCompressedTexSubImageSupport;
1046bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com
1047160b478eed1dd4924a86a87fd60c91139e08ff71commit-bot@chromium.org    fMapBufferFlags = other.fMapBufferFlags;
1048160b478eed1dd4924a86a87fd60c91139e08ff71commit-bot@chromium.org
1049bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    fMaxRenderTargetSize = other.fMaxRenderTargetSize;
1050bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    fMaxTextureSize = other.fMaxTextureSize;
1051bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    fMaxSampleCount = other.fMaxSampleCount;
1052bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com
10537388051d745590d7759e7ed49c233caec6bea0f7commit-bot@chromium.org    memcpy(fConfigRenderSupport, other.fConfigRenderSupport, sizeof(fConfigRenderSupport));
10546e7ddaae0a077a777b8b8872ec27f8faab275536commit-bot@chromium.org    memcpy(fConfigTextureSupport, other.fConfigTextureSupport, sizeof(fConfigTextureSupport));
10557388051d745590d7759e7ed49c233caec6bea0f7commit-bot@chromium.org
1056bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    return *this;
1057bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com}
1058bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com
1059160b478eed1dd4924a86a87fd60c91139e08ff71commit-bot@chromium.orgstatic SkString map_flags_to_string(uint32_t flags) {
1060160b478eed1dd4924a86a87fd60c91139e08ff71commit-bot@chromium.org    SkString str;
1061160b478eed1dd4924a86a87fd60c91139e08ff71commit-bot@chromium.org    if (GrDrawTargetCaps::kNone_MapFlags == flags) {
1062160b478eed1dd4924a86a87fd60c91139e08ff71commit-bot@chromium.org        str = "none";
1063160b478eed1dd4924a86a87fd60c91139e08ff71commit-bot@chromium.org    } else {
1064160b478eed1dd4924a86a87fd60c91139e08ff71commit-bot@chromium.org        SkASSERT(GrDrawTargetCaps::kCanMap_MapFlag & flags);
1065160b478eed1dd4924a86a87fd60c91139e08ff71commit-bot@chromium.org        SkDEBUGCODE(flags &= ~GrDrawTargetCaps::kCanMap_MapFlag);
1066160b478eed1dd4924a86a87fd60c91139e08ff71commit-bot@chromium.org        str = "can_map";
1067160b478eed1dd4924a86a87fd60c91139e08ff71commit-bot@chromium.org
1068160b478eed1dd4924a86a87fd60c91139e08ff71commit-bot@chromium.org        if (GrDrawTargetCaps::kSubset_MapFlag & flags) {
1069160b478eed1dd4924a86a87fd60c91139e08ff71commit-bot@chromium.org            str.append(" partial");
1070160b478eed1dd4924a86a87fd60c91139e08ff71commit-bot@chromium.org        } else {
1071160b478eed1dd4924a86a87fd60c91139e08ff71commit-bot@chromium.org            str.append(" full");
1072160b478eed1dd4924a86a87fd60c91139e08ff71commit-bot@chromium.org        }
1073160b478eed1dd4924a86a87fd60c91139e08ff71commit-bot@chromium.org        SkDEBUGCODE(flags &= ~GrDrawTargetCaps::kSubset_MapFlag);
1074160b478eed1dd4924a86a87fd60c91139e08ff71commit-bot@chromium.org    }
1075160b478eed1dd4924a86a87fd60c91139e08ff71commit-bot@chromium.org    SkASSERT(0 == flags); // Make sure we handled all the flags.
1076160b478eed1dd4924a86a87fd60c91139e08ff71commit-bot@chromium.org    return str;
1077160b478eed1dd4924a86a87fd60c91139e08ff71commit-bot@chromium.org}
1078160b478eed1dd4924a86a87fd60c91139e08ff71commit-bot@chromium.org
10798b656c6db40a99af241e38eae853f887413040cccommit-bot@chromium.orgSkString GrDrawTargetCaps::dump() const {
10808b656c6db40a99af241e38eae853f887413040cccommit-bot@chromium.org    SkString r;
108118c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com    static const char* gNY[] = {"NO", "YES"};
108228361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org    r.appendf("MIP Map Support              : %s\n", gNY[fMipMapSupport]);
108328361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org    r.appendf("NPOT Texture Tile Support    : %s\n", gNY[fNPOTTextureTileSupport]);
108428361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org    r.appendf("Two Sided Stencil Support    : %s\n", gNY[fTwoSidedStencilSupport]);
108528361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org    r.appendf("Stencil Wrap Ops  Support    : %s\n", gNY[fStencilWrapOpsSupport]);
108628361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org    r.appendf("HW AA Lines Support          : %s\n", gNY[fHWAALineSupport]);
108728361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org    r.appendf("Shader Derivative Support    : %s\n", gNY[fShaderDerivativeSupport]);
108828361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org    r.appendf("Geometry Shader Support      : %s\n", gNY[fGeometryShaderSupport]);
108928361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org    r.appendf("Dual Source Blending Support : %s\n", gNY[fDualSourceBlendingSupport]);
109028361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org    r.appendf("Path Rendering Support       : %s\n", gNY[fPathRenderingSupport]);
109128361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org    r.appendf("Dst Read In Shader Support   : %s\n", gNY[fDstReadInShaderSupport]);
109228361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org    r.appendf("Discard Render Target Support: %s\n", gNY[fDiscardRenderTargetSupport]);
109328361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org    r.appendf("Reuse Scratch Textures       : %s\n", gNY[fReuseScratchTextures]);
109428361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org    r.appendf("Gpu Tracing Support          : %s\n", gNY[fGpuTracingSupport]);
109578697816b0a345c614071070eaa895d71f598e22krajcevski    r.appendf("Compressed Update Support    : %s\n", gNY[fCompressedTexSubImageSupport]);
109628361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org    r.appendf("Max Texture Size             : %d\n", fMaxTextureSize);
109728361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org    r.appendf("Max Render Target Size       : %d\n", fMaxRenderTargetSize);
109828361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org    r.appendf("Max Sample Count             : %d\n", fMaxSampleCount);
10997388051d745590d7759e7ed49c233caec6bea0f7commit-bot@chromium.org
1100160b478eed1dd4924a86a87fd60c91139e08ff71commit-bot@chromium.org    r.appendf("Map Buffer Support           : %s\n", map_flags_to_string(fMapBufferFlags).c_str());
1101160b478eed1dd4924a86a87fd60c91139e08ff71commit-bot@chromium.org
11027388051d745590d7759e7ed49c233caec6bea0f7commit-bot@chromium.org    static const char* kConfigNames[] = {
11037388051d745590d7759e7ed49c233caec6bea0f7commit-bot@chromium.org        "Unknown",  // kUnknown_GrPixelConfig
11047388051d745590d7759e7ed49c233caec6bea0f7commit-bot@chromium.org        "Alpha8",   // kAlpha_8_GrPixelConfig,
11057388051d745590d7759e7ed49c233caec6bea0f7commit-bot@chromium.org        "Index8",   // kIndex_8_GrPixelConfig,
11067388051d745590d7759e7ed49c233caec6bea0f7commit-bot@chromium.org        "RGB565",   // kRGB_565_GrPixelConfig,
11077388051d745590d7759e7ed49c233caec6bea0f7commit-bot@chromium.org        "RGBA444",  // kRGBA_4444_GrPixelConfig,
11087388051d745590d7759e7ed49c233caec6bea0f7commit-bot@chromium.org        "RGBA8888", // kRGBA_8888_GrPixelConfig,
11097388051d745590d7759e7ed49c233caec6bea0f7commit-bot@chromium.org        "BGRA8888", // kBGRA_8888_GrPixelConfig,
11106e7ddaae0a077a777b8b8872ec27f8faab275536commit-bot@chromium.org        "ETC1",     // kETC1_GrPixelConfig,
11116e7ddaae0a077a777b8b8872ec27f8faab275536commit-bot@chromium.org        "LATC",     // kLATC_GrPixelConfig,
1112238b456a7c6fb85c15f1ec288ea4f406a1a89da2krajcevski        "R11EAC",   // kR11_EAC_GrPixelConfig,
11137ef21622b2ed6b9c5fc4c149cb62944fc191f054krajcevski        "ASTC12x12",// kASTC_12x12_GrPixelConfig,
1114ee5da55477d1679eaf50b56b6017cbfc07af02a7joshualitt        "RGBAFloat",  // kRGBA_float_GrPixelConfig
11157388051d745590d7759e7ed49c233caec6bea0f7commit-bot@chromium.org    };
11167ef21622b2ed6b9c5fc4c149cb62944fc191f054krajcevski    GR_STATIC_ASSERT(0  == kUnknown_GrPixelConfig);
11177ef21622b2ed6b9c5fc4c149cb62944fc191f054krajcevski    GR_STATIC_ASSERT(1  == kAlpha_8_GrPixelConfig);
11187ef21622b2ed6b9c5fc4c149cb62944fc191f054krajcevski    GR_STATIC_ASSERT(2  == kIndex_8_GrPixelConfig);
11197ef21622b2ed6b9c5fc4c149cb62944fc191f054krajcevski    GR_STATIC_ASSERT(3  == kRGB_565_GrPixelConfig);
11207ef21622b2ed6b9c5fc4c149cb62944fc191f054krajcevski    GR_STATIC_ASSERT(4  == kRGBA_4444_GrPixelConfig);
11217ef21622b2ed6b9c5fc4c149cb62944fc191f054krajcevski    GR_STATIC_ASSERT(5  == kRGBA_8888_GrPixelConfig);
11227ef21622b2ed6b9c5fc4c149cb62944fc191f054krajcevski    GR_STATIC_ASSERT(6  == kBGRA_8888_GrPixelConfig);
11237ef21622b2ed6b9c5fc4c149cb62944fc191f054krajcevski    GR_STATIC_ASSERT(7  == kETC1_GrPixelConfig);
11247ef21622b2ed6b9c5fc4c149cb62944fc191f054krajcevski    GR_STATIC_ASSERT(8  == kLATC_GrPixelConfig);
11257ef21622b2ed6b9c5fc4c149cb62944fc191f054krajcevski    GR_STATIC_ASSERT(9  == kR11_EAC_GrPixelConfig);
11267ef21622b2ed6b9c5fc4c149cb62944fc191f054krajcevski    GR_STATIC_ASSERT(10 == kASTC_12x12_GrPixelConfig);
11277ef21622b2ed6b9c5fc4c149cb62944fc191f054krajcevski    GR_STATIC_ASSERT(11 == kRGBA_float_GrPixelConfig);
11287388051d745590d7759e7ed49c233caec6bea0f7commit-bot@chromium.org    GR_STATIC_ASSERT(SK_ARRAY_COUNT(kConfigNames) == kGrPixelConfigCnt);
11297388051d745590d7759e7ed49c233caec6bea0f7commit-bot@chromium.org
11309901727f213e459901a175c119b2fad8816002a0commit-bot@chromium.org    SkASSERT(!fConfigRenderSupport[kUnknown_GrPixelConfig][0]);
11319901727f213e459901a175c119b2fad8816002a0commit-bot@chromium.org    SkASSERT(!fConfigRenderSupport[kUnknown_GrPixelConfig][1]);
11326e7ddaae0a077a777b8b8872ec27f8faab275536commit-bot@chromium.org
11336e7ddaae0a077a777b8b8872ec27f8faab275536commit-bot@chromium.org    for (size_t i = 1; i < SK_ARRAY_COUNT(kConfigNames); ++i)  {
11346e7ddaae0a077a777b8b8872ec27f8faab275536commit-bot@chromium.org        r.appendf("%s is renderable: %s, with MSAA: %s\n",
11356e7ddaae0a077a777b8b8872ec27f8faab275536commit-bot@chromium.org                  kConfigNames[i],
11366e7ddaae0a077a777b8b8872ec27f8faab275536commit-bot@chromium.org                  gNY[fConfigRenderSupport[i][0]],
11376e7ddaae0a077a777b8b8872ec27f8faab275536commit-bot@chromium.org                  gNY[fConfigRenderSupport[i][1]]);
11387388051d745590d7759e7ed49c233caec6bea0f7commit-bot@chromium.org    }
113942dc8136914ee0777bb9110a5e04a75016687c0dcommit-bot@chromium.org
11406e7ddaae0a077a777b8b8872ec27f8faab275536commit-bot@chromium.org    SkASSERT(!fConfigTextureSupport[kUnknown_GrPixelConfig]);
11416e7ddaae0a077a777b8b8872ec27f8faab275536commit-bot@chromium.org
11426e7ddaae0a077a777b8b8872ec27f8faab275536commit-bot@chromium.org    for (size_t i = 1; i < SK_ARRAY_COUNT(kConfigNames); ++i)  {
11436e7ddaae0a077a777b8b8872ec27f8faab275536commit-bot@chromium.org        r.appendf("%s is uploadable to a texture: %s\n",
11446e7ddaae0a077a777b8b8872ec27f8faab275536commit-bot@chromium.org                  kConfigNames[i],
11456e7ddaae0a077a777b8b8872ec27f8faab275536commit-bot@chromium.org                  gNY[fConfigTextureSupport[i]]);
114642dc8136914ee0777bb9110a5e04a75016687c0dcommit-bot@chromium.org    }
114742dc8136914ee0777bb9110a5e04a75016687c0dcommit-bot@chromium.org
11488b656c6db40a99af241e38eae853f887413040cccommit-bot@chromium.org    return r;
114918c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com}
1150bc127a3fdaeaa9c3cf18fbe3a1139887aaff9903egdaniel
1151bc127a3fdaeaa9c3cf18fbe3a1139887aaff9903egdanieluint32_t GrDrawTargetCaps::CreateUniqueID() {
1152bc127a3fdaeaa9c3cf18fbe3a1139887aaff9903egdaniel    static int32_t gUniqueID = SK_InvalidUniqueID;
1153bc127a3fdaeaa9c3cf18fbe3a1139887aaff9903egdaniel    uint32_t id;
1154bc127a3fdaeaa9c3cf18fbe3a1139887aaff9903egdaniel    do {
1155bc127a3fdaeaa9c3cf18fbe3a1139887aaff9903egdaniel        id = static_cast<uint32_t>(sk_atomic_inc(&gUniqueID) + 1);
1156bc127a3fdaeaa9c3cf18fbe3a1139887aaff9903egdaniel    } while (id == SK_InvalidUniqueID);
1157bc127a3fdaeaa9c3cf18fbe3a1139887aaff9903egdaniel    return id;
1158bc127a3fdaeaa9c3cf18fbe3a1139887aaff9903egdaniel}
1159bc127a3fdaeaa9c3cf18fbe3a1139887aaff9903egdaniel
1160