blob: 2bdfb0d5f3731faef0b67a04f5d836bcb9815414 [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
bsalomon@google.com5b819c12012-03-28 21:34:22 +000010
reed@google.comac10a2d2010-12-22 21:39:39 +000011#include "GrInOrderDrawBuffer.h"
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +000012#include "GrRenderTarget.h"
reed@google.comac10a2d2010-12-22 21:39:39 +000013#include "GrTexture.h"
bsalomon@google.com1c13c962011-02-14 16:51:21 +000014#include "GrBufferAllocPool.h"
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000015#include "GrIndexBuffer.h"
16#include "GrVertexBuffer.h"
reed@google.comac10a2d2010-12-22 21:39:39 +000017#include "GrGpu.h"
18
bsalomon@google.com471d4712011-08-23 15:45:25 +000019GrInOrderDrawBuffer::GrInOrderDrawBuffer(const GrGpu* gpu,
20 GrVertexBufferAllocPool* vertexPool,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000021 GrIndexBufferAllocPool* indexPool)
bsalomon@google.com97805382012-03-13 14:32:07 +000022 : fAutoFlushTarget(NULL)
23 , fClipSet(true)
robertphillips@google.com69705572012-03-21 19:46:50 +000024 , fVertexPool(*vertexPool)
25 , fIndexPool(*indexPool)
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000026 , fLastRectVertexLayout(0)
27 , fQuadIndexBuffer(NULL)
28 , fMaxQuads(0)
robertphillips@google.com69705572012-03-21 19:46:50 +000029 , fCurrQuad(0) {
bsalomon@google.com18c9c192011-09-22 21:01:31 +000030
31 fCaps = gpu->getCaps();
32
bsalomon@google.com1c13c962011-02-14 16:51:21 +000033 GrAssert(NULL != vertexPool);
34 GrAssert(NULL != indexPool);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000035
36 GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
37 poolState.fUsedPoolVertexBytes = 0;
38 poolState.fUsedPoolIndexBytes = 0;
39#if GR_DEBUG
40 poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0;
41 poolState.fPoolStartVertex = ~0;
42 poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0;
43 poolState.fPoolStartIndex = ~0;
44#endif
bsalomon@google.com934c5702012-03-20 21:17:58 +000045 fInstancedDrawTracker.reset();
reed@google.comac10a2d2010-12-22 21:39:39 +000046}
47
48GrInOrderDrawBuffer::~GrInOrderDrawBuffer() {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000049 this->reset();
bsalomon@google.com4a018bb2011-10-28 19:50:21 +000050 // This must be called by before the GrDrawTarget destructor
51 this->releaseGeometry();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000052 GrSafeUnref(fQuadIndexBuffer);
bsalomon@google.com97805382012-03-13 14:32:07 +000053 GrSafeUnref(fAutoFlushTarget);
reed@google.comac10a2d2010-12-22 21:39:39 +000054}
55
bsalomon@google.com5b819c12012-03-28 21:34:22 +000056void GrInOrderDrawBuffer::initializeDrawStateAndClip(const GrDrawTarget& target) {
57 this->copyDrawState(target);
58 this->setClip(target.getClip());
59}
60
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000061void GrInOrderDrawBuffer::setQuadIndexBuffer(const GrIndexBuffer* indexBuffer) {
62 bool newIdxBuffer = fQuadIndexBuffer != indexBuffer;
63 if (newIdxBuffer) {
64 GrSafeUnref(fQuadIndexBuffer);
65 fQuadIndexBuffer = indexBuffer;
66 GrSafeRef(fQuadIndexBuffer);
67 fCurrQuad = 0;
68 fMaxQuads = (NULL == indexBuffer) ? 0 : indexBuffer->maxQuads();
69 } else {
bsalomon@google.comd302f142011-03-03 13:54:13 +000070 GrAssert((NULL == indexBuffer && 0 == fMaxQuads) ||
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000071 (indexBuffer->maxQuads() == fMaxQuads));
72 }
73}
74
bsalomon@google.com934c5702012-03-20 21:17:58 +000075////////////////////////////////////////////////////////////////////////////////
76
77void GrInOrderDrawBuffer::resetDrawTracking() {
78 fCurrQuad = 0;
79 fInstancedDrawTracker.reset();
80}
81
bsalomon@google.comd302f142011-03-03 13:54:13 +000082void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000083 const GrMatrix* matrix,
bsalomon@google.com39ee0ff2011-12-06 15:32:52 +000084 StageMask stageMask,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000085 const GrRect* srcRects[],
86 const GrMatrix* srcMatrices[]) {
bsalomon@google.comd302f142011-03-03 13:54:13 +000087
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000088 GrAssert(!(NULL == fQuadIndexBuffer && fCurrQuad));
89 GrAssert(!(fDraws.empty() && fCurrQuad));
90 GrAssert(!(0 != fMaxQuads && NULL == fQuadIndexBuffer));
91
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +000092 GrDrawState* drawState = this->drawState();
93
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000094 // if we have a quad IB then either append to the previous run of
95 // rects or start a new run
96 if (fMaxQuads) {
bsalomon@google.comd302f142011-03-03 13:54:13 +000097
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000098 bool appendToPreviousDraw = false;
bsalomon@google.com39ee0ff2011-12-06 15:32:52 +000099 GrVertexLayout layout = GetRectVertexLayout(stageMask, srcRects);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000100 AutoReleaseGeometry geo(this, layout, 4, 0);
bsalomon@google.com6513cd02011-08-05 20:12:30 +0000101 if (!geo.succeeded()) {
102 GrPrintf("Failed to get space for vertices!\n");
103 return;
104 }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000105 GrMatrix combinedMatrix = drawState->getViewMatrix();
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000106 // We go to device space so that matrix changes allow us to concat
107 // rect draws. When the caller has provided explicit source rects
108 // then we don't want to modify the sampler matrices. Otherwise we do
109 // we have to account for the view matrix change in the sampler
110 // matrices.
111 StageMask devCoordMask = (NULL == srcRects) ? stageMask : 0;
112 GrDrawTarget::AutoDeviceCoordDraw adcd(this, devCoordMask);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000113 if (NULL != matrix) {
114 combinedMatrix.preConcat(*matrix);
115 }
116
117 SetRectVertices(rect, &combinedMatrix, srcRects, srcMatrices, layout, geo.vertices());
118
119 // we don't want to miss an opportunity to batch rects together
120 // simply because the clip has changed if the clip doesn't affect
121 // the rect.
122 bool disabledClip = false;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000123 if (drawState->isClipState() && fClip.isRect()) {
bsalomon@google.comd302f142011-03-03 13:54:13 +0000124
bsalomon@google.com0b50b2e2011-03-08 21:07:21 +0000125 GrRect clipRect = fClip.getRect(0);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000126 // If the clip rect touches the edge of the viewport, extended it
127 // out (close) to infinity to avoid bogus intersections.
bsalomon@google.comd302f142011-03-03 13:54:13 +0000128 // We might consider a more exact clip to viewport if this
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000129 // conservative test fails.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000130 const GrRenderTarget* target = drawState->getRenderTarget();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000131 if (0 >= clipRect.fLeft) {
132 clipRect.fLeft = GR_ScalarMin;
133 }
134 if (target->width() <= clipRect.fRight) {
135 clipRect.fRight = GR_ScalarMax;
136 }
137 if (0 >= clipRect.top()) {
138 clipRect.fTop = GR_ScalarMin;
139 }
140 if (target->height() <= clipRect.fBottom) {
141 clipRect.fBottom = GR_ScalarMax;
142 }
143 int stride = VertexSize(layout);
144 bool insideClip = true;
145 for (int v = 0; v < 4; ++v) {
146 const GrPoint& p = *GetVertexPoint(geo.vertices(), v, stride);
147 if (!clipRect.contains(p)) {
148 insideClip = false;
149 break;
150 }
151 }
152 if (insideClip) {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000153 drawState->disableState(GrDrawState::kClip_StateBit);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000154 disabledClip = true;
155 }
156 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000157 if (!needsNewClip() && !needsNewState() && fCurrQuad > 0 &&
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000158 fCurrQuad < fMaxQuads && layout == fLastRectVertexLayout) {
159
160 int vsize = VertexSize(layout);
bsalomon@google.comd302f142011-03-03 13:54:13 +0000161
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000162 Draw& lastDraw = fDraws.back();
163
164 GrAssert(lastDraw.fIndexBuffer == fQuadIndexBuffer);
165 GrAssert(kTriangles_PrimitiveType == lastDraw.fPrimitiveType);
166 GrAssert(0 == lastDraw.fVertexCount % 4);
167 GrAssert(0 == lastDraw.fIndexCount % 6);
168 GrAssert(0 == lastDraw.fStartIndex);
169
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000170 GeometryPoolState& poolState = fGeoPoolStateStack.back();
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000171 bool clearSinceLastDraw =
172 fClears.count() &&
173 fClears.back().fBeforeDrawIdx == fDraws.count();
174
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000175 appendToPreviousDraw =
176 !clearSinceLastDraw &&
177 lastDraw.fVertexBuffer == poolState.fPoolVertexBuffer &&
178 (fCurrQuad * 4 + lastDraw.fStartVertex) == poolState.fPoolStartVertex;
179
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000180 if (appendToPreviousDraw) {
181 lastDraw.fVertexCount += 4;
182 lastDraw.fIndexCount += 6;
183 fCurrQuad += 1;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000184 // we reserved above, so we should be the first
185 // use of this vertex reserveation.
186 GrAssert(0 == poolState.fUsedPoolVertexBytes);
187 poolState.fUsedPoolVertexBytes = 4 * vsize;
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000188 }
189 }
190 if (!appendToPreviousDraw) {
191 this->setIndexSourceToBuffer(fQuadIndexBuffer);
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000192 this->drawIndexed(kTriangles_PrimitiveType, 0, 0, 4, 6);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000193 fCurrQuad = 1;
194 fLastRectVertexLayout = layout;
195 }
196 if (disabledClip) {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000197 drawState->enableState(GrDrawState::kClip_StateBit);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000198 }
bsalomon@google.com934c5702012-03-20 21:17:58 +0000199 fInstancedDrawTracker.reset();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000200 } else {
bsalomon@google.com39ee0ff2011-12-06 15:32:52 +0000201 INHERITED::drawRect(rect, matrix, stageMask, srcRects, srcMatrices);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000202 }
203}
204
bsalomon@google.com934c5702012-03-20 21:17:58 +0000205void GrInOrderDrawBuffer::drawIndexedInstances(GrPrimitiveType type,
206 int instanceCount,
207 int verticesPerInstance,
208 int indicesPerInstance) {
209 if (!verticesPerInstance || !indicesPerInstance) {
210 return;
211 }
212
213 const GeometrySrcState& geomSrc = this->getGeomSrc();
214
215 // we only attempt to concat the case when reserved verts are used with
216 // an index buffer.
217 if (kReserved_GeometrySrcType == geomSrc.fVertexSrc &&
218 kBuffer_GeometrySrcType == geomSrc.fIndexSrc) {
219
220 Draw* draw = NULL;
221 // if the last draw used the same indices/vertices per shape then we
222 // may be able to append to it.
223 if (verticesPerInstance == fInstancedDrawTracker.fVerticesPerInstance &&
224 indicesPerInstance == fInstancedDrawTracker.fIndicesPerInstance) {
225 GrAssert(fDraws.count());
226 draw = &fDraws.back();
227 }
228
229 bool clipChanged = this->needsNewClip();
230 bool stateChanged = this->needsNewState();
231 if (clipChanged) {
232 this->pushClip();
233 }
234 if (stateChanged) {
235 this->pushState();
236 }
237
238 GeometryPoolState& poolState = fGeoPoolStateStack.back();
239 const GrVertexBuffer* vertexBuffer = poolState.fPoolVertexBuffer;
240
241 // Check whether the draw is compatible with this draw in order to
242 // append
243 if (NULL == draw ||
244 clipChanged ||
245 stateChanged ||
246 draw->fIndexBuffer != geomSrc.fIndexBuffer ||
247 draw->fPrimitiveType != type ||
248 draw->fVertexBuffer != vertexBuffer) {
249
250 draw = &fDraws.push_back();
251 draw->fClipChanged = clipChanged;
252 draw->fStateChanged = stateChanged;
253 draw->fIndexBuffer = geomSrc.fIndexBuffer;
254 geomSrc.fIndexBuffer->ref();
255 draw->fVertexBuffer = vertexBuffer;
256 vertexBuffer->ref();
257 draw->fPrimitiveType = type;
258 draw->fStartIndex = 0;
259 draw->fIndexCount = 0;
260 draw->fStartVertex = poolState.fPoolStartVertex;
261 draw->fVertexCount = 0;
262 draw->fVertexLayout = geomSrc.fVertexLayout;
263 } else {
264 GrAssert(!(draw->fIndexCount % indicesPerInstance));
265 GrAssert(!(draw->fVertexCount % verticesPerInstance));
266 GrAssert(poolState.fPoolStartVertex == draw->fStartVertex +
267 draw->fVertexCount);
268 }
269
270 // how many instances can be in a single draw
271 int maxInstancesPerDraw = this->indexCountInCurrentSource() /
272 indicesPerInstance;
273 if (!maxInstancesPerDraw) {
274 return;
275 }
276 // how many instances should be concat'ed onto draw
277 int instancesToConcat = maxInstancesPerDraw - draw->fVertexCount /
278 verticesPerInstance;
279 if (maxInstancesPerDraw > instanceCount) {
280 maxInstancesPerDraw = instanceCount;
281 if (instancesToConcat > instanceCount) {
282 instancesToConcat = instanceCount;
283 }
284 }
285
286 // update the amount of reserved data actually referenced in draws
287 size_t vertexBytes = instanceCount * verticesPerInstance *
288 VertexSize(draw->fVertexLayout);
289 poolState.fUsedPoolVertexBytes =
290 GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
291
292 while (instanceCount) {
293 if (!instancesToConcat) {
294 int startVertex = draw->fStartVertex + draw->fVertexCount;
295 draw = &fDraws.push_back();
296 draw->fClipChanged = false;
297 draw->fStateChanged = false;
298 draw->fIndexBuffer = geomSrc.fIndexBuffer;
299 geomSrc.fIndexBuffer->ref();
300 draw->fVertexBuffer = vertexBuffer;
301 vertexBuffer->ref();
302 draw->fPrimitiveType = type;
303 draw->fStartIndex = 0;
304 draw->fStartVertex = startVertex;
305 draw->fVertexCount = 0;
306 draw->fVertexLayout = geomSrc.fVertexLayout;
307 instancesToConcat = maxInstancesPerDraw;
308 }
309 draw->fVertexCount += instancesToConcat * verticesPerInstance;
310 draw->fIndexCount += instancesToConcat * indicesPerInstance;
311 instanceCount -= instancesToConcat;
312 instancesToConcat = 0;
313 }
314
315 // update draw tracking for next draw
316 fCurrQuad = 0;
317 fInstancedDrawTracker.fVerticesPerInstance = verticesPerInstance;
318 fInstancedDrawTracker.fIndicesPerInstance = indicesPerInstance;
319 } else {
320 this->INHERITED::drawIndexedInstances(type,
321 instanceCount,
322 verticesPerInstance,
323 indicesPerInstance);
324 }
325
326}
327
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000328void GrInOrderDrawBuffer::onDrawIndexed(GrPrimitiveType primitiveType,
329 int startVertex,
330 int startIndex,
331 int vertexCount,
332 int indexCount) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000333
334 if (!vertexCount || !indexCount) {
335 return;
336 }
337
bsalomon@google.com934c5702012-03-20 21:17:58 +0000338 this->resetDrawTracking();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000339
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000340 GeometryPoolState& poolState = fGeoPoolStateStack.back();
341
reed@google.comac10a2d2010-12-22 21:39:39 +0000342 Draw& draw = fDraws.push_back();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000343 draw.fPrimitiveType = primitiveType;
reed@google.comac10a2d2010-12-22 21:39:39 +0000344 draw.fStartVertex = startVertex;
345 draw.fStartIndex = startIndex;
346 draw.fVertexCount = vertexCount;
347 draw.fIndexCount = indexCount;
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000348
349 draw.fClipChanged = this->needsNewClip();
350 if (draw.fClipChanged) {
351 this->pushClip();
352 }
353
354 draw.fStateChanged = this->needsNewState();
355 if (draw.fStateChanged) {
356 this->pushState();
357 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000358
bsalomon@google.come79c8152012-03-29 19:07:12 +0000359 draw.fVertexLayout = this->getVertexLayout();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000360 switch (this->getGeomSrc().fVertexSrc) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000361 case kBuffer_GeometrySrcType:
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000362 draw.fVertexBuffer = this->getGeomSrc().fVertexBuffer;
reed@google.comac10a2d2010-12-22 21:39:39 +0000363 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000364 case kReserved_GeometrySrcType: // fallthrough
365 case kArray_GeometrySrcType: {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000366 size_t vertexBytes = (vertexCount + startVertex) *
bsalomon@google.come79c8152012-03-29 19:07:12 +0000367 VertexSize(draw.fVertexLayout);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000368 poolState.fUsedPoolVertexBytes =
369 GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
370 draw.fVertexBuffer = poolState.fPoolVertexBuffer;
371 draw.fStartVertex += poolState.fPoolStartVertex;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000372 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000373 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000374 default:
375 GrCrash("unknown geom src type");
reed@google.comac10a2d2010-12-22 21:39:39 +0000376 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000377 draw.fVertexBuffer->ref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000378
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000379 switch (this->getGeomSrc().fIndexSrc) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000380 case kBuffer_GeometrySrcType:
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000381 draw.fIndexBuffer = this->getGeomSrc().fIndexBuffer;
reed@google.comac10a2d2010-12-22 21:39:39 +0000382 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000383 case kReserved_GeometrySrcType: // fallthrough
384 case kArray_GeometrySrcType: {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000385 size_t indexBytes = (indexCount + startIndex) * sizeof(uint16_t);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000386 poolState.fUsedPoolIndexBytes =
387 GrMax(poolState.fUsedPoolIndexBytes, indexBytes);
388 draw.fIndexBuffer = poolState.fPoolIndexBuffer;
bsalomon@google.comd127ffe2012-02-24 20:11:52 +0000389 draw.fStartIndex += poolState.fPoolStartIndex;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000390 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000391 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000392 default:
393 GrCrash("unknown geom src type");
reed@google.comac10a2d2010-12-22 21:39:39 +0000394 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000395 draw.fIndexBuffer->ref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000396}
397
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000398void GrInOrderDrawBuffer::onDrawNonIndexed(GrPrimitiveType primitiveType,
399 int startVertex,
400 int vertexCount) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000401 if (!vertexCount) {
402 return;
403 }
404
bsalomon@google.com934c5702012-03-20 21:17:58 +0000405 this->resetDrawTracking();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000406
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000407 GeometryPoolState& poolState = fGeoPoolStateStack.back();
408
reed@google.comac10a2d2010-12-22 21:39:39 +0000409 Draw& draw = fDraws.push_back();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000410 draw.fPrimitiveType = primitiveType;
reed@google.comac10a2d2010-12-22 21:39:39 +0000411 draw.fStartVertex = startVertex;
412 draw.fStartIndex = 0;
413 draw.fVertexCount = vertexCount;
414 draw.fIndexCount = 0;
415
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000416 draw.fClipChanged = this->needsNewClip();
417 if (draw.fClipChanged) {
418 this->pushClip();
419 }
420
421 draw.fStateChanged = this->needsNewState();
422 if (draw.fStateChanged) {
423 this->pushState();
424 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000425
bsalomon@google.come79c8152012-03-29 19:07:12 +0000426 draw.fVertexLayout = this->getVertexLayout();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000427 switch (this->getGeomSrc().fVertexSrc) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000428 case kBuffer_GeometrySrcType:
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000429 draw.fVertexBuffer = this->getGeomSrc().fVertexBuffer;
reed@google.comac10a2d2010-12-22 21:39:39 +0000430 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000431 case kReserved_GeometrySrcType: // fallthrough
432 case kArray_GeometrySrcType: {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000433 size_t vertexBytes = (vertexCount + startVertex) *
bsalomon@google.come79c8152012-03-29 19:07:12 +0000434 VertexSize(draw.fVertexLayout);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000435 poolState.fUsedPoolVertexBytes =
436 GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
437 draw.fVertexBuffer = poolState.fPoolVertexBuffer;
438 draw.fStartVertex += poolState.fPoolStartVertex;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000439 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000440 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000441 default:
442 GrCrash("unknown geom src type");
reed@google.comac10a2d2010-12-22 21:39:39 +0000443 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000444 draw.fVertexBuffer->ref();
445 draw.fIndexBuffer = NULL;
reed@google.comac10a2d2010-12-22 21:39:39 +0000446}
447
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000448void GrInOrderDrawBuffer::clear(const GrIRect* rect, GrColor color) {
449 GrIRect r;
450 if (NULL == rect) {
451 // We could do something smart and remove previous draws and clears to
452 // the current render target. If we get that smart we have to make sure
453 // those draws aren't read before this clear (render-to-texture).
454 r.setLTRB(0, 0,
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000455 this->getDrawState().getRenderTarget()->width(),
456 this->getDrawState().getRenderTarget()->height());
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000457 rect = &r;
458 }
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000459 Clear& clr = fClears.push_back();
460 clr.fColor = color;
461 clr.fBeforeDrawIdx = fDraws.count();
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000462 clr.fRect = *rect;
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000463}
464
reed@google.comac10a2d2010-12-22 21:39:39 +0000465void GrInOrderDrawBuffer::reset() {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000466 GrAssert(1 == fGeoPoolStateStack.count());
467 this->resetVertexSource();
468 this->resetIndexSource();
reed@google.comac10a2d2010-12-22 21:39:39 +0000469 uint32_t numStates = fStates.count();
470 for (uint32_t i = 0; i < numStates; ++i) {
tomhudson@google.com93813632011-10-27 20:21:16 +0000471 const GrDrawState& dstate = this->accessSavedDrawState(fStates[i]);
472 for (int s = 0; s < GrDrawState::kNumStages; ++s) {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000473 GrSafeUnref(dstate.getTexture(s));
reed@google.comac10a2d2010-12-22 21:39:39 +0000474 }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000475 GrSafeUnref(dstate.getRenderTarget());
reed@google.comac10a2d2010-12-22 21:39:39 +0000476 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000477 int numDraws = fDraws.count();
478 for (int d = 0; d < numDraws; ++d) {
479 // we always have a VB, but not always an IB
480 GrAssert(NULL != fDraws[d].fVertexBuffer);
481 fDraws[d].fVertexBuffer->unref();
482 GrSafeUnref(fDraws[d].fIndexBuffer);
483 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000484 fDraws.reset();
485 fStates.reset();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000486
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000487 fClears.reset();
488
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000489 fVertexPool.reset();
490 fIndexPool.reset();
491
reed@google.comac10a2d2010-12-22 21:39:39 +0000492 fClips.reset();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000493
bsalomon@google.com934c5702012-03-20 21:17:58 +0000494 this->resetDrawTracking();
reed@google.comac10a2d2010-12-22 21:39:39 +0000495}
496
497void GrInOrderDrawBuffer::playback(GrDrawTarget* target) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000498 GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fVertexSrc);
499 GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fIndexSrc);
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000500
reed@google.comac10a2d2010-12-22 21:39:39 +0000501 GrAssert(NULL != target);
502 GrAssert(target != this); // not considered and why?
503
bsalomon@google.com898d9e52011-04-26 13:22:33 +0000504 int numDraws = fDraws.count();
reed@google.comac10a2d2010-12-22 21:39:39 +0000505 if (!numDraws) {
506 return;
507 }
508
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000509 fVertexPool.unlock();
510 fIndexPool.unlock();
reed@google.comac10a2d2010-12-22 21:39:39 +0000511
reed@google.comac10a2d2010-12-22 21:39:39 +0000512 GrDrawTarget::AutoClipRestore acr(target);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000513 AutoGeometryPush agp(target);
bsalomon@google.coma5d056a2012-03-27 15:59:58 +0000514 GrDrawState* prevDrawState = target->drawState();
515 prevDrawState->ref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000516
bsalomon@google.com6a77cc52011-04-28 17:33:34 +0000517 int currState = ~0;
518 int currClip = ~0;
519 int currClear = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000520
bsalomon@google.com898d9e52011-04-26 13:22:33 +0000521 for (int i = 0; i < numDraws; ++i) {
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000522 while (currClear < fClears.count() &&
523 i == fClears[currClear].fBeforeDrawIdx) {
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000524 target->clear(&fClears[currClear].fRect, fClears[currClear].fColor);
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000525 ++currClear;
526 }
527
reed@google.comac10a2d2010-12-22 21:39:39 +0000528 const Draw& draw = fDraws[i];
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000529 if (draw.fStateChanged) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000530 ++currState;
bsalomon@google.coma5d056a2012-03-27 15:59:58 +0000531 GrDrawState* ds = &GrDrawTarget::accessSavedDrawState(fStates[currState]);
532 target->setDrawState(ds);
reed@google.comac10a2d2010-12-22 21:39:39 +0000533 }
534 if (draw.fClipChanged) {
535 ++currClip;
536 target->setClip(fClips[currClip]);
537 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000538
539 target->setVertexSourceToBuffer(draw.fVertexLayout, draw.fVertexBuffer);
540
reed@google.comac10a2d2010-12-22 21:39:39 +0000541 if (draw.fIndexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000542 target->setIndexSourceToBuffer(draw.fIndexBuffer);
543 }
544
545 if (draw.fIndexCount) {
546 target->drawIndexed(draw.fPrimitiveType,
reed@google.comac10a2d2010-12-22 21:39:39 +0000547 draw.fStartVertex,
548 draw.fStartIndex,
549 draw.fVertexCount,
550 draw.fIndexCount);
551 } else {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000552 target->drawNonIndexed(draw.fPrimitiveType,
reed@google.comac10a2d2010-12-22 21:39:39 +0000553 draw.fStartVertex,
554 draw.fVertexCount);
555 }
556 }
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000557 while (currClear < fClears.count()) {
558 GrAssert(fDraws.count() == fClears[currClear].fBeforeDrawIdx);
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000559 target->clear(&fClears[currClear].fRect, fClears[currClear].fColor);
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000560 ++currClear;
561 }
bsalomon@google.coma5d056a2012-03-27 15:59:58 +0000562 target->setDrawState(prevDrawState);
563 prevDrawState->unref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000564}
565
bsalomon@google.com97805382012-03-13 14:32:07 +0000566void GrInOrderDrawBuffer::setAutoFlushTarget(GrDrawTarget* target) {
567 GrSafeAssign(fAutoFlushTarget, target);
568}
569
570void GrInOrderDrawBuffer::willReserveVertexAndIndexSpace(
571 GrVertexLayout vertexLayout,
572 int vertexCount,
573 int indexCount) {
574 if (NULL != fAutoFlushTarget) {
575 // We use geometryHints() to know whether to flush the draw buffer. We
576 // can't flush if we are inside an unbalanced pushGeometrySource.
577 // Moreover, flushing blows away vertex and index data that was
578 // previously reserved. So if the vertex or index data is pulled from
579 // reserved space and won't be released by this request then we can't
580 // flush.
581 bool insideGeoPush = fGeoPoolStateStack.count() > 1;
582
583 bool unreleasedVertexSpace =
584 !vertexCount &&
585 kReserved_GeometrySrcType == this->getGeomSrc().fVertexSrc;
586
587 bool unreleasedIndexSpace =
588 !indexCount &&
589 kReserved_GeometrySrcType == this->getGeomSrc().fIndexSrc;
590
591 // we don't want to finalize any reserved geom on the target since
592 // we don't know that the client has finished writing to it.
593 bool targetHasReservedGeom =
594 fAutoFlushTarget->hasReservedVerticesOrIndices();
595
596 int vcount = vertexCount;
597 int icount = indexCount;
598
599 if (!insideGeoPush &&
600 !unreleasedVertexSpace &&
601 !unreleasedIndexSpace &&
602 !targetHasReservedGeom &&
603 this->geometryHints(vertexLayout, &vcount, &icount)) {
604
605 this->flushTo(fAutoFlushTarget);
606 }
607 }
608}
609
reed@google.comac10a2d2010-12-22 21:39:39 +0000610bool GrInOrderDrawBuffer::geometryHints(GrVertexLayout vertexLayout,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000611 int* vertexCount,
612 int* indexCount) const {
613 // we will recommend a flush if the data could fit in a single
614 // preallocated buffer but none are left and it can't fit
615 // in the current buffer (which may not be prealloced).
reed@google.comac10a2d2010-12-22 21:39:39 +0000616 bool flush = false;
617 if (NULL != indexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000618 int32_t currIndices = fIndexPool.currentBufferIndices();
619 if (*indexCount > currIndices &&
620 (!fIndexPool.preallocatedBuffersRemaining() &&
621 *indexCount <= fIndexPool.preallocatedBufferIndices())) {
622
623 flush = true;
624 }
625 *indexCount = currIndices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000626 }
627 if (NULL != vertexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000628 int32_t currVertices = fVertexPool.currentBufferVertices(vertexLayout);
629 if (*vertexCount > currVertices &&
630 (!fVertexPool.preallocatedBuffersRemaining() &&
631 *vertexCount <= fVertexPool.preallocatedBufferVertices(vertexLayout))) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000632
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000633 flush = true;
reed@google.comac10a2d2010-12-22 21:39:39 +0000634 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000635 *vertexCount = currVertices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000636 }
637 return flush;
638}
639
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000640bool GrInOrderDrawBuffer::onReserveVertexSpace(GrVertexLayout vertexLayout,
641 int vertexCount,
642 void** vertices) {
643 GeometryPoolState& poolState = fGeoPoolStateStack.back();
644 GrAssert(vertexCount > 0);
645 GrAssert(NULL != vertices);
646 GrAssert(0 == poolState.fUsedPoolVertexBytes);
647
648 *vertices = fVertexPool.makeSpace(vertexLayout,
649 vertexCount,
650 &poolState.fPoolVertexBuffer,
651 &poolState.fPoolStartVertex);
652 return NULL != *vertices;
653}
654
655bool GrInOrderDrawBuffer::onReserveIndexSpace(int indexCount, void** indices) {
656 GeometryPoolState& poolState = fGeoPoolStateStack.back();
657 GrAssert(indexCount > 0);
658 GrAssert(NULL != indices);
659 GrAssert(0 == poolState.fUsedPoolIndexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000660
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000661 *indices = fIndexPool.makeSpace(indexCount,
662 &poolState.fPoolIndexBuffer,
663 &poolState.fPoolStartIndex);
664 return NULL != *indices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000665}
666
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000667void GrInOrderDrawBuffer::releaseReservedVertexSpace() {
668 GeometryPoolState& poolState = fGeoPoolStateStack.back();
669 const GeometrySrcState& geoSrc = this->getGeomSrc();
670
671 GrAssert(kReserved_GeometrySrcType == geoSrc.fVertexSrc);
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000672
673 // When the caller reserved vertex buffer space we gave it back a pointer
674 // provided by the vertex buffer pool. At each draw we tracked the largest
675 // offset into the pool's pointer that was referenced. Now we return to the
676 // pool any portion at the tail of the allocation that no draw referenced.
677 size_t reservedVertexBytes = VertexSize(geoSrc.fVertexLayout) *
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000678 geoSrc.fVertexCount;
679 fVertexPool.putBack(reservedVertexBytes -
680 poolState.fUsedPoolVertexBytes);
681 poolState.fUsedPoolVertexBytes = 0;
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000682 poolState.fPoolVertexBuffer = NULL;
683 poolState.fPoolStartVertex = 0;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000684}
685
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000686void GrInOrderDrawBuffer::releaseReservedIndexSpace() {
687 GeometryPoolState& poolState = fGeoPoolStateStack.back();
688 const GeometrySrcState& geoSrc = this->getGeomSrc();
689
690 GrAssert(kReserved_GeometrySrcType == geoSrc.fIndexSrc);
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000691
692 // Similar to releaseReservedVertexSpace we return any unused portion at
693 // the tail
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000694 size_t reservedIndexBytes = sizeof(uint16_t) * geoSrc.fIndexCount;
695 fIndexPool.putBack(reservedIndexBytes - poolState.fUsedPoolIndexBytes);
696 poolState.fUsedPoolIndexBytes = 0;
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000697 poolState.fPoolIndexBuffer = NULL;
698 poolState.fPoolStartIndex = 0;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000699}
700
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000701void GrInOrderDrawBuffer::onSetVertexSourceToArray(const void* vertexArray,
702 int vertexCount) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000703
704 GeometryPoolState& poolState = fGeoPoolStateStack.back();
705 GrAssert(0 == poolState.fUsedPoolVertexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000706#if GR_DEBUG
707 bool success =
708#endif
bsalomon@google.come79c8152012-03-29 19:07:12 +0000709 fVertexPool.appendVertices(this->getVertexLayout(),
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000710 vertexCount,
711 vertexArray,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000712 &poolState.fPoolVertexBuffer,
713 &poolState.fPoolStartVertex);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000714 GR_DEBUGASSERT(success);
715}
716
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000717void GrInOrderDrawBuffer::onSetIndexSourceToArray(const void* indexArray,
718 int indexCount) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000719 GeometryPoolState& poolState = fGeoPoolStateStack.back();
720 GrAssert(0 == poolState.fUsedPoolIndexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000721#if GR_DEBUG
722 bool success =
723#endif
724 fIndexPool.appendIndices(indexCount,
725 indexArray,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000726 &poolState.fPoolIndexBuffer,
727 &poolState.fPoolStartIndex);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000728 GR_DEBUGASSERT(success);
reed@google.comac10a2d2010-12-22 21:39:39 +0000729}
730
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000731void GrInOrderDrawBuffer::releaseVertexArray() {
732 // When the client provides an array as the vertex source we handled it
733 // by copying their array into reserved space.
734 this->GrInOrderDrawBuffer::releaseReservedVertexSpace();
735}
736
737void GrInOrderDrawBuffer::releaseIndexArray() {
738 // When the client provides an array as the index source we handled it
739 // by copying their array into reserved space.
740 this->GrInOrderDrawBuffer::releaseReservedIndexSpace();
741}
742
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000743void GrInOrderDrawBuffer::geometrySourceWillPush() {
744 GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
745 poolState.fUsedPoolVertexBytes = 0;
746 poolState.fUsedPoolIndexBytes = 0;
bsalomon@google.com934c5702012-03-20 21:17:58 +0000747 this->resetDrawTracking();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000748#if GR_DEBUG
749 poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0;
750 poolState.fPoolStartVertex = ~0;
751 poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0;
752 poolState.fPoolStartIndex = ~0;
753#endif
754}
755
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000756void GrInOrderDrawBuffer::geometrySourceWillPop(
757 const GeometrySrcState& restoredState) {
758 GrAssert(fGeoPoolStateStack.count() > 1);
759 fGeoPoolStateStack.pop_back();
760 GeometryPoolState& poolState = fGeoPoolStateStack.back();
761 // we have to assume that any slack we had in our vertex/index data
762 // is now unreleasable because data may have been appended later in the
763 // pool.
764 if (kReserved_GeometrySrcType == restoredState.fVertexSrc ||
765 kArray_GeometrySrcType == restoredState.fVertexSrc) {
766 poolState.fUsedPoolVertexBytes =
767 VertexSize(restoredState.fVertexLayout) *
768 restoredState.fVertexCount;
769 }
770 if (kReserved_GeometrySrcType == restoredState.fIndexSrc ||
771 kArray_GeometrySrcType == restoredState.fIndexSrc) {
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000772 poolState.fUsedPoolIndexBytes = sizeof(uint16_t) *
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000773 restoredState.fIndexCount;
774 }
bsalomon@google.com934c5702012-03-20 21:17:58 +0000775 this->resetDrawTracking();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000776}
777
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000778bool GrInOrderDrawBuffer::needsNewState() const {
779 if (fStates.empty()) {
780 return true;
781 } else {
tomhudson@google.com93813632011-10-27 20:21:16 +0000782 const GrDrawState& old = this->accessSavedDrawState(fStates.back());
bsalomon@google.coma5d056a2012-03-27 15:59:58 +0000783 return old != this->getDrawState();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000784 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000785}
786
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000787void GrInOrderDrawBuffer::pushState() {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000788 const GrDrawState& drawState = this->getDrawState();
tomhudson@google.com93813632011-10-27 20:21:16 +0000789 for (int s = 0; s < GrDrawState::kNumStages; ++s) {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000790 GrSafeRef(drawState.getTexture(s));
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000791 }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000792 GrSafeRef(drawState.getRenderTarget());
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000793 this->saveCurrentDrawState(&fStates.push_back());
794 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000795
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000796bool GrInOrderDrawBuffer::needsNewClip() const {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000797 if (this->getDrawState().isClipState()) {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000798 if (fClips.empty() || (fClipSet && fClips.back() != fClip)) {
799 return true;
800 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000801 }
802 return false;
803}
bsalomon@google.comd302f142011-03-03 13:54:13 +0000804
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000805void GrInOrderDrawBuffer::pushClip() {
806 fClips.push_back() = fClip;
807 fClipSet = false;
reed@google.comac10a2d2010-12-22 21:39:39 +0000808}
bsalomon@google.comd302f142011-03-03 13:54:13 +0000809
bsalomon@google.comdea2f8d2011-08-01 15:51:05 +0000810void GrInOrderDrawBuffer::clipWillBeSet(const GrClip& newClip) {
811 INHERITED::clipWillBeSet(newClip);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000812 fClipSet = true;
813}