blob: e6b3ca8c43ecd2a1aa9471589b426e3f2139ad9b [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
reed@google.comac10a2d2010-12-22 21:39:39 +00002/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00003 * 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.
reed@google.comac10a2d2010-12-22 21:39:39 +00007 */
8
9
10#include "GrInOrderDrawBuffer.h"
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +000011#include "GrRenderTarget.h"
reed@google.comac10a2d2010-12-22 21:39:39 +000012#include "GrTexture.h"
bsalomon@google.com1c13c962011-02-14 16:51:21 +000013#include "GrBufferAllocPool.h"
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000014#include "GrIndexBuffer.h"
15#include "GrVertexBuffer.h"
reed@google.comac10a2d2010-12-22 21:39:39 +000016#include "GrGpu.h"
17
bsalomon@google.com471d4712011-08-23 15:45:25 +000018GrInOrderDrawBuffer::GrInOrderDrawBuffer(const GrGpu* gpu,
19 GrVertexBufferAllocPool* vertexPool,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000020 GrIndexBufferAllocPool* indexPool)
bsalomon@google.com97805382012-03-13 14:32:07 +000021 : fAutoFlushTarget(NULL)
22 , fClipSet(true)
robertphillips@google.com69705572012-03-21 19:46:50 +000023 , fVertexPool(*vertexPool)
24 , fIndexPool(*indexPool)
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000025 , fLastRectVertexLayout(0)
26 , fQuadIndexBuffer(NULL)
27 , fMaxQuads(0)
robertphillips@google.com69705572012-03-21 19:46:50 +000028 , fCurrQuad(0) {
bsalomon@google.com18c9c192011-09-22 21:01:31 +000029
30 fCaps = gpu->getCaps();
31
bsalomon@google.com1c13c962011-02-14 16:51:21 +000032 GrAssert(NULL != vertexPool);
33 GrAssert(NULL != indexPool);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000034
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
bsalomon@google.com934c5702012-03-20 21:17:58 +000044 fInstancedDrawTracker.reset();
reed@google.comac10a2d2010-12-22 21:39:39 +000045}
46
47GrInOrderDrawBuffer::~GrInOrderDrawBuffer() {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000048 this->reset();
bsalomon@google.com4a018bb2011-10-28 19:50:21 +000049 // This must be called by before the GrDrawTarget destructor
50 this->releaseGeometry();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000051 GrSafeUnref(fQuadIndexBuffer);
bsalomon@google.com97805382012-03-13 14:32:07 +000052 GrSafeUnref(fAutoFlushTarget);
reed@google.comac10a2d2010-12-22 21:39:39 +000053}
54
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000055void GrInOrderDrawBuffer::setQuadIndexBuffer(const GrIndexBuffer* indexBuffer) {
56 bool newIdxBuffer = fQuadIndexBuffer != indexBuffer;
57 if (newIdxBuffer) {
58 GrSafeUnref(fQuadIndexBuffer);
59 fQuadIndexBuffer = indexBuffer;
60 GrSafeRef(fQuadIndexBuffer);
61 fCurrQuad = 0;
62 fMaxQuads = (NULL == indexBuffer) ? 0 : indexBuffer->maxQuads();
63 } else {
bsalomon@google.comd302f142011-03-03 13:54:13 +000064 GrAssert((NULL == indexBuffer && 0 == fMaxQuads) ||
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000065 (indexBuffer->maxQuads() == fMaxQuads));
66 }
67}
68
bsalomon@google.com934c5702012-03-20 21:17:58 +000069////////////////////////////////////////////////////////////////////////////////
70
71void GrInOrderDrawBuffer::resetDrawTracking() {
72 fCurrQuad = 0;
73 fInstancedDrawTracker.reset();
74}
75
bsalomon@google.comd302f142011-03-03 13:54:13 +000076void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000077 const GrMatrix* matrix,
bsalomon@google.com39ee0ff2011-12-06 15:32:52 +000078 StageMask stageMask,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000079 const GrRect* srcRects[],
80 const GrMatrix* srcMatrices[]) {
bsalomon@google.comd302f142011-03-03 13:54:13 +000081
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000082 GrAssert(!(NULL == fQuadIndexBuffer && fCurrQuad));
83 GrAssert(!(fDraws.empty() && fCurrQuad));
84 GrAssert(!(0 != fMaxQuads && NULL == fQuadIndexBuffer));
85
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +000086 GrDrawState* drawState = this->drawState();
87
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000088 // if we have a quad IB then either append to the previous run of
89 // rects or start a new run
90 if (fMaxQuads) {
bsalomon@google.comd302f142011-03-03 13:54:13 +000091
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000092 bool appendToPreviousDraw = false;
bsalomon@google.com39ee0ff2011-12-06 15:32:52 +000093 GrVertexLayout layout = GetRectVertexLayout(stageMask, srcRects);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000094 AutoReleaseGeometry geo(this, layout, 4, 0);
bsalomon@google.com6513cd02011-08-05 20:12:30 +000095 if (!geo.succeeded()) {
96 GrPrintf("Failed to get space for vertices!\n");
97 return;
98 }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +000099 GrMatrix combinedMatrix = drawState->getViewMatrix();
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000100 // We go to device space so that matrix changes allow us to concat
101 // rect draws. When the caller has provided explicit source rects
102 // then we don't want to modify the sampler matrices. Otherwise we do
103 // we have to account for the view matrix change in the sampler
104 // matrices.
105 StageMask devCoordMask = (NULL == srcRects) ? stageMask : 0;
106 GrDrawTarget::AutoDeviceCoordDraw adcd(this, devCoordMask);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000107 if (NULL != matrix) {
108 combinedMatrix.preConcat(*matrix);
109 }
110
111 SetRectVertices(rect, &combinedMatrix, srcRects, srcMatrices, layout, geo.vertices());
112
113 // we don't want to miss an opportunity to batch rects together
114 // simply because the clip has changed if the clip doesn't affect
115 // the rect.
116 bool disabledClip = false;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000117 if (drawState->isClipState() && fClip.isRect()) {
bsalomon@google.comd302f142011-03-03 13:54:13 +0000118
bsalomon@google.com0b50b2e2011-03-08 21:07:21 +0000119 GrRect clipRect = fClip.getRect(0);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000120 // If the clip rect touches the edge of the viewport, extended it
121 // out (close) to infinity to avoid bogus intersections.
bsalomon@google.comd302f142011-03-03 13:54:13 +0000122 // We might consider a more exact clip to viewport if this
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000123 // conservative test fails.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000124 const GrRenderTarget* target = drawState->getRenderTarget();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000125 if (0 >= clipRect.fLeft) {
126 clipRect.fLeft = GR_ScalarMin;
127 }
128 if (target->width() <= clipRect.fRight) {
129 clipRect.fRight = GR_ScalarMax;
130 }
131 if (0 >= clipRect.top()) {
132 clipRect.fTop = GR_ScalarMin;
133 }
134 if (target->height() <= clipRect.fBottom) {
135 clipRect.fBottom = GR_ScalarMax;
136 }
137 int stride = VertexSize(layout);
138 bool insideClip = true;
139 for (int v = 0; v < 4; ++v) {
140 const GrPoint& p = *GetVertexPoint(geo.vertices(), v, stride);
141 if (!clipRect.contains(p)) {
142 insideClip = false;
143 break;
144 }
145 }
146 if (insideClip) {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000147 drawState->disableState(GrDrawState::kClip_StateBit);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000148 disabledClip = true;
149 }
150 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000151 if (!needsNewClip() && !needsNewState() && fCurrQuad > 0 &&
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000152 fCurrQuad < fMaxQuads && layout == fLastRectVertexLayout) {
153
154 int vsize = VertexSize(layout);
bsalomon@google.comd302f142011-03-03 13:54:13 +0000155
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000156 Draw& lastDraw = fDraws.back();
157
158 GrAssert(lastDraw.fIndexBuffer == fQuadIndexBuffer);
159 GrAssert(kTriangles_PrimitiveType == lastDraw.fPrimitiveType);
160 GrAssert(0 == lastDraw.fVertexCount % 4);
161 GrAssert(0 == lastDraw.fIndexCount % 6);
162 GrAssert(0 == lastDraw.fStartIndex);
163
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000164 GeometryPoolState& poolState = fGeoPoolStateStack.back();
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000165 bool clearSinceLastDraw =
166 fClears.count() &&
167 fClears.back().fBeforeDrawIdx == fDraws.count();
168
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000169 appendToPreviousDraw =
170 !clearSinceLastDraw &&
171 lastDraw.fVertexBuffer == poolState.fPoolVertexBuffer &&
172 (fCurrQuad * 4 + lastDraw.fStartVertex) == poolState.fPoolStartVertex;
173
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000174 if (appendToPreviousDraw) {
175 lastDraw.fVertexCount += 4;
176 lastDraw.fIndexCount += 6;
177 fCurrQuad += 1;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000178 // we reserved above, so we should be the first
179 // use of this vertex reserveation.
180 GrAssert(0 == poolState.fUsedPoolVertexBytes);
181 poolState.fUsedPoolVertexBytes = 4 * vsize;
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000182 }
183 }
184 if (!appendToPreviousDraw) {
185 this->setIndexSourceToBuffer(fQuadIndexBuffer);
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000186 this->drawIndexed(kTriangles_PrimitiveType, 0, 0, 4, 6);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000187 fCurrQuad = 1;
188 fLastRectVertexLayout = layout;
189 }
190 if (disabledClip) {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000191 drawState->enableState(GrDrawState::kClip_StateBit);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000192 }
bsalomon@google.com934c5702012-03-20 21:17:58 +0000193 fInstancedDrawTracker.reset();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000194 } else {
bsalomon@google.com39ee0ff2011-12-06 15:32:52 +0000195 INHERITED::drawRect(rect, matrix, stageMask, srcRects, srcMatrices);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000196 }
197}
198
bsalomon@google.com934c5702012-03-20 21:17:58 +0000199void GrInOrderDrawBuffer::drawIndexedInstances(GrPrimitiveType type,
200 int instanceCount,
201 int verticesPerInstance,
202 int indicesPerInstance) {
203 if (!verticesPerInstance || !indicesPerInstance) {
204 return;
205 }
206
207 const GeometrySrcState& geomSrc = this->getGeomSrc();
208
209 // we only attempt to concat the case when reserved verts are used with
210 // an index buffer.
211 if (kReserved_GeometrySrcType == geomSrc.fVertexSrc &&
212 kBuffer_GeometrySrcType == geomSrc.fIndexSrc) {
213
214 Draw* draw = NULL;
215 // if the last draw used the same indices/vertices per shape then we
216 // may be able to append to it.
217 if (verticesPerInstance == fInstancedDrawTracker.fVerticesPerInstance &&
218 indicesPerInstance == fInstancedDrawTracker.fIndicesPerInstance) {
219 GrAssert(fDraws.count());
220 draw = &fDraws.back();
221 }
222
223 bool clipChanged = this->needsNewClip();
224 bool stateChanged = this->needsNewState();
225 if (clipChanged) {
226 this->pushClip();
227 }
228 if (stateChanged) {
229 this->pushState();
230 }
231
232 GeometryPoolState& poolState = fGeoPoolStateStack.back();
233 const GrVertexBuffer* vertexBuffer = poolState.fPoolVertexBuffer;
234
235 // Check whether the draw is compatible with this draw in order to
236 // append
237 if (NULL == draw ||
238 clipChanged ||
239 stateChanged ||
240 draw->fIndexBuffer != geomSrc.fIndexBuffer ||
241 draw->fPrimitiveType != type ||
242 draw->fVertexBuffer != vertexBuffer) {
243
244 draw = &fDraws.push_back();
245 draw->fClipChanged = clipChanged;
246 draw->fStateChanged = stateChanged;
247 draw->fIndexBuffer = geomSrc.fIndexBuffer;
248 geomSrc.fIndexBuffer->ref();
249 draw->fVertexBuffer = vertexBuffer;
250 vertexBuffer->ref();
251 draw->fPrimitiveType = type;
252 draw->fStartIndex = 0;
253 draw->fIndexCount = 0;
254 draw->fStartVertex = poolState.fPoolStartVertex;
255 draw->fVertexCount = 0;
256 draw->fVertexLayout = geomSrc.fVertexLayout;
257 } else {
258 GrAssert(!(draw->fIndexCount % indicesPerInstance));
259 GrAssert(!(draw->fVertexCount % verticesPerInstance));
260 GrAssert(poolState.fPoolStartVertex == draw->fStartVertex +
261 draw->fVertexCount);
262 }
263
264 // how many instances can be in a single draw
265 int maxInstancesPerDraw = this->indexCountInCurrentSource() /
266 indicesPerInstance;
267 if (!maxInstancesPerDraw) {
268 return;
269 }
270 // how many instances should be concat'ed onto draw
271 int instancesToConcat = maxInstancesPerDraw - draw->fVertexCount /
272 verticesPerInstance;
273 if (maxInstancesPerDraw > instanceCount) {
274 maxInstancesPerDraw = instanceCount;
275 if (instancesToConcat > instanceCount) {
276 instancesToConcat = instanceCount;
277 }
278 }
279
280 // update the amount of reserved data actually referenced in draws
281 size_t vertexBytes = instanceCount * verticesPerInstance *
282 VertexSize(draw->fVertexLayout);
283 poolState.fUsedPoolVertexBytes =
284 GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
285
286 while (instanceCount) {
287 if (!instancesToConcat) {
288 int startVertex = draw->fStartVertex + draw->fVertexCount;
289 draw = &fDraws.push_back();
290 draw->fClipChanged = false;
291 draw->fStateChanged = false;
292 draw->fIndexBuffer = geomSrc.fIndexBuffer;
293 geomSrc.fIndexBuffer->ref();
294 draw->fVertexBuffer = vertexBuffer;
295 vertexBuffer->ref();
296 draw->fPrimitiveType = type;
297 draw->fStartIndex = 0;
298 draw->fStartVertex = startVertex;
299 draw->fVertexCount = 0;
300 draw->fVertexLayout = geomSrc.fVertexLayout;
301 instancesToConcat = maxInstancesPerDraw;
302 }
303 draw->fVertexCount += instancesToConcat * verticesPerInstance;
304 draw->fIndexCount += instancesToConcat * indicesPerInstance;
305 instanceCount -= instancesToConcat;
306 instancesToConcat = 0;
307 }
308
309 // update draw tracking for next draw
310 fCurrQuad = 0;
311 fInstancedDrawTracker.fVerticesPerInstance = verticesPerInstance;
312 fInstancedDrawTracker.fIndicesPerInstance = indicesPerInstance;
313 } else {
314 this->INHERITED::drawIndexedInstances(type,
315 instanceCount,
316 verticesPerInstance,
317 indicesPerInstance);
318 }
319
320}
321
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000322void GrInOrderDrawBuffer::onDrawIndexed(GrPrimitiveType primitiveType,
323 int startVertex,
324 int startIndex,
325 int vertexCount,
326 int indexCount) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000327
328 if (!vertexCount || !indexCount) {
329 return;
330 }
331
bsalomon@google.com934c5702012-03-20 21:17:58 +0000332 this->resetDrawTracking();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000333
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000334 GeometryPoolState& poolState = fGeoPoolStateStack.back();
335
reed@google.comac10a2d2010-12-22 21:39:39 +0000336 Draw& draw = fDraws.push_back();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000337 draw.fPrimitiveType = primitiveType;
reed@google.comac10a2d2010-12-22 21:39:39 +0000338 draw.fStartVertex = startVertex;
339 draw.fStartIndex = startIndex;
340 draw.fVertexCount = vertexCount;
341 draw.fIndexCount = indexCount;
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000342
343 draw.fClipChanged = this->needsNewClip();
344 if (draw.fClipChanged) {
345 this->pushClip();
346 }
347
348 draw.fStateChanged = this->needsNewState();
349 if (draw.fStateChanged) {
350 this->pushState();
351 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000352
bsalomon@google.come79c8152012-03-29 19:07:12 +0000353 draw.fVertexLayout = this->getVertexLayout();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000354 switch (this->getGeomSrc().fVertexSrc) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000355 case kBuffer_GeometrySrcType:
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000356 draw.fVertexBuffer = this->getGeomSrc().fVertexBuffer;
reed@google.comac10a2d2010-12-22 21:39:39 +0000357 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000358 case kReserved_GeometrySrcType: // fallthrough
359 case kArray_GeometrySrcType: {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000360 size_t vertexBytes = (vertexCount + startVertex) *
bsalomon@google.come79c8152012-03-29 19:07:12 +0000361 VertexSize(draw.fVertexLayout);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000362 poolState.fUsedPoolVertexBytes =
363 GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
364 draw.fVertexBuffer = poolState.fPoolVertexBuffer;
365 draw.fStartVertex += poolState.fPoolStartVertex;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000366 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000367 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000368 default:
369 GrCrash("unknown geom src type");
reed@google.comac10a2d2010-12-22 21:39:39 +0000370 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000371 draw.fVertexBuffer->ref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000372
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000373 switch (this->getGeomSrc().fIndexSrc) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000374 case kBuffer_GeometrySrcType:
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000375 draw.fIndexBuffer = this->getGeomSrc().fIndexBuffer;
reed@google.comac10a2d2010-12-22 21:39:39 +0000376 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000377 case kReserved_GeometrySrcType: // fallthrough
378 case kArray_GeometrySrcType: {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000379 size_t indexBytes = (indexCount + startIndex) * sizeof(uint16_t);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000380 poolState.fUsedPoolIndexBytes =
381 GrMax(poolState.fUsedPoolIndexBytes, indexBytes);
382 draw.fIndexBuffer = poolState.fPoolIndexBuffer;
bsalomon@google.comd127ffe2012-02-24 20:11:52 +0000383 draw.fStartIndex += poolState.fPoolStartIndex;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000384 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000385 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000386 default:
387 GrCrash("unknown geom src type");
reed@google.comac10a2d2010-12-22 21:39:39 +0000388 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000389 draw.fIndexBuffer->ref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000390}
391
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000392void GrInOrderDrawBuffer::onDrawNonIndexed(GrPrimitiveType primitiveType,
393 int startVertex,
394 int vertexCount) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000395 if (!vertexCount) {
396 return;
397 }
398
bsalomon@google.com934c5702012-03-20 21:17:58 +0000399 this->resetDrawTracking();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000400
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000401 GeometryPoolState& poolState = fGeoPoolStateStack.back();
402
reed@google.comac10a2d2010-12-22 21:39:39 +0000403 Draw& draw = fDraws.push_back();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000404 draw.fPrimitiveType = primitiveType;
reed@google.comac10a2d2010-12-22 21:39:39 +0000405 draw.fStartVertex = startVertex;
406 draw.fStartIndex = 0;
407 draw.fVertexCount = vertexCount;
408 draw.fIndexCount = 0;
409
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000410 draw.fClipChanged = this->needsNewClip();
411 if (draw.fClipChanged) {
412 this->pushClip();
413 }
414
415 draw.fStateChanged = this->needsNewState();
416 if (draw.fStateChanged) {
417 this->pushState();
418 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000419
bsalomon@google.come79c8152012-03-29 19:07:12 +0000420 draw.fVertexLayout = this->getVertexLayout();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000421 switch (this->getGeomSrc().fVertexSrc) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000422 case kBuffer_GeometrySrcType:
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000423 draw.fVertexBuffer = this->getGeomSrc().fVertexBuffer;
reed@google.comac10a2d2010-12-22 21:39:39 +0000424 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000425 case kReserved_GeometrySrcType: // fallthrough
426 case kArray_GeometrySrcType: {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000427 size_t vertexBytes = (vertexCount + startVertex) *
bsalomon@google.come79c8152012-03-29 19:07:12 +0000428 VertexSize(draw.fVertexLayout);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000429 poolState.fUsedPoolVertexBytes =
430 GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
431 draw.fVertexBuffer = poolState.fPoolVertexBuffer;
432 draw.fStartVertex += poolState.fPoolStartVertex;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000433 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000434 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000435 default:
436 GrCrash("unknown geom src type");
reed@google.comac10a2d2010-12-22 21:39:39 +0000437 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000438 draw.fVertexBuffer->ref();
439 draw.fIndexBuffer = NULL;
reed@google.comac10a2d2010-12-22 21:39:39 +0000440}
441
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000442void GrInOrderDrawBuffer::clear(const GrIRect* rect, GrColor color) {
443 GrIRect r;
444 if (NULL == rect) {
445 // We could do something smart and remove previous draws and clears to
446 // the current render target. If we get that smart we have to make sure
447 // those draws aren't read before this clear (render-to-texture).
448 r.setLTRB(0, 0,
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000449 this->getDrawState().getRenderTarget()->width(),
450 this->getDrawState().getRenderTarget()->height());
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000451 rect = &r;
452 }
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000453 Clear& clr = fClears.push_back();
454 clr.fColor = color;
455 clr.fBeforeDrawIdx = fDraws.count();
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000456 clr.fRect = *rect;
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000457}
458
reed@google.comac10a2d2010-12-22 21:39:39 +0000459void GrInOrderDrawBuffer::reset() {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000460 GrAssert(1 == fGeoPoolStateStack.count());
461 this->resetVertexSource();
462 this->resetIndexSource();
reed@google.comac10a2d2010-12-22 21:39:39 +0000463 uint32_t numStates = fStates.count();
464 for (uint32_t i = 0; i < numStates; ++i) {
tomhudson@google.com93813632011-10-27 20:21:16 +0000465 for (int s = 0; s < GrDrawState::kNumStages; ++s) {
bsalomon@google.com873ea0c2012-03-30 15:55:32 +0000466 GrSafeUnref(fStates[i].getTexture(s));
reed@google.comac10a2d2010-12-22 21:39:39 +0000467 }
bsalomon@google.com873ea0c2012-03-30 15:55:32 +0000468 GrSafeUnref(fStates[i].getRenderTarget());
reed@google.comac10a2d2010-12-22 21:39:39 +0000469 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000470 int numDraws = fDraws.count();
471 for (int d = 0; d < numDraws; ++d) {
472 // we always have a VB, but not always an IB
473 GrAssert(NULL != fDraws[d].fVertexBuffer);
474 fDraws[d].fVertexBuffer->unref();
475 GrSafeUnref(fDraws[d].fIndexBuffer);
476 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000477 fDraws.reset();
478 fStates.reset();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000479
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000480 fClears.reset();
481
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000482 fVertexPool.reset();
483 fIndexPool.reset();
484
reed@google.comac10a2d2010-12-22 21:39:39 +0000485 fClips.reset();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000486
bsalomon@google.com934c5702012-03-20 21:17:58 +0000487 this->resetDrawTracking();
reed@google.comac10a2d2010-12-22 21:39:39 +0000488}
489
490void GrInOrderDrawBuffer::playback(GrDrawTarget* target) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000491 GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fVertexSrc);
492 GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fIndexSrc);
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000493
reed@google.comac10a2d2010-12-22 21:39:39 +0000494 GrAssert(NULL != target);
495 GrAssert(target != this); // not considered and why?
496
bsalomon@google.com898d9e52011-04-26 13:22:33 +0000497 int numDraws = fDraws.count();
reed@google.comac10a2d2010-12-22 21:39:39 +0000498 if (!numDraws) {
499 return;
500 }
501
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000502 fVertexPool.unlock();
503 fIndexPool.unlock();
reed@google.comac10a2d2010-12-22 21:39:39 +0000504
reed@google.comac10a2d2010-12-22 21:39:39 +0000505 GrDrawTarget::AutoClipRestore acr(target);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000506 AutoGeometryPush agp(target);
bsalomon@google.coma5d056a2012-03-27 15:59:58 +0000507 GrDrawState* prevDrawState = target->drawState();
508 prevDrawState->ref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000509
bsalomon@google.com6a77cc52011-04-28 17:33:34 +0000510 int currState = ~0;
511 int currClip = ~0;
512 int currClear = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000513
bsalomon@google.com898d9e52011-04-26 13:22:33 +0000514 for (int i = 0; i < numDraws; ++i) {
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000515 while (currClear < fClears.count() &&
516 i == fClears[currClear].fBeforeDrawIdx) {
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000517 target->clear(&fClears[currClear].fRect, fClears[currClear].fColor);
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000518 ++currClear;
519 }
520
reed@google.comac10a2d2010-12-22 21:39:39 +0000521 const Draw& draw = fDraws[i];
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000522 if (draw.fStateChanged) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000523 ++currState;
bsalomon@google.com873ea0c2012-03-30 15:55:32 +0000524 target->setDrawState(&fStates[currState]);
reed@google.comac10a2d2010-12-22 21:39:39 +0000525 }
526 if (draw.fClipChanged) {
527 ++currClip;
528 target->setClip(fClips[currClip]);
529 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000530
531 target->setVertexSourceToBuffer(draw.fVertexLayout, draw.fVertexBuffer);
532
reed@google.comac10a2d2010-12-22 21:39:39 +0000533 if (draw.fIndexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000534 target->setIndexSourceToBuffer(draw.fIndexBuffer);
535 }
536
537 if (draw.fIndexCount) {
538 target->drawIndexed(draw.fPrimitiveType,
reed@google.comac10a2d2010-12-22 21:39:39 +0000539 draw.fStartVertex,
540 draw.fStartIndex,
541 draw.fVertexCount,
542 draw.fIndexCount);
543 } else {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000544 target->drawNonIndexed(draw.fPrimitiveType,
reed@google.comac10a2d2010-12-22 21:39:39 +0000545 draw.fStartVertex,
546 draw.fVertexCount);
547 }
548 }
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000549 while (currClear < fClears.count()) {
550 GrAssert(fDraws.count() == fClears[currClear].fBeforeDrawIdx);
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000551 target->clear(&fClears[currClear].fRect, fClears[currClear].fColor);
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000552 ++currClear;
553 }
bsalomon@google.coma5d056a2012-03-27 15:59:58 +0000554 target->setDrawState(prevDrawState);
555 prevDrawState->unref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000556}
557
bsalomon@google.com97805382012-03-13 14:32:07 +0000558void GrInOrderDrawBuffer::setAutoFlushTarget(GrDrawTarget* target) {
559 GrSafeAssign(fAutoFlushTarget, target);
560}
561
562void GrInOrderDrawBuffer::willReserveVertexAndIndexSpace(
563 GrVertexLayout vertexLayout,
564 int vertexCount,
565 int indexCount) {
566 if (NULL != fAutoFlushTarget) {
567 // We use geometryHints() to know whether to flush the draw buffer. We
568 // can't flush if we are inside an unbalanced pushGeometrySource.
569 // Moreover, flushing blows away vertex and index data that was
570 // previously reserved. So if the vertex or index data is pulled from
571 // reserved space and won't be released by this request then we can't
572 // flush.
573 bool insideGeoPush = fGeoPoolStateStack.count() > 1;
574
575 bool unreleasedVertexSpace =
576 !vertexCount &&
577 kReserved_GeometrySrcType == this->getGeomSrc().fVertexSrc;
578
579 bool unreleasedIndexSpace =
580 !indexCount &&
581 kReserved_GeometrySrcType == this->getGeomSrc().fIndexSrc;
582
583 // we don't want to finalize any reserved geom on the target since
584 // we don't know that the client has finished writing to it.
585 bool targetHasReservedGeom =
586 fAutoFlushTarget->hasReservedVerticesOrIndices();
587
588 int vcount = vertexCount;
589 int icount = indexCount;
590
591 if (!insideGeoPush &&
592 !unreleasedVertexSpace &&
593 !unreleasedIndexSpace &&
594 !targetHasReservedGeom &&
595 this->geometryHints(vertexLayout, &vcount, &icount)) {
596
597 this->flushTo(fAutoFlushTarget);
598 }
599 }
600}
601
reed@google.comac10a2d2010-12-22 21:39:39 +0000602bool GrInOrderDrawBuffer::geometryHints(GrVertexLayout vertexLayout,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000603 int* vertexCount,
604 int* indexCount) const {
605 // we will recommend a flush if the data could fit in a single
606 // preallocated buffer but none are left and it can't fit
607 // in the current buffer (which may not be prealloced).
reed@google.comac10a2d2010-12-22 21:39:39 +0000608 bool flush = false;
609 if (NULL != indexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000610 int32_t currIndices = fIndexPool.currentBufferIndices();
611 if (*indexCount > currIndices &&
612 (!fIndexPool.preallocatedBuffersRemaining() &&
613 *indexCount <= fIndexPool.preallocatedBufferIndices())) {
614
615 flush = true;
616 }
617 *indexCount = currIndices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000618 }
619 if (NULL != vertexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000620 int32_t currVertices = fVertexPool.currentBufferVertices(vertexLayout);
621 if (*vertexCount > currVertices &&
622 (!fVertexPool.preallocatedBuffersRemaining() &&
623 *vertexCount <= fVertexPool.preallocatedBufferVertices(vertexLayout))) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000624
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000625 flush = true;
reed@google.comac10a2d2010-12-22 21:39:39 +0000626 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000627 *vertexCount = currVertices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000628 }
629 return flush;
630}
631
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000632bool GrInOrderDrawBuffer::onReserveVertexSpace(GrVertexLayout vertexLayout,
633 int vertexCount,
634 void** vertices) {
635 GeometryPoolState& poolState = fGeoPoolStateStack.back();
636 GrAssert(vertexCount > 0);
637 GrAssert(NULL != vertices);
638 GrAssert(0 == poolState.fUsedPoolVertexBytes);
639
640 *vertices = fVertexPool.makeSpace(vertexLayout,
641 vertexCount,
642 &poolState.fPoolVertexBuffer,
643 &poolState.fPoolStartVertex);
644 return NULL != *vertices;
645}
646
647bool GrInOrderDrawBuffer::onReserveIndexSpace(int indexCount, void** indices) {
648 GeometryPoolState& poolState = fGeoPoolStateStack.back();
649 GrAssert(indexCount > 0);
650 GrAssert(NULL != indices);
651 GrAssert(0 == poolState.fUsedPoolIndexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000652
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000653 *indices = fIndexPool.makeSpace(indexCount,
654 &poolState.fPoolIndexBuffer,
655 &poolState.fPoolStartIndex);
656 return NULL != *indices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000657}
658
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000659void GrInOrderDrawBuffer::releaseReservedVertexSpace() {
660 GeometryPoolState& poolState = fGeoPoolStateStack.back();
661 const GeometrySrcState& geoSrc = this->getGeomSrc();
662
663 GrAssert(kReserved_GeometrySrcType == geoSrc.fVertexSrc);
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000664
665 // When the caller reserved vertex buffer space we gave it back a pointer
666 // provided by the vertex buffer pool. At each draw we tracked the largest
667 // offset into the pool's pointer that was referenced. Now we return to the
668 // pool any portion at the tail of the allocation that no draw referenced.
669 size_t reservedVertexBytes = VertexSize(geoSrc.fVertexLayout) *
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000670 geoSrc.fVertexCount;
671 fVertexPool.putBack(reservedVertexBytes -
672 poolState.fUsedPoolVertexBytes);
673 poolState.fUsedPoolVertexBytes = 0;
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000674 poolState.fPoolVertexBuffer = NULL;
675 poolState.fPoolStartVertex = 0;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000676}
677
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000678void GrInOrderDrawBuffer::releaseReservedIndexSpace() {
679 GeometryPoolState& poolState = fGeoPoolStateStack.back();
680 const GeometrySrcState& geoSrc = this->getGeomSrc();
681
682 GrAssert(kReserved_GeometrySrcType == geoSrc.fIndexSrc);
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000683
684 // Similar to releaseReservedVertexSpace we return any unused portion at
685 // the tail
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000686 size_t reservedIndexBytes = sizeof(uint16_t) * geoSrc.fIndexCount;
687 fIndexPool.putBack(reservedIndexBytes - poolState.fUsedPoolIndexBytes);
688 poolState.fUsedPoolIndexBytes = 0;
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000689 poolState.fPoolIndexBuffer = NULL;
690 poolState.fPoolStartIndex = 0;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000691}
692
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000693void GrInOrderDrawBuffer::onSetVertexSourceToArray(const void* vertexArray,
694 int vertexCount) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000695
696 GeometryPoolState& poolState = fGeoPoolStateStack.back();
697 GrAssert(0 == poolState.fUsedPoolVertexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000698#if GR_DEBUG
699 bool success =
700#endif
bsalomon@google.come79c8152012-03-29 19:07:12 +0000701 fVertexPool.appendVertices(this->getVertexLayout(),
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000702 vertexCount,
703 vertexArray,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000704 &poolState.fPoolVertexBuffer,
705 &poolState.fPoolStartVertex);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000706 GR_DEBUGASSERT(success);
707}
708
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000709void GrInOrderDrawBuffer::onSetIndexSourceToArray(const void* indexArray,
710 int indexCount) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000711 GeometryPoolState& poolState = fGeoPoolStateStack.back();
712 GrAssert(0 == poolState.fUsedPoolIndexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000713#if GR_DEBUG
714 bool success =
715#endif
716 fIndexPool.appendIndices(indexCount,
717 indexArray,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000718 &poolState.fPoolIndexBuffer,
719 &poolState.fPoolStartIndex);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000720 GR_DEBUGASSERT(success);
reed@google.comac10a2d2010-12-22 21:39:39 +0000721}
722
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000723void GrInOrderDrawBuffer::releaseVertexArray() {
724 // When the client provides an array as the vertex source we handled it
725 // by copying their array into reserved space.
726 this->GrInOrderDrawBuffer::releaseReservedVertexSpace();
727}
728
729void GrInOrderDrawBuffer::releaseIndexArray() {
730 // When the client provides an array as the index source we handled it
731 // by copying their array into reserved space.
732 this->GrInOrderDrawBuffer::releaseReservedIndexSpace();
733}
734
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000735void GrInOrderDrawBuffer::geometrySourceWillPush() {
736 GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
737 poolState.fUsedPoolVertexBytes = 0;
738 poolState.fUsedPoolIndexBytes = 0;
bsalomon@google.com934c5702012-03-20 21:17:58 +0000739 this->resetDrawTracking();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000740#if GR_DEBUG
741 poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0;
742 poolState.fPoolStartVertex = ~0;
743 poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0;
744 poolState.fPoolStartIndex = ~0;
745#endif
746}
747
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000748void GrInOrderDrawBuffer::geometrySourceWillPop(
749 const GeometrySrcState& restoredState) {
750 GrAssert(fGeoPoolStateStack.count() > 1);
751 fGeoPoolStateStack.pop_back();
752 GeometryPoolState& poolState = fGeoPoolStateStack.back();
753 // we have to assume that any slack we had in our vertex/index data
754 // is now unreleasable because data may have been appended later in the
755 // pool.
756 if (kReserved_GeometrySrcType == restoredState.fVertexSrc ||
757 kArray_GeometrySrcType == restoredState.fVertexSrc) {
758 poolState.fUsedPoolVertexBytes =
759 VertexSize(restoredState.fVertexLayout) *
760 restoredState.fVertexCount;
761 }
762 if (kReserved_GeometrySrcType == restoredState.fIndexSrc ||
763 kArray_GeometrySrcType == restoredState.fIndexSrc) {
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000764 poolState.fUsedPoolIndexBytes = sizeof(uint16_t) *
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000765 restoredState.fIndexCount;
766 }
bsalomon@google.com934c5702012-03-20 21:17:58 +0000767 this->resetDrawTracking();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000768}
769
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000770bool GrInOrderDrawBuffer::needsNewState() const {
771 if (fStates.empty()) {
772 return true;
773 } else {
bsalomon@google.com873ea0c2012-03-30 15:55:32 +0000774 return fStates.back() != this->getDrawState();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000775 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000776}
777
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000778void GrInOrderDrawBuffer::pushState() {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000779 const GrDrawState& drawState = this->getDrawState();
tomhudson@google.com93813632011-10-27 20:21:16 +0000780 for (int s = 0; s < GrDrawState::kNumStages; ++s) {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000781 GrSafeRef(drawState.getTexture(s));
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000782 }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000783 GrSafeRef(drawState.getRenderTarget());
bsalomon@google.com873ea0c2012-03-30 15:55:32 +0000784 fStates.push_back(this->getDrawState());
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000785 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000786
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000787bool GrInOrderDrawBuffer::needsNewClip() const {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000788 if (this->getDrawState().isClipState()) {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000789 if (fClips.empty() || (fClipSet && fClips.back() != fClip)) {
790 return true;
791 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000792 }
793 return false;
794}
bsalomon@google.comd302f142011-03-03 13:54:13 +0000795
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000796void GrInOrderDrawBuffer::pushClip() {
797 fClips.push_back() = fClip;
798 fClipSet = false;
reed@google.comac10a2d2010-12-22 21:39:39 +0000799}
bsalomon@google.comd302f142011-03-03 13:54:13 +0000800
bsalomon@google.comdea2f8d2011-08-01 15:51:05 +0000801void GrInOrderDrawBuffer::clipWillBeSet(const GrClip& newClip) {
802 INHERITED::clipWillBeSet(newClip);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000803 fClipSet = true;
804}