• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
GrInOrderDrawBuffer(const GrGpu * gpu,GrVertexBufferAllocPool * vertexPool,GrIndexBufferAllocPool * indexPool)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 
~GrInOrderDrawBuffer()46 GrInOrderDrawBuffer::~GrInOrderDrawBuffer() {
47     this->reset();
48     // This must be called by before the GrDrawTarget destructor
49     this->releaseGeometry();
50     GrSafeUnref(fQuadIndexBuffer);
51 }
52 
initializeDrawStateAndClip(const GrDrawTarget & target)53 void GrInOrderDrawBuffer::initializeDrawStateAndClip(const GrDrawTarget& target) {
54     this->copyDrawState(target);
55     this->setClip(target.getClip());
56 }
57 
setQuadIndexBuffer(const GrIndexBuffer * indexBuffer)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 
drawRect(const GrRect & rect,const GrMatrix * matrix,StageMask stageMask,const GrRect * srcRects[],const GrMatrix * srcMatrices[])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 
onDrawIndexed(GrPrimitiveType primitiveType,int startVertex,int startIndex,int vertexCount,int indexCount)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 
onDrawNonIndexed(GrPrimitiveType primitiveType,int startVertex,int vertexCount)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 
clear(const GrIRect * rect,GrColor color)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 
reset()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 
playback(GrDrawTarget * target)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 
geometryHints(GrVertexLayout vertexLayout,int * vertexCount,int * indexCount) const421 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 
onReserveVertexSpace(GrVertexLayout vertexLayout,int vertexCount,void ** vertices)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 
onReserveIndexSpace(int indexCount,void ** indices)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 
releaseReservedVertexSpace()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 
releaseReservedIndexSpace()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 
onSetVertexSourceToArray(const void * vertexArray,int vertexCount)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 
onSetIndexSourceToArray(const void * indexArray,int indexCount)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 
geometrySourceWillPush()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 
releaseVertexArray()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 
releaseIndexArray()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 
geometrySourceWillPop(const GeometrySrcState & restoredState)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 
needsNewState() const588 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 
pushState()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 
needsNewClip() const606 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 
pushClip()615 void GrInOrderDrawBuffer::pushClip() {
616     fClips.push_back() = fClip;
617     fClipSet = false;
618 }
619 
clipWillBeSet(const GrClip & newClip)620 void GrInOrderDrawBuffer::clipWillBeSet(const GrClip& newClip) {
621     INHERITED::clipWillBeSet(newClip);
622     fClipSet = true;
623 }
624