GrInOrderDrawBuffer.cpp revision 74749cd45c29b4f5300e2518f2c2c765ce8ae208
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"
12ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com#include "GrGpu.h"
1386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com#include "GrIndexBuffer.h"
14ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com#include "GrPath.h"
15ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com#include "GrRenderTarget.h"
16ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com#include "GrTexture.h"
1786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com#include "GrVertexBuffer.h"
18ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
19471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.comGrInOrderDrawBuffer::GrInOrderDrawBuffer(const GrGpu* gpu,
20471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com                                         GrVertexBufferAllocPool* vertexPool,
2125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                         GrIndexBufferAllocPool* indexPool)
2297805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com    : fAutoFlushTarget(NULL)
2397805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com    , fClipSet(true)
246970557055acaed619d7bb89451868e1570249b2robertphillips@google.com    , fVertexPool(*vertexPool)
256970557055acaed619d7bb89451868e1570249b2robertphillips@google.com    , fIndexPool(*indexPool)
2625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    , fLastRectVertexLayout(0)
2725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    , fQuadIndexBuffer(NULL)
2825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    , fMaxQuads(0)
29c82a8b7aa4ec19fba508c394920a9e88d3e5bd12robertphillips@google.com    , fFlushing(false) {
3018c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com
3118c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com    fCaps = gpu->getCaps();
3218c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com
331c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    GrAssert(NULL != vertexPool);
341c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    GrAssert(NULL != indexPool);
3525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
3625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
3725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fUsedPoolVertexBytes = 0;
3825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fUsedPoolIndexBytes = 0;
3925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#if GR_DEBUG
4025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0;
4125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fPoolStartVertex = ~0;
4225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0;
4325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fPoolStartIndex = ~0;
4425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#endif
45a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    this->reset();
46ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
47ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
48ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrInOrderDrawBuffer::~GrInOrderDrawBuffer() {
4986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    this->reset();
504a018bb20bf969a38ec11d9506843f06366dfa7cbsalomon@google.com    // This must be called by before the GrDrawTarget destructor
514a018bb20bf969a38ec11d9506843f06366dfa7cbsalomon@google.com    this->releaseGeometry();
5286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    GrSafeUnref(fQuadIndexBuffer);
5397805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com    GrSafeUnref(fAutoFlushTarget);
54ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
55ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
5686afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.comvoid GrInOrderDrawBuffer::setQuadIndexBuffer(const GrIndexBuffer* indexBuffer) {
5786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    bool newIdxBuffer = fQuadIndexBuffer != indexBuffer;
5886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    if (newIdxBuffer) {
5986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        GrSafeUnref(fQuadIndexBuffer);
6086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        fQuadIndexBuffer = indexBuffer;
6186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        GrSafeRef(fQuadIndexBuffer);
6286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        fCurrQuad = 0;
6386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        fMaxQuads = (NULL == indexBuffer) ? 0 : indexBuffer->maxQuads();
6486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    } else {
65d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com        GrAssert((NULL == indexBuffer && 0 == fMaxQuads) ||
6686afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                 (indexBuffer->maxQuads() == fMaxQuads));
6786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    }
6886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com}
6986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
70934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com////////////////////////////////////////////////////////////////////////////////
71934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com
72934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.comvoid GrInOrderDrawBuffer::resetDrawTracking() {
73934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com    fCurrQuad = 0;
74934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com    fInstancedDrawTracker.reset();
75934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com}
76934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com
77d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.comvoid GrInOrderDrawBuffer::drawRect(const GrRect& rect,
78b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com                                   const SkMatrix* matrix,
7986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                                   const GrRect* srcRects[],
80b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com                                   const SkMatrix* srcMatrices[]) {
81d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
8286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    GrAssert(!(NULL == fQuadIndexBuffer && fCurrQuad));
8386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    GrAssert(!(fDraws.empty() && fCurrQuad));
8486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    GrAssert(!(0 != fMaxQuads && NULL == fQuadIndexBuffer));
8586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
868f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrDrawState* drawState = this->drawState();
878f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
8886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    // if we have a quad IB then either append to the previous run of
8986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    // rects or start a new run
9086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    if (fMaxQuads) {
91d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
9286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        bool appendToPreviousDraw = false;
93e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com        GrVertexLayout layout = GetRectVertexLayout(srcRects);
948b129aa3379ece6c43d9ce2ad0cdeafb089b7eb5robertphillips@google.com
95f04c40ef1e60e21f3e1b2a03b910211bf895b339robertphillips@google.com        // Batching across colors means we move the draw color into the
96f04c40ef1e60e21f3e1b2a03b910211bf895b339robertphillips@google.com        // rect's vertex colors to allow greater batching (a lot of rects
97f04c40ef1e60e21f3e1b2a03b910211bf895b339robertphillips@google.com        // in a row differing only in color is a common occurence in tables).
98f04c40ef1e60e21f3e1b2a03b910211bf895b339robertphillips@google.com        bool batchAcrossColors = true;
99f04c40ef1e60e21f3e1b2a03b910211bf895b339robertphillips@google.com        if (!this->getCaps().dualSourceBlendingSupport()) {
100f04c40ef1e60e21f3e1b2a03b910211bf895b339robertphillips@google.com            for (int s = 0; s < GrDrawState::kNumStages; ++s) {
101f04c40ef1e60e21f3e1b2a03b910211bf895b339robertphillips@google.com                if (this->getDrawState().isStageEnabled(s)) {
102439cb51451ef6f55f65dab90eb7f91acf67ea8feskia.committer@gmail.com                    // We disable batching across colors when there is a texture
103f04c40ef1e60e21f3e1b2a03b910211bf895b339robertphillips@google.com                    // present because (by pushing the the color to the vertices)
104f04c40ef1e60e21f3e1b2a03b910211bf895b339robertphillips@google.com                    // Ganesh loses track of the rect's opacity. This, in turn, can
105f04c40ef1e60e21f3e1b2a03b910211bf895b339robertphillips@google.com                    // cause some of the blending optimizations to be disabled. This
106f04c40ef1e60e21f3e1b2a03b910211bf895b339robertphillips@google.com                    // becomes a huge problem on some of the smaller devices where
107f04c40ef1e60e21f3e1b2a03b910211bf895b339robertphillips@google.com                    // shader derivatives and dual source blending aren't supported.
108f04c40ef1e60e21f3e1b2a03b910211bf895b339robertphillips@google.com                    // In those cases paths are often drawn to a texture and then
109f04c40ef1e60e21f3e1b2a03b910211bf895b339robertphillips@google.com                    // drawn as a texture (using this method). Because dual source
110f04c40ef1e60e21f3e1b2a03b910211bf895b339robertphillips@google.com                    // blending is disabled (and the blend optimizations are short
111f04c40ef1e60e21f3e1b2a03b910211bf895b339robertphillips@google.com                    // circuited) some of the more esoteric blend modes can no longer
112f04c40ef1e60e21f3e1b2a03b910211bf895b339robertphillips@google.com                    // be supported.
113f04c40ef1e60e21f3e1b2a03b910211bf895b339robertphillips@google.com                    // TODO: add tracking of batchAcrossColors's opacity
114f04c40ef1e60e21f3e1b2a03b910211bf895b339robertphillips@google.com                    batchAcrossColors = false;
115f04c40ef1e60e21f3e1b2a03b910211bf895b339robertphillips@google.com                    break;
116f04c40ef1e60e21f3e1b2a03b910211bf895b339robertphillips@google.com                }
117f04c40ef1e60e21f3e1b2a03b910211bf895b339robertphillips@google.com            }
118f04c40ef1e60e21f3e1b2a03b910211bf895b339robertphillips@google.com        }
119f04c40ef1e60e21f3e1b2a03b910211bf895b339robertphillips@google.com
120f04c40ef1e60e21f3e1b2a03b910211bf895b339robertphillips@google.com        if (batchAcrossColors) {
121cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com            layout |= GrDrawState::kColor_VertexLayoutBit;
122f04c40ef1e60e21f3e1b2a03b910211bf895b339robertphillips@google.com        }
1238b129aa3379ece6c43d9ce2ad0cdeafb089b7eb5robertphillips@google.com
12486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        AutoReleaseGeometry geo(this, layout, 4, 0);
1256513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com        if (!geo.succeeded()) {
1266513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com            GrPrintf("Failed to get space for vertices!\n");
1276513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com            return;
1286513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com        }
129b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com        SkMatrix combinedMatrix = drawState->getViewMatrix();
1303f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com        // We go to device space so that matrix changes allow us to concat
1313f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com        // rect draws. When the caller has provided explicit source rects
13208283afc265f1153834256fc1012519813ba6b73bsalomon@google.com        // then we don't want to modify the stages' matrices. Otherwise
13308283afc265f1153834256fc1012519813ba6b73bsalomon@google.com        // we have to account for the view matrix change in the stage
1343f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com        // matrices.
135e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com        uint32_t explicitCoordMask = 0;
136e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com        if (srcRects) {
137e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com            for (int s = 0; s < GrDrawState::kNumStages; ++s) {
138e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com                if (srcRects[s]) {
139e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com                    explicitCoordMask |= (1 << s);
140e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com                }
141e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com            }
142e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com        }
1435b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com        GrDrawState::AutoDeviceCoordDraw adcd(this->drawState(), explicitCoordMask);
144e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com        if (!adcd.succeeded()) {
145e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com            return;
146e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com        }
14786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        if (NULL != matrix) {
14886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            combinedMatrix.preConcat(*matrix);
14986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        }
15086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
151a18ed032186e9a52899d9cb51d67b9bf6cace492skia.committer@gmail.com        SetRectVertices(rect, &combinedMatrix, srcRects, srcMatrices,
1528b129aa3379ece6c43d9ce2ad0cdeafb089b7eb5robertphillips@google.com                        this->getDrawState().getColor(), layout, geo.vertices());
1538b129aa3379ece6c43d9ce2ad0cdeafb089b7eb5robertphillips@google.com
1548b129aa3379ece6c43d9ce2ad0cdeafb089b7eb5robertphillips@google.com        // Now that the paint's color is stored in the vertices set it to
1558b129aa3379ece6c43d9ce2ad0cdeafb089b7eb5robertphillips@google.com        // white so that the following code can batch all the rects regardless
1568b129aa3379ece6c43d9ce2ad0cdeafb089b7eb5robertphillips@google.com        // of paint color
157439cb51451ef6f55f65dab90eb7f91acf67ea8feskia.committer@gmail.com        GrDrawState::AutoColorRestore acr(this->drawState(),
158f04c40ef1e60e21f3e1b2a03b910211bf895b339robertphillips@google.com                                          batchAcrossColors ? SK_ColorWHITE
159f04c40ef1e60e21f3e1b2a03b910211bf895b339robertphillips@google.com                                                            : this->getDrawState().getColor());
16086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
16186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        // we don't want to miss an opportunity to batch rects together
16286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        // simply because the clip has changed if the clip doesn't affect
16386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        // the rect.
16486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        bool disabledClip = false;
165d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
166641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com        if (drawState->isClipState()) {
167fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
168641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com            GrRect devClipRect;
169641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com            bool isIntersectionOfRects = false;
17002ddc8b85ace91b15feb329a6a1d5d62b2b846c6bsalomon@google.com            const GrClipData* clip = this->getClip();
17102ddc8b85ace91b15feb329a6a1d5d62b2b846c6bsalomon@google.com            clip->fClipStack->getConservativeBounds(-clip->fOrigin.fX,
17202ddc8b85ace91b15feb329a6a1d5d62b2b846c6bsalomon@google.com                                                    -clip->fOrigin.fY,
17302ddc8b85ace91b15feb329a6a1d5d62b2b846c6bsalomon@google.com                                                    drawState->getRenderTarget()->width(),
17402ddc8b85ace91b15feb329a6a1d5d62b2b846c6bsalomon@google.com                                                    drawState->getRenderTarget()->height(),
17502ddc8b85ace91b15feb329a6a1d5d62b2b846c6bsalomon@google.com                                                    &devClipRect,
17602ddc8b85ace91b15feb329a6a1d5d62b2b846c6bsalomon@google.com                                                    &isIntersectionOfRects);
177641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com
178641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com            if (isIntersectionOfRects) {
179641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                // If the clip rect touches the edge of the viewport, extended it
180641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                // out (close) to infinity to avoid bogus intersections.
181641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                // We might consider a more exact clip to viewport if this
182641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                // conservative test fails.
183641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                const GrRenderTarget* target = drawState->getRenderTarget();
184641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                if (0 >= devClipRect.fLeft) {
18581712883419f76e25d2ffec38a9438284a45a48dbsalomon@google.com                    devClipRect.fLeft = SK_ScalarMin;
186641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                }
187641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                if (target->width() <= devClipRect.fRight) {
18881712883419f76e25d2ffec38a9438284a45a48dbsalomon@google.com                    devClipRect.fRight = SK_ScalarMax;
189641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                }
190641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                if (0 >= devClipRect.top()) {
19181712883419f76e25d2ffec38a9438284a45a48dbsalomon@google.com                    devClipRect.fTop = SK_ScalarMin;
192641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                }
193641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                if (target->height() <= devClipRect.fBottom) {
19481712883419f76e25d2ffec38a9438284a45a48dbsalomon@google.com                    devClipRect.fBottom = SK_ScalarMax;
195641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                }
196cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                int stride = GrDrawState::VertexSize(layout);
197641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                bool insideClip = true;
198641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                for (int v = 0; v < 4; ++v) {
199cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                    const GrPoint& p = *GrDrawState::GetVertexPoint(geo.vertices(), v, stride);
200641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                    if (!devClipRect.contains(p)) {
201641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                        insideClip = false;
202641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                        break;
203641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                    }
204641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                }
205641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                if (insideClip) {
206641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                    drawState->disableState(GrDrawState::kClip_StateBit);
207641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                    disabledClip = true;
20886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                }
20986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            }
21086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        }
211641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com
212a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com        if (!this->needsNewClip() &&
213a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com            !this->needsNewState() &&
214a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com            fCurrQuad > 0 &&
215a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com            fCurrQuad < fMaxQuads &&
216a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com            layout == fLastRectVertexLayout) {
21786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
218cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com            int vsize = GrDrawState::VertexSize(layout);
219d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
22074749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com            DrawRecord& lastDraw = fDraws.back();
22186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
22286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            GrAssert(lastDraw.fIndexBuffer == fQuadIndexBuffer);
22347059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com            GrAssert(kTriangles_GrPrimitiveType == lastDraw.fPrimitiveType);
22486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            GrAssert(0 == lastDraw.fVertexCount % 4);
22586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            GrAssert(0 == lastDraw.fIndexCount % 6);
22686afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            GrAssert(0 == lastDraw.fStartIndex);
22786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
22825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            GeometryPoolState& poolState = fGeoPoolStateStack.back();
2296aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com
23074749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com            appendToPreviousDraw = kDraw_Cmd == fCmds.back() &&
23174749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com                                   lastDraw.fVertexBuffer == poolState.fPoolVertexBuffer &&
23274749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com                                   (fCurrQuad * 4 + lastDraw.fStartVertex) ==
23374749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com                                   poolState.fPoolStartVertex;
23425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
23586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            if (appendToPreviousDraw) {
23686afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                lastDraw.fVertexCount += 4;
23786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                lastDraw.fIndexCount += 6;
23886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                fCurrQuad += 1;
23925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                // we reserved above, so we should be the first
240a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                // use of this vertex reservation.
24125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                GrAssert(0 == poolState.fUsedPoolVertexBytes);
24225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                poolState.fUsedPoolVertexBytes = 4 * vsize;
24386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            }
24486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        }
24586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        if (!appendToPreviousDraw) {
24686afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            this->setIndexSourceToBuffer(fQuadIndexBuffer);
24747059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com            this->drawIndexed(kTriangles_GrPrimitiveType, 0, 0, 4, 6);
24886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            fCurrQuad = 1;
24986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            fLastRectVertexLayout = layout;
25086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        }
25186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        if (disabledClip) {
2528f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            drawState->enableState(GrDrawState::kClip_StateBit);
25386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        }
254934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        fInstancedDrawTracker.reset();
25586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    } else {
256e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com        INHERITED::drawRect(rect, matrix, srcRects, srcMatrices);
25786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    }
25886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com}
25986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
260934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.comvoid GrInOrderDrawBuffer::drawIndexedInstances(GrPrimitiveType type,
261934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com                                               int instanceCount,
262934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com                                               int verticesPerInstance,
263934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com                                               int indicesPerInstance) {
264934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com    if (!verticesPerInstance || !indicesPerInstance) {
265934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        return;
266934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com    }
267934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com
268934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com    const GeometrySrcState& geomSrc = this->getGeomSrc();
269934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com
270934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com    // we only attempt to concat the case when reserved verts are used with
271934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com    // an index buffer.
272934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com    if (kReserved_GeometrySrcType == geomSrc.fVertexSrc &&
273934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        kBuffer_GeometrySrcType == geomSrc.fIndexSrc) {
274934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com
275a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com        if (this->needsNewClip()) {
276a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com            this->recordClip();
277a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com        }
278a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com        if (this->needsNewState()) {
279a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com            this->recordState();
280a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com        }
281a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com
28274749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com        DrawRecord* draw = NULL;
283934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        // if the last draw used the same indices/vertices per shape then we
284934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        // may be able to append to it.
285a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com        if (kDraw_Cmd == fCmds.back() &&
286a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com            verticesPerInstance == fInstancedDrawTracker.fVerticesPerInstance &&
287934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            indicesPerInstance == fInstancedDrawTracker.fIndicesPerInstance) {
288934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            GrAssert(fDraws.count());
289934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            draw = &fDraws.back();
290934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        }
291934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com
292934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        GeometryPoolState& poolState = fGeoPoolStateStack.back();
293934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        const GrVertexBuffer* vertexBuffer = poolState.fPoolVertexBuffer;
294934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com
295934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        // Check whether the draw is compatible with this draw in order to
296934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        // append
297934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        if (NULL == draw ||
298934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            draw->fIndexBuffer != geomSrc.fIndexBuffer ||
299934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            draw->fPrimitiveType != type ||
300934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            draw->fVertexBuffer != vertexBuffer) {
301934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com
302a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com            draw = this->recordDraw();
303934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            draw->fPrimitiveType = type;
304934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            draw->fStartVertex = poolState.fPoolStartVertex;
3056d0673042f6225f16fc5ea91cb1fdf4c8e96d880robertphillips@google.com            draw->fStartIndex = 0;
306934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            draw->fVertexCount = 0;
3076d0673042f6225f16fc5ea91cb1fdf4c8e96d880robertphillips@google.com            draw->fIndexCount = 0;
308934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            draw->fVertexLayout = geomSrc.fVertexLayout;
3096d0673042f6225f16fc5ea91cb1fdf4c8e96d880robertphillips@google.com            draw->fVertexBuffer = vertexBuffer;
3106d0673042f6225f16fc5ea91cb1fdf4c8e96d880robertphillips@google.com            vertexBuffer->ref();
3116d0673042f6225f16fc5ea91cb1fdf4c8e96d880robertphillips@google.com            draw->fIndexBuffer = geomSrc.fIndexBuffer;
3126d0673042f6225f16fc5ea91cb1fdf4c8e96d880robertphillips@google.com            geomSrc.fIndexBuffer->ref();
313934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        } else {
314934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            GrAssert(!(draw->fIndexCount % indicesPerInstance));
315934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            GrAssert(!(draw->fVertexCount % verticesPerInstance));
316934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            GrAssert(poolState.fPoolStartVertex == draw->fStartVertex +
317934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com                                                   draw->fVertexCount);
318934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        }
319934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com
320934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        // how many instances can be in a single draw
321934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        int maxInstancesPerDraw = this->indexCountInCurrentSource() /
322934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com                                  indicesPerInstance;
323934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        if (!maxInstancesPerDraw) {
324934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            return;
325934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        }
326934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        // how many instances should be concat'ed onto draw
327934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        int instancesToConcat = maxInstancesPerDraw - draw->fVertexCount /
328934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com                                                      verticesPerInstance;
329934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        if (maxInstancesPerDraw > instanceCount) {
330934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            maxInstancesPerDraw = instanceCount;
331934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            if (instancesToConcat > instanceCount) {
332934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com                instancesToConcat = instanceCount;
333934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            }
334934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        }
335934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com
336934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        // update the amount of reserved data actually referenced in draws
337934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        size_t vertexBytes = instanceCount * verticesPerInstance *
338cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                             GrDrawState::VertexSize(draw->fVertexLayout);
339934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        poolState.fUsedPoolVertexBytes =
340934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com                            GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
341934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com
342934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        while (instanceCount) {
343934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            if (!instancesToConcat) {
344934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com                int startVertex = draw->fStartVertex + draw->fVertexCount;
345a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                draw = this->recordDraw();
346934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com                draw->fPrimitiveType = type;
347934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com                draw->fStartVertex = startVertex;
3486d0673042f6225f16fc5ea91cb1fdf4c8e96d880robertphillips@google.com                draw->fStartIndex = 0;
349934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com                draw->fVertexCount = 0;
3506d0673042f6225f16fc5ea91cb1fdf4c8e96d880robertphillips@google.com                draw->fIndexCount = 0;
351934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com                draw->fVertexLayout = geomSrc.fVertexLayout;
3526d0673042f6225f16fc5ea91cb1fdf4c8e96d880robertphillips@google.com                draw->fVertexBuffer = vertexBuffer;
3536d0673042f6225f16fc5ea91cb1fdf4c8e96d880robertphillips@google.com                vertexBuffer->ref();
3546d0673042f6225f16fc5ea91cb1fdf4c8e96d880robertphillips@google.com                draw->fIndexBuffer = geomSrc.fIndexBuffer;
3556d0673042f6225f16fc5ea91cb1fdf4c8e96d880robertphillips@google.com                geomSrc.fIndexBuffer->ref();
356934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com                instancesToConcat = maxInstancesPerDraw;
357934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            }
358934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            draw->fVertexCount += instancesToConcat * verticesPerInstance;
359934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            draw->fIndexCount += instancesToConcat * indicesPerInstance;
360934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            instanceCount -= instancesToConcat;
361934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            instancesToConcat = 0;
362934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        }
363934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com
364934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        // update draw tracking for next draw
365934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        fCurrQuad = 0;
366934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        fInstancedDrawTracker.fVerticesPerInstance = verticesPerInstance;
367934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        fInstancedDrawTracker.fIndicesPerInstance = indicesPerInstance;
368934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com    } else {
369934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        this->INHERITED::drawIndexedInstances(type,
370934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com                                              instanceCount,
371934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com                                              verticesPerInstance,
372934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com                                              indicesPerInstance);
373934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com    }
374934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com}
375934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com
37674749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.comvoid GrInOrderDrawBuffer::onDraw(const DrawInfo& info) {
377ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
378934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com    this->resetDrawTracking();
37986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
38025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometryPoolState& poolState = fGeoPoolStateStack.back();
38125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
382a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    if (this->needsNewClip()) {
383a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com       this->recordClip();
38486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    }
385a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    if (this->needsNewState()) {
386a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com        this->recordState();
38786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    }
388ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
38974749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com    DrawRecord* draw = this->recordDraw(info);
390a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    draw->fVertexLayout = this->getVertexLayout();
39174749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com
39225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    switch (this->getGeomSrc().fVertexSrc) {
39374749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com        case kBuffer_GeometrySrcType:
39474749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com            draw->fVertexBuffer = this->getGeomSrc().fVertexBuffer;
39574749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com            break;
39674749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com        case kReserved_GeometrySrcType: // fallthrough
39774749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com        case kArray_GeometrySrcType: {
39874749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com            size_t vertexBytes = (info.vertexCount() + info.startVertex()) *
39974749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com                                 GrDrawState::VertexSize(draw->fVertexLayout);
40074749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com            poolState.fUsedPoolVertexBytes = GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
40174749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com            draw->fVertexBuffer = poolState.fPoolVertexBuffer;
40274749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com            draw->fStartVertex += poolState.fPoolStartVertex;
40374749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com            break;
40474749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com        }
40574749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com        default:
40674749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com            GrCrash("unknown geom src type");
407ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
408a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    draw->fVertexBuffer->ref();
409ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
41074749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com    if (info.isIndexed()) {
41174749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com        switch (this->getGeomSrc().fIndexSrc) {
41274749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com            case kBuffer_GeometrySrcType:
41374749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com                draw->fIndexBuffer = this->getGeomSrc().fIndexBuffer;
41474749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com                break;
41574749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com            case kReserved_GeometrySrcType: // fallthrough
41674749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com            case kArray_GeometrySrcType: {
41774749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com                size_t indexBytes = (info.indexCount() + info.startIndex()) * sizeof(uint16_t);
41874749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com                poolState.fUsedPoolIndexBytes = GrMax(poolState.fUsedPoolIndexBytes, indexBytes);
41974749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com                draw->fIndexBuffer = poolState.fPoolIndexBuffer;
42074749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com                draw->fStartIndex += poolState.fPoolStartIndex;
42174749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com                break;
42274749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com            }
42374749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com            default:
42474749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com                GrCrash("unknown geom src type");
42574749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com        }
42674749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com        draw->fIndexBuffer->ref();
42774749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com    } else {
42874749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com        draw->fIndexBuffer = NULL;
429ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
430ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
431ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
432ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
4335f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.comGrInOrderDrawBuffer::StencilPath::StencilPath() : fStroke(SkStrokeRec::kFill_InitStyle) {}
4345f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com
4355f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.comvoid GrInOrderDrawBuffer::onStencilPath(const GrPath* path, const SkStrokeRec& stroke,
43612b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com                                        SkPath::FillType fill) {
437ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    if (this->needsNewClip()) {
438ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com        this->recordClip();
439ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    }
440ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    // Only compare the subset of GrDrawState relevant to path stenciling?
441ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    if (this->needsNewState()) {
442ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com        this->recordState();
443ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    }
444ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    StencilPath* sp = this->recordStencilPath();
445ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    sp->fPath.reset(path);
446ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    path->ref();
447ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    sp->fFill = fill;
44812b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com    sp->fStroke = stroke;
44964aef2bacd1f5c25ffd9347aabd6265c9b60c0f4bsalomon@google.com}
45064aef2bacd1f5c25ffd9347aabd6265c9b60c0f4bsalomon@google.com
451fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.comvoid GrInOrderDrawBuffer::clear(const GrIRect* rect,
452c82a8b7aa4ec19fba508c394920a9e88d3e5bd12robertphillips@google.com                                GrColor color,
453c82a8b7aa4ec19fba508c394920a9e88d3e5bd12robertphillips@google.com                                GrRenderTarget* renderTarget) {
4546aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com    GrIRect r;
4551b3ce47c7b6c14c84d7aaee249b33f9d3b473050bsalomon@google.com    if (NULL == renderTarget) {
4561b3ce47c7b6c14c84d7aaee249b33f9d3b473050bsalomon@google.com        renderTarget = this->drawState()->getRenderTarget();
4571b3ce47c7b6c14c84d7aaee249b33f9d3b473050bsalomon@google.com        GrAssert(NULL != renderTarget);
4581b3ce47c7b6c14c84d7aaee249b33f9d3b473050bsalomon@google.com    }
4596aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com    if (NULL == rect) {
4606aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com        // We could do something smart and remove previous draws and clears to
4616aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com        // the current render target. If we get that smart we have to make sure
4626aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com        // those draws aren't read before this clear (render-to-texture).
4631b3ce47c7b6c14c84d7aaee249b33f9d3b473050bsalomon@google.com        r.setLTRB(0, 0, renderTarget->width(), renderTarget->height());
4646aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com        rect = &r;
4656aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com    }
466a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    Clear* clr = this->recordClear();
467a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    clr->fColor = color;
468a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    clr->fRect = *rect;
469a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    clr->fRenderTarget = renderTarget;
4701b3ce47c7b6c14c84d7aaee249b33f9d3b473050bsalomon@google.com    renderTarget->ref();
4710b335c1ac100aeacf79a4c98a052286fd46661e7bsalomon@google.com}
4720b335c1ac100aeacf79a4c98a052286fd46661e7bsalomon@google.com
473ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrInOrderDrawBuffer::reset() {
47425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(1 == fGeoPoolStateStack.count());
47525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    this->resetVertexSource();
47625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    this->resetIndexSource();
47786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    int numDraws = fDraws.count();
47886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    for (int d = 0; d < numDraws; ++d) {
47986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        // we always have a VB, but not always an IB
48086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        GrAssert(NULL != fDraws[d].fVertexBuffer);
48186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        fDraws[d].fVertexBuffer->unref();
48286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        GrSafeUnref(fDraws[d].fIndexBuffer);
48386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    }
484a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    fCmds.reset();
485ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fDraws.reset();
486ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    fStencilPaths.reset();
487ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fStates.reset();
4880b335c1ac100aeacf79a4c98a052286fd46661e7bsalomon@google.com    fClears.reset();
4891c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    fVertexPool.reset();
4901c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    fIndexPool.reset();
491ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fClips.reset();
492beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.com    fClipOrigins.reset();
493a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    fClipSet = true;
49486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
495934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com    this->resetDrawTracking();
496ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
497ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
49855e4a2005eae1e4f677ec145c577c615a63cf05dbsalomon@google.combool GrInOrderDrawBuffer::flushTo(GrDrawTarget* target) {
49925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fVertexSrc);
50025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fIndexSrc);
5013f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com
502ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    GrAssert(NULL != target);
503ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    GrAssert(target != this); // not considered and why?
504ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
505a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    int numCmds = fCmds.count();
506358e427763f0971af436f07170c641f747b94595bsalomon@google.com    if (0 == numCmds) {
507a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com        return false;
508ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
509ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
5101c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    fVertexPool.unlock();
5111c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    fIndexPool.unlock();
512ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
513ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    GrDrawTarget::AutoClipRestore acr(target);
51425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    AutoGeometryPush agp(target);
515ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com
516ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    GrDrawState playbackState;
517a5d056ae0b04021dfb44c2c7a3d6a34e060261b8bsalomon@google.com    GrDrawState* prevDrawState = target->drawState();
518a5d056ae0b04021dfb44c2c7a3d6a34e060261b8bsalomon@google.com    prevDrawState->ref();
519ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    target->setDrawState(&playbackState);
520ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
521beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.com    GrClipData clipData;
522beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.com
523ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    int currState       = 0;
524ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    int currClip        = 0;
525ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    int currClear       = 0;
526ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    int currDraw        = 0;
527ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    int currStencilPath = 0;
528a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com
529ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com
530a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    for (int c = 0; c < numCmds; ++c) {
531a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com        switch (fCmds[c]) {
532a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com            case kDraw_Cmd: {
53374749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com                const DrawRecord& draw = fDraws[currDraw];
534a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                target->setVertexSourceToBuffer(draw.fVertexLayout, draw.fVertexBuffer);
535a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                if (draw.fIndexCount) {
536a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                    target->setIndexSourceToBuffer(draw.fIndexBuffer);
537a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                }
538ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
539a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                if (draw.fIndexCount) {
540a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                    target->drawIndexed(draw.fPrimitiveType,
541a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                                        draw.fStartVertex,
542a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                                        draw.fStartIndex,
543a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                                        draw.fVertexCount,
544a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                                        draw.fIndexCount);
545a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                } else {
546a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                    target->drawNonIndexed(draw.fPrimitiveType,
547a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                                           draw.fStartVertex,
548a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                                           draw.fVertexCount);
549a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                }
550a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                ++currDraw;
551a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                break;
552a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com            }
553ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com            case kStencilPath_Cmd: {
554ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com                const StencilPath& sp = fStencilPaths[currStencilPath];
55512b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com                target->stencilPath(sp.fPath.get(), sp.fStroke, sp.fFill);
556ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com                ++currStencilPath;
557ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com                break;
558ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com            }
559a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com            case kSetState_Cmd:
560ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com                fStates[currState].restoreTo(&playbackState);
561a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                ++currState;
562a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                break;
563a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com            case kSetClip_Cmd:
564beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.com                clipData.fClipStack = &fClips[currClip];
565beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.com                clipData.fOrigin = fClipOrigins[currClip];
566beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.com                target->setClip(&clipData);
567a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                ++currClip;
568a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                break;
569a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com            case kClear_Cmd:
570fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com                target->clear(&fClears[currClear].fRect,
571a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                              fClears[currClear].fColor,
572a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                              fClears[currClear].fRenderTarget);
573a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                ++currClear;
574a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                break;
575ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        }
576ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
577a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    // we should have consumed all the states, clips, etc.
578a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    GrAssert(fStates.count() == currState);
579a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    GrAssert(fClips.count() == currClip);
580beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.com    GrAssert(fClipOrigins.count() == currClip);
581a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    GrAssert(fClears.count() == currClear);
582a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    GrAssert(fDraws.count()  == currDraw);
583a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com
584a5d056ae0b04021dfb44c2c7a3d6a34e060261b8bsalomon@google.com    target->setDrawState(prevDrawState);
585a5d056ae0b04021dfb44c2c7a3d6a34e060261b8bsalomon@google.com    prevDrawState->unref();
58655e4a2005eae1e4f677ec145c577c615a63cf05dbsalomon@google.com    this->reset();
587a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    return true;
588ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
589ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
59097805382d89b717de3355312a79a957ea4a864c9bsalomon@google.comvoid GrInOrderDrawBuffer::setAutoFlushTarget(GrDrawTarget* target) {
59197805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com    GrSafeAssign(fAutoFlushTarget, target);
59297805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com}
59397805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com
59497805382d89b717de3355312a79a957ea4a864c9bsalomon@google.comvoid GrInOrderDrawBuffer::willReserveVertexAndIndexSpace(
59597805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com                                GrVertexLayout vertexLayout,
59697805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com                                int vertexCount,
59797805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com                                int indexCount) {
59897805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com    if (NULL != fAutoFlushTarget) {
59997805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com        // We use geometryHints() to know whether to flush the draw buffer. We
60097805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com        // can't flush if we are inside an unbalanced pushGeometrySource.
60197805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com        // Moreover, flushing blows away vertex and index data that was
60297805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com        // previously reserved. So if the vertex or index data is pulled from
60397805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com        // reserved space and won't be released by this request then we can't
60497805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com        // flush.
60597805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com        bool insideGeoPush = fGeoPoolStateStack.count() > 1;
60697805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com
60797805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com        bool unreleasedVertexSpace =
60897805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com            !vertexCount &&
60997805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com            kReserved_GeometrySrcType == this->getGeomSrc().fVertexSrc;
61097805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com
61197805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com        bool unreleasedIndexSpace =
61297805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com            !indexCount &&
61397805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com            kReserved_GeometrySrcType == this->getGeomSrc().fIndexSrc;
61497805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com
61597805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com        // we don't want to finalize any reserved geom on the target since
61697805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com        // we don't know that the client has finished writing to it.
61797805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com        bool targetHasReservedGeom =
61897805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com            fAutoFlushTarget->hasReservedVerticesOrIndices();
619fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
62097805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com        int vcount = vertexCount;
62197805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com        int icount = indexCount;
622fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
62397805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com        if (!insideGeoPush &&
62497805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com            !unreleasedVertexSpace &&
62597805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com            !unreleasedIndexSpace &&
62697805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com            !targetHasReservedGeom &&
62797805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com            this->geometryHints(vertexLayout, &vcount, &icount)) {
62897805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com
62997805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com            this->flushTo(fAutoFlushTarget);
63097805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com        }
63197805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com    }
63297805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com}
63397805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com
634ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.combool GrInOrderDrawBuffer::geometryHints(GrVertexLayout vertexLayout,
6351c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com                                        int* vertexCount,
6361c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com                                        int* indexCount) const {
6371c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    // we will recommend a flush if the data could fit in a single
6381c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    // preallocated buffer but none are left and it can't fit
6391c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    // in the current buffer (which may not be prealloced).
640ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    bool flush = false;
641ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    if (NULL != indexCount) {
6421c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com        int32_t currIndices = fIndexPool.currentBufferIndices();
6431c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com        if (*indexCount > currIndices &&
6441c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com            (!fIndexPool.preallocatedBuffersRemaining() &&
6451c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com             *indexCount <= fIndexPool.preallocatedBufferIndices())) {
6461c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com
6471c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com            flush = true;
6481c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com        }
6491c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com        *indexCount = currIndices;
650ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
651ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    if (NULL != vertexCount) {
6521c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com        int32_t currVertices = fVertexPool.currentBufferVertices(vertexLayout);
6531c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com        if (*vertexCount > currVertices &&
6541c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com            (!fVertexPool.preallocatedBuffersRemaining() &&
6551c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com             *vertexCount <= fVertexPool.preallocatedBufferVertices(vertexLayout))) {
6561c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com
6571c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com            flush = true;
658ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        }
6591c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com        *vertexCount = currVertices;
660ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
661ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    return flush;
662ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
663ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
66425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.combool GrInOrderDrawBuffer::onReserveVertexSpace(GrVertexLayout vertexLayout,
66525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                               int vertexCount,
66625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                               void** vertices) {
66725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometryPoolState& poolState = fGeoPoolStateStack.back();
66825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(vertexCount > 0);
66925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(NULL != vertices);
67025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(0 == poolState.fUsedPoolVertexBytes);
671fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
67225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    *vertices = fVertexPool.makeSpace(vertexLayout,
67325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                      vertexCount,
67425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                      &poolState.fPoolVertexBuffer,
67525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                      &poolState.fPoolStartVertex);
67625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    return NULL != *vertices;
67725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
678fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
67925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.combool GrInOrderDrawBuffer::onReserveIndexSpace(int indexCount, void** indices) {
68025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometryPoolState& poolState = fGeoPoolStateStack.back();
68125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(indexCount > 0);
68225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(NULL != indices);
68325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(0 == poolState.fUsedPoolIndexBytes);
68425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
68525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    *indices = fIndexPool.makeSpace(indexCount,
68625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                    &poolState.fPoolIndexBuffer,
68725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                    &poolState.fPoolStartIndex);
68825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    return NULL != *indices;
689ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
690ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
69125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrInOrderDrawBuffer::releaseReservedVertexSpace() {
69225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometryPoolState& poolState = fGeoPoolStateStack.back();
693fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com    const GeometrySrcState& geoSrc = this->getGeomSrc();
694d57d71a5b857c273d9cf834856e10e663c1ccb91bsalomon@google.com
695d57d71a5b857c273d9cf834856e10e663c1ccb91bsalomon@google.com    // If we get a release vertex space call then our current source should either be reserved
696d57d71a5b857c273d9cf834856e10e663c1ccb91bsalomon@google.com    // or array (which we copied into reserved space).
697d57d71a5b857c273d9cf834856e10e663c1ccb91bsalomon@google.com    GrAssert(kReserved_GeometrySrcType == geoSrc.fVertexSrc ||
698d57d71a5b857c273d9cf834856e10e663c1ccb91bsalomon@google.com             kArray_GeometrySrcType == geoSrc.fVertexSrc);
6993f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com
7003f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com    // When the caller reserved vertex buffer space we gave it back a pointer
7013f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com    // provided by the vertex buffer pool. At each draw we tracked the largest
7023f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com    // offset into the pool's pointer that was referenced. Now we return to the
7033f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com    // pool any portion at the tail of the allocation that no draw referenced.
704cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com    size_t reservedVertexBytes = GrDrawState::VertexSize(geoSrc.fVertexLayout) *
70525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                 geoSrc.fVertexCount;
706fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com    fVertexPool.putBack(reservedVertexBytes -
70725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                        poolState.fUsedPoolVertexBytes);
70825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fUsedPoolVertexBytes = 0;
7093f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com    poolState.fPoolVertexBuffer = NULL;
7103f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com    poolState.fPoolStartVertex = 0;
71125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
712ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
71325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrInOrderDrawBuffer::releaseReservedIndexSpace() {
71425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometryPoolState& poolState = fGeoPoolStateStack.back();
715fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com    const GeometrySrcState& geoSrc = this->getGeomSrc();
7161c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com
717d57d71a5b857c273d9cf834856e10e663c1ccb91bsalomon@google.com    // If we get a release index space call then our current source should either be reserved
718d57d71a5b857c273d9cf834856e10e663c1ccb91bsalomon@google.com    // or array (which we copied into reserved space).
719d57d71a5b857c273d9cf834856e10e663c1ccb91bsalomon@google.com    GrAssert(kReserved_GeometrySrcType == geoSrc.fIndexSrc ||
720d57d71a5b857c273d9cf834856e10e663c1ccb91bsalomon@google.com             kArray_GeometrySrcType == geoSrc.fIndexSrc);
7213f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com
7223f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com    // Similar to releaseReservedVertexSpace we return any unused portion at
7233f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com    // the tail
72425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    size_t reservedIndexBytes = sizeof(uint16_t) * geoSrc.fIndexCount;
72525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    fIndexPool.putBack(reservedIndexBytes - poolState.fUsedPoolIndexBytes);
72625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fUsedPoolIndexBytes = 0;
7273f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com    poolState.fPoolIndexBuffer = NULL;
7283f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com    poolState.fPoolStartIndex = 0;
7291c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com}
730fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
731bcdbbe61e1a3f89545b2c1461164f0f8bf5f0797bsalomon@google.comvoid GrInOrderDrawBuffer::onSetVertexSourceToArray(const void* vertexArray,
732bcdbbe61e1a3f89545b2c1461164f0f8bf5f0797bsalomon@google.com                                                   int vertexCount) {
73325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
73425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometryPoolState& poolState = fGeoPoolStateStack.back();
73525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(0 == poolState.fUsedPoolVertexBytes);
7361c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com#if GR_DEBUG
7371c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    bool success =
7381c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com#endif
739e79c815bca39fa552983b7a8107219aa5084acdbbsalomon@google.com    fVertexPool.appendVertices(this->getVertexLayout(),
7401c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com                               vertexCount,
7411c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com                               vertexArray,
74225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                               &poolState.fPoolVertexBuffer,
74325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                               &poolState.fPoolStartVertex);
7441c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    GR_DEBUGASSERT(success);
7451c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com}
7461c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com
747bcdbbe61e1a3f89545b2c1461164f0f8bf5f0797bsalomon@google.comvoid GrInOrderDrawBuffer::onSetIndexSourceToArray(const void* indexArray,
748bcdbbe61e1a3f89545b2c1461164f0f8bf5f0797bsalomon@google.com                                                  int indexCount) {
74925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometryPoolState& poolState = fGeoPoolStateStack.back();
75025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(0 == poolState.fUsedPoolIndexBytes);
7511c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com#if GR_DEBUG
7521c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    bool success =
7531c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com#endif
7541c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    fIndexPool.appendIndices(indexCount,
7551c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com                             indexArray,
75625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                             &poolState.fPoolIndexBuffer,
75725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                             &poolState.fPoolStartIndex);
7581c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    GR_DEBUGASSERT(success);
759ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
760ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
7613f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.comvoid GrInOrderDrawBuffer::releaseVertexArray() {
7623f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com    // When the client provides an array as the vertex source we handled it
7633f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com    // by copying their array into reserved space.
7643f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com    this->GrInOrderDrawBuffer::releaseReservedVertexSpace();
7653f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com}
7663f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com
7673f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.comvoid GrInOrderDrawBuffer::releaseIndexArray() {
7683f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com    // When the client provides an array as the index source we handled it
7693f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com    // by copying their array into reserved space.
7703f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com    this->GrInOrderDrawBuffer::releaseReservedIndexSpace();
7713f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com}
7723f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com
77325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrInOrderDrawBuffer::geometrySourceWillPush() {
77425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
77525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fUsedPoolVertexBytes = 0;
77625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fUsedPoolIndexBytes = 0;
777934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com    this->resetDrawTracking();
77825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#if GR_DEBUG
77925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0;
78025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fPoolStartVertex = ~0;
78125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0;
78225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fPoolStartIndex = ~0;
78325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#endif
78425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
78525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
78625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrInOrderDrawBuffer::geometrySourceWillPop(
78725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                        const GeometrySrcState& restoredState) {
78825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(fGeoPoolStateStack.count() > 1);
78925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    fGeoPoolStateStack.pop_back();
79025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometryPoolState& poolState = fGeoPoolStateStack.back();
79125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    // we have to assume that any slack we had in our vertex/index data
79225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    // is now unreleasable because data may have been appended later in the
79325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    // pool.
79425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    if (kReserved_GeometrySrcType == restoredState.fVertexSrc ||
79525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        kArray_GeometrySrcType == restoredState.fVertexSrc) {
796fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com        poolState.fUsedPoolVertexBytes =
797cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com            GrDrawState::VertexSize(restoredState.fVertexLayout) *
79825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            restoredState.fVertexCount;
79925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
80025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    if (kReserved_GeometrySrcType == restoredState.fIndexSrc ||
80125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        kArray_GeometrySrcType == restoredState.fIndexSrc) {
802fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com        poolState.fUsedPoolIndexBytes = sizeof(uint16_t) *
80325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                         restoredState.fIndexCount;
80425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
805934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com    this->resetDrawTracking();
80625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
80725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
80886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.combool GrInOrderDrawBuffer::needsNewState() const {
809ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    return fStates.empty() || !fStates.back().isEqual(this->getDrawState());
810ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
811ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
81286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.combool GrInOrderDrawBuffer::needsNewClip() const {
813358e427763f0971af436f07170c641f747b94595bsalomon@google.com    GrAssert(fClips.count() == fClipOrigins.count());
814358e427763f0971af436f07170c641f747b94595bsalomon@google.com    if (this->getDrawState().isClipState()) {
815fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com       if (fClipSet &&
816358e427763f0971af436f07170c641f747b94595bsalomon@google.com           (fClips.empty() ||
81702ddc8b85ace91b15feb329a6a1d5d62b2b846c6bsalomon@google.com            fClips.back() != *this->getClip()->fClipStack ||
81802ddc8b85ace91b15feb329a6a1d5d62b2b846c6bsalomon@google.com            fClipOrigins.back() != this->getClip()->fOrigin)) {
81986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com           return true;
82086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com       }
821ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
822ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    return false;
823ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
824d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
825a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.comvoid GrInOrderDrawBuffer::recordClip() {
82602ddc8b85ace91b15feb329a6a1d5d62b2b846c6bsalomon@google.com    fClips.push_back() = *this->getClip()->fClipStack;
82702ddc8b85ace91b15feb329a6a1d5d62b2b846c6bsalomon@google.com    fClipOrigins.push_back() = this->getClip()->fOrigin;
82886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    fClipSet = false;
829a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    fCmds.push_back(kSetClip_Cmd);
830a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com}
831a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com
832a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.comvoid GrInOrderDrawBuffer::recordState() {
833ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    fStates.push_back().saveFrom(this->getDrawState());
834a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    fCmds.push_back(kSetState_Cmd);
835a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com}
836a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com
83774749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.comGrInOrderDrawBuffer::DrawRecord* GrInOrderDrawBuffer::recordDraw() {
838a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    fCmds.push_back(kDraw_Cmd);
839a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    return &fDraws.push_back();
840a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com}
841a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com
84274749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.comGrInOrderDrawBuffer::DrawRecord* GrInOrderDrawBuffer::recordDraw(const DrawInfo& info) {
84374749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com    DrawRecord* record = this->recordDraw();
84474749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com    record->fPrimitiveType  = info.primitiveType();
84574749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com    record->fStartVertex    = info.startVertex();
84674749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com    record->fVertexCount    = info.vertexCount();
84774749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com    record->fStartIndex     = info.startIndex();
84874749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com    record->fIndexCount     = info.indexCount();
84974749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com    return record;
85074749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com}
85174749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com
852ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.comGrInOrderDrawBuffer::StencilPath* GrInOrderDrawBuffer::recordStencilPath() {
853ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    fCmds.push_back(kStencilPath_Cmd);
854ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    return &fStencilPaths.push_back();
855ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com}
856ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com
857a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.comGrInOrderDrawBuffer::Clear* GrInOrderDrawBuffer::recordClear() {
858a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    fCmds.push_back(kClear_Cmd);
859a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    return &fClears.push_back();
86086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com}
861d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
862beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.comvoid GrInOrderDrawBuffer::clipWillBeSet(const GrClipData* newClipData) {
863beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.com    INHERITED::clipWillBeSet(newClipData);
86486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    fClipSet = true;
865ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
866