GrInOrderDrawBuffer.cpp revision 471d471dcd7422e5dd9c822c1092b2ba4721dcfe
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
10ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
11ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#include "GrInOrderDrawBuffer.h"
12ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#include "GrTexture.h"
131c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com#include "GrBufferAllocPool.h"
1486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com#include "GrIndexBuffer.h"
1586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com#include "GrVertexBuffer.h"
16ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#include "GrGpu.h"
17ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
18471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.comGrInOrderDrawBuffer::GrInOrderDrawBuffer(const GrGpu* gpu,
19471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com                                         GrVertexBufferAllocPool* vertexPool,
2025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                         GrIndexBufferAllocPool* indexPool)
21471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com    : fGpu(gpu)
22471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com    , fDraws(&fDrawStorage)
2325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    , fStates(&fStateStorage)
2425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    , fClears(&fClearStorage)
2525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    , fClips(&fClipStorage)
2625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    , fClipSet(true)
2725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
2825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    , fLastRectVertexLayout(0)
2925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    , fQuadIndexBuffer(NULL)
3025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    , fMaxQuads(0)
3125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    , fCurrQuad(0)
3225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
3325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    , fVertexPool(*vertexPool)
3425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    , fIndexPool(*indexPool)
3525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    , fGeoPoolStateStack(&fGeoStackStorage) {
3625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
371c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    GrAssert(NULL != vertexPool);
381c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    GrAssert(NULL != indexPool);
3925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
40471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com    gpu->ref();
41471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com
4225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
4325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fUsedPoolVertexBytes = 0;
4425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fUsedPoolIndexBytes = 0;
4525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#if GR_DEBUG
4625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0;
4725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fPoolStartVertex = ~0;
4825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0;
4925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fPoolStartIndex = ~0;
5025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#endif
51ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
52ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
53ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrInOrderDrawBuffer::~GrInOrderDrawBuffer() {
5486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    this->reset();
5586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    GrSafeUnref(fQuadIndexBuffer);
56471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com    fGpu->unref();
57ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
58ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
59ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrInOrderDrawBuffer::initializeDrawStateAndClip(const GrDrawTarget& target) {
60ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    this->copyDrawState(target);
61ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    this->setClip(target.getClip());
62ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
63ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
6486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.comvoid GrInOrderDrawBuffer::setQuadIndexBuffer(const GrIndexBuffer* indexBuffer) {
6586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    bool newIdxBuffer = fQuadIndexBuffer != indexBuffer;
6686afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    if (newIdxBuffer) {
6786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        GrSafeUnref(fQuadIndexBuffer);
6886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        fQuadIndexBuffer = indexBuffer;
6986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        GrSafeRef(fQuadIndexBuffer);
7086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        fCurrQuad = 0;
7186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        fMaxQuads = (NULL == indexBuffer) ? 0 : indexBuffer->maxQuads();
7286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    } else {
73d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com        GrAssert((NULL == indexBuffer && 0 == fMaxQuads) ||
7486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                 (indexBuffer->maxQuads() == fMaxQuads));
7586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    }
7686afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com}
7786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
78d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.comvoid GrInOrderDrawBuffer::drawRect(const GrRect& rect,
7986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                                   const GrMatrix* matrix,
80ffca400ef6f96a280c3e2c09210f950af64a1f24bsalomon@google.com                                   StageBitfield stageEnableBitfield,
8186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                                   const GrRect* srcRects[],
8286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                                   const GrMatrix* srcMatrices[]) {
83d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
8486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    GrAssert(!(NULL == fQuadIndexBuffer && fCurrQuad));
8586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    GrAssert(!(fDraws.empty() && fCurrQuad));
8686afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    GrAssert(!(0 != fMaxQuads && NULL == fQuadIndexBuffer));
8786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@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;
93ffca400ef6f96a280c3e2c09210f950af64a1f24bsalomon@google.com        GrVertexLayout layout = GetRectVertexLayout(stageEnableBitfield, 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        }
9986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        AutoViewMatrixRestore avmr(this);
10086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        GrMatrix combinedMatrix = this->getViewMatrix();
10186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        this->setViewMatrix(GrMatrix::I());
10286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        if (NULL != matrix) {
10386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            combinedMatrix.preConcat(*matrix);
10486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        }
10586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
10686afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        SetRectVertices(rect, &combinedMatrix, srcRects, srcMatrices, layout, geo.vertices());
10786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
10886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        // we don't want to miss an opportunity to batch rects together
10986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        // simply because the clip has changed if the clip doesn't affect
11086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        // the rect.
11186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        bool disabledClip = false;
11286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        if (this->isClipState() && fClip.isRect()) {
113d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
1140b50b2ed462505c452de8b6d978c4e522e0f9fe1bsalomon@google.com            GrRect clipRect = fClip.getRect(0);
11586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            // If the clip rect touches the edge of the viewport, extended it
11686afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            // out (close) to infinity to avoid bogus intersections.
117d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com            // We might consider a more exact clip to viewport if this
11886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            // conservative test fails.
11986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            const GrRenderTarget* target = this->getRenderTarget();
12086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            if (0 >= clipRect.fLeft) {
12186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                clipRect.fLeft = GR_ScalarMin;
12286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            }
12386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            if (target->width() <= clipRect.fRight) {
12486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                clipRect.fRight = GR_ScalarMax;
12586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            }
12686afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            if (0 >= clipRect.top()) {
12786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                clipRect.fTop = GR_ScalarMin;
12886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            }
12986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            if (target->height() <= clipRect.fBottom) {
13086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                clipRect.fBottom = GR_ScalarMax;
13186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            }
13286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            int stride = VertexSize(layout);
13386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            bool insideClip = true;
13486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            for (int v = 0; v < 4; ++v) {
13586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                const GrPoint& p = *GetVertexPoint(geo.vertices(), v, stride);
13686afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                if (!clipRect.contains(p)) {
13786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                    insideClip = false;
13886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                    break;
13986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                }
14086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            }
14186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            if (insideClip) {
14286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                this->disableState(kClip_StateBit);
14386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                disabledClip = true;
14486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            }
14586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        }
146d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com        if (!needsNewClip() && !needsNewState() && fCurrQuad > 0 &&
14786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            fCurrQuad < fMaxQuads && layout == fLastRectVertexLayout) {
14886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
14986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            int vsize = VertexSize(layout);
150d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
15186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            Draw& lastDraw = fDraws.back();
15286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
15386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            GrAssert(lastDraw.fIndexBuffer == fQuadIndexBuffer);
15486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            GrAssert(kTriangles_PrimitiveType == lastDraw.fPrimitiveType);
15586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            GrAssert(0 == lastDraw.fVertexCount % 4);
15686afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            GrAssert(0 == lastDraw.fIndexCount % 6);
15786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            GrAssert(0 == lastDraw.fStartIndex);
15886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
15925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            GeometryPoolState& poolState = fGeoPoolStateStack.back();
1606aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com            bool clearSinceLastDraw =
1616aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com                            fClears.count() &&
1626aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com                            fClears.back().fBeforeDrawIdx == fDraws.count();
1636aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com
16425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            appendToPreviousDraw =
16525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                !clearSinceLastDraw &&
16625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                lastDraw.fVertexBuffer == poolState.fPoolVertexBuffer &&
16725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                (fCurrQuad * 4 + lastDraw.fStartVertex) == poolState.fPoolStartVertex;
16825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
16986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            if (appendToPreviousDraw) {
17086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                lastDraw.fVertexCount += 4;
17186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                lastDraw.fIndexCount += 6;
17286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com                fCurrQuad += 1;
17325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                // we reserved above, so we should be the first
17425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                // use of this vertex reserveation.
17525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                GrAssert(0 == poolState.fUsedPoolVertexBytes);
17625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                poolState.fUsedPoolVertexBytes = 4 * vsize;
17786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            }
17886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        }
17986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        if (!appendToPreviousDraw) {
18086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            this->setIndexSourceToBuffer(fQuadIndexBuffer);
18186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            drawIndexed(kTriangles_PrimitiveType, 0, 0, 4, 6);
18286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            fCurrQuad = 1;
18386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            fLastRectVertexLayout = layout;
18486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        }
18586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        if (disabledClip) {
18686afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com            this->enableState(kClip_StateBit);
18786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        }
18886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    } else {
189ffca400ef6f96a280c3e2c09210f950af64a1f24bsalomon@google.com        INHERITED::drawRect(rect, matrix, stageEnableBitfield, srcRects, srcMatrices);
19086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    }
19186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com}
19286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
19325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrInOrderDrawBuffer::onDrawIndexed(GrPrimitiveType primitiveType,
19425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                        int startVertex,
19525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                        int startIndex,
19625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                        int vertexCount,
19725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                        int indexCount) {
198ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
199ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    if (!vertexCount || !indexCount) {
200ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        return;
201ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
202ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
20386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    fCurrQuad = 0;
20486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
20525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometryPoolState& poolState = fGeoPoolStateStack.back();
20625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
207ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    Draw& draw = fDraws.push_back();
2081c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    draw.fPrimitiveType = primitiveType;
209ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    draw.fStartVertex   = startVertex;
210ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    draw.fStartIndex    = startIndex;
211ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    draw.fVertexCount   = vertexCount;
212ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    draw.fIndexCount    = indexCount;
21386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
21486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    draw.fClipChanged = this->needsNewClip();
21586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    if (draw.fClipChanged) {
21686afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com       this->pushClip();
21786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    }
21886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
21986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    draw.fStateChanged = this->needsNewState();
22086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    if (draw.fStateChanged) {
22186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        this->pushState();
22286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    }
223ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
22425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    draw.fVertexLayout = this->getGeomSrc().fVertexLayout;
22525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    switch (this->getGeomSrc().fVertexSrc) {
2261c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    case kBuffer_GeometrySrcType:
22725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        draw.fVertexBuffer = this->getGeomSrc().fVertexBuffer;
228ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        break;
22925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    case kReserved_GeometrySrcType: // fallthrough
23025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    case kArray_GeometrySrcType: {
231ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        size_t vertexBytes = (vertexCount + startVertex) *
23225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                             VertexSize(this->getGeomSrc().fVertexLayout);
23325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        poolState.fUsedPoolVertexBytes =
23425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                            GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
23525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        draw.fVertexBuffer = poolState.fPoolVertexBuffer;
23625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        draw.fStartVertex += poolState.fPoolStartVertex;
237ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        break;
23825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
2391c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    default:
2401c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com        GrCrash("unknown geom src type");
241ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
24286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    draw.fVertexBuffer->ref();
243ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
24425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    switch (this->getGeomSrc().fIndexSrc) {
2451c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    case kBuffer_GeometrySrcType:
24625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        draw.fIndexBuffer = this->getGeomSrc().fIndexBuffer;
247ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        break;
24825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    case kReserved_GeometrySrcType: // fallthrough
24925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    case kArray_GeometrySrcType: {
250ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        size_t indexBytes = (indexCount + startIndex) * sizeof(uint16_t);
25125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        poolState.fUsedPoolIndexBytes =
25225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                            GrMax(poolState.fUsedPoolIndexBytes, indexBytes);
25325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        draw.fIndexBuffer = poolState.fPoolIndexBuffer;
25425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        draw.fStartIndex += poolState.fPoolStartVertex;
255ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        break;
25625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
2571c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    default:
2581c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com        GrCrash("unknown geom src type");
259ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
26086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    draw.fIndexBuffer->ref();
261ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
262ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
26325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrInOrderDrawBuffer::onDrawNonIndexed(GrPrimitiveType primitiveType,
26425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                           int startVertex,
26525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                           int vertexCount) {
266ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    if (!vertexCount) {
267ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        return;
268ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
269ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
27086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    fCurrQuad = 0;
27186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
27225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometryPoolState& poolState = fGeoPoolStateStack.back();
27325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
274ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    Draw& draw = fDraws.push_back();
2751c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    draw.fPrimitiveType = primitiveType;
276ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    draw.fStartVertex   = startVertex;
277ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    draw.fStartIndex    = 0;
278ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    draw.fVertexCount   = vertexCount;
279ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    draw.fIndexCount    = 0;
280ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
28186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    draw.fClipChanged = this->needsNewClip();
28286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    if (draw.fClipChanged) {
28386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        this->pushClip();
28486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    }
28586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
28686afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    draw.fStateChanged = this->needsNewState();
28786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    if (draw.fStateChanged) {
28886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        this->pushState();
28986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    }
290ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
29125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    draw.fVertexLayout = this->getGeomSrc().fVertexLayout;
29225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    switch (this->getGeomSrc().fVertexSrc) {
2931c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    case kBuffer_GeometrySrcType:
29425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        draw.fVertexBuffer = this->getGeomSrc().fVertexBuffer;
295ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        break;
29625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    case kReserved_GeometrySrcType: // fallthrough
29725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    case kArray_GeometrySrcType: {
298ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        size_t vertexBytes = (vertexCount + startVertex) *
29925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                             VertexSize(this->getGeomSrc().fVertexLayout);
30025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        poolState.fUsedPoolVertexBytes =
30125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                            GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
30225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        draw.fVertexBuffer = poolState.fPoolVertexBuffer;
30325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        draw.fStartVertex += poolState.fPoolStartVertex;
304ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        break;
30525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
3061c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    default:
3071c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com        GrCrash("unknown geom src type");
308ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
30986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    draw.fVertexBuffer->ref();
31086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    draw.fIndexBuffer = NULL;
311ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
312ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
3136aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.comvoid GrInOrderDrawBuffer::clear(const GrIRect* rect, GrColor color) {
3146aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com    GrIRect r;
3156aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com    if (NULL == rect) {
3166aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com        // We could do something smart and remove previous draws and clears to
3176aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com        // the current render target. If we get that smart we have to make sure
3186aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com        // those draws aren't read before this clear (render-to-texture).
3196aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com        r.setLTRB(0, 0,
3206aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com                  this->getRenderTarget()->width(),
3216aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com                  this->getRenderTarget()->height());
3226aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com        rect = &r;
3236aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com    }
3240b335c1ac100aeacf79a4c98a052286fd46661e7bsalomon@google.com    Clear& clr = fClears.push_back();
3250b335c1ac100aeacf79a4c98a052286fd46661e7bsalomon@google.com    clr.fColor = color;
3260b335c1ac100aeacf79a4c98a052286fd46661e7bsalomon@google.com    clr.fBeforeDrawIdx = fDraws.count();
3276aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com    clr.fRect = *rect;
3280b335c1ac100aeacf79a4c98a052286fd46661e7bsalomon@google.com}
3290b335c1ac100aeacf79a4c98a052286fd46661e7bsalomon@google.com
330ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrInOrderDrawBuffer::reset() {
33125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(1 == fGeoPoolStateStack.count());
33225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    this->resetVertexSource();
33325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    this->resetIndexSource();
334ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    uint32_t numStates = fStates.count();
335ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    for (uint32_t i = 0; i < numStates; ++i) {
3361da0746fa155cdca982ae8deb68cc64f540c92dfbsalomon@google.com        const DrState& dstate = this->accessSavedDrawState(fStates[i]);
3378531c1cea2a9cf7702ef314ccd0a6cd1dd33c76cbsalomon@google.com        for (int s = 0; s < kNumStages; ++s) {
3381da0746fa155cdca982ae8deb68cc64f540c92dfbsalomon@google.com            GrSafeUnref(dstate.fTextures[s]);
339ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        }
3401da0746fa155cdca982ae8deb68cc64f540c92dfbsalomon@google.com        GrSafeUnref(dstate.fRenderTarget);
341ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
34286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    int numDraws = fDraws.count();
34386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    for (int d = 0; d < numDraws; ++d) {
34486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        // we always have a VB, but not always an IB
34586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        GrAssert(NULL != fDraws[d].fVertexBuffer);
34686afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        fDraws[d].fVertexBuffer->unref();
34786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        GrSafeUnref(fDraws[d].fIndexBuffer);
34886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    }
349ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fDraws.reset();
350ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fStates.reset();
3511c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com
3520b335c1ac100aeacf79a4c98a052286fd46661e7bsalomon@google.com    fClears.reset();
3530b335c1ac100aeacf79a4c98a052286fd46661e7bsalomon@google.com
3541c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    fVertexPool.reset();
3551c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    fIndexPool.reset();
3561c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com
357ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fClips.reset();
35886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com
35986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    fCurrQuad = 0;
360ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
361ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
362ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrInOrderDrawBuffer::playback(GrDrawTarget* target) {
36325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fVertexSrc);
36425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fIndexSrc);
365ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    GrAssert(NULL != target);
366ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    GrAssert(target != this); // not considered and why?
367ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
368898d9e5dc677ae69b701b4fb6bab77ab10002cefbsalomon@google.com    int numDraws = fDraws.count();
369ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    if (!numDraws) {
370ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        return;
371ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
372ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
3731c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    fVertexPool.unlock();
3741c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    fIndexPool.unlock();
375ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
376ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    GrDrawTarget::AutoStateRestore asr(target);
377ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    GrDrawTarget::AutoClipRestore acr(target);
37825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    AutoGeometryPush agp(target);
379ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
3806a77cc5dde4bc01a0a9ba9ac32140146247d113fbsalomon@google.com    int currState = ~0;
3816a77cc5dde4bc01a0a9ba9ac32140146247d113fbsalomon@google.com    int currClip  = ~0;
3826a77cc5dde4bc01a0a9ba9ac32140146247d113fbsalomon@google.com    int currClear = 0;
383ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
384898d9e5dc677ae69b701b4fb6bab77ab10002cefbsalomon@google.com    for (int i = 0; i < numDraws; ++i) {
3850b335c1ac100aeacf79a4c98a052286fd46661e7bsalomon@google.com        while (currClear < fClears.count() &&
3860b335c1ac100aeacf79a4c98a052286fd46661e7bsalomon@google.com               i == fClears[currClear].fBeforeDrawIdx) {
3876aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com            target->clear(&fClears[currClear].fRect, fClears[currClear].fColor);
3880b335c1ac100aeacf79a4c98a052286fd46661e7bsalomon@google.com            ++currClear;
3890b335c1ac100aeacf79a4c98a052286fd46661e7bsalomon@google.com        }
3900b335c1ac100aeacf79a4c98a052286fd46661e7bsalomon@google.com
391ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        const Draw& draw = fDraws[i];
3921c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com        if (draw.fStateChanged) {
393ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com            ++currState;
394ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com            target->restoreDrawState(fStates[currState]);
395ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        }
396ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        if (draw.fClipChanged) {
397ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com            ++currClip;
398ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com            target->setClip(fClips[currClip]);
399ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        }
4001c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com
4011c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com        target->setVertexSourceToBuffer(draw.fVertexLayout, draw.fVertexBuffer);
4021c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com
4031c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com        if (draw.fIndexCount) {
4041c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com            target->setIndexSourceToBuffer(draw.fIndexBuffer);
405ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        }
4061c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com
407ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        if (draw.fIndexCount) {
4081c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com            target->drawIndexed(draw.fPrimitiveType,
409ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com                                draw.fStartVertex,
410ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com                                draw.fStartIndex,
411ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com                                draw.fVertexCount,
412ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com                                draw.fIndexCount);
413ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        } else {
4141c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com            target->drawNonIndexed(draw.fPrimitiveType,
415ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com                                   draw.fStartVertex,
416ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com                                   draw.fVertexCount);
417ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        }
418ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
4190b335c1ac100aeacf79a4c98a052286fd46661e7bsalomon@google.com    while (currClear < fClears.count()) {
4200b335c1ac100aeacf79a4c98a052286fd46661e7bsalomon@google.com        GrAssert(fDraws.count() == fClears[currClear].fBeforeDrawIdx);
4216aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com        target->clear(&fClears[currClear].fRect, fClears[currClear].fColor);
4220b335c1ac100aeacf79a4c98a052286fd46661e7bsalomon@google.com        ++currClear;
4230b335c1ac100aeacf79a4c98a052286fd46661e7bsalomon@google.com    }
424ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
425ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
426ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.combool GrInOrderDrawBuffer::geometryHints(GrVertexLayout vertexLayout,
4271c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com                                        int* vertexCount,
4281c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com                                        int* indexCount) const {
4291c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    // we will recommend a flush if the data could fit in a single
4301c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    // preallocated buffer but none are left and it can't fit
4311c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    // in the current buffer (which may not be prealloced).
432ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    bool flush = false;
433ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    if (NULL != indexCount) {
4341c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com        int32_t currIndices = fIndexPool.currentBufferIndices();
4351c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com        if (*indexCount > currIndices &&
4361c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com            (!fIndexPool.preallocatedBuffersRemaining() &&
4371c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com             *indexCount <= fIndexPool.preallocatedBufferIndices())) {
4381c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com
4391c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com            flush = true;
4401c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com        }
4411c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com        *indexCount = currIndices;
442ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
443ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    if (NULL != vertexCount) {
4441c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com        int32_t currVertices = fVertexPool.currentBufferVertices(vertexLayout);
4451c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com        if (*vertexCount > currVertices &&
4461c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com            (!fVertexPool.preallocatedBuffersRemaining() &&
4471c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com             *vertexCount <= fVertexPool.preallocatedBufferVertices(vertexLayout))) {
4481c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com
4491c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com            flush = true;
450ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        }
4511c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com        *vertexCount = currVertices;
452ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
453ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    return flush;
454ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
455ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
45625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.combool GrInOrderDrawBuffer::onReserveVertexSpace(GrVertexLayout vertexLayout,
45725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                               int vertexCount,
45825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                               void** vertices) {
45925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometryPoolState& poolState = fGeoPoolStateStack.back();
46025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(vertexCount > 0);
46125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(NULL != vertices);
46225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(0 == poolState.fUsedPoolVertexBytes);
46325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
46425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    *vertices = fVertexPool.makeSpace(vertexLayout,
46525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                      vertexCount,
46625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                      &poolState.fPoolVertexBuffer,
46725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                      &poolState.fPoolStartVertex);
46825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    return NULL != *vertices;
46925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
47025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
47125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.combool GrInOrderDrawBuffer::onReserveIndexSpace(int indexCount, void** indices) {
47225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometryPoolState& poolState = fGeoPoolStateStack.back();
47325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(indexCount > 0);
47425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(NULL != indices);
47525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(0 == poolState.fUsedPoolIndexBytes);
47625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
47725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    *indices = fIndexPool.makeSpace(indexCount,
47825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                    &poolState.fPoolIndexBuffer,
47925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                    &poolState.fPoolStartIndex);
48025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    return NULL != *indices;
481ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
482ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
48325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrInOrderDrawBuffer::releaseReservedVertexSpace() {
48425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometryPoolState& poolState = fGeoPoolStateStack.back();
48525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    const GeometrySrcState& geoSrc = this->getGeomSrc();
48625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
48725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(kReserved_GeometrySrcType == geoSrc.fVertexSrc);
48825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
48925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    size_t reservedVertexBytes = VertexSize(geoSrc.fVertexLayout) *
49025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                 geoSrc.fVertexCount;
49125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    fVertexPool.putBack(reservedVertexBytes -
49225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                        poolState.fUsedPoolVertexBytes);
49325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fUsedPoolVertexBytes = 0;
49425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fPoolVertexBuffer = 0;
49525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
496ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
49725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrInOrderDrawBuffer::releaseReservedIndexSpace() {
49825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometryPoolState& poolState = fGeoPoolStateStack.back();
49925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    const GeometrySrcState& geoSrc = this->getGeomSrc();
5001c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com
50125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(kReserved_GeometrySrcType == geoSrc.fIndexSrc);
50225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
50325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    size_t reservedIndexBytes = sizeof(uint16_t) * geoSrc.fIndexCount;
50425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    fIndexPool.putBack(reservedIndexBytes - poolState.fUsedPoolIndexBytes);
50525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fUsedPoolIndexBytes = 0;
50625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fPoolStartVertex = 0;
5071c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com}
50825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
509bcdbbe61e1a3f89545b2c1461164f0f8bf5f0797bsalomon@google.comvoid GrInOrderDrawBuffer::onSetVertexSourceToArray(const void* vertexArray,
510bcdbbe61e1a3f89545b2c1461164f0f8bf5f0797bsalomon@google.com                                                   int vertexCount) {
51125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
51225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometryPoolState& poolState = fGeoPoolStateStack.back();
51325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(0 == poolState.fUsedPoolVertexBytes);
5141c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com#if GR_DEBUG
5151c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    bool success =
5161c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com#endif
51725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    fVertexPool.appendVertices(this->getGeomSrc().fVertexLayout,
5181c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com                               vertexCount,
5191c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com                               vertexArray,
52025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                               &poolState.fPoolVertexBuffer,
52125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                               &poolState.fPoolStartVertex);
5221c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    GR_DEBUGASSERT(success);
5231c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com}
5241c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com
525bcdbbe61e1a3f89545b2c1461164f0f8bf5f0797bsalomon@google.comvoid GrInOrderDrawBuffer::onSetIndexSourceToArray(const void* indexArray,
526bcdbbe61e1a3f89545b2c1461164f0f8bf5f0797bsalomon@google.com                                                  int indexCount) {
52725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometryPoolState& poolState = fGeoPoolStateStack.back();
52825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(0 == poolState.fUsedPoolIndexBytes);
5291c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com#if GR_DEBUG
5301c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    bool success =
5311c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com#endif
5321c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    fIndexPool.appendIndices(indexCount,
5331c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com                             indexArray,
53425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                             &poolState.fPoolIndexBuffer,
53525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                             &poolState.fPoolStartIndex);
5361c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    GR_DEBUGASSERT(success);
537ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
538ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
53925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrInOrderDrawBuffer::geometrySourceWillPush() {
54025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
54125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fUsedPoolVertexBytes = 0;
54225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fUsedPoolIndexBytes = 0;
54325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#if GR_DEBUG
54425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0;
54525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fPoolStartVertex = ~0;
54625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0;
54725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fPoolStartIndex = ~0;
54825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#endif
54925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
55025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
55125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrInOrderDrawBuffer::releaseVertexArray() {
55225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometryPoolState& poolState = fGeoPoolStateStack.back();
55325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    const GeometrySrcState& geoSrc = this->getGeomSrc();
55425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
55525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    size_t reservedVertexBytes = VertexSize(geoSrc.fVertexLayout) *
55625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    geoSrc.fVertexCount;
55725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    fVertexPool.putBack(reservedVertexBytes - poolState.fUsedPoolVertexBytes);
55825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
55925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fUsedPoolVertexBytes = 0;
56025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
56125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
56225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrInOrderDrawBuffer::releaseIndexArray() {
56325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometryPoolState& poolState = fGeoPoolStateStack.back();
56425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    const GeometrySrcState& geoSrc = this->getGeomSrc();
56525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
56625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    size_t reservedIndexBytes = sizeof(uint16_t) * geoSrc.fIndexCount;
56725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    fIndexPool.putBack(reservedIndexBytes - poolState.fUsedPoolIndexBytes);
56825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
56925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fUsedPoolIndexBytes = 0;
57025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
57125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
57225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrInOrderDrawBuffer::geometrySourceWillPop(
57325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                        const GeometrySrcState& restoredState) {
57425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GrAssert(fGeoPoolStateStack.count() > 1);
57525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    fGeoPoolStateStack.pop_back();
57625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometryPoolState& poolState = fGeoPoolStateStack.back();
57725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    // we have to assume that any slack we had in our vertex/index data
57825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    // is now unreleasable because data may have been appended later in the
57925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    // pool.
58025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    if (kReserved_GeometrySrcType == restoredState.fVertexSrc ||
58125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        kArray_GeometrySrcType == restoredState.fVertexSrc) {
58225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        poolState.fUsedPoolVertexBytes =
58325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            VertexSize(restoredState.fVertexLayout) *
58425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com            restoredState.fVertexCount;
58525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
58625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    if (kReserved_GeometrySrcType == restoredState.fIndexSrc ||
58725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        kArray_GeometrySrcType == restoredState.fIndexSrc) {
58825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        poolState.fUsedPoolVertexBytes = sizeof(uint16_t) *
58925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                         restoredState.fIndexCount;
59025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
59125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
59225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
59386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.combool GrInOrderDrawBuffer::needsNewState() const {
59486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com     if (fStates.empty()) {
59586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        return true;
59686afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com     } else {
59786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com         const DrState& old = this->accessSavedDrawState(fStates.back());
59886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        return old != fCurrDrawState;
59986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com     }
600ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
601ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
60286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.comvoid GrInOrderDrawBuffer::pushState() {
60386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    for (int s = 0; s < kNumStages; ++s) {
60486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com        GrSafeRef(fCurrDrawState.fTextures[s]);
60586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    }
6061da0746fa155cdca982ae8deb68cc64f540c92dfbsalomon@google.com    GrSafeRef(fCurrDrawState.fRenderTarget);
60786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    this->saveCurrentDrawState(&fStates.push_back());
60886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com }
609d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
61086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.combool GrInOrderDrawBuffer::needsNewClip() const {
61186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com   if (fCurrDrawState.fFlagBits & kClip_StateBit) {
61286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com       if (fClips.empty() || (fClipSet && fClips.back() != fClip)) {
61386afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com           return true;
61486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com       }
615ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
616ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    return false;
617ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
618d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
61986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.comvoid GrInOrderDrawBuffer::pushClip() {
62086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    fClips.push_back() = fClip;
62186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    fClipSet = false;
62286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com}
623d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
624dea2f8d86378b791a2de94384a18e29f13f65a3ebsalomon@google.comvoid GrInOrderDrawBuffer::clipWillBeSet(const GrClip& newClip) {
625dea2f8d86378b791a2de94384a18e29f13f65a3ebsalomon@google.com    INHERITED::clipWillBeSet(newClip);
62686afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com    fClipSet = true;
627ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
628471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com
629471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.combool GrInOrderDrawBuffer::willUseHWAALines() const {
630471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com    return fGpu->supportsHWAALines() &&
631471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com           CanUseHWAALines(this->getGeomSrc().fVertexLayout, fCurrDrawState);
632471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com}
633471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com
634