GrInOrderDrawBuffer.cpp revision c26d94fd7dc0b00cd6d0e42d28285f4a38aff021
1ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
7ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com */
8ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
9ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
10ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#include "GrInOrderDrawBuffer.h"
111c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com#include "GrBufferAllocPool.h"
12c26d94fd7dc0b00cd6d0e42d28285f4a38aff021bsalomon@google.com#include "GrDrawTargetCaps.h"
13ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com#include "GrGpu.h"
1486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com#include "GrIndexBuffer.h"
15ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com#include "GrPath.h"
16ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com#include "GrRenderTarget.h"
176e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com#include "GrTemplates.h"
18ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com#include "GrTexture.h"
1986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com#include "GrVertexBuffer.h"
20ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
216e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.comGrInOrderDrawBuffer::GrInOrderDrawBuffer(GrGpu* gpu,
22471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com                                         GrVertexBufferAllocPool* vertexPool,
2325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                         GrIndexBufferAllocPool* indexPool)
246e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com    : GrDrawTarget(gpu->getContext())
256e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com    , fDstGpu(gpu)
2697805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com    , fClipSet(true)
27d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    , fClipProxyState(kUnknown_ClipProxyState)
286970557055acaed619d7bb89451868e1570249b2robertphillips@google.com    , fVertexPool(*vertexPool)
296970557055acaed619d7bb89451868e1570249b2robertphillips@google.com    , fIndexPool(*indexPool)
30c82a8b7aa4ec19fba508c394920a9e88d3e5bd12robertphillips@google.com    , fFlushing(false) {
3118c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com
326e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com    fDstGpu->ref();
33bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    fCaps.reset(SkRef(fDstGpu->caps()));
3418c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com
351c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    GrAssert(NULL != vertexPool);
361c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    GrAssert(NULL != indexPool);
3725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
3825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
3925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fUsedPoolVertexBytes = 0;
4025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fUsedPoolIndexBytes = 0;
4125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#if GR_DEBUG
4225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0;
4325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fPoolStartVertex = ~0;
4425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0;
4525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fPoolStartIndex = ~0;
4625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#endif
47a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    this->reset();
48ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
49ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
50ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrInOrderDrawBuffer::~GrInOrderDrawBuffer() {
5186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    this->reset();
524a018bb20bf969a38ec11d9506843f06366dfa7cbsalomon@google.com    // This must be called by before the GrDrawTarget destructor
534a018bb20bf969a38ec11d9506843f06366dfa7cbsalomon@google.com    this->releaseGeometry();
546e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com    fDstGpu->unref();
55ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
56ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
57934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com////////////////////////////////////////////////////////////////////////////////
58934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com
59d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.comnamespace {
60d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.comvoid get_vertex_bounds(const void* vertices,
61d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com                       size_t vertexSize,
62d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com                       int vertexCount,
63d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com                       SkRect* bounds) {
64d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    GrAssert(vertexSize >= sizeof(GrPoint));
65d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    GrAssert(vertexCount > 0);
66d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    const GrPoint* point = static_cast<const GrPoint*>(vertices);
67d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    bounds->fLeft = bounds->fRight = point->fX;
68d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    bounds->fTop = bounds->fBottom = point->fY;
69d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    for (int i = 1; i < vertexCount; ++i) {
70d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        point = reinterpret_cast<GrPoint*>(reinterpret_cast<intptr_t>(point) + vertexSize);
71d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        bounds->growToInclude(point->fX, point->fY);
72d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    }
73d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com}
74934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com}
75934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com
76d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.comvoid GrInOrderDrawBuffer::drawRect(const GrRect& rect,
77b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com                                   const SkMatrix* matrix,
78c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com                                   const GrRect* localRect,
79c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com                                   const SkMatrix* localMatrix) {
80d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
819b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    GrAttribBindings bindings = GrDrawState::kDefault_AttribBindings;
82d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    GrDrawState::AutoColorRestore acr;
839b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
849b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    GrDrawState* drawState = this->drawState();
859b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
869b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    GrColor color = drawState->getColor();
879b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    GrVertexAttribArray<3> attribs;
889b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    size_t currentOffset = 0;
89c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com    int colorOffset = -1, localOffset = -1;
909b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
919b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    // set position attrib
929b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    drawState->setAttribIndex(GrDrawState::kPosition_AttribIndex, attribs.count());
933b0d631cdfe2dcf59e7b7ea60d92566eade7bfc0jvanverth@google.com    GrVertexAttrib currAttrib = {kVec2f_GrVertexAttribType, currentOffset};
943b0d631cdfe2dcf59e7b7ea60d92566eade7bfc0jvanverth@google.com    attribs.push_back(currAttrib);
959b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    currentOffset += sizeof(GrPoint);
96d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com
97d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    // Using per-vertex colors allows batching across colors. (A lot of rects in a row differing
98d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    // only in color is a common occurrence in tables). However, having per-vertex colors disables
99d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    // blending optimizations because we don't know if the color will be solid or not. These
100d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    // optimizations help determine whether coverage and color can be blended correctly when
101d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    // dual-source blending isn't available. This comes into play when there is coverage. If colors
102d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    // were a stage it could take a hint that every vertex's color will be opaque.
103bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    if (this->caps()->dualSourceBlendingSupport() ||
1049b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        drawState->hasSolidCoverage(drawState->getAttribBindings())) {
1059b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        bindings |= GrDrawState::kColor_AttribBindingsBit;
1069b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        drawState->setAttribIndex(GrDrawState::kColor_AttribIndex, attribs.count());
1073b0d631cdfe2dcf59e7b7ea60d92566eade7bfc0jvanverth@google.com        currAttrib.set(kVec4ub_GrVertexAttribType, currentOffset);
1083b0d631cdfe2dcf59e7b7ea60d92566eade7bfc0jvanverth@google.com        attribs.push_back(currAttrib);
1099b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        colorOffset = currentOffset;
1109b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        currentOffset += sizeof(GrColor);
111d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        // We set the draw state's color to white here. This is done so that any batching performed
112d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        // in our subclass's onDraw() won't get a false from GrDrawState::op== due to a color
113d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        // mismatch. TODO: Once vertex layout is owned by GrDrawState it should skip comparing the
114d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        // constant color in its op== when the kColor layout bit is set and then we can remove this.
1159b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        acr.set(drawState, 0xFFFFFFFF);
116d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    }
117d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com
118c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com    if (NULL != localRect) {
119c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        bindings |= GrDrawState::kLocalCoords_AttribBindingsBit;
120c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        drawState->setAttribIndex(GrDrawState::kLocalCoords_AttribIndex, attribs.count());
1213b0d631cdfe2dcf59e7b7ea60d92566eade7bfc0jvanverth@google.com        currAttrib.set(kVec2f_GrVertexAttribType, currentOffset);
1223b0d631cdfe2dcf59e7b7ea60d92566eade7bfc0jvanverth@google.com        attribs.push_back(currAttrib);
123c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        localOffset = currentOffset;
1249b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        currentOffset += sizeof(GrPoint);
125d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    }
126f04c40ef1e60e21f3e1b2a03b910211bf895b339robertphillips@google.com
1279b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    drawState->setVertexAttribs(attribs.begin(), attribs.count());
1289b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    drawState->setAttribBindings(bindings);
129b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com    AutoReleaseGeometry geo(this, 4, 0);
130d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    if (!geo.succeeded()) {
131d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        GrPrintf("Failed to get space for vertices!\n");
132d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        return;
133d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    }
1348b129aa3379ece6c43d9ce2ad0cdeafb089b7eb5robertphillips@google.com
135d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    // Go to device coords to allow batching across matrix changes
136d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    SkMatrix combinedMatrix;
137d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    if (NULL != matrix) {
138d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        combinedMatrix = *matrix;
139d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    } else {
140d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        combinedMatrix.reset();
141d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    }
1429b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    combinedMatrix.postConcat(drawState->getViewMatrix());
1433976825a21532e254311b90b4a9046e25717e335jvanverth@google.com    // When the caller has provided an explicit source rect for a stage then we don't want to
144d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    // modify that stage's matrix. Otherwise if the effect is generating its source rect from
145d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    // the vertex positions then we have to account for the view matrix change.
146c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com    GrDrawState::AutoDeviceCoordDraw adcd(drawState);
147d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    if (!adcd.succeeded()) {
148d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        return;
149d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    }
150d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com
1519b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    size_t vsize = drawState->getVertexSize();
1529b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    GrAssert(vsize == currentOffset);
153d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com
154d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    geo.positions()->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, vsize);
155d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    combinedMatrix.mapPointsWithStride(geo.positions(), vsize, 4);
156d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com
157d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    SkRect devBounds;
158d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    // since we already computed the dev verts, set the bounds hint. This will help us avoid
159d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    // unnecessary clipping in our onDraw().
160d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    get_vertex_bounds(geo.vertices(), vsize, 4, &devBounds);
161d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com
162c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com    if (localOffset >= 0) {
163c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        GrPoint* coords = GrTCast<GrPoint*>(GrTCast<intptr_t>(geo.vertices()) + localOffset);
164c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        coords->setRectFan(localRect->fLeft, localRect->fTop,
165c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com                           localRect->fRight, localRect->fBottom,
1669b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com                            vsize);
167c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        if (NULL != localMatrix) {
168c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com            localMatrix->mapPointsWithStride(coords, vsize, 4);
169e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com        }
170d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    }
17186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
172d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    if (colorOffset >= 0) {
173d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        GrColor* vertColor = GrTCast<GrColor*>(GrTCast<intptr_t>(geo.vertices()) + colorOffset);
174d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        for (int i = 0; i < 4; ++i) {
175d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com            *vertColor = color;
176d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com            vertColor = (GrColor*) ((intptr_t) vertColor + vsize);
177d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        }
178d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    }
179d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
1806e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com    this->setIndexSourceToBuffer(this->getContext()->getQuadIndexBuffer());
181d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    this->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 4, 6, &devBounds);
1829b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
1839b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    // to ensure that stashing the drawState ptr is valid
1849b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    GrAssert(this->drawState() == drawState);
185d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com}
186fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
187d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.combool GrInOrderDrawBuffer::quickInsideClip(const SkRect& devBounds) {
188d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    if (!this->getDrawState().isClipState()) {
189d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        return true;
190d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    }
191d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    if (kUnknown_ClipProxyState == fClipProxyState) {
192d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        SkIRect rect;
193d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        bool iior;
194d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        this->getClip()->getConservativeBounds(this->getDrawState().getRenderTarget(), &rect, &iior);
195d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        if (iior) {
196d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com            // The clip is a rect. We will remember that in fProxyClip. It is common for an edge (or
197d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com            // all edges) of the clip to be at the edge of the RT. However, we get that clipping for
198d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com            // free via the viewport. We don't want to think that clipping must be enabled in this
199d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com            // case. So we extend the clip outward from the edge to avoid these false negatives.
200d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com            fClipProxyState = kValid_ClipProxyState;
201d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com            fClipProxy = SkRect::MakeFromIRect(rect);
202d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com
203d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com            if (fClipProxy.fLeft <= 0) {
204d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com                fClipProxy.fLeft = SK_ScalarMin;
20586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            }
206d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com            if (fClipProxy.fTop <= 0) {
207d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com                fClipProxy.fTop = SK_ScalarMin;
20886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            }
209d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com            if (fClipProxy.fRight >= this->getDrawState().getRenderTarget()->width()) {
210d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com                fClipProxy.fRight = SK_ScalarMax;
211d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com            }
212d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com            if (fClipProxy.fBottom >= this->getDrawState().getRenderTarget()->height()) {
213d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com                fClipProxy.fBottom = SK_ScalarMax;
214d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com            }
215d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        } else {
216d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com            fClipProxyState = kInvalid_ClipProxyState;
21786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        }
21886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    }
219d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    if (kValid_ClipProxyState == fClipProxyState) {
220d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        return fClipProxy.contains(devBounds);
221d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    }
222d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    SkPoint originOffset = {SkIntToScalar(this->getClip()->fOrigin.fX),
223d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com                            SkIntToScalar(this->getClip()->fOrigin.fY)};
224d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    SkRect clipSpaceBounds = devBounds;
225d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    clipSpaceBounds.offset(originOffset);
226d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    return this->getClip()->fClipStack->quickContains(clipSpaceBounds);
22786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com}
22886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
229d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.comint GrInOrderDrawBuffer::concatInstancedDraw(const DrawInfo& info) {
230d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    GrAssert(info.isInstanced());
231934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com
232934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com    const GeometrySrcState& geomSrc = this->getGeomSrc();
233b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com    const GrDrawState& drawState = this->getDrawState();
234934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com
235d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    // we only attempt to concat the case when reserved verts are used with a client-specified index
236d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    // buffer. To make this work with client-specified VBs we'd need to know if the VB was updated
237d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    // between draws.
238d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    if (kReserved_GeometrySrcType != geomSrc.fVertexSrc ||
239d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        kBuffer_GeometrySrcType != geomSrc.fIndexSrc) {
240d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        return 0;
241d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    }
242d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    // Check if there is a draw info that is compatible that uses the same VB from the pool and
243d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    // the same IB
244d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    if (kDraw_Cmd != fCmds.back()) {
245d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        return 0;
246d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    }
247934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com
248d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    DrawRecord* draw = &fDraws.back();
249d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    GeometryPoolState& poolState = fGeoPoolStateStack.back();
250d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    const GrVertexBuffer* vertexBuffer = poolState.fPoolVertexBuffer;
251d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com
252d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    if (!draw->isInstanced() ||
253d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        draw->verticesPerInstance() != info.verticesPerInstance() ||
254d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        draw->indicesPerInstance() != info.indicesPerInstance() ||
255d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        draw->fVertexBuffer != vertexBuffer ||
256b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com        draw->fIndexBuffer != geomSrc.fIndexBuffer) {
257d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        return 0;
258d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    }
259d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    // info does not yet account for the offset from the start of the pool's VB while the previous
260d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    // draw record does.
261d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    int adjustedStartVertex = poolState.fPoolStartVertex + info.startVertex();
262d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    if (draw->startVertex() + draw->vertexCount() != adjustedStartVertex) {
263d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        return 0;
264d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    }
265a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com
266d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    GrAssert(poolState.fPoolStartVertex == draw->startVertex() + draw->vertexCount());
267934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com
268d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    // how many instances can be concat'ed onto draw given the size of the index buffer
269d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    int instancesToConcat = this->indexCountInCurrentSource() / info.indicesPerInstance();
270d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    instancesToConcat -= draw->instanceCount();
271d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    instancesToConcat = GrMin(instancesToConcat, info.instanceCount());
272934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com
273d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    // update the amount of reserved vertex data actually referenced in draws
274ae683921ffda9108147a29da7319c7eee4dc9245skia.committer@gmail.com    size_t vertexBytes = instancesToConcat * info.verticesPerInstance() *
275b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com                         drawState.getVertexSize();
276d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    poolState.fUsedPoolVertexBytes = GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
277934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com
278d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    draw->adjustInstanceCount(instancesToConcat);
279d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    return instancesToConcat;
280d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com}
281934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com
282d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.comclass AutoClipReenable {
283d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.compublic:
284d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    AutoClipReenable() : fDrawState(NULL) {}
285d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    ~AutoClipReenable() {
286d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        if (NULL != fDrawState) {
287d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com            fDrawState->enableState(GrDrawState::kClip_StateBit);
288d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        }
289934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com    }
290d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    void set(GrDrawState* drawState) {
291d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        if (drawState->isClipState()) {
292d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com            fDrawState = drawState;
293d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com            drawState->disableState(GrDrawState::kClip_StateBit);
294d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        }
295d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    }
296d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.comprivate:
297d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    GrDrawState*    fDrawState;
298d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com};
299934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com
30074749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.comvoid GrInOrderDrawBuffer::onDraw(const DrawInfo& info) {
301ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
30225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometryPoolState& poolState = fGeoPoolStateStack.back();
303b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com    const GrDrawState& drawState = this->getDrawState();
304d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    AutoClipReenable acr;
305d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com
306b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com    if (drawState.isClipState() &&
307d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        NULL != info.getDevBounds() &&
308d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        this->quickInsideClip(*info.getDevBounds())) {
309d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        acr.set(this->drawState());
310d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    }
31125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
312a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    if (this->needsNewClip()) {
313a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com       this->recordClip();
31486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    }
315a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    if (this->needsNewState()) {
316a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com        this->recordState();
31786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    }
318ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
319d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    DrawRecord* draw;
320d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    if (info.isInstanced()) {
321d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        int instancesConcated = this->concatInstancedDraw(info);
322d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        if (info.instanceCount() > instancesConcated) {
323d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com            draw = this->recordDraw(info);
324d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com            draw->adjustInstanceCount(-instancesConcated);
325d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        } else {
326d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com            return;
327d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        }
328d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    } else {
329d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        draw = this->recordDraw(info);
330d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    }
33174749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com
33225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    switch (this->getGeomSrc().fVertexSrc) {
33374749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com        case kBuffer_GeometrySrcType:
33474749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com            draw->fVertexBuffer = this->getGeomSrc().fVertexBuffer;
33574749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com            break;
33674749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com        case kReserved_GeometrySrcType: // fallthrough
33774749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com        case kArray_GeometrySrcType: {
338ae683921ffda9108147a29da7319c7eee4dc9245skia.committer@gmail.com            size_t vertexBytes = (info.vertexCount() + info.startVertex()) *
339b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com                                 drawState.getVertexSize();
34074749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com            poolState.fUsedPoolVertexBytes = GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
34174749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com            draw->fVertexBuffer = poolState.fPoolVertexBuffer;
342d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com            draw->adjustStartVertex(poolState.fPoolStartVertex);
34374749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com            break;
34474749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com        }
34574749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com        default:
34674749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com            GrCrash("unknown geom src type");
347ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
348a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    draw->fVertexBuffer->ref();
349ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
35074749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com    if (info.isIndexed()) {
35174749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com        switch (this->getGeomSrc().fIndexSrc) {
35274749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com            case kBuffer_GeometrySrcType:
35374749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com                draw->fIndexBuffer = this->getGeomSrc().fIndexBuffer;
35474749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com                break;
35574749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com            case kReserved_GeometrySrcType: // fallthrough
35674749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com            case kArray_GeometrySrcType: {
35774749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com                size_t indexBytes = (info.indexCount() + info.startIndex()) * sizeof(uint16_t);
35874749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com                poolState.fUsedPoolIndexBytes = GrMax(poolState.fUsedPoolIndexBytes, indexBytes);
35974749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com                draw->fIndexBuffer = poolState.fPoolIndexBuffer;
360d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com                draw->adjustStartIndex(poolState.fPoolStartIndex);
36174749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com                break;
36274749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com            }
36374749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com            default:
36474749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com                GrCrash("unknown geom src type");
36574749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com        }
36674749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com        draw->fIndexBuffer->ref();
36774749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com    } else {
36874749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com        draw->fIndexBuffer = NULL;
369ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
370ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
371ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
3725f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.comGrInOrderDrawBuffer::StencilPath::StencilPath() : fStroke(SkStrokeRec::kFill_InitStyle) {}
3735f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com
3745f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.comvoid GrInOrderDrawBuffer::onStencilPath(const GrPath* path, const SkStrokeRec& stroke,
37512b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com                                        SkPath::FillType fill) {
376ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    if (this->needsNewClip()) {
377ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com        this->recordClip();
378ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    }
379ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    // Only compare the subset of GrDrawState relevant to path stenciling?
380ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    if (this->needsNewState()) {
381ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com        this->recordState();
382ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    }
383ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    StencilPath* sp = this->recordStencilPath();
384ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    sp->fPath.reset(path);
385ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    path->ref();
386ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    sp->fFill = fill;
38712b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com    sp->fStroke = stroke;
38864aef2bacd1f5c25ffd9347aabd6265c9b60c0f4bsalomon@google.com}
38964aef2bacd1f5c25ffd9347aabd6265c9b60c0f4bsalomon@google.com
390d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.comvoid GrInOrderDrawBuffer::clear(const GrIRect* rect, GrColor color, GrRenderTarget* renderTarget) {
3916aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com    GrIRect r;
3921b3ce47c7b6c14c84d7aaee249b33f9d3b473050bsalomon@google.com    if (NULL == renderTarget) {
3931b3ce47c7b6c14c84d7aaee249b33f9d3b473050bsalomon@google.com        renderTarget = this->drawState()->getRenderTarget();
3941b3ce47c7b6c14c84d7aaee249b33f9d3b473050bsalomon@google.com        GrAssert(NULL != renderTarget);
3951b3ce47c7b6c14c84d7aaee249b33f9d3b473050bsalomon@google.com    }
3966aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com    if (NULL == rect) {
3976aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com        // We could do something smart and remove previous draws and clears to
3986aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com        // the current render target. If we get that smart we have to make sure
3996aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com        // those draws aren't read before this clear (render-to-texture).
4001b3ce47c7b6c14c84d7aaee249b33f9d3b473050bsalomon@google.com        r.setLTRB(0, 0, renderTarget->width(), renderTarget->height());
4016aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com        rect = &r;
4026aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com    }
403a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    Clear* clr = this->recordClear();
404a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    clr->fColor = color;
405a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    clr->fRect = *rect;
406a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    clr->fRenderTarget = renderTarget;
4071b3ce47c7b6c14c84d7aaee249b33f9d3b473050bsalomon@google.com    renderTarget->ref();
4080b335c1ac100aeacf79a4c98a052286fd46661e7bsalomon@google.com}
4090b335c1ac100aeacf79a4c98a052286fd46661e7bsalomon@google.com
410ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrInOrderDrawBuffer::reset() {
41125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(1 == fGeoPoolStateStack.count());
41225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    this->resetVertexSource();
41325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    this->resetIndexSource();
41486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    int numDraws = fDraws.count();
41586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    for (int d = 0; d < numDraws; ++d) {
41686afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        // we always have a VB, but not always an IB
41786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        GrAssert(NULL != fDraws[d].fVertexBuffer);
41886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        fDraws[d].fVertexBuffer->unref();
41986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        GrSafeUnref(fDraws[d].fIndexBuffer);
42086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    }
421a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    fCmds.reset();
422ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fDraws.reset();
423ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    fStencilPaths.reset();
424ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fStates.reset();
4250b335c1ac100aeacf79a4c98a052286fd46661e7bsalomon@google.com    fClears.reset();
4261c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    fVertexPool.reset();
4271c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    fIndexPool.reset();
428ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fClips.reset();
429beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.com    fClipOrigins.reset();
430a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    fClipSet = true;
431ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
432ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
4336e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.combool GrInOrderDrawBuffer::flush() {
43425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fVertexSrc);
43525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fIndexSrc);
4363f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com
437a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    int numCmds = fCmds.count();
438358e427763f0971af436f07170c641f747b94595bsalomon@google.com    if (0 == numCmds) {
439a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com        return false;
440ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
4416e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com    GrAssert(!fFlushing);
4426e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com
4436e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com    GrAutoTRestore<bool> flushRestore(&fFlushing);
4446e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com    fFlushing = true;
445ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
4461c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    fVertexPool.unlock();
4471c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    fIndexPool.unlock();
448ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
4496e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com    GrDrawTarget::AutoClipRestore acr(fDstGpu);
4506e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com    AutoGeometryAndStatePush agasp(fDstGpu, kPreserve_ASRInit);
451ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com
452ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    GrDrawState playbackState;
4536e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com    GrDrawState* prevDrawState = fDstGpu->drawState();
454a5d056ae0b04021dfb44c2c7a3d6a34e060261b8bsalomon@google.com    prevDrawState->ref();
4556e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com    fDstGpu->setDrawState(&playbackState);
456ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
457beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.com    GrClipData clipData;
458beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.com
459ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    int currState       = 0;
460ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    int currClip        = 0;
461ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    int currClear       = 0;
462ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    int currDraw        = 0;
463ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    int currStencilPath = 0;
464a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com
465a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    for (int c = 0; c < numCmds; ++c) {
466a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com        switch (fCmds[c]) {
467a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com            case kDraw_Cmd: {
46874749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com                const DrawRecord& draw = fDraws[currDraw];
4696e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com                fDstGpu->setVertexSourceToBuffer(draw.fVertexBuffer);
470d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com                if (draw.isIndexed()) {
4716e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com                    fDstGpu->setIndexSourceToBuffer(draw.fIndexBuffer);
472a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                }
4736e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com                fDstGpu->executeDraw(draw);
474ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
475a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                ++currDraw;
476a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                break;
477a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com            }
478ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com            case kStencilPath_Cmd: {
479ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com                const StencilPath& sp = fStencilPaths[currStencilPath];
4806e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com                fDstGpu->stencilPath(sp.fPath.get(), sp.fStroke, sp.fFill);
481ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com                ++currStencilPath;
482ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com                break;
483ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com            }
484a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com            case kSetState_Cmd:
485ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com                fStates[currState].restoreTo(&playbackState);
486a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                ++currState;
487a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                break;
488a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com            case kSetClip_Cmd:
489beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.com                clipData.fClipStack = &fClips[currClip];
490beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.com                clipData.fOrigin = fClipOrigins[currClip];
4916e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com                fDstGpu->setClip(&clipData);
492a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                ++currClip;
493a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                break;
494a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com            case kClear_Cmd:
4956e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com                fDstGpu->clear(&fClears[currClear].fRect,
4966e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com                               fClears[currClear].fColor,
4976e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com                               fClears[currClear].fRenderTarget);
498a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                ++currClear;
499a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                break;
500ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        }
501ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
502a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    // we should have consumed all the states, clips, etc.
503a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    GrAssert(fStates.count() == currState);
504a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    GrAssert(fClips.count() == currClip);
505beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.com    GrAssert(fClipOrigins.count() == currClip);
506a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    GrAssert(fClears.count() == currClear);
507a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    GrAssert(fDraws.count()  == currDraw);
508a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com
5096e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com    fDstGpu->setDrawState(prevDrawState);
510a5d056ae0b04021dfb44c2c7a3d6a34e060261b8bsalomon@google.com    prevDrawState->unref();
51155e4a2005eae1e4f677ec145c577c615a63cf05dbsalomon@google.com    this->reset();
512a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    return true;
513ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
514ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
51597805382d89b717de3355312a79a957ea4a864c9bsalomon@google.comvoid GrInOrderDrawBuffer::willReserveVertexAndIndexSpace(
51697805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com                                int vertexCount,
51797805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com                                int indexCount) {
5186e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com    // We use geometryHints() to know whether to flush the draw buffer. We
5196e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com    // can't flush if we are inside an unbalanced pushGeometrySource.
5206e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com    // Moreover, flushing blows away vertex and index data that was
5216e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com    // previously reserved. So if the vertex or index data is pulled from
5226e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com    // reserved space and won't be released by this request then we can't
5236e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com    // flush.
5246e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com    bool insideGeoPush = fGeoPoolStateStack.count() > 1;
5256e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com
5266e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com    bool unreleasedVertexSpace =
5276e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com        !vertexCount &&
5286e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com        kReserved_GeometrySrcType == this->getGeomSrc().fVertexSrc;
5296e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com
5306e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com    bool unreleasedIndexSpace =
5316e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com        !indexCount &&
5326e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com        kReserved_GeometrySrcType == this->getGeomSrc().fIndexSrc;
5336e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com
5346e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com    // we don't want to finalize any reserved geom on the target since
5356e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com    // we don't know that the client has finished writing to it.
5366e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com    bool targetHasReservedGeom = fDstGpu->hasReservedVerticesOrIndices();
5376e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com
5386e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com    int vcount = vertexCount;
5396e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com    int icount = indexCount;
5406e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com
5416e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com    if (!insideGeoPush &&
5426e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com        !unreleasedVertexSpace &&
5436e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com        !unreleasedIndexSpace &&
5446e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com        !targetHasReservedGeom &&
5456e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com        this->geometryHints(&vcount, &icount)) {
5466e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com
5476e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com        this->flush();
54897805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com    }
54997805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com}
55097805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com
551b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.combool GrInOrderDrawBuffer::geometryHints(int* vertexCount,
5521c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com                                        int* indexCount) const {
5531c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    // we will recommend a flush if the data could fit in a single
5541c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    // preallocated buffer but none are left and it can't fit
5551c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    // in the current buffer (which may not be prealloced).
556ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    bool flush = false;
557ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    if (NULL != indexCount) {
5581c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com        int32_t currIndices = fIndexPool.currentBufferIndices();
5591c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com        if (*indexCount > currIndices &&
5601c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com            (!fIndexPool.preallocatedBuffersRemaining() &&
5611c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com             *indexCount <= fIndexPool.preallocatedBufferIndices())) {
5621c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com
5631c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com            flush = true;
5641c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com        }
5651c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com        *indexCount = currIndices;
566ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
567ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    if (NULL != vertexCount) {
568b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com        size_t vertexSize = this->getDrawState().getVertexSize();
569a63389843dd18003382d61c2e4610af09ed07d38jvanverth@google.com        int32_t currVertices = fVertexPool.currentBufferVertices(vertexSize);
5701c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com        if (*vertexCount > currVertices &&
5711c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com            (!fVertexPool.preallocatedBuffersRemaining() &&
572a63389843dd18003382d61c2e4610af09ed07d38jvanverth@google.com             *vertexCount <= fVertexPool.preallocatedBufferVertices(vertexSize))) {
5731c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com
5741c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com            flush = true;
575ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        }
5761c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com        *vertexCount = currVertices;
577ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
578ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    return flush;
579ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
580ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
581a63389843dd18003382d61c2e4610af09ed07d38jvanverth@google.combool GrInOrderDrawBuffer::onReserveVertexSpace(size_t vertexSize,
58225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                               int vertexCount,
58325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                               void** vertices) {
58425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometryPoolState& poolState = fGeoPoolStateStack.back();
58525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(vertexCount > 0);
58625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(NULL != vertices);
58725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(0 == poolState.fUsedPoolVertexBytes);
588fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
589a63389843dd18003382d61c2e4610af09ed07d38jvanverth@google.com    *vertices = fVertexPool.makeSpace(vertexSize,
59025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                      vertexCount,
59125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                      &poolState.fPoolVertexBuffer,
59225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                      &poolState.fPoolStartVertex);
59325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    return NULL != *vertices;
59425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
595fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
59625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.combool GrInOrderDrawBuffer::onReserveIndexSpace(int indexCount, void** indices) {
59725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometryPoolState& poolState = fGeoPoolStateStack.back();
59825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(indexCount > 0);
59925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(NULL != indices);
60025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(0 == poolState.fUsedPoolIndexBytes);
60125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
60225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    *indices = fIndexPool.makeSpace(indexCount,
60325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                    &poolState.fPoolIndexBuffer,
60425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                    &poolState.fPoolStartIndex);
60525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    return NULL != *indices;
606ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
607ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
60825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrInOrderDrawBuffer::releaseReservedVertexSpace() {
60925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometryPoolState& poolState = fGeoPoolStateStack.back();
610fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com    const GeometrySrcState& geoSrc = this->getGeomSrc();
611d57d71a5b857c273d9cf834856e10e663c1ccb91bsalomon@google.com
612d57d71a5b857c273d9cf834856e10e663c1ccb91bsalomon@google.com    // If we get a release vertex space call then our current source should either be reserved
613d57d71a5b857c273d9cf834856e10e663c1ccb91bsalomon@google.com    // or array (which we copied into reserved space).
614d57d71a5b857c273d9cf834856e10e663c1ccb91bsalomon@google.com    GrAssert(kReserved_GeometrySrcType == geoSrc.fVertexSrc ||
615d57d71a5b857c273d9cf834856e10e663c1ccb91bsalomon@google.com             kArray_GeometrySrcType == geoSrc.fVertexSrc);
6163f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com
6173f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com    // When the caller reserved vertex buffer space we gave it back a pointer
6183f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com    // provided by the vertex buffer pool. At each draw we tracked the largest
6193f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com    // offset into the pool's pointer that was referenced. Now we return to the
6203f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com    // pool any portion at the tail of the allocation that no draw referenced.
621b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com    size_t reservedVertexBytes = geoSrc.fVertexSize * geoSrc.fVertexCount;
622fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com    fVertexPool.putBack(reservedVertexBytes -
62325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                        poolState.fUsedPoolVertexBytes);
62425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fUsedPoolVertexBytes = 0;
6253f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com    poolState.fPoolVertexBuffer = NULL;
6263f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com    poolState.fPoolStartVertex = 0;
62725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
628ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
62925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrInOrderDrawBuffer::releaseReservedIndexSpace() {
63025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometryPoolState& poolState = fGeoPoolStateStack.back();
631fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com    const GeometrySrcState& geoSrc = this->getGeomSrc();
6321c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com
633d57d71a5b857c273d9cf834856e10e663c1ccb91bsalomon@google.com    // If we get a release index space call then our current source should either be reserved
634d57d71a5b857c273d9cf834856e10e663c1ccb91bsalomon@google.com    // or array (which we copied into reserved space).
635d57d71a5b857c273d9cf834856e10e663c1ccb91bsalomon@google.com    GrAssert(kReserved_GeometrySrcType == geoSrc.fIndexSrc ||
636d57d71a5b857c273d9cf834856e10e663c1ccb91bsalomon@google.com             kArray_GeometrySrcType == geoSrc.fIndexSrc);
6373f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com
6383f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com    // Similar to releaseReservedVertexSpace we return any unused portion at
6393f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com    // the tail
64025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    size_t reservedIndexBytes = sizeof(uint16_t) * geoSrc.fIndexCount;
64125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    fIndexPool.putBack(reservedIndexBytes - poolState.fUsedPoolIndexBytes);
64225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fUsedPoolIndexBytes = 0;
6433f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com    poolState.fPoolIndexBuffer = NULL;
6443f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com    poolState.fPoolStartIndex = 0;
6451c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com}
646fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
647bcdbbe61e1a3f89545b2c1461164f0f8bf5f0797bsalomon@google.comvoid GrInOrderDrawBuffer::onSetVertexSourceToArray(const void* vertexArray,
648bcdbbe61e1a3f89545b2c1461164f0f8bf5f0797bsalomon@google.com                                                   int vertexCount) {
64925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
65025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometryPoolState& poolState = fGeoPoolStateStack.back();
65125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(0 == poolState.fUsedPoolVertexBytes);
6521c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com#if GR_DEBUG
6531c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    bool success =
6541c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com#endif
655b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com    fVertexPool.appendVertices(this->getVertexSize(),
6561c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com                               vertexCount,
6571c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com                               vertexArray,
65825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                               &poolState.fPoolVertexBuffer,
65925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                               &poolState.fPoolStartVertex);
6601c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    GR_DEBUGASSERT(success);
6611c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com}
6621c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com
663bcdbbe61e1a3f89545b2c1461164f0f8bf5f0797bsalomon@google.comvoid GrInOrderDrawBuffer::onSetIndexSourceToArray(const void* indexArray,
664bcdbbe61e1a3f89545b2c1461164f0f8bf5f0797bsalomon@google.com                                                  int indexCount) {
66525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometryPoolState& poolState = fGeoPoolStateStack.back();
66625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(0 == poolState.fUsedPoolIndexBytes);
6671c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com#if GR_DEBUG
6681c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    bool success =
6691c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com#endif
6701c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    fIndexPool.appendIndices(indexCount,
6711c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com                             indexArray,
67225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                             &poolState.fPoolIndexBuffer,
67325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                             &poolState.fPoolStartIndex);
6741c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    GR_DEBUGASSERT(success);
675ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
676ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
6773f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.comvoid GrInOrderDrawBuffer::releaseVertexArray() {
6783f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com    // When the client provides an array as the vertex source we handled it
6793f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com    // by copying their array into reserved space.
6803f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com    this->GrInOrderDrawBuffer::releaseReservedVertexSpace();
6813f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com}
6823f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com
6833f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.comvoid GrInOrderDrawBuffer::releaseIndexArray() {
6843f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com    // When the client provides an array as the index source we handled it
6853f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com    // by copying their array into reserved space.
6863f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com    this->GrInOrderDrawBuffer::releaseReservedIndexSpace();
6873f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com}
6883f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com
68925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrInOrderDrawBuffer::geometrySourceWillPush() {
69025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
69125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fUsedPoolVertexBytes = 0;
69225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fUsedPoolIndexBytes = 0;
69325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#if GR_DEBUG
69425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0;
69525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fPoolStartVertex = ~0;
69625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0;
69725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fPoolStartIndex = ~0;
69825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#endif
69925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
70025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
70125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrInOrderDrawBuffer::geometrySourceWillPop(
70225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                        const GeometrySrcState& restoredState) {
70325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(fGeoPoolStateStack.count() > 1);
70425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    fGeoPoolStateStack.pop_back();
70525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometryPoolState& poolState = fGeoPoolStateStack.back();
70625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    // we have to assume that any slack we had in our vertex/index data
70725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    // is now unreleasable because data may have been appended later in the
70825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    // pool.
70925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    if (kReserved_GeometrySrcType == restoredState.fVertexSrc ||
71025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        kArray_GeometrySrcType == restoredState.fVertexSrc) {
711b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com        poolState.fUsedPoolVertexBytes = restoredState.fVertexSize * restoredState.fVertexCount;
71225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
71325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    if (kReserved_GeometrySrcType == restoredState.fIndexSrc ||
71425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        kArray_GeometrySrcType == restoredState.fIndexSrc) {
715fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com        poolState.fUsedPoolIndexBytes = sizeof(uint16_t) *
71625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                         restoredState.fIndexCount;
71725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
71825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
71925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
72086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.combool GrInOrderDrawBuffer::needsNewState() const {
721ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    return fStates.empty() || !fStates.back().isEqual(this->getDrawState());
722ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
723ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
72486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.combool GrInOrderDrawBuffer::needsNewClip() const {
725358e427763f0971af436f07170c641f747b94595bsalomon@google.com    GrAssert(fClips.count() == fClipOrigins.count());
726358e427763f0971af436f07170c641f747b94595bsalomon@google.com    if (this->getDrawState().isClipState()) {
727fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com       if (fClipSet &&
728358e427763f0971af436f07170c641f747b94595bsalomon@google.com           (fClips.empty() ||
72902ddc8b85ace91b15feb329a6a1d5d62b2b846c6bsalomon@google.com            fClips.back() != *this->getClip()->fClipStack ||
73002ddc8b85ace91b15feb329a6a1d5d62b2b846c6bsalomon@google.com            fClipOrigins.back() != this->getClip()->fOrigin)) {
73186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com           return true;
73286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com       }
733ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
734ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    return false;
735ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
736d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
737a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.comvoid GrInOrderDrawBuffer::recordClip() {
73802ddc8b85ace91b15feb329a6a1d5d62b2b846c6bsalomon@google.com    fClips.push_back() = *this->getClip()->fClipStack;
73902ddc8b85ace91b15feb329a6a1d5d62b2b846c6bsalomon@google.com    fClipOrigins.push_back() = this->getClip()->fOrigin;
74086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    fClipSet = false;
741a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    fCmds.push_back(kSetClip_Cmd);
742a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com}
743a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com
744a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.comvoid GrInOrderDrawBuffer::recordState() {
745ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    fStates.push_back().saveFrom(this->getDrawState());
746a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    fCmds.push_back(kSetState_Cmd);
747a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com}
748a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com
74974749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.comGrInOrderDrawBuffer::DrawRecord* GrInOrderDrawBuffer::recordDraw(const DrawInfo& info) {
750d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    fCmds.push_back(kDraw_Cmd);
751d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    return &fDraws.push_back(info);
75274749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com}
75374749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com
754ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.comGrInOrderDrawBuffer::StencilPath* GrInOrderDrawBuffer::recordStencilPath() {
755ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    fCmds.push_back(kStencilPath_Cmd);
756ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    return &fStencilPaths.push_back();
757ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com}
758ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com
759a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.comGrInOrderDrawBuffer::Clear* GrInOrderDrawBuffer::recordClear() {
760a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    fCmds.push_back(kClear_Cmd);
761a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    return &fClears.push_back();
76286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com}
763d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
764beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.comvoid GrInOrderDrawBuffer::clipWillBeSet(const GrClipData* newClipData) {
765beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.com    INHERITED::clipWillBeSet(newClipData);
76686afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    fClipSet = true;
767d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    fClipProxyState = kUnknown_ClipProxyState;
768ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
769