GrInOrderDrawBuffer.cpp revision fbfcd5602128ec010c82cb733c9cdc0a3254f9f3
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,
7886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                                   const GrMatrix* matrix,
7986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                                   const GrRect* srcRects[],
8086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                                   const GrMatrix* 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);
9486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        AutoReleaseGeometry geo(this, layout, 4, 0);
956513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com        if (!geo.succeeded()) {
966513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com            GrPrintf("Failed to get space for vertices!\n");
976513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com            return;
986513cd06ae34f5d777b3aaea0b4533014d0a10f2bsalomon@google.com        }
998f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrMatrix combinedMatrix = drawState->getViewMatrix();
1003f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com        // We go to device space so that matrix changes allow us to concat
1013f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com        // rect draws. When the caller has provided explicit source rects
1023f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com        // then we don't want to modify the sampler matrices. Otherwise we do
1033f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com        // we have to account for the view matrix change in the sampler
1043f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com        // matrices.
105e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com        uint32_t explicitCoordMask = 0;
106e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com        if (srcRects) {
107e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com            for (int s = 0; s < GrDrawState::kNumStages; ++s) {
108e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com                if (srcRects[s]) {
109e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com                    explicitCoordMask |= (1 << s);
110e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com                }
111e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com            }
112e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com        }
113e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com        GrDrawTarget::AutoDeviceCoordDraw adcd(this, explicitCoordMask);
114e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com        if (!adcd.succeeded()) {
115e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com            return;
116e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com        }
11786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        if (NULL != matrix) {
11886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            combinedMatrix.preConcat(*matrix);
11986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        }
12086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
12186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        SetRectVertices(rect, &combinedMatrix, srcRects, srcMatrices, layout, geo.vertices());
12286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
12386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        // we don't want to miss an opportunity to batch rects together
12486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        // simply because the clip has changed if the clip doesn't affect
12586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        // the rect.
12686afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        bool disabledClip = false;
127d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
128641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com        if (drawState->isClipState()) {
129fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
130641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com            GrRect devClipRect;
131641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com            bool isIntersectionOfRects = false;
132641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com
133641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com            fClip->fClipStack->getConservativeBounds(-fClip->fOrigin.fX,
134641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                                                     -fClip->fOrigin.fY,
135641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                                                     drawState->getRenderTarget()->width(),
136641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                                                     drawState->getRenderTarget()->height(),
137641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                                                     &devClipRect,
138641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                                                     &isIntersectionOfRects);
139641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com
140641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com            if (isIntersectionOfRects) {
141641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                // If the clip rect touches the edge of the viewport, extended it
142641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                // out (close) to infinity to avoid bogus intersections.
143641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                // We might consider a more exact clip to viewport if this
144641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                // conservative test fails.
145641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                const GrRenderTarget* target = drawState->getRenderTarget();
146641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                if (0 >= devClipRect.fLeft) {
147641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                    devClipRect.fLeft = GR_ScalarMin;
148641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                }
149641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                if (target->width() <= devClipRect.fRight) {
150641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                    devClipRect.fRight = GR_ScalarMax;
151641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                }
152641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                if (0 >= devClipRect.top()) {
153641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                    devClipRect.fTop = GR_ScalarMin;
154641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                }
155641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                if (target->height() <= devClipRect.fBottom) {
156641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                    devClipRect.fBottom = GR_ScalarMax;
157641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                }
158641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                int stride = VertexSize(layout);
159641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                bool insideClip = true;
160641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                for (int v = 0; v < 4; ++v) {
161641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                    const GrPoint& p = *GetVertexPoint(geo.vertices(), v, stride);
162641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                    if (!devClipRect.contains(p)) {
163641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                        insideClip = false;
164641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                        break;
165641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                    }
166641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                }
167641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                if (insideClip) {
168641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                    drawState->disableState(GrDrawState::kClip_StateBit);
169641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                    disabledClip = true;
17086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                }
17186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            }
17286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        }
173641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com
174a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com        if (!this->needsNewClip() &&
175a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com            !this->needsNewState() &&
176a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com            fCurrQuad > 0 &&
177a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com            fCurrQuad < fMaxQuads &&
178a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com            layout == fLastRectVertexLayout) {
17986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
18086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            int vsize = VertexSize(layout);
181d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
18286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            Draw& lastDraw = fDraws.back();
18386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
18486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            GrAssert(lastDraw.fIndexBuffer == fQuadIndexBuffer);
18547059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com            GrAssert(kTriangles_GrPrimitiveType == lastDraw.fPrimitiveType);
18686afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            GrAssert(0 == lastDraw.fVertexCount % 4);
18786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            GrAssert(0 == lastDraw.fIndexCount % 6);
18886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            GrAssert(0 == lastDraw.fStartIndex);
18986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
19025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            GeometryPoolState& poolState = fGeoPoolStateStack.back();
1916aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com
192fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com            appendToPreviousDraw =
193a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                kDraw_Cmd != fCmds.back() &&
19425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                lastDraw.fVertexBuffer == poolState.fPoolVertexBuffer &&
19525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                (fCurrQuad * 4 + lastDraw.fStartVertex) == poolState.fPoolStartVertex;
19625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
19786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            if (appendToPreviousDraw) {
19886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                lastDraw.fVertexCount += 4;
19986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                lastDraw.fIndexCount += 6;
20086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                fCurrQuad += 1;
20125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                // we reserved above, so we should be the first
202a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                // use of this vertex reservation.
20325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                GrAssert(0 == poolState.fUsedPoolVertexBytes);
20425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                poolState.fUsedPoolVertexBytes = 4 * vsize;
20586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            }
20686afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        }
20786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        if (!appendToPreviousDraw) {
20886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            this->setIndexSourceToBuffer(fQuadIndexBuffer);
20947059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com            this->drawIndexed(kTriangles_GrPrimitiveType, 0, 0, 4, 6);
21086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            fCurrQuad = 1;
21186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            fLastRectVertexLayout = layout;
21286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        }
21386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        if (disabledClip) {
2148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            drawState->enableState(GrDrawState::kClip_StateBit);
21586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        }
216934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        fInstancedDrawTracker.reset();
21786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    } else {
218e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com        INHERITED::drawRect(rect, matrix, srcRects, srcMatrices);
21986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    }
22086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com}
22186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
222934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.comvoid GrInOrderDrawBuffer::drawIndexedInstances(GrPrimitiveType type,
223934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com                                               int instanceCount,
224934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com                                               int verticesPerInstance,
225934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com                                               int indicesPerInstance) {
226934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com    if (!verticesPerInstance || !indicesPerInstance) {
227934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        return;
228934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com    }
229934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com
230934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com    const GeometrySrcState& geomSrc = this->getGeomSrc();
231934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com
232934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com    // we only attempt to concat the case when reserved verts are used with
233934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com    // an index buffer.
234934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com    if (kReserved_GeometrySrcType == geomSrc.fVertexSrc &&
235934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        kBuffer_GeometrySrcType == geomSrc.fIndexSrc) {
236934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com
237a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com        if (this->needsNewClip()) {
238a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com            this->recordClip();
239a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com        }
240a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com        if (this->needsNewState()) {
241a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com            this->recordState();
242a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com        }
243a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com
244934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        Draw* draw = NULL;
245934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        // if the last draw used the same indices/vertices per shape then we
246934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        // may be able to append to it.
247a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com        if (kDraw_Cmd == fCmds.back() &&
248a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com            verticesPerInstance == fInstancedDrawTracker.fVerticesPerInstance &&
249934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            indicesPerInstance == fInstancedDrawTracker.fIndicesPerInstance) {
250934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            GrAssert(fDraws.count());
251934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            draw = &fDraws.back();
252934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        }
253934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com
254934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        GeometryPoolState& poolState = fGeoPoolStateStack.back();
255934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        const GrVertexBuffer* vertexBuffer = poolState.fPoolVertexBuffer;
256934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com
257934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        // Check whether the draw is compatible with this draw in order to
258934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        // append
259934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        if (NULL == draw ||
260934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            draw->fIndexBuffer != geomSrc.fIndexBuffer ||
261934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            draw->fPrimitiveType != type ||
262934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            draw->fVertexBuffer != vertexBuffer) {
263934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com
264a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com            draw = this->recordDraw();
265934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            draw->fIndexBuffer = geomSrc.fIndexBuffer;
266934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            geomSrc.fIndexBuffer->ref();
267934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            draw->fVertexBuffer = vertexBuffer;
268934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            vertexBuffer->ref();
269934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            draw->fPrimitiveType = type;
270934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            draw->fStartIndex = 0;
271934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            draw->fIndexCount = 0;
272934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            draw->fStartVertex = poolState.fPoolStartVertex;
273934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            draw->fVertexCount = 0;
274934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            draw->fVertexLayout = geomSrc.fVertexLayout;
275934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        } else {
276934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            GrAssert(!(draw->fIndexCount % indicesPerInstance));
277934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            GrAssert(!(draw->fVertexCount % verticesPerInstance));
278934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            GrAssert(poolState.fPoolStartVertex == draw->fStartVertex +
279934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com                                                   draw->fVertexCount);
280934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        }
281934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com
282934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        // how many instances can be in a single draw
283934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        int maxInstancesPerDraw = this->indexCountInCurrentSource() /
284934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com                                  indicesPerInstance;
285934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        if (!maxInstancesPerDraw) {
286934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            return;
287934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        }
288934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        // how many instances should be concat'ed onto draw
289934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        int instancesToConcat = maxInstancesPerDraw - draw->fVertexCount /
290934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com                                                      verticesPerInstance;
291934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        if (maxInstancesPerDraw > instanceCount) {
292934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            maxInstancesPerDraw = instanceCount;
293934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            if (instancesToConcat > instanceCount) {
294934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com                instancesToConcat = instanceCount;
295934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            }
296934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        }
297934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com
298934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        // update the amount of reserved data actually referenced in draws
299934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        size_t vertexBytes = instanceCount * verticesPerInstance *
300934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com                             VertexSize(draw->fVertexLayout);
301934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        poolState.fUsedPoolVertexBytes =
302934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com                            GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
303934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com
304934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        while (instanceCount) {
305934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            if (!instancesToConcat) {
306934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com                int startVertex = draw->fStartVertex + draw->fVertexCount;
307a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                draw = this->recordDraw();
308934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com                draw->fIndexBuffer = geomSrc.fIndexBuffer;
309934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com                geomSrc.fIndexBuffer->ref();
310934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com                draw->fVertexBuffer = vertexBuffer;
311934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com                vertexBuffer->ref();
312934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com                draw->fPrimitiveType = type;
313934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com                draw->fStartIndex = 0;
314934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com                draw->fStartVertex = startVertex;
315934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com                draw->fVertexCount = 0;
316934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com                draw->fVertexLayout = geomSrc.fVertexLayout;
317934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com                instancesToConcat = maxInstancesPerDraw;
318934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            }
319934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            draw->fVertexCount += instancesToConcat * verticesPerInstance;
320934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            draw->fIndexCount += instancesToConcat * indicesPerInstance;
321934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            instanceCount -= instancesToConcat;
322934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com            instancesToConcat = 0;
323934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        }
324934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com
325934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        // update draw tracking for next draw
326934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        fCurrQuad = 0;
327934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        fInstancedDrawTracker.fVerticesPerInstance = verticesPerInstance;
328934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        fInstancedDrawTracker.fIndicesPerInstance = indicesPerInstance;
329934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com    } else {
330934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com        this->INHERITED::drawIndexedInstances(type,
331934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com                                              instanceCount,
332934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com                                              verticesPerInstance,
333934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com                                              indicesPerInstance);
334934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com    }
335934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com
336934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com}
337934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com
33825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrInOrderDrawBuffer::onDrawIndexed(GrPrimitiveType primitiveType,
33925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                        int startVertex,
34025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                        int startIndex,
34125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                        int vertexCount,
34225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                        int indexCount) {
343ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
344ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    if (!vertexCount || !indexCount) {
345ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        return;
346ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
347ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
348934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com    this->resetDrawTracking();
34986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
35025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometryPoolState& poolState = fGeoPoolStateStack.back();
35125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
352a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    if (this->needsNewClip()) {
353a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com       this->recordClip();
35486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    }
355a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    if (this->needsNewState()) {
356a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com        this->recordState();
35786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    }
358ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
359a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    Draw* draw = this->recordDraw();
360a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com
361a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    draw->fPrimitiveType = primitiveType;
362a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    draw->fStartVertex   = startVertex;
363a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    draw->fStartIndex    = startIndex;
364a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    draw->fVertexCount   = vertexCount;
365a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    draw->fIndexCount    = indexCount;
366a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com
367a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    draw->fVertexLayout = this->getVertexLayout();
36825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    switch (this->getGeomSrc().fVertexSrc) {
3691c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    case kBuffer_GeometrySrcType:
370a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com        draw->fVertexBuffer = this->getGeomSrc().fVertexBuffer;
371ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        break;
37225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    case kReserved_GeometrySrcType: // fallthrough
37325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    case kArray_GeometrySrcType: {
374ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        size_t vertexBytes = (vertexCount + startVertex) *
375a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                             VertexSize(draw->fVertexLayout);
376fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com        poolState.fUsedPoolVertexBytes =
37725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                            GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
378a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com        draw->fVertexBuffer = poolState.fPoolVertexBuffer;
379a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com        draw->fStartVertex += poolState.fPoolStartVertex;
380ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        break;
38125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
3821c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    default:
3831c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com        GrCrash("unknown geom src type");
384ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
385a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    draw->fVertexBuffer->ref();
386ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
38725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    switch (this->getGeomSrc().fIndexSrc) {
3881c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    case kBuffer_GeometrySrcType:
389a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com        draw->fIndexBuffer = this->getGeomSrc().fIndexBuffer;
390ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        break;
391fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com    case kReserved_GeometrySrcType: // fallthrough
39225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    case kArray_GeometrySrcType: {
393ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        size_t indexBytes = (indexCount + startIndex) * sizeof(uint16_t);
394fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com        poolState.fUsedPoolIndexBytes =
39525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                            GrMax(poolState.fUsedPoolIndexBytes, indexBytes);
396a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com        draw->fIndexBuffer = poolState.fPoolIndexBuffer;
397a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com        draw->fStartIndex += poolState.fPoolStartIndex;
398ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        break;
39925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
4001c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    default:
4011c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com        GrCrash("unknown geom src type");
402ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
403a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    draw->fIndexBuffer->ref();
404ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
405ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
40625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrInOrderDrawBuffer::onDrawNonIndexed(GrPrimitiveType primitiveType,
40725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                           int startVertex,
40825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                           int vertexCount) {
409ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    if (!vertexCount) {
410ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        return;
411ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
412ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
413934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com    this->resetDrawTracking();
41486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
41525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometryPoolState& poolState = fGeoPoolStateStack.back();
416a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    if (this->needsNewClip()) {
417a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com        this->recordClip();
41886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    }
419a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    if (this->needsNewState()) {
420a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com        this->recordState();
42186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    }
422ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
423a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    Draw* draw = this->recordDraw();
424a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    draw->fPrimitiveType = primitiveType;
425a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    draw->fStartVertex   = startVertex;
426a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    draw->fStartIndex    = 0;
427a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    draw->fVertexCount   = vertexCount;
428a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    draw->fIndexCount    = 0;
429a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com
430a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    draw->fVertexLayout = this->getVertexLayout();
43125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    switch (this->getGeomSrc().fVertexSrc) {
4321c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    case kBuffer_GeometrySrcType:
433a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com        draw->fVertexBuffer = this->getGeomSrc().fVertexBuffer;
434ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        break;
43525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    case kReserved_GeometrySrcType: // fallthrough
43625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    case kArray_GeometrySrcType: {
437ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        size_t vertexBytes = (vertexCount + startVertex) *
438a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                             VertexSize(draw->fVertexLayout);
439fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com        poolState.fUsedPoolVertexBytes =
44025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                            GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
441a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com        draw->fVertexBuffer = poolState.fPoolVertexBuffer;
442a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com        draw->fStartVertex += poolState.fPoolStartVertex;
443ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        break;
44425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
4451c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    default:
4461c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com        GrCrash("unknown geom src type");
447ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
448a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    draw->fVertexBuffer->ref();
449a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    draw->fIndexBuffer = NULL;
450ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
451ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
452ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.comvoid GrInOrderDrawBuffer::onStencilPath(const GrPath* path, GrPathFill fill) {
453ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    if (this->needsNewClip()) {
454ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com        this->recordClip();
455ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    }
456ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    // Only compare the subset of GrDrawState relevant to path stenciling?
457ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    if (this->needsNewState()) {
458ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com        this->recordState();
459ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    }
460ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    StencilPath* sp = this->recordStencilPath();
461ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    sp->fPath.reset(path);
462ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    path->ref();
463ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    sp->fFill = fill;
46464aef2bacd1f5c25ffd9347aabd6265c9b60c0f4bsalomon@google.com}
46564aef2bacd1f5c25ffd9347aabd6265c9b60c0f4bsalomon@google.com
466fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.comvoid GrInOrderDrawBuffer::clear(const GrIRect* rect,
467c82a8b7aa4ec19fba508c394920a9e88d3e5bd12robertphillips@google.com                                GrColor color,
468c82a8b7aa4ec19fba508c394920a9e88d3e5bd12robertphillips@google.com                                GrRenderTarget* renderTarget) {
4696aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com    GrIRect r;
4701b3ce47c7b6c14c84d7aaee249b33f9d3b473050bsalomon@google.com    if (NULL == renderTarget) {
4711b3ce47c7b6c14c84d7aaee249b33f9d3b473050bsalomon@google.com        renderTarget = this->drawState()->getRenderTarget();
4721b3ce47c7b6c14c84d7aaee249b33f9d3b473050bsalomon@google.com        GrAssert(NULL != renderTarget);
4731b3ce47c7b6c14c84d7aaee249b33f9d3b473050bsalomon@google.com    }
4746aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com    if (NULL == rect) {
4756aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com        // We could do something smart and remove previous draws and clears to
4766aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com        // the current render target. If we get that smart we have to make sure
4776aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com        // those draws aren't read before this clear (render-to-texture).
4781b3ce47c7b6c14c84d7aaee249b33f9d3b473050bsalomon@google.com        r.setLTRB(0, 0, renderTarget->width(), renderTarget->height());
4796aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com        rect = &r;
4806aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com    }
481a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    Clear* clr = this->recordClear();
482a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    clr->fColor = color;
483a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    clr->fRect = *rect;
484a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    clr->fRenderTarget = renderTarget;
4851b3ce47c7b6c14c84d7aaee249b33f9d3b473050bsalomon@google.com    renderTarget->ref();
4860b335c1ac100aeacf79a4c98a052286fd46661e7bsalomon@google.com}
4870b335c1ac100aeacf79a4c98a052286fd46661e7bsalomon@google.com
488ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrInOrderDrawBuffer::reset() {
48925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(1 == fGeoPoolStateStack.count());
49025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    this->resetVertexSource();
49125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    this->resetIndexSource();
49286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    int numDraws = fDraws.count();
49386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    for (int d = 0; d < numDraws; ++d) {
49486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        // we always have a VB, but not always an IB
49586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        GrAssert(NULL != fDraws[d].fVertexBuffer);
49686afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        fDraws[d].fVertexBuffer->unref();
49786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        GrSafeUnref(fDraws[d].fIndexBuffer);
49886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    }
499a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    fCmds.reset();
500ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fDraws.reset();
501ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    fStencilPaths.reset();
502ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fStates.reset();
5030b335c1ac100aeacf79a4c98a052286fd46661e7bsalomon@google.com    fClears.reset();
5041c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    fVertexPool.reset();
5051c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    fIndexPool.reset();
506ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fClips.reset();
507beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.com    fClipOrigins.reset();
508a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    fClipSet = true;
50986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
510934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com    this->resetDrawTracking();
511a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com
512a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    // we start off with a default clip and state so that we don't have
513a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    // to do count checks on fClips, fStates, or fCmds before checking their
514a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    // last entry.
515a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    this->recordDefaultState();
516a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    this->recordDefaultClip();
517ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
518ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
519a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.combool GrInOrderDrawBuffer::playback(GrDrawTarget* target) {
52025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fVertexSrc);
52125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fIndexSrc);
5223f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com
523ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    GrAssert(NULL != target);
524ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    GrAssert(target != this); // not considered and why?
525ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
526a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    int numCmds = fCmds.count();
527a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    GrAssert(numCmds >= 2);
528a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    if (2 == numCmds) {
529a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com        GrAssert(kSetState_Cmd == fCmds[0]);
530a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com        GrAssert(kSetClip_Cmd  == fCmds[1]);
531a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com        return false;
532ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
533ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
5341c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    fVertexPool.unlock();
5351c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    fIndexPool.unlock();
536ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
537ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    GrDrawTarget::AutoClipRestore acr(target);
53825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    AutoGeometryPush agp(target);
539a5d056ae0b04021dfb44c2c7a3d6a34e060261b8bsalomon@google.com    GrDrawState* prevDrawState = target->drawState();
540a5d056ae0b04021dfb44c2c7a3d6a34e060261b8bsalomon@google.com    prevDrawState->ref();
541ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
542beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.com    GrClipData clipData;
543beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.com
544ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    int currState       = 0;
545ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    int currClip        = 0;
546ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    int currClear       = 0;
547ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    int currDraw        = 0;
548ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    int currStencilPath = 0;
549a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com
550a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    for (int c = 0; c < numCmds; ++c) {
551a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com        switch (fCmds[c]) {
552a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com            case kDraw_Cmd: {
553a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                const Draw& draw = fDraws[currDraw];
554a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                target->setVertexSourceToBuffer(draw.fVertexLayout, draw.fVertexBuffer);
555a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                if (draw.fIndexCount) {
556a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                    target->setIndexSourceToBuffer(draw.fIndexBuffer);
557a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                }
558ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
559a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                if (draw.fIndexCount) {
560a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                    target->drawIndexed(draw.fPrimitiveType,
561a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                                        draw.fStartVertex,
562a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                                        draw.fStartIndex,
563a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                                        draw.fVertexCount,
564a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                                        draw.fIndexCount);
565a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                } else {
566a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                    target->drawNonIndexed(draw.fPrimitiveType,
567a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                                           draw.fStartVertex,
568a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                                           draw.fVertexCount);
569a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                }
570a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                ++currDraw;
571a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                break;
572a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com            }
573ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com            case kStencilPath_Cmd: {
574ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com                const StencilPath& sp = fStencilPaths[currStencilPath];
575ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com                target->stencilPath(sp.fPath.get(), sp.fFill);
576ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com                ++currStencilPath;
577ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com                break;
578ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com            }
579a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com            case kSetState_Cmd:
580a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                target->setDrawState(&fStates[currState]);
581a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                ++currState;
582a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                break;
583a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com            case kSetClip_Cmd:
584beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.com                clipData.fClipStack = &fClips[currClip];
585beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.com                clipData.fOrigin = fClipOrigins[currClip];
586beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.com                target->setClip(&clipData);
587a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                ++currClip;
588a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                break;
589a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com            case kClear_Cmd:
590fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com                target->clear(&fClears[currClear].fRect,
591a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                              fClears[currClear].fColor,
592a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                              fClears[currClear].fRenderTarget);
593a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                ++currClear;
594a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com                break;
595ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        }
596ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
597a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    // we should have consumed all the states, clips, etc.
598a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    GrAssert(fStates.count() == currState);
599a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    GrAssert(fClips.count() == currClip);
600beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.com    GrAssert(fClipOrigins.count() == currClip);
601a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    GrAssert(fClears.count() == currClear);
602a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    GrAssert(fDraws.count()  == currDraw);
603a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com
604a5d056ae0b04021dfb44c2c7a3d6a34e060261b8bsalomon@google.com    target->setDrawState(prevDrawState);
605a5d056ae0b04021dfb44c2c7a3d6a34e060261b8bsalomon@google.com    prevDrawState->unref();
606a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    return true;
607ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
608ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
60997805382d89b717de3355312a79a957ea4a864c9bsalomon@google.comvoid GrInOrderDrawBuffer::setAutoFlushTarget(GrDrawTarget* target) {
61097805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com    GrSafeAssign(fAutoFlushTarget, target);
61197805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com}
61297805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com
61397805382d89b717de3355312a79a957ea4a864c9bsalomon@google.comvoid GrInOrderDrawBuffer::willReserveVertexAndIndexSpace(
61497805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com                                GrVertexLayout vertexLayout,
61597805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com                                int vertexCount,
61697805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com                                int indexCount) {
61797805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com    if (NULL != fAutoFlushTarget) {
61897805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com        // We use geometryHints() to know whether to flush the draw buffer. We
61997805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com        // can't flush if we are inside an unbalanced pushGeometrySource.
62097805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com        // Moreover, flushing blows away vertex and index data that was
62197805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com        // previously reserved. So if the vertex or index data is pulled from
62297805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com        // reserved space and won't be released by this request then we can't
62397805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com        // flush.
62497805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com        bool insideGeoPush = fGeoPoolStateStack.count() > 1;
62597805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com
62697805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com        bool unreleasedVertexSpace =
62797805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com            !vertexCount &&
62897805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com            kReserved_GeometrySrcType == this->getGeomSrc().fVertexSrc;
62997805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com
63097805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com        bool unreleasedIndexSpace =
63197805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com            !indexCount &&
63297805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com            kReserved_GeometrySrcType == this->getGeomSrc().fIndexSrc;
63397805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com
63497805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com        // we don't want to finalize any reserved geom on the target since
63597805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com        // we don't know that the client has finished writing to it.
63697805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com        bool targetHasReservedGeom =
63797805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com            fAutoFlushTarget->hasReservedVerticesOrIndices();
638fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
63997805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com        int vcount = vertexCount;
64097805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com        int icount = indexCount;
641fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
64297805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com        if (!insideGeoPush &&
64397805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com            !unreleasedVertexSpace &&
64497805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com            !unreleasedIndexSpace &&
64597805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com            !targetHasReservedGeom &&
64697805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com            this->geometryHints(vertexLayout, &vcount, &icount)) {
64797805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com
64897805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com            this->flushTo(fAutoFlushTarget);
64997805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com        }
65097805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com    }
65197805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com}
65297805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com
653ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.combool GrInOrderDrawBuffer::geometryHints(GrVertexLayout vertexLayout,
6541c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com                                        int* vertexCount,
6551c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com                                        int* indexCount) const {
6561c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    // we will recommend a flush if the data could fit in a single
6571c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    // preallocated buffer but none are left and it can't fit
6581c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    // in the current buffer (which may not be prealloced).
659ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    bool flush = false;
660ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    if (NULL != indexCount) {
6611c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com        int32_t currIndices = fIndexPool.currentBufferIndices();
6621c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com        if (*indexCount > currIndices &&
6631c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com            (!fIndexPool.preallocatedBuffersRemaining() &&
6641c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com             *indexCount <= fIndexPool.preallocatedBufferIndices())) {
6651c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com
6661c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com            flush = true;
6671c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com        }
6681c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com        *indexCount = currIndices;
669ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
670ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    if (NULL != vertexCount) {
6711c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com        int32_t currVertices = fVertexPool.currentBufferVertices(vertexLayout);
6721c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com        if (*vertexCount > currVertices &&
6731c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com            (!fVertexPool.preallocatedBuffersRemaining() &&
6741c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com             *vertexCount <= fVertexPool.preallocatedBufferVertices(vertexLayout))) {
6751c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com
6761c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com            flush = true;
677ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        }
6781c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com        *vertexCount = currVertices;
679ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
680ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    return flush;
681ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
682ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
68325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.combool GrInOrderDrawBuffer::onReserveVertexSpace(GrVertexLayout vertexLayout,
68425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                               int vertexCount,
68525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                               void** vertices) {
68625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometryPoolState& poolState = fGeoPoolStateStack.back();
68725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(vertexCount > 0);
68825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(NULL != vertices);
68925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(0 == poolState.fUsedPoolVertexBytes);
690fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
69125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    *vertices = fVertexPool.makeSpace(vertexLayout,
69225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                      vertexCount,
69325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                      &poolState.fPoolVertexBuffer,
69425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                      &poolState.fPoolStartVertex);
69525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    return NULL != *vertices;
69625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
697fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
69825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.combool GrInOrderDrawBuffer::onReserveIndexSpace(int indexCount, void** indices) {
69925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometryPoolState& poolState = fGeoPoolStateStack.back();
70025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(indexCount > 0);
70125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(NULL != indices);
70225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(0 == poolState.fUsedPoolIndexBytes);
70325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
70425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    *indices = fIndexPool.makeSpace(indexCount,
70525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                    &poolState.fPoolIndexBuffer,
70625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                    &poolState.fPoolStartIndex);
70725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    return NULL != *indices;
708ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
709ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
71025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrInOrderDrawBuffer::releaseReservedVertexSpace() {
71125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometryPoolState& poolState = fGeoPoolStateStack.back();
712fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com    const GeometrySrcState& geoSrc = this->getGeomSrc();
713d57d71a5b857c273d9cf834856e10e663c1ccb91bsalomon@google.com
714d57d71a5b857c273d9cf834856e10e663c1ccb91bsalomon@google.com    // If we get a release vertex space call then our current source should either be reserved
715d57d71a5b857c273d9cf834856e10e663c1ccb91bsalomon@google.com    // or array (which we copied into reserved space).
716d57d71a5b857c273d9cf834856e10e663c1ccb91bsalomon@google.com    GrAssert(kReserved_GeometrySrcType == geoSrc.fVertexSrc ||
717d57d71a5b857c273d9cf834856e10e663c1ccb91bsalomon@google.com             kArray_GeometrySrcType == geoSrc.fVertexSrc);
7183f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com
7193f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com    // When the caller reserved vertex buffer space we gave it back a pointer
7203f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com    // provided by the vertex buffer pool. At each draw we tracked the largest
7213f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com    // offset into the pool's pointer that was referenced. Now we return to the
7223f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com    // pool any portion at the tail of the allocation that no draw referenced.
7233f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com    size_t reservedVertexBytes = VertexSize(geoSrc.fVertexLayout) *
72425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                 geoSrc.fVertexCount;
725fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com    fVertexPool.putBack(reservedVertexBytes -
72625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                        poolState.fUsedPoolVertexBytes);
72725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fUsedPoolVertexBytes = 0;
7283f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com    poolState.fPoolVertexBuffer = NULL;
7293f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com    poolState.fPoolStartVertex = 0;
73025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
731ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
73225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrInOrderDrawBuffer::releaseReservedIndexSpace() {
73325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometryPoolState& poolState = fGeoPoolStateStack.back();
734fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com    const GeometrySrcState& geoSrc = this->getGeomSrc();
7351c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com
736d57d71a5b857c273d9cf834856e10e663c1ccb91bsalomon@google.com    // If we get a release index space call then our current source should either be reserved
737d57d71a5b857c273d9cf834856e10e663c1ccb91bsalomon@google.com    // or array (which we copied into reserved space).
738d57d71a5b857c273d9cf834856e10e663c1ccb91bsalomon@google.com    GrAssert(kReserved_GeometrySrcType == geoSrc.fIndexSrc ||
739d57d71a5b857c273d9cf834856e10e663c1ccb91bsalomon@google.com             kArray_GeometrySrcType == geoSrc.fIndexSrc);
7403f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com
7413f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com    // Similar to releaseReservedVertexSpace we return any unused portion at
7423f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com    // the tail
74325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    size_t reservedIndexBytes = sizeof(uint16_t) * geoSrc.fIndexCount;
74425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    fIndexPool.putBack(reservedIndexBytes - poolState.fUsedPoolIndexBytes);
74525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fUsedPoolIndexBytes = 0;
7463f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com    poolState.fPoolIndexBuffer = NULL;
7473f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com    poolState.fPoolStartIndex = 0;
7481c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com}
749fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
750bcdbbe61e1a3f89545b2c1461164f0f8bf5f0797bsalomon@google.comvoid GrInOrderDrawBuffer::onSetVertexSourceToArray(const void* vertexArray,
751bcdbbe61e1a3f89545b2c1461164f0f8bf5f0797bsalomon@google.com                                                   int vertexCount) {
75225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
75325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometryPoolState& poolState = fGeoPoolStateStack.back();
75425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(0 == poolState.fUsedPoolVertexBytes);
7551c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com#if GR_DEBUG
7561c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    bool success =
7571c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com#endif
758e79c815bca39fa552983b7a8107219aa5084acdbbsalomon@google.com    fVertexPool.appendVertices(this->getVertexLayout(),
7591c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com                               vertexCount,
7601c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com                               vertexArray,
76125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                               &poolState.fPoolVertexBuffer,
76225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                               &poolState.fPoolStartVertex);
7631c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    GR_DEBUGASSERT(success);
7641c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com}
7651c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com
766bcdbbe61e1a3f89545b2c1461164f0f8bf5f0797bsalomon@google.comvoid GrInOrderDrawBuffer::onSetIndexSourceToArray(const void* indexArray,
767bcdbbe61e1a3f89545b2c1461164f0f8bf5f0797bsalomon@google.com                                                  int indexCount) {
76825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometryPoolState& poolState = fGeoPoolStateStack.back();
76925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(0 == poolState.fUsedPoolIndexBytes);
7701c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com#if GR_DEBUG
7711c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    bool success =
7721c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com#endif
7731c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    fIndexPool.appendIndices(indexCount,
7741c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com                             indexArray,
77525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                             &poolState.fPoolIndexBuffer,
77625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                             &poolState.fPoolStartIndex);
7771c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    GR_DEBUGASSERT(success);
778ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
779ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
7803f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.comvoid GrInOrderDrawBuffer::releaseVertexArray() {
7813f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com    // When the client provides an array as the vertex source we handled it
7823f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com    // by copying their array into reserved space.
7833f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com    this->GrInOrderDrawBuffer::releaseReservedVertexSpace();
7843f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com}
7853f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com
7863f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.comvoid GrInOrderDrawBuffer::releaseIndexArray() {
7873f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com    // When the client provides an array as the index source we handled it
7883f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com    // by copying their array into reserved space.
7893f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com    this->GrInOrderDrawBuffer::releaseReservedIndexSpace();
7903f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com}
7913f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com
79225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrInOrderDrawBuffer::geometrySourceWillPush() {
79325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
79425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fUsedPoolVertexBytes = 0;
79525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fUsedPoolIndexBytes = 0;
796934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com    this->resetDrawTracking();
79725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#if GR_DEBUG
79825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0;
79925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fPoolStartVertex = ~0;
80025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0;
80125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fPoolStartIndex = ~0;
80225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#endif
80325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
80425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
80525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrInOrderDrawBuffer::geometrySourceWillPop(
80625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                        const GeometrySrcState& restoredState) {
80725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(fGeoPoolStateStack.count() > 1);
80825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    fGeoPoolStateStack.pop_back();
80925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometryPoolState& poolState = fGeoPoolStateStack.back();
81025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    // we have to assume that any slack we had in our vertex/index data
81125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    // is now unreleasable because data may have been appended later in the
81225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    // pool.
81325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    if (kReserved_GeometrySrcType == restoredState.fVertexSrc ||
81425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        kArray_GeometrySrcType == restoredState.fVertexSrc) {
815fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com        poolState.fUsedPoolVertexBytes =
816fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com            VertexSize(restoredState.fVertexLayout) *
81725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            restoredState.fVertexCount;
81825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
81925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    if (kReserved_GeometrySrcType == restoredState.fIndexSrc ||
82025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        kArray_GeometrySrcType == restoredState.fIndexSrc) {
821fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com        poolState.fUsedPoolIndexBytes = sizeof(uint16_t) *
82225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                         restoredState.fIndexCount;
82325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
824934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com    this->resetDrawTracking();
82525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
82625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
82786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.combool GrInOrderDrawBuffer::needsNewState() const {
828a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    // we should have recorded a default state in reset()
829a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    GrAssert(!fStates.empty());
830a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    return fStates.back() != this->getDrawState();
831ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
832ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
83386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.combool GrInOrderDrawBuffer::needsNewClip() const {
8348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com   if (this->getDrawState().isClipState()) {
835fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com       if (fClipSet &&
836beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.com           (fClips.back() != *fClip->fClipStack ||
837beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.com            fClipOrigins.back() != fClip->fOrigin)) {
83886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com           return true;
83986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com       }
840ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
841ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    return false;
842ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
843d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
844a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.comvoid GrInOrderDrawBuffer::recordClip() {
845beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.com    fClips.push_back() = *fClip->fClipStack;
846beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.com    fClipOrigins.push_back() = fClip->fOrigin;
84786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    fClipSet = false;
848a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    fCmds.push_back(kSetClip_Cmd);
849a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com}
850a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com
851a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.comvoid GrInOrderDrawBuffer::recordDefaultClip() {
852641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com    fClips.push_back() = SkClipStack();
853beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.com    fClipOrigins.push_back() = SkIPoint::Make(0, 0);
854a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    fCmds.push_back(kSetClip_Cmd);
855a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com}
856a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com
857a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.comvoid GrInOrderDrawBuffer::recordState() {
858a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    fStates.push_back(this->getDrawState());
859a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    fCmds.push_back(kSetState_Cmd);
860a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com}
861a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com
862a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.comvoid GrInOrderDrawBuffer::recordDefaultState() {
863a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    fStates.push_back(GrDrawState());
864a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    fCmds.push_back(kSetState_Cmd);
865a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com}
866a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com
867a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.comGrInOrderDrawBuffer::Draw* GrInOrderDrawBuffer::recordDraw() {
868a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    fCmds.push_back(kDraw_Cmd);
869a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    return &fDraws.push_back();
870a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com}
871a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com
872ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.comGrInOrderDrawBuffer::StencilPath* GrInOrderDrawBuffer::recordStencilPath() {
873ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    fCmds.push_back(kStencilPath_Cmd);
874ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com    return &fStencilPaths.push_back();
875ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com}
876ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com
877a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.comGrInOrderDrawBuffer::Clear* GrInOrderDrawBuffer::recordClear() {
878a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    fCmds.push_back(kClear_Cmd);
879a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com    return &fClears.push_back();
88086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com}
881d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
882beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.comvoid GrInOrderDrawBuffer::clipWillBeSet(const GrClipData* newClipData) {
883beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.com    INHERITED::clipWillBeSet(newClipData);
88486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    fClipSet = true;
885ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
886