Home | History | Annotate | Download | only in gpu
      1 
      2 /*
      3  * Copyright 2011 Google Inc.
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 
     10 
     11 #include "GrInOrderDrawBuffer.h"
     12 #include "GrRenderTarget.h"
     13 #include "GrTexture.h"
     14 #include "GrBufferAllocPool.h"
     15 #include "GrIndexBuffer.h"
     16 #include "GrVertexBuffer.h"
     17 #include "GrGpu.h"
     18 
     19 GrInOrderDrawBuffer::GrInOrderDrawBuffer(const GrGpu* gpu,
     20                                          GrVertexBufferAllocPool* vertexPool,
     21                                          GrIndexBufferAllocPool* indexPool)
     22     : fClipSet(true)
     23     , fLastRectVertexLayout(0)
     24     , fQuadIndexBuffer(NULL)
     25     , fMaxQuads(0)
     26     , fCurrQuad(0)
     27     , fVertexPool(*vertexPool)
     28     , fIndexPool(*indexPool) {
     29 
     30     fCaps = gpu->getCaps();
     31 
     32     GrAssert(NULL != vertexPool);
     33     GrAssert(NULL != indexPool);
     34 
     35     GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
     36     poolState.fUsedPoolVertexBytes = 0;
     37     poolState.fUsedPoolIndexBytes = 0;
     38 #if GR_DEBUG
     39     poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0;
     40     poolState.fPoolStartVertex = ~0;
     41     poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0;
     42     poolState.fPoolStartIndex = ~0;
     43 #endif
     44 }
     45 
     46 GrInOrderDrawBuffer::~GrInOrderDrawBuffer() {
     47     this->reset();
     48     // This must be called by before the GrDrawTarget destructor
     49     this->releaseGeometry();
     50     GrSafeUnref(fQuadIndexBuffer);
     51 }
     52 
     53 void GrInOrderDrawBuffer::initializeDrawStateAndClip(const GrDrawTarget& target) {
     54     this->copyDrawState(target);
     55     this->setClip(target.getClip());
     56 }
     57 
     58 void GrInOrderDrawBuffer::setQuadIndexBuffer(const GrIndexBuffer* indexBuffer) {
     59     bool newIdxBuffer = fQuadIndexBuffer != indexBuffer;
     60     if (newIdxBuffer) {
     61         GrSafeUnref(fQuadIndexBuffer);
     62         fQuadIndexBuffer = indexBuffer;
     63         GrSafeRef(fQuadIndexBuffer);
     64         fCurrQuad = 0;
     65         fMaxQuads = (NULL == indexBuffer) ? 0 : indexBuffer->maxQuads();
     66     } else {
     67         GrAssert((NULL == indexBuffer && 0 == fMaxQuads) ||
     68                  (indexBuffer->maxQuads() == fMaxQuads));
     69     }
     70 }
     71 
     72 void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
     73                                    const GrMatrix* matrix,
     74                                    StageMask stageMask,
     75                                    const GrRect* srcRects[],
     76                                    const GrMatrix* srcMatrices[]) {
     77 
     78     GrAssert(!(NULL == fQuadIndexBuffer && fCurrQuad));
     79     GrAssert(!(fDraws.empty() && fCurrQuad));
     80     GrAssert(!(0 != fMaxQuads && NULL == fQuadIndexBuffer));
     81 
     82     GrDrawState* drawState = this->drawState();
     83 
     84     // if we have a quad IB then either append to the previous run of
     85     // rects or start a new run
     86     if (fMaxQuads) {
     87 
     88         bool appendToPreviousDraw = false;
     89         GrVertexLayout layout = GetRectVertexLayout(stageMask, srcRects);
     90         AutoReleaseGeometry geo(this, layout, 4, 0);
     91         if (!geo.succeeded()) {
     92             GrPrintf("Failed to get space for vertices!\n");
     93             return;
     94         }
     95         GrMatrix combinedMatrix = drawState->getViewMatrix();
     96         GrDrawState::AutoViewMatrixRestore avmr(drawState, GrMatrix::I());
     97         if (NULL != matrix) {
     98             combinedMatrix.preConcat(*matrix);
     99         }
    100 
    101         SetRectVertices(rect, &combinedMatrix, srcRects, srcMatrices, layout, geo.vertices());
    102 
    103         // we don't want to miss an opportunity to batch rects together
    104         // simply because the clip has changed if the clip doesn't affect
    105         // the rect.
    106         bool disabledClip = false;
    107         if (drawState->isClipState() && fClip.isRect()) {
    108 
    109             GrRect clipRect = fClip.getRect(0);
    110             // If the clip rect touches the edge of the viewport, extended it
    111             // out (close) to infinity to avoid bogus intersections.
    112             // We might consider a more exact clip to viewport if this
    113             // conservative test fails.
    114             const GrRenderTarget* target = drawState->getRenderTarget();
    115             if (0 >= clipRect.fLeft) {
    116                 clipRect.fLeft = GR_ScalarMin;
    117             }
    118             if (target->width() <= clipRect.fRight) {
    119                 clipRect.fRight = GR_ScalarMax;
    120             }
    121             if (0 >= clipRect.top()) {
    122                 clipRect.fTop = GR_ScalarMin;
    123             }
    124             if (target->height() <= clipRect.fBottom) {
    125                 clipRect.fBottom = GR_ScalarMax;
    126             }
    127             int stride = VertexSize(layout);
    128             bool insideClip = true;
    129             for (int v = 0; v < 4; ++v) {
    130                 const GrPoint& p = *GetVertexPoint(geo.vertices(), v, stride);
    131                 if (!clipRect.contains(p)) {
    132                     insideClip = false;
    133                     break;
    134                 }
    135             }
    136             if (insideClip) {
    137                 drawState->disableState(GrDrawState::kClip_StateBit);
    138                 disabledClip = true;
    139             }
    140         }
    141         if (!needsNewClip() && !needsNewState() && fCurrQuad > 0 &&
    142             fCurrQuad < fMaxQuads && layout == fLastRectVertexLayout) {
    143 
    144             int vsize = VertexSize(layout);
    145 
    146             Draw& lastDraw = fDraws.back();
    147 
    148             GrAssert(lastDraw.fIndexBuffer == fQuadIndexBuffer);
    149             GrAssert(kTriangles_PrimitiveType == lastDraw.fPrimitiveType);
    150             GrAssert(0 == lastDraw.fVertexCount % 4);
    151             GrAssert(0 == lastDraw.fIndexCount % 6);
    152             GrAssert(0 == lastDraw.fStartIndex);
    153 
    154             GeometryPoolState& poolState = fGeoPoolStateStack.back();
    155             bool clearSinceLastDraw =
    156                             fClears.count() &&
    157                             fClears.back().fBeforeDrawIdx == fDraws.count();
    158 
    159             appendToPreviousDraw =
    160                 !clearSinceLastDraw &&
    161                 lastDraw.fVertexBuffer == poolState.fPoolVertexBuffer &&
    162                 (fCurrQuad * 4 + lastDraw.fStartVertex) == poolState.fPoolStartVertex;
    163 
    164             if (appendToPreviousDraw) {
    165                 lastDraw.fVertexCount += 4;
    166                 lastDraw.fIndexCount += 6;
    167                 fCurrQuad += 1;
    168                 // we reserved above, so we should be the first
    169                 // use of this vertex reserveation.
    170                 GrAssert(0 == poolState.fUsedPoolVertexBytes);
    171                 poolState.fUsedPoolVertexBytes = 4 * vsize;
    172             }
    173         }
    174         if (!appendToPreviousDraw) {
    175             this->setIndexSourceToBuffer(fQuadIndexBuffer);
    176             drawIndexed(kTriangles_PrimitiveType, 0, 0, 4, 6);
    177             fCurrQuad = 1;
    178             fLastRectVertexLayout = layout;
    179         }
    180         if (disabledClip) {
    181             drawState->enableState(GrDrawState::kClip_StateBit);
    182         }
    183     } else {
    184         INHERITED::drawRect(rect, matrix, stageMask, srcRects, srcMatrices);
    185     }
    186 }
    187 
    188 void GrInOrderDrawBuffer::onDrawIndexed(GrPrimitiveType primitiveType,
    189                                         int startVertex,
    190                                         int startIndex,
    191                                         int vertexCount,
    192                                         int indexCount) {
    193 
    194     if (!vertexCount || !indexCount) {
    195         return;
    196     }
    197 
    198     fCurrQuad = 0;
    199 
    200     GeometryPoolState& poolState = fGeoPoolStateStack.back();
    201 
    202     Draw& draw = fDraws.push_back();
    203     draw.fPrimitiveType = primitiveType;
    204     draw.fStartVertex   = startVertex;
    205     draw.fStartIndex    = startIndex;
    206     draw.fVertexCount   = vertexCount;
    207     draw.fIndexCount    = indexCount;
    208 
    209     draw.fClipChanged = this->needsNewClip();
    210     if (draw.fClipChanged) {
    211        this->pushClip();
    212     }
    213 
    214     draw.fStateChanged = this->needsNewState();
    215     if (draw.fStateChanged) {
    216         this->pushState();
    217     }
    218 
    219     draw.fVertexLayout = this->getGeomSrc().fVertexLayout;
    220     switch (this->getGeomSrc().fVertexSrc) {
    221     case kBuffer_GeometrySrcType:
    222         draw.fVertexBuffer = this->getGeomSrc().fVertexBuffer;
    223         break;
    224     case kReserved_GeometrySrcType: // fallthrough
    225     case kArray_GeometrySrcType: {
    226         size_t vertexBytes = (vertexCount + startVertex) *
    227                              VertexSize(this->getGeomSrc().fVertexLayout);
    228         poolState.fUsedPoolVertexBytes =
    229                             GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
    230         draw.fVertexBuffer = poolState.fPoolVertexBuffer;
    231         draw.fStartVertex += poolState.fPoolStartVertex;
    232         break;
    233     }
    234     default:
    235         GrCrash("unknown geom src type");
    236     }
    237     draw.fVertexBuffer->ref();
    238 
    239     switch (this->getGeomSrc().fIndexSrc) {
    240     case kBuffer_GeometrySrcType:
    241         draw.fIndexBuffer = this->getGeomSrc().fIndexBuffer;
    242         break;
    243     case kReserved_GeometrySrcType: // fallthrough
    244     case kArray_GeometrySrcType: {
    245         size_t indexBytes = (indexCount + startIndex) * sizeof(uint16_t);
    246         poolState.fUsedPoolIndexBytes =
    247                             GrMax(poolState.fUsedPoolIndexBytes, indexBytes);
    248         draw.fIndexBuffer = poolState.fPoolIndexBuffer;
    249         draw.fStartIndex += poolState.fPoolStartIndex;
    250         break;
    251     }
    252     default:
    253         GrCrash("unknown geom src type");
    254     }
    255     draw.fIndexBuffer->ref();
    256 }
    257 
    258 void GrInOrderDrawBuffer::onDrawNonIndexed(GrPrimitiveType primitiveType,
    259                                            int startVertex,
    260                                            int vertexCount) {
    261     if (!vertexCount) {
    262         return;
    263     }
    264 
    265     fCurrQuad = 0;
    266 
    267     GeometryPoolState& poolState = fGeoPoolStateStack.back();
    268 
    269     Draw& draw = fDraws.push_back();
    270     draw.fPrimitiveType = primitiveType;
    271     draw.fStartVertex   = startVertex;
    272     draw.fStartIndex    = 0;
    273     draw.fVertexCount   = vertexCount;
    274     draw.fIndexCount    = 0;
    275 
    276     draw.fClipChanged = this->needsNewClip();
    277     if (draw.fClipChanged) {
    278         this->pushClip();
    279     }
    280 
    281     draw.fStateChanged = this->needsNewState();
    282     if (draw.fStateChanged) {
    283         this->pushState();
    284     }
    285 
    286     draw.fVertexLayout = this->getGeomSrc().fVertexLayout;
    287     switch (this->getGeomSrc().fVertexSrc) {
    288     case kBuffer_GeometrySrcType:
    289         draw.fVertexBuffer = this->getGeomSrc().fVertexBuffer;
    290         break;
    291     case kReserved_GeometrySrcType: // fallthrough
    292     case kArray_GeometrySrcType: {
    293         size_t vertexBytes = (vertexCount + startVertex) *
    294                              VertexSize(this->getGeomSrc().fVertexLayout);
    295         poolState.fUsedPoolVertexBytes =
    296                             GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
    297         draw.fVertexBuffer = poolState.fPoolVertexBuffer;
    298         draw.fStartVertex += poolState.fPoolStartVertex;
    299         break;
    300     }
    301     default:
    302         GrCrash("unknown geom src type");
    303     }
    304     draw.fVertexBuffer->ref();
    305     draw.fIndexBuffer = NULL;
    306 }
    307 
    308 void GrInOrderDrawBuffer::clear(const GrIRect* rect, GrColor color) {
    309     GrIRect r;
    310     if (NULL == rect) {
    311         // We could do something smart and remove previous draws and clears to
    312         // the current render target. If we get that smart we have to make sure
    313         // those draws aren't read before this clear (render-to-texture).
    314         r.setLTRB(0, 0,
    315                   this->getDrawState().getRenderTarget()->width(),
    316                   this->getDrawState().getRenderTarget()->height());
    317         rect = &r;
    318     }
    319     Clear& clr = fClears.push_back();
    320     clr.fColor = color;
    321     clr.fBeforeDrawIdx = fDraws.count();
    322     clr.fRect = *rect;
    323 }
    324 
    325 void GrInOrderDrawBuffer::reset() {
    326     GrAssert(1 == fGeoPoolStateStack.count());
    327     this->resetVertexSource();
    328     this->resetIndexSource();
    329     uint32_t numStates = fStates.count();
    330     for (uint32_t i = 0; i < numStates; ++i) {
    331         const GrDrawState& dstate = this->accessSavedDrawState(fStates[i]);
    332         for (int s = 0; s < GrDrawState::kNumStages; ++s) {
    333             GrSafeUnref(dstate.getTexture(s));
    334         }
    335         GrSafeUnref(dstate.getRenderTarget());
    336     }
    337     int numDraws = fDraws.count();
    338     for (int d = 0; d < numDraws; ++d) {
    339         // we always have a VB, but not always an IB
    340         GrAssert(NULL != fDraws[d].fVertexBuffer);
    341         fDraws[d].fVertexBuffer->unref();
    342         GrSafeUnref(fDraws[d].fIndexBuffer);
    343     }
    344     fDraws.reset();
    345     fStates.reset();
    346 
    347     fClears.reset();
    348 
    349     fVertexPool.reset();
    350     fIndexPool.reset();
    351 
    352     fClips.reset();
    353 
    354     fCurrQuad = 0;
    355 }
    356 
    357 void GrInOrderDrawBuffer::playback(GrDrawTarget* target) {
    358     GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fVertexSrc);
    359     GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fIndexSrc);
    360     GrAssert(NULL != target);
    361     GrAssert(target != this); // not considered and why?
    362 
    363     int numDraws = fDraws.count();
    364     if (!numDraws) {
    365         return;
    366     }
    367 
    368     fVertexPool.unlock();
    369     fIndexPool.unlock();
    370 
    371     GrDrawTarget::AutoStateRestore asr(target);
    372     GrDrawTarget::AutoClipRestore acr(target);
    373     AutoGeometryPush agp(target);
    374 
    375     int currState = ~0;
    376     int currClip  = ~0;
    377     int currClear = 0;
    378 
    379     for (int i = 0; i < numDraws; ++i) {
    380         while (currClear < fClears.count() &&
    381                i == fClears[currClear].fBeforeDrawIdx) {
    382             target->clear(&fClears[currClear].fRect, fClears[currClear].fColor);
    383             ++currClear;
    384         }
    385 
    386         const Draw& draw = fDraws[i];
    387         if (draw.fStateChanged) {
    388             ++currState;
    389             target->restoreDrawState(fStates[currState]);
    390         }
    391         if (draw.fClipChanged) {
    392             ++currClip;
    393             target->setClip(fClips[currClip]);
    394         }
    395 
    396         target->setVertexSourceToBuffer(draw.fVertexLayout, draw.fVertexBuffer);
    397 
    398         if (draw.fIndexCount) {
    399             target->setIndexSourceToBuffer(draw.fIndexBuffer);
    400         }
    401 
    402         if (draw.fIndexCount) {
    403             target->drawIndexed(draw.fPrimitiveType,
    404                                 draw.fStartVertex,
    405                                 draw.fStartIndex,
    406                                 draw.fVertexCount,
    407                                 draw.fIndexCount);
    408         } else {
    409             target->drawNonIndexed(draw.fPrimitiveType,
    410                                    draw.fStartVertex,
    411                                    draw.fVertexCount);
    412         }
    413     }
    414     while (currClear < fClears.count()) {
    415         GrAssert(fDraws.count() == fClears[currClear].fBeforeDrawIdx);
    416         target->clear(&fClears[currClear].fRect, fClears[currClear].fColor);
    417         ++currClear;
    418     }
    419 }
    420 
    421 bool GrInOrderDrawBuffer::geometryHints(GrVertexLayout vertexLayout,
    422                                         int* vertexCount,
    423                                         int* indexCount) const {
    424     // we will recommend a flush if the data could fit in a single
    425     // preallocated buffer but none are left and it can't fit
    426     // in the current buffer (which may not be prealloced).
    427     bool flush = false;
    428     if (NULL != indexCount) {
    429         int32_t currIndices = fIndexPool.currentBufferIndices();
    430         if (*indexCount > currIndices &&
    431             (!fIndexPool.preallocatedBuffersRemaining() &&
    432              *indexCount <= fIndexPool.preallocatedBufferIndices())) {
    433 
    434             flush = true;
    435         }
    436         *indexCount = currIndices;
    437     }
    438     if (NULL != vertexCount) {
    439         int32_t currVertices = fVertexPool.currentBufferVertices(vertexLayout);
    440         if (*vertexCount > currVertices &&
    441             (!fVertexPool.preallocatedBuffersRemaining() &&
    442              *vertexCount <= fVertexPool.preallocatedBufferVertices(vertexLayout))) {
    443 
    444             flush = true;
    445         }
    446         *vertexCount = currVertices;
    447     }
    448     return flush;
    449 }
    450 
    451 bool GrInOrderDrawBuffer::onReserveVertexSpace(GrVertexLayout vertexLayout,
    452                                                int vertexCount,
    453                                                void** vertices) {
    454     GeometryPoolState& poolState = fGeoPoolStateStack.back();
    455     GrAssert(vertexCount > 0);
    456     GrAssert(NULL != vertices);
    457     GrAssert(0 == poolState.fUsedPoolVertexBytes);
    458 
    459     *vertices = fVertexPool.makeSpace(vertexLayout,
    460                                       vertexCount,
    461                                       &poolState.fPoolVertexBuffer,
    462                                       &poolState.fPoolStartVertex);
    463     return NULL != *vertices;
    464 }
    465 
    466 bool GrInOrderDrawBuffer::onReserveIndexSpace(int indexCount, void** indices) {
    467     GeometryPoolState& poolState = fGeoPoolStateStack.back();
    468     GrAssert(indexCount > 0);
    469     GrAssert(NULL != indices);
    470     GrAssert(0 == poolState.fUsedPoolIndexBytes);
    471 
    472     *indices = fIndexPool.makeSpace(indexCount,
    473                                     &poolState.fPoolIndexBuffer,
    474                                     &poolState.fPoolStartIndex);
    475     return NULL != *indices;
    476 }
    477 
    478 void GrInOrderDrawBuffer::releaseReservedVertexSpace() {
    479     GeometryPoolState& poolState = fGeoPoolStateStack.back();
    480     const GeometrySrcState& geoSrc = this->getGeomSrc();
    481 
    482     GrAssert(kReserved_GeometrySrcType == geoSrc.fVertexSrc);
    483 
    484     size_t reservedVertexBytes = VertexSize(geoSrc.fVertexLayout) *
    485                                  geoSrc.fVertexCount;
    486     fVertexPool.putBack(reservedVertexBytes -
    487                         poolState.fUsedPoolVertexBytes);
    488     poolState.fUsedPoolVertexBytes = 0;
    489     poolState.fPoolVertexBuffer = 0;
    490 }
    491 
    492 void GrInOrderDrawBuffer::releaseReservedIndexSpace() {
    493     GeometryPoolState& poolState = fGeoPoolStateStack.back();
    494     const GeometrySrcState& geoSrc = this->getGeomSrc();
    495 
    496     GrAssert(kReserved_GeometrySrcType == geoSrc.fIndexSrc);
    497 
    498     size_t reservedIndexBytes = sizeof(uint16_t) * geoSrc.fIndexCount;
    499     fIndexPool.putBack(reservedIndexBytes - poolState.fUsedPoolIndexBytes);
    500     poolState.fUsedPoolIndexBytes = 0;
    501     poolState.fPoolStartVertex = 0;
    502 }
    503 
    504 void GrInOrderDrawBuffer::onSetVertexSourceToArray(const void* vertexArray,
    505                                                    int vertexCount) {
    506 
    507     GeometryPoolState& poolState = fGeoPoolStateStack.back();
    508     GrAssert(0 == poolState.fUsedPoolVertexBytes);
    509 #if GR_DEBUG
    510     bool success =
    511 #endif
    512     fVertexPool.appendVertices(this->getGeomSrc().fVertexLayout,
    513                                vertexCount,
    514                                vertexArray,
    515                                &poolState.fPoolVertexBuffer,
    516                                &poolState.fPoolStartVertex);
    517     GR_DEBUGASSERT(success);
    518 }
    519 
    520 void GrInOrderDrawBuffer::onSetIndexSourceToArray(const void* indexArray,
    521                                                   int indexCount) {
    522     GeometryPoolState& poolState = fGeoPoolStateStack.back();
    523     GrAssert(0 == poolState.fUsedPoolIndexBytes);
    524 #if GR_DEBUG
    525     bool success =
    526 #endif
    527     fIndexPool.appendIndices(indexCount,
    528                              indexArray,
    529                              &poolState.fPoolIndexBuffer,
    530                              &poolState.fPoolStartIndex);
    531     GR_DEBUGASSERT(success);
    532 }
    533 
    534 void GrInOrderDrawBuffer::geometrySourceWillPush() {
    535     GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
    536     poolState.fUsedPoolVertexBytes = 0;
    537     poolState.fUsedPoolIndexBytes = 0;
    538 #if GR_DEBUG
    539     poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0;
    540     poolState.fPoolStartVertex = ~0;
    541     poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0;
    542     poolState.fPoolStartIndex = ~0;
    543 #endif
    544 }
    545 
    546 void GrInOrderDrawBuffer::releaseVertexArray() {
    547     GeometryPoolState& poolState = fGeoPoolStateStack.back();
    548     const GeometrySrcState& geoSrc = this->getGeomSrc();
    549 
    550     size_t reservedVertexBytes = VertexSize(geoSrc.fVertexLayout) *
    551     geoSrc.fVertexCount;
    552     fVertexPool.putBack(reservedVertexBytes - poolState.fUsedPoolVertexBytes);
    553 
    554     poolState.fUsedPoolVertexBytes = 0;
    555 }
    556 
    557 void GrInOrderDrawBuffer::releaseIndexArray() {
    558     GeometryPoolState& poolState = fGeoPoolStateStack.back();
    559     const GeometrySrcState& geoSrc = this->getGeomSrc();
    560 
    561     size_t reservedIndexBytes = sizeof(uint16_t) * geoSrc.fIndexCount;
    562     fIndexPool.putBack(reservedIndexBytes - poolState.fUsedPoolIndexBytes);
    563 
    564     poolState.fUsedPoolIndexBytes = 0;
    565 }
    566 
    567 void GrInOrderDrawBuffer::geometrySourceWillPop(
    568                                         const GeometrySrcState& restoredState) {
    569     GrAssert(fGeoPoolStateStack.count() > 1);
    570     fGeoPoolStateStack.pop_back();
    571     GeometryPoolState& poolState = fGeoPoolStateStack.back();
    572     // we have to assume that any slack we had in our vertex/index data
    573     // is now unreleasable because data may have been appended later in the
    574     // pool.
    575     if (kReserved_GeometrySrcType == restoredState.fVertexSrc ||
    576         kArray_GeometrySrcType == restoredState.fVertexSrc) {
    577         poolState.fUsedPoolVertexBytes =
    578             VertexSize(restoredState.fVertexLayout) *
    579             restoredState.fVertexCount;
    580     }
    581     if (kReserved_GeometrySrcType == restoredState.fIndexSrc ||
    582         kArray_GeometrySrcType == restoredState.fIndexSrc) {
    583         poolState.fUsedPoolVertexBytes = sizeof(uint16_t) *
    584                                          restoredState.fIndexCount;
    585     }
    586 }
    587 
    588 bool GrInOrderDrawBuffer::needsNewState() const {
    589      if (fStates.empty()) {
    590         return true;
    591      } else {
    592         const GrDrawState& old = this->accessSavedDrawState(fStates.back());
    593         return old != fCurrDrawState;
    594      }
    595 }
    596 
    597 void GrInOrderDrawBuffer::pushState() {
    598     const GrDrawState& drawState = this->getDrawState();
    599     for (int s = 0; s < GrDrawState::kNumStages; ++s) {
    600         GrSafeRef(drawState.getTexture(s));
    601     }
    602     GrSafeRef(drawState.getRenderTarget());
    603     this->saveCurrentDrawState(&fStates.push_back());
    604  }
    605 
    606 bool GrInOrderDrawBuffer::needsNewClip() const {
    607    if (this->getDrawState().isClipState()) {
    608        if (fClips.empty() || (fClipSet && fClips.back() != fClip)) {
    609            return true;
    610        }
    611     }
    612     return false;
    613 }
    614 
    615 void GrInOrderDrawBuffer::pushClip() {
    616     fClips.push_back() = fClip;
    617     fClipSet = false;
    618 }
    619 
    620 void GrInOrderDrawBuffer::clipWillBeSet(const GrClip& newClip) {
    621     INHERITED::clipWillBeSet(newClip);
    622     fClipSet = true;
    623 }
    624