blob: de49e8c8bfc36d5f775cd4c9b00b5f2e0de82a03 [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());
robertphillips@google.com1942c052012-05-03 17:58:27 +0000469
470 // GrInOrderDrawBuffer is no longer managing the refs/unrefs
471 // for the stored GrDrawStates
472 fStates[i].disableState(GrDrawState::kTexturesNeedRef_StateBit);
reed@google.comac10a2d2010-12-22 21:39:39 +0000473 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000474 int numDraws = fDraws.count();
475 for (int d = 0; d < numDraws; ++d) {
476 // we always have a VB, but not always an IB
477 GrAssert(NULL != fDraws[d].fVertexBuffer);
478 fDraws[d].fVertexBuffer->unref();
479 GrSafeUnref(fDraws[d].fIndexBuffer);
480 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000481 fDraws.reset();
482 fStates.reset();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000483
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000484 fClears.reset();
485
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000486 fVertexPool.reset();
487 fIndexPool.reset();
488
reed@google.comac10a2d2010-12-22 21:39:39 +0000489 fClips.reset();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000490
bsalomon@google.com934c5702012-03-20 21:17:58 +0000491 this->resetDrawTracking();
reed@google.comac10a2d2010-12-22 21:39:39 +0000492}
493
494void GrInOrderDrawBuffer::playback(GrDrawTarget* target) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000495 GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fVertexSrc);
496 GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fIndexSrc);
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000497
reed@google.comac10a2d2010-12-22 21:39:39 +0000498 GrAssert(NULL != target);
499 GrAssert(target != this); // not considered and why?
500
bsalomon@google.com898d9e52011-04-26 13:22:33 +0000501 int numDraws = fDraws.count();
reed@google.comac10a2d2010-12-22 21:39:39 +0000502 if (!numDraws) {
503 return;
504 }
505
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000506 fVertexPool.unlock();
507 fIndexPool.unlock();
reed@google.comac10a2d2010-12-22 21:39:39 +0000508
reed@google.comac10a2d2010-12-22 21:39:39 +0000509 GrDrawTarget::AutoClipRestore acr(target);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000510 AutoGeometryPush agp(target);
bsalomon@google.coma5d056a2012-03-27 15:59:58 +0000511 GrDrawState* prevDrawState = target->drawState();
512 prevDrawState->ref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000513
bsalomon@google.com6a77cc52011-04-28 17:33:34 +0000514 int currState = ~0;
515 int currClip = ~0;
516 int currClear = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000517
bsalomon@google.com898d9e52011-04-26 13:22:33 +0000518 for (int i = 0; i < numDraws; ++i) {
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000519 while (currClear < fClears.count() &&
520 i == fClears[currClear].fBeforeDrawIdx) {
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000521 target->clear(&fClears[currClear].fRect, fClears[currClear].fColor);
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000522 ++currClear;
523 }
524
reed@google.comac10a2d2010-12-22 21:39:39 +0000525 const Draw& draw = fDraws[i];
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000526 if (draw.fStateChanged) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000527 ++currState;
bsalomon@google.com873ea0c2012-03-30 15:55:32 +0000528 target->setDrawState(&fStates[currState]);
reed@google.comac10a2d2010-12-22 21:39:39 +0000529 }
530 if (draw.fClipChanged) {
531 ++currClip;
532 target->setClip(fClips[currClip]);
533 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000534
535 target->setVertexSourceToBuffer(draw.fVertexLayout, draw.fVertexBuffer);
536
reed@google.comac10a2d2010-12-22 21:39:39 +0000537 if (draw.fIndexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000538 target->setIndexSourceToBuffer(draw.fIndexBuffer);
539 }
540
541 if (draw.fIndexCount) {
542 target->drawIndexed(draw.fPrimitiveType,
reed@google.comac10a2d2010-12-22 21:39:39 +0000543 draw.fStartVertex,
544 draw.fStartIndex,
545 draw.fVertexCount,
546 draw.fIndexCount);
547 } else {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000548 target->drawNonIndexed(draw.fPrimitiveType,
reed@google.comac10a2d2010-12-22 21:39:39 +0000549 draw.fStartVertex,
550 draw.fVertexCount);
551 }
552 }
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000553 while (currClear < fClears.count()) {
554 GrAssert(fDraws.count() == fClears[currClear].fBeforeDrawIdx);
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000555 target->clear(&fClears[currClear].fRect, fClears[currClear].fColor);
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000556 ++currClear;
557 }
bsalomon@google.coma5d056a2012-03-27 15:59:58 +0000558 target->setDrawState(prevDrawState);
559 prevDrawState->unref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000560}
561
bsalomon@google.com97805382012-03-13 14:32:07 +0000562void GrInOrderDrawBuffer::setAutoFlushTarget(GrDrawTarget* target) {
563 GrSafeAssign(fAutoFlushTarget, target);
564}
565
566void GrInOrderDrawBuffer::willReserveVertexAndIndexSpace(
567 GrVertexLayout vertexLayout,
568 int vertexCount,
569 int indexCount) {
570 if (NULL != fAutoFlushTarget) {
571 // We use geometryHints() to know whether to flush the draw buffer. We
572 // can't flush if we are inside an unbalanced pushGeometrySource.
573 // Moreover, flushing blows away vertex and index data that was
574 // previously reserved. So if the vertex or index data is pulled from
575 // reserved space and won't be released by this request then we can't
576 // flush.
577 bool insideGeoPush = fGeoPoolStateStack.count() > 1;
578
579 bool unreleasedVertexSpace =
580 !vertexCount &&
581 kReserved_GeometrySrcType == this->getGeomSrc().fVertexSrc;
582
583 bool unreleasedIndexSpace =
584 !indexCount &&
585 kReserved_GeometrySrcType == this->getGeomSrc().fIndexSrc;
586
587 // we don't want to finalize any reserved geom on the target since
588 // we don't know that the client has finished writing to it.
589 bool targetHasReservedGeom =
590 fAutoFlushTarget->hasReservedVerticesOrIndices();
591
592 int vcount = vertexCount;
593 int icount = indexCount;
594
595 if (!insideGeoPush &&
596 !unreleasedVertexSpace &&
597 !unreleasedIndexSpace &&
598 !targetHasReservedGeom &&
599 this->geometryHints(vertexLayout, &vcount, &icount)) {
600
601 this->flushTo(fAutoFlushTarget);
602 }
603 }
604}
605
reed@google.comac10a2d2010-12-22 21:39:39 +0000606bool GrInOrderDrawBuffer::geometryHints(GrVertexLayout vertexLayout,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000607 int* vertexCount,
608 int* indexCount) const {
609 // we will recommend a flush if the data could fit in a single
610 // preallocated buffer but none are left and it can't fit
611 // in the current buffer (which may not be prealloced).
reed@google.comac10a2d2010-12-22 21:39:39 +0000612 bool flush = false;
613 if (NULL != indexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000614 int32_t currIndices = fIndexPool.currentBufferIndices();
615 if (*indexCount > currIndices &&
616 (!fIndexPool.preallocatedBuffersRemaining() &&
617 *indexCount <= fIndexPool.preallocatedBufferIndices())) {
618
619 flush = true;
620 }
621 *indexCount = currIndices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000622 }
623 if (NULL != vertexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000624 int32_t currVertices = fVertexPool.currentBufferVertices(vertexLayout);
625 if (*vertexCount > currVertices &&
626 (!fVertexPool.preallocatedBuffersRemaining() &&
627 *vertexCount <= fVertexPool.preallocatedBufferVertices(vertexLayout))) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000628
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000629 flush = true;
reed@google.comac10a2d2010-12-22 21:39:39 +0000630 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000631 *vertexCount = currVertices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000632 }
633 return flush;
634}
635
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000636bool GrInOrderDrawBuffer::onReserveVertexSpace(GrVertexLayout vertexLayout,
637 int vertexCount,
638 void** vertices) {
639 GeometryPoolState& poolState = fGeoPoolStateStack.back();
640 GrAssert(vertexCount > 0);
641 GrAssert(NULL != vertices);
642 GrAssert(0 == poolState.fUsedPoolVertexBytes);
643
644 *vertices = fVertexPool.makeSpace(vertexLayout,
645 vertexCount,
646 &poolState.fPoolVertexBuffer,
647 &poolState.fPoolStartVertex);
648 return NULL != *vertices;
649}
650
651bool GrInOrderDrawBuffer::onReserveIndexSpace(int indexCount, void** indices) {
652 GeometryPoolState& poolState = fGeoPoolStateStack.back();
653 GrAssert(indexCount > 0);
654 GrAssert(NULL != indices);
655 GrAssert(0 == poolState.fUsedPoolIndexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000656
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000657 *indices = fIndexPool.makeSpace(indexCount,
658 &poolState.fPoolIndexBuffer,
659 &poolState.fPoolStartIndex);
660 return NULL != *indices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000661}
662
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000663void GrInOrderDrawBuffer::releaseReservedVertexSpace() {
664 GeometryPoolState& poolState = fGeoPoolStateStack.back();
665 const GeometrySrcState& geoSrc = this->getGeomSrc();
666
667 GrAssert(kReserved_GeometrySrcType == geoSrc.fVertexSrc);
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000668
669 // When the caller reserved vertex buffer space we gave it back a pointer
670 // provided by the vertex buffer pool. At each draw we tracked the largest
671 // offset into the pool's pointer that was referenced. Now we return to the
672 // pool any portion at the tail of the allocation that no draw referenced.
673 size_t reservedVertexBytes = VertexSize(geoSrc.fVertexLayout) *
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000674 geoSrc.fVertexCount;
675 fVertexPool.putBack(reservedVertexBytes -
676 poolState.fUsedPoolVertexBytes);
677 poolState.fUsedPoolVertexBytes = 0;
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000678 poolState.fPoolVertexBuffer = NULL;
679 poolState.fPoolStartVertex = 0;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000680}
681
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000682void GrInOrderDrawBuffer::releaseReservedIndexSpace() {
683 GeometryPoolState& poolState = fGeoPoolStateStack.back();
684 const GeometrySrcState& geoSrc = this->getGeomSrc();
685
686 GrAssert(kReserved_GeometrySrcType == geoSrc.fIndexSrc);
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000687
688 // Similar to releaseReservedVertexSpace we return any unused portion at
689 // the tail
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000690 size_t reservedIndexBytes = sizeof(uint16_t) * geoSrc.fIndexCount;
691 fIndexPool.putBack(reservedIndexBytes - poolState.fUsedPoolIndexBytes);
692 poolState.fUsedPoolIndexBytes = 0;
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000693 poolState.fPoolIndexBuffer = NULL;
694 poolState.fPoolStartIndex = 0;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000695}
696
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000697void GrInOrderDrawBuffer::onSetVertexSourceToArray(const void* vertexArray,
698 int vertexCount) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000699
700 GeometryPoolState& poolState = fGeoPoolStateStack.back();
701 GrAssert(0 == poolState.fUsedPoolVertexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000702#if GR_DEBUG
703 bool success =
704#endif
bsalomon@google.come79c8152012-03-29 19:07:12 +0000705 fVertexPool.appendVertices(this->getVertexLayout(),
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000706 vertexCount,
707 vertexArray,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000708 &poolState.fPoolVertexBuffer,
709 &poolState.fPoolStartVertex);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000710 GR_DEBUGASSERT(success);
711}
712
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000713void GrInOrderDrawBuffer::onSetIndexSourceToArray(const void* indexArray,
714 int indexCount) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000715 GeometryPoolState& poolState = fGeoPoolStateStack.back();
716 GrAssert(0 == poolState.fUsedPoolIndexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000717#if GR_DEBUG
718 bool success =
719#endif
720 fIndexPool.appendIndices(indexCount,
721 indexArray,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000722 &poolState.fPoolIndexBuffer,
723 &poolState.fPoolStartIndex);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000724 GR_DEBUGASSERT(success);
reed@google.comac10a2d2010-12-22 21:39:39 +0000725}
726
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000727void GrInOrderDrawBuffer::releaseVertexArray() {
728 // When the client provides an array as the vertex source we handled it
729 // by copying their array into reserved space.
730 this->GrInOrderDrawBuffer::releaseReservedVertexSpace();
731}
732
733void GrInOrderDrawBuffer::releaseIndexArray() {
734 // When the client provides an array as the index source we handled it
735 // by copying their array into reserved space.
736 this->GrInOrderDrawBuffer::releaseReservedIndexSpace();
737}
738
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000739void GrInOrderDrawBuffer::geometrySourceWillPush() {
740 GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
741 poolState.fUsedPoolVertexBytes = 0;
742 poolState.fUsedPoolIndexBytes = 0;
bsalomon@google.com934c5702012-03-20 21:17:58 +0000743 this->resetDrawTracking();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000744#if GR_DEBUG
745 poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0;
746 poolState.fPoolStartVertex = ~0;
747 poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0;
748 poolState.fPoolStartIndex = ~0;
749#endif
750}
751
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000752void GrInOrderDrawBuffer::geometrySourceWillPop(
753 const GeometrySrcState& restoredState) {
754 GrAssert(fGeoPoolStateStack.count() > 1);
755 fGeoPoolStateStack.pop_back();
756 GeometryPoolState& poolState = fGeoPoolStateStack.back();
757 // we have to assume that any slack we had in our vertex/index data
758 // is now unreleasable because data may have been appended later in the
759 // pool.
760 if (kReserved_GeometrySrcType == restoredState.fVertexSrc ||
761 kArray_GeometrySrcType == restoredState.fVertexSrc) {
762 poolState.fUsedPoolVertexBytes =
763 VertexSize(restoredState.fVertexLayout) *
764 restoredState.fVertexCount;
765 }
766 if (kReserved_GeometrySrcType == restoredState.fIndexSrc ||
767 kArray_GeometrySrcType == restoredState.fIndexSrc) {
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000768 poolState.fUsedPoolIndexBytes = sizeof(uint16_t) *
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000769 restoredState.fIndexCount;
770 }
bsalomon@google.com934c5702012-03-20 21:17:58 +0000771 this->resetDrawTracking();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000772}
773
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000774bool GrInOrderDrawBuffer::needsNewState() const {
775 if (fStates.empty()) {
776 return true;
777 } else {
bsalomon@google.com873ea0c2012-03-30 15:55:32 +0000778 return fStates.back() != this->getDrawState();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000779 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000780}
781
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000782void GrInOrderDrawBuffer::pushState() {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000783 const GrDrawState& drawState = this->getDrawState();
tomhudson@google.com93813632011-10-27 20:21:16 +0000784 for (int s = 0; s < GrDrawState::kNumStages; ++s) {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000785 GrSafeRef(drawState.getTexture(s));
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000786 }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000787 GrSafeRef(drawState.getRenderTarget());
bsalomon@google.com873ea0c2012-03-30 15:55:32 +0000788 fStates.push_back(this->getDrawState());
robertphillips@google.com1942c052012-05-03 17:58:27 +0000789
790 // Any textures that are added to the stored state need to be
791 // reffed so the unref in reset doesn't inappropriately free them
792 fStates.back().enableState(GrDrawState::kTexturesNeedRef_StateBit);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000793 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000794
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000795bool GrInOrderDrawBuffer::needsNewClip() const {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000796 if (this->getDrawState().isClipState()) {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000797 if (fClips.empty() || (fClipSet && fClips.back() != fClip)) {
798 return true;
799 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000800 }
801 return false;
802}
bsalomon@google.comd302f142011-03-03 13:54:13 +0000803
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000804void GrInOrderDrawBuffer::pushClip() {
805 fClips.push_back() = fClip;
806 fClipSet = false;
reed@google.comac10a2d2010-12-22 21:39:39 +0000807}
bsalomon@google.comd302f142011-03-03 13:54:13 +0000808
bsalomon@google.comdea2f8d2011-08-01 15:51:05 +0000809void GrInOrderDrawBuffer::clipWillBeSet(const GrClip& newClip) {
810 INHERITED::clipWillBeSet(newClip);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000811 fClipSet = true;
812}