blob: d0bb225cf0a8b8c806f7fc28a62073aa44931835 [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.comded4f4b2012-06-28 18:48:06 +000011#include "GrBufferAllocPool.h"
12#include "GrGpu.h"
13#include "GrIndexBuffer.h"
14#include "GrPath.h"
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +000015#include "GrRenderTarget.h"
reed@google.comac10a2d2010-12-22 21:39:39 +000016#include "GrTexture.h"
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000017#include "GrVertexBuffer.h"
reed@google.comac10a2d2010-12-22 21:39:39 +000018
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.comc82a8b72012-06-21 20:15:48 +000029 , fFlushing(false) {
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.coma4f6b102012-06-26 21:04:22 +000045 this->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.com86afc2a2011-02-16 16:12:19 +000056void GrInOrderDrawBuffer::setQuadIndexBuffer(const GrIndexBuffer* indexBuffer) {
57 bool newIdxBuffer = fQuadIndexBuffer != indexBuffer;
58 if (newIdxBuffer) {
59 GrSafeUnref(fQuadIndexBuffer);
60 fQuadIndexBuffer = indexBuffer;
61 GrSafeRef(fQuadIndexBuffer);
62 fCurrQuad = 0;
63 fMaxQuads = (NULL == indexBuffer) ? 0 : indexBuffer->maxQuads();
64 } else {
bsalomon@google.comd302f142011-03-03 13:54:13 +000065 GrAssert((NULL == indexBuffer && 0 == fMaxQuads) ||
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000066 (indexBuffer->maxQuads() == fMaxQuads));
67 }
68}
69
bsalomon@google.com934c5702012-03-20 21:17:58 +000070////////////////////////////////////////////////////////////////////////////////
71
72void GrInOrderDrawBuffer::resetDrawTracking() {
73 fCurrQuad = 0;
74 fInstancedDrawTracker.reset();
75}
76
bsalomon@google.comd302f142011-03-03 13:54:13 +000077void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000078 const GrMatrix* matrix,
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.come3d32162012-07-20 13:37:06 +000093 GrVertexLayout layout = GetRectVertexLayout(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.
bsalomon@google.come3d32162012-07-20 13:37:06 +0000105 uint32_t explicitCoordMask = 0;
106 if (srcRects) {
107 for (int s = 0; s < GrDrawState::kNumStages; ++s) {
108 if (srcRects[s]) {
109 explicitCoordMask |= (1 << s);
110 }
111 }
112 }
113 GrDrawTarget::AutoDeviceCoordDraw adcd(this, explicitCoordMask);
114 if (!adcd.succeeded()) {
115 return;
116 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000117 if (NULL != matrix) {
118 combinedMatrix.preConcat(*matrix);
119 }
120
121 SetRectVertices(rect, &combinedMatrix, srcRects, srcMatrices, layout, geo.vertices());
122
123 // we don't want to miss an opportunity to batch rects together
124 // simply because the clip has changed if the clip doesn't affect
125 // the rect.
126 bool disabledClip = false;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000127 if (drawState->isClipState() && fClip.isRect()) {
bsalomon@google.comd302f142011-03-03 13:54:13 +0000128
robertphillips@google.coma6f11c42012-07-23 17:39:44 +0000129 GrClip::Iter iter(fClip, GrClip::Iter::kBottom_IterStart);
130 const GrClip::Iter::Clip* clip = iter.next();
131 GrAssert(NULL != clip && NULL != clip->fRect);
132
133 GrRect clipRect = *clip->fRect;
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000134 // If the clip rect touches the edge of the viewport, extended it
135 // out (close) to infinity to avoid bogus intersections.
bsalomon@google.comd302f142011-03-03 13:54:13 +0000136 // We might consider a more exact clip to viewport if this
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000137 // conservative test fails.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000138 const GrRenderTarget* target = drawState->getRenderTarget();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000139 if (0 >= clipRect.fLeft) {
140 clipRect.fLeft = GR_ScalarMin;
141 }
142 if (target->width() <= clipRect.fRight) {
143 clipRect.fRight = GR_ScalarMax;
144 }
145 if (0 >= clipRect.top()) {
146 clipRect.fTop = GR_ScalarMin;
147 }
148 if (target->height() <= clipRect.fBottom) {
149 clipRect.fBottom = GR_ScalarMax;
150 }
151 int stride = VertexSize(layout);
152 bool insideClip = true;
153 for (int v = 0; v < 4; ++v) {
154 const GrPoint& p = *GetVertexPoint(geo.vertices(), v, stride);
155 if (!clipRect.contains(p)) {
156 insideClip = false;
157 break;
158 }
159 }
160 if (insideClip) {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000161 drawState->disableState(GrDrawState::kClip_StateBit);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000162 disabledClip = true;
163 }
164 }
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000165 if (!this->needsNewClip() &&
166 !this->needsNewState() &&
167 fCurrQuad > 0 &&
168 fCurrQuad < fMaxQuads &&
169 layout == fLastRectVertexLayout) {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000170
171 int vsize = VertexSize(layout);
bsalomon@google.comd302f142011-03-03 13:54:13 +0000172
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000173 Draw& lastDraw = fDraws.back();
174
175 GrAssert(lastDraw.fIndexBuffer == fQuadIndexBuffer);
bsalomon@google.com47059542012-06-06 20:51:20 +0000176 GrAssert(kTriangles_GrPrimitiveType == lastDraw.fPrimitiveType);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000177 GrAssert(0 == lastDraw.fVertexCount % 4);
178 GrAssert(0 == lastDraw.fIndexCount % 6);
179 GrAssert(0 == lastDraw.fStartIndex);
180
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000181 GeometryPoolState& poolState = fGeoPoolStateStack.back();
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000182
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000183 appendToPreviousDraw =
184 kDraw_Cmd != fCmds.back() &&
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000185 lastDraw.fVertexBuffer == poolState.fPoolVertexBuffer &&
186 (fCurrQuad * 4 + lastDraw.fStartVertex) == poolState.fPoolStartVertex;
187
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000188 if (appendToPreviousDraw) {
189 lastDraw.fVertexCount += 4;
190 lastDraw.fIndexCount += 6;
191 fCurrQuad += 1;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000192 // we reserved above, so we should be the first
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000193 // use of this vertex reservation.
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000194 GrAssert(0 == poolState.fUsedPoolVertexBytes);
195 poolState.fUsedPoolVertexBytes = 4 * vsize;
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000196 }
197 }
198 if (!appendToPreviousDraw) {
199 this->setIndexSourceToBuffer(fQuadIndexBuffer);
bsalomon@google.com47059542012-06-06 20:51:20 +0000200 this->drawIndexed(kTriangles_GrPrimitiveType, 0, 0, 4, 6);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000201 fCurrQuad = 1;
202 fLastRectVertexLayout = layout;
203 }
204 if (disabledClip) {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000205 drawState->enableState(GrDrawState::kClip_StateBit);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000206 }
bsalomon@google.com934c5702012-03-20 21:17:58 +0000207 fInstancedDrawTracker.reset();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000208 } else {
bsalomon@google.come3d32162012-07-20 13:37:06 +0000209 INHERITED::drawRect(rect, matrix, srcRects, srcMatrices);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000210 }
211}
212
bsalomon@google.com934c5702012-03-20 21:17:58 +0000213void GrInOrderDrawBuffer::drawIndexedInstances(GrPrimitiveType type,
214 int instanceCount,
215 int verticesPerInstance,
216 int indicesPerInstance) {
217 if (!verticesPerInstance || !indicesPerInstance) {
218 return;
219 }
220
221 const GeometrySrcState& geomSrc = this->getGeomSrc();
222
223 // we only attempt to concat the case when reserved verts are used with
224 // an index buffer.
225 if (kReserved_GeometrySrcType == geomSrc.fVertexSrc &&
226 kBuffer_GeometrySrcType == geomSrc.fIndexSrc) {
227
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000228 if (this->needsNewClip()) {
229 this->recordClip();
230 }
231 if (this->needsNewState()) {
232 this->recordState();
233 }
234
bsalomon@google.com934c5702012-03-20 21:17:58 +0000235 Draw* draw = NULL;
236 // if the last draw used the same indices/vertices per shape then we
237 // may be able to append to it.
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000238 if (kDraw_Cmd == fCmds.back() &&
239 verticesPerInstance == fInstancedDrawTracker.fVerticesPerInstance &&
bsalomon@google.com934c5702012-03-20 21:17:58 +0000240 indicesPerInstance == fInstancedDrawTracker.fIndicesPerInstance) {
241 GrAssert(fDraws.count());
242 draw = &fDraws.back();
243 }
244
bsalomon@google.com934c5702012-03-20 21:17:58 +0000245 GeometryPoolState& poolState = fGeoPoolStateStack.back();
246 const GrVertexBuffer* vertexBuffer = poolState.fPoolVertexBuffer;
247
248 // Check whether the draw is compatible with this draw in order to
249 // append
250 if (NULL == draw ||
bsalomon@google.com934c5702012-03-20 21:17:58 +0000251 draw->fIndexBuffer != geomSrc.fIndexBuffer ||
252 draw->fPrimitiveType != type ||
253 draw->fVertexBuffer != vertexBuffer) {
254
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000255 draw = this->recordDraw();
bsalomon@google.com934c5702012-03-20 21:17:58 +0000256 draw->fIndexBuffer = geomSrc.fIndexBuffer;
257 geomSrc.fIndexBuffer->ref();
258 draw->fVertexBuffer = vertexBuffer;
259 vertexBuffer->ref();
260 draw->fPrimitiveType = type;
261 draw->fStartIndex = 0;
262 draw->fIndexCount = 0;
263 draw->fStartVertex = poolState.fPoolStartVertex;
264 draw->fVertexCount = 0;
265 draw->fVertexLayout = geomSrc.fVertexLayout;
266 } else {
267 GrAssert(!(draw->fIndexCount % indicesPerInstance));
268 GrAssert(!(draw->fVertexCount % verticesPerInstance));
269 GrAssert(poolState.fPoolStartVertex == draw->fStartVertex +
270 draw->fVertexCount);
271 }
272
273 // how many instances can be in a single draw
274 int maxInstancesPerDraw = this->indexCountInCurrentSource() /
275 indicesPerInstance;
276 if (!maxInstancesPerDraw) {
277 return;
278 }
279 // how many instances should be concat'ed onto draw
280 int instancesToConcat = maxInstancesPerDraw - draw->fVertexCount /
281 verticesPerInstance;
282 if (maxInstancesPerDraw > instanceCount) {
283 maxInstancesPerDraw = instanceCount;
284 if (instancesToConcat > instanceCount) {
285 instancesToConcat = instanceCount;
286 }
287 }
288
289 // update the amount of reserved data actually referenced in draws
290 size_t vertexBytes = instanceCount * verticesPerInstance *
291 VertexSize(draw->fVertexLayout);
292 poolState.fUsedPoolVertexBytes =
293 GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
294
295 while (instanceCount) {
296 if (!instancesToConcat) {
297 int startVertex = draw->fStartVertex + draw->fVertexCount;
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000298 draw = this->recordDraw();
bsalomon@google.com934c5702012-03-20 21:17:58 +0000299 draw->fIndexBuffer = geomSrc.fIndexBuffer;
300 geomSrc.fIndexBuffer->ref();
301 draw->fVertexBuffer = vertexBuffer;
302 vertexBuffer->ref();
303 draw->fPrimitiveType = type;
304 draw->fStartIndex = 0;
305 draw->fStartVertex = startVertex;
306 draw->fVertexCount = 0;
307 draw->fVertexLayout = geomSrc.fVertexLayout;
308 instancesToConcat = maxInstancesPerDraw;
309 }
310 draw->fVertexCount += instancesToConcat * verticesPerInstance;
311 draw->fIndexCount += instancesToConcat * indicesPerInstance;
312 instanceCount -= instancesToConcat;
313 instancesToConcat = 0;
314 }
315
316 // update draw tracking for next draw
317 fCurrQuad = 0;
318 fInstancedDrawTracker.fVerticesPerInstance = verticesPerInstance;
319 fInstancedDrawTracker.fIndicesPerInstance = indicesPerInstance;
320 } else {
321 this->INHERITED::drawIndexedInstances(type,
322 instanceCount,
323 verticesPerInstance,
324 indicesPerInstance);
325 }
326
327}
328
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000329void GrInOrderDrawBuffer::onDrawIndexed(GrPrimitiveType primitiveType,
330 int startVertex,
331 int startIndex,
332 int vertexCount,
333 int indexCount) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000334
335 if (!vertexCount || !indexCount) {
336 return;
337 }
338
bsalomon@google.com934c5702012-03-20 21:17:58 +0000339 this->resetDrawTracking();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000340
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000341 GeometryPoolState& poolState = fGeoPoolStateStack.back();
342
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000343 if (this->needsNewClip()) {
344 this->recordClip();
345 }
346 if (this->needsNewState()) {
347 this->recordState();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000348 }
349
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000350 Draw* draw = this->recordDraw();
reed@google.comac10a2d2010-12-22 21:39:39 +0000351
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000352 draw->fPrimitiveType = primitiveType;
353 draw->fStartVertex = startVertex;
354 draw->fStartIndex = startIndex;
355 draw->fVertexCount = vertexCount;
356 draw->fIndexCount = indexCount;
357
358 draw->fVertexLayout = this->getVertexLayout();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000359 switch (this->getGeomSrc().fVertexSrc) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000360 case kBuffer_GeometrySrcType:
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000361 draw->fVertexBuffer = this->getGeomSrc().fVertexBuffer;
reed@google.comac10a2d2010-12-22 21:39:39 +0000362 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000363 case kReserved_GeometrySrcType: // fallthrough
364 case kArray_GeometrySrcType: {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000365 size_t vertexBytes = (vertexCount + startVertex) *
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000366 VertexSize(draw->fVertexLayout);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000367 poolState.fUsedPoolVertexBytes =
368 GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000369 draw->fVertexBuffer = poolState.fPoolVertexBuffer;
370 draw->fStartVertex += poolState.fPoolStartVertex;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000371 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000372 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000373 default:
374 GrCrash("unknown geom src type");
reed@google.comac10a2d2010-12-22 21:39:39 +0000375 }
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000376 draw->fVertexBuffer->ref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000377
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000378 switch (this->getGeomSrc().fIndexSrc) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000379 case kBuffer_GeometrySrcType:
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000380 draw->fIndexBuffer = this->getGeomSrc().fIndexBuffer;
reed@google.comac10a2d2010-12-22 21:39:39 +0000381 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000382 case kReserved_GeometrySrcType: // fallthrough
383 case kArray_GeometrySrcType: {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000384 size_t indexBytes = (indexCount + startIndex) * sizeof(uint16_t);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000385 poolState.fUsedPoolIndexBytes =
386 GrMax(poolState.fUsedPoolIndexBytes, indexBytes);
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000387 draw->fIndexBuffer = poolState.fPoolIndexBuffer;
388 draw->fStartIndex += poolState.fPoolStartIndex;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000389 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000390 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000391 default:
392 GrCrash("unknown geom src type");
reed@google.comac10a2d2010-12-22 21:39:39 +0000393 }
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000394 draw->fIndexBuffer->ref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000395}
396
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000397void GrInOrderDrawBuffer::onDrawNonIndexed(GrPrimitiveType primitiveType,
398 int startVertex,
399 int vertexCount) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000400 if (!vertexCount) {
401 return;
402 }
403
bsalomon@google.com934c5702012-03-20 21:17:58 +0000404 this->resetDrawTracking();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000405
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000406 GeometryPoolState& poolState = fGeoPoolStateStack.back();
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000407 if (this->needsNewClip()) {
408 this->recordClip();
409 }
410 if (this->needsNewState()) {
411 this->recordState();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000412 }
413
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000414 Draw* draw = this->recordDraw();
415 draw->fPrimitiveType = primitiveType;
416 draw->fStartVertex = startVertex;
417 draw->fStartIndex = 0;
418 draw->fVertexCount = vertexCount;
419 draw->fIndexCount = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000420
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000421 draw->fVertexLayout = this->getVertexLayout();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000422 switch (this->getGeomSrc().fVertexSrc) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000423 case kBuffer_GeometrySrcType:
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000424 draw->fVertexBuffer = this->getGeomSrc().fVertexBuffer;
reed@google.comac10a2d2010-12-22 21:39:39 +0000425 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000426 case kReserved_GeometrySrcType: // fallthrough
427 case kArray_GeometrySrcType: {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000428 size_t vertexBytes = (vertexCount + startVertex) *
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000429 VertexSize(draw->fVertexLayout);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000430 poolState.fUsedPoolVertexBytes =
431 GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000432 draw->fVertexBuffer = poolState.fPoolVertexBuffer;
433 draw->fStartVertex += poolState.fPoolStartVertex;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000434 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000435 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000436 default:
437 GrCrash("unknown geom src type");
reed@google.comac10a2d2010-12-22 21:39:39 +0000438 }
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000439 draw->fVertexBuffer->ref();
440 draw->fIndexBuffer = NULL;
reed@google.comac10a2d2010-12-22 21:39:39 +0000441}
442
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000443void GrInOrderDrawBuffer::onStencilPath(const GrPath* path, GrPathFill fill) {
444 if (this->needsNewClip()) {
445 this->recordClip();
446 }
447 // Only compare the subset of GrDrawState relevant to path stenciling?
448 if (this->needsNewState()) {
449 this->recordState();
450 }
451 StencilPath* sp = this->recordStencilPath();
452 sp->fPath.reset(path);
453 path->ref();
454 sp->fFill = fill;
bsalomon@google.com64aef2b2012-06-11 15:36:13 +0000455}
456
robertphillips@google.comc82a8b72012-06-21 20:15:48 +0000457void GrInOrderDrawBuffer::clear(const GrIRect* rect,
458 GrColor color,
459 GrRenderTarget* renderTarget) {
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000460 GrIRect r;
461 if (NULL == rect) {
462 // We could do something smart and remove previous draws and clears to
463 // the current render target. If we get that smart we have to make sure
464 // those draws aren't read before this clear (render-to-texture).
465 r.setLTRB(0, 0,
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000466 this->getDrawState().getRenderTarget()->width(),
467 this->getDrawState().getRenderTarget()->height());
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000468 rect = &r;
469 }
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000470 Clear* clr = this->recordClear();
471 clr->fColor = color;
472 clr->fRect = *rect;
473 clr->fRenderTarget = renderTarget;
474 GrSafeRef(clr->fRenderTarget);
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000475}
476
reed@google.comac10a2d2010-12-22 21:39:39 +0000477void GrInOrderDrawBuffer::reset() {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000478 GrAssert(1 == fGeoPoolStateStack.count());
479 this->resetVertexSource();
480 this->resetIndexSource();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000481 int numDraws = fDraws.count();
482 for (int d = 0; d < numDraws; ++d) {
483 // we always have a VB, but not always an IB
484 GrAssert(NULL != fDraws[d].fVertexBuffer);
485 fDraws[d].fVertexBuffer->unref();
486 GrSafeUnref(fDraws[d].fIndexBuffer);
487 }
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000488 fCmds.reset();
reed@google.comac10a2d2010-12-22 21:39:39 +0000489 fDraws.reset();
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000490 fStencilPaths.reset();
reed@google.comac10a2d2010-12-22 21:39:39 +0000491 fStates.reset();
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000492 fClears.reset();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000493 fVertexPool.reset();
494 fIndexPool.reset();
reed@google.comac10a2d2010-12-22 21:39:39 +0000495 fClips.reset();
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000496 fClipSet = true;
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000497
bsalomon@google.com934c5702012-03-20 21:17:58 +0000498 this->resetDrawTracking();
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000499
500 // we start off with a default clip and state so that we don't have
501 // to do count checks on fClips, fStates, or fCmds before checking their
502 // last entry.
503 this->recordDefaultState();
504 this->recordDefaultClip();
reed@google.comac10a2d2010-12-22 21:39:39 +0000505}
506
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000507bool GrInOrderDrawBuffer::playback(GrDrawTarget* target) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000508 GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fVertexSrc);
509 GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fIndexSrc);
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000510
reed@google.comac10a2d2010-12-22 21:39:39 +0000511 GrAssert(NULL != target);
512 GrAssert(target != this); // not considered and why?
513
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000514 int numCmds = fCmds.count();
515 GrAssert(numCmds >= 2);
516 if (2 == numCmds) {
517 GrAssert(kSetState_Cmd == fCmds[0]);
518 GrAssert(kSetClip_Cmd == fCmds[1]);
519 return false;
reed@google.comac10a2d2010-12-22 21:39:39 +0000520 }
521
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000522 fVertexPool.unlock();
523 fIndexPool.unlock();
reed@google.comac10a2d2010-12-22 21:39:39 +0000524
reed@google.comac10a2d2010-12-22 21:39:39 +0000525 GrDrawTarget::AutoClipRestore acr(target);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000526 AutoGeometryPush agp(target);
bsalomon@google.coma5d056a2012-03-27 15:59:58 +0000527 GrDrawState* prevDrawState = target->drawState();
528 prevDrawState->ref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000529
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000530 int currState = 0;
531 int currClip = 0;
532 int currClear = 0;
533 int currDraw = 0;
534 int currStencilPath = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000535
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000536 for (int c = 0; c < numCmds; ++c) {
537 switch (fCmds[c]) {
538 case kDraw_Cmd: {
539 const Draw& draw = fDraws[currDraw];
540 target->setVertexSourceToBuffer(draw.fVertexLayout, draw.fVertexBuffer);
541 if (draw.fIndexCount) {
542 target->setIndexSourceToBuffer(draw.fIndexBuffer);
543 }
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000544
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000545 if (draw.fIndexCount) {
546 target->drawIndexed(draw.fPrimitiveType,
547 draw.fStartVertex,
548 draw.fStartIndex,
549 draw.fVertexCount,
550 draw.fIndexCount);
551 } else {
552 target->drawNonIndexed(draw.fPrimitiveType,
553 draw.fStartVertex,
554 draw.fVertexCount);
555 }
556 ++currDraw;
557 break;
558 }
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000559 case kStencilPath_Cmd: {
560 const StencilPath& sp = fStencilPaths[currStencilPath];
561 target->stencilPath(sp.fPath.get(), sp.fFill);
562 ++currStencilPath;
563 break;
564 }
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000565 case kSetState_Cmd:
566 target->setDrawState(&fStates[currState]);
567 ++currState;
568 break;
569 case kSetClip_Cmd:
570 target->setClip(fClips[currClip]);
571 ++currClip;
572 break;
573 case kClear_Cmd:
574 target->clear(&fClears[currClear].fRect,
575 fClears[currClear].fColor,
576 fClears[currClear].fRenderTarget);
577 ++currClear;
578 break;
reed@google.comac10a2d2010-12-22 21:39:39 +0000579 }
580 }
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000581 // we should have consumed all the states, clips, etc.
582 GrAssert(fStates.count() == currState);
583 GrAssert(fClips.count() == currClip);
584 GrAssert(fClears.count() == currClear);
585 GrAssert(fDraws.count() == currDraw);
586
bsalomon@google.coma5d056a2012-03-27 15:59:58 +0000587 target->setDrawState(prevDrawState);
588 prevDrawState->unref();
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000589 return true;
reed@google.comac10a2d2010-12-22 21:39:39 +0000590}
591
bsalomon@google.com97805382012-03-13 14:32:07 +0000592void GrInOrderDrawBuffer::setAutoFlushTarget(GrDrawTarget* target) {
593 GrSafeAssign(fAutoFlushTarget, target);
594}
595
596void GrInOrderDrawBuffer::willReserveVertexAndIndexSpace(
597 GrVertexLayout vertexLayout,
598 int vertexCount,
599 int indexCount) {
600 if (NULL != fAutoFlushTarget) {
601 // We use geometryHints() to know whether to flush the draw buffer. We
602 // can't flush if we are inside an unbalanced pushGeometrySource.
603 // Moreover, flushing blows away vertex and index data that was
604 // previously reserved. So if the vertex or index data is pulled from
605 // reserved space and won't be released by this request then we can't
606 // flush.
607 bool insideGeoPush = fGeoPoolStateStack.count() > 1;
608
609 bool unreleasedVertexSpace =
610 !vertexCount &&
611 kReserved_GeometrySrcType == this->getGeomSrc().fVertexSrc;
612
613 bool unreleasedIndexSpace =
614 !indexCount &&
615 kReserved_GeometrySrcType == this->getGeomSrc().fIndexSrc;
616
617 // we don't want to finalize any reserved geom on the target since
618 // we don't know that the client has finished writing to it.
619 bool targetHasReservedGeom =
620 fAutoFlushTarget->hasReservedVerticesOrIndices();
621
622 int vcount = vertexCount;
623 int icount = indexCount;
624
625 if (!insideGeoPush &&
626 !unreleasedVertexSpace &&
627 !unreleasedIndexSpace &&
628 !targetHasReservedGeom &&
629 this->geometryHints(vertexLayout, &vcount, &icount)) {
630
631 this->flushTo(fAutoFlushTarget);
632 }
633 }
634}
635
reed@google.comac10a2d2010-12-22 21:39:39 +0000636bool GrInOrderDrawBuffer::geometryHints(GrVertexLayout vertexLayout,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000637 int* vertexCount,
638 int* indexCount) const {
639 // we will recommend a flush if the data could fit in a single
640 // preallocated buffer but none are left and it can't fit
641 // in the current buffer (which may not be prealloced).
reed@google.comac10a2d2010-12-22 21:39:39 +0000642 bool flush = false;
643 if (NULL != indexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000644 int32_t currIndices = fIndexPool.currentBufferIndices();
645 if (*indexCount > currIndices &&
646 (!fIndexPool.preallocatedBuffersRemaining() &&
647 *indexCount <= fIndexPool.preallocatedBufferIndices())) {
648
649 flush = true;
650 }
651 *indexCount = currIndices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000652 }
653 if (NULL != vertexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000654 int32_t currVertices = fVertexPool.currentBufferVertices(vertexLayout);
655 if (*vertexCount > currVertices &&
656 (!fVertexPool.preallocatedBuffersRemaining() &&
657 *vertexCount <= fVertexPool.preallocatedBufferVertices(vertexLayout))) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000658
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000659 flush = true;
reed@google.comac10a2d2010-12-22 21:39:39 +0000660 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000661 *vertexCount = currVertices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000662 }
663 return flush;
664}
665
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000666bool GrInOrderDrawBuffer::onReserveVertexSpace(GrVertexLayout vertexLayout,
667 int vertexCount,
668 void** vertices) {
669 GeometryPoolState& poolState = fGeoPoolStateStack.back();
670 GrAssert(vertexCount > 0);
671 GrAssert(NULL != vertices);
672 GrAssert(0 == poolState.fUsedPoolVertexBytes);
673
674 *vertices = fVertexPool.makeSpace(vertexLayout,
675 vertexCount,
676 &poolState.fPoolVertexBuffer,
677 &poolState.fPoolStartVertex);
678 return NULL != *vertices;
679}
680
681bool GrInOrderDrawBuffer::onReserveIndexSpace(int indexCount, void** indices) {
682 GeometryPoolState& poolState = fGeoPoolStateStack.back();
683 GrAssert(indexCount > 0);
684 GrAssert(NULL != indices);
685 GrAssert(0 == poolState.fUsedPoolIndexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000686
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000687 *indices = fIndexPool.makeSpace(indexCount,
688 &poolState.fPoolIndexBuffer,
689 &poolState.fPoolStartIndex);
690 return NULL != *indices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000691}
692
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000693void GrInOrderDrawBuffer::releaseReservedVertexSpace() {
694 GeometryPoolState& poolState = fGeoPoolStateStack.back();
695 const GeometrySrcState& geoSrc = this->getGeomSrc();
696
697 GrAssert(kReserved_GeometrySrcType == geoSrc.fVertexSrc);
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000698
699 // When the caller reserved vertex buffer space we gave it back a pointer
700 // provided by the vertex buffer pool. At each draw we tracked the largest
701 // offset into the pool's pointer that was referenced. Now we return to the
702 // pool any portion at the tail of the allocation that no draw referenced.
703 size_t reservedVertexBytes = VertexSize(geoSrc.fVertexLayout) *
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000704 geoSrc.fVertexCount;
705 fVertexPool.putBack(reservedVertexBytes -
706 poolState.fUsedPoolVertexBytes);
707 poolState.fUsedPoolVertexBytes = 0;
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000708 poolState.fPoolVertexBuffer = NULL;
709 poolState.fPoolStartVertex = 0;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000710}
711
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000712void GrInOrderDrawBuffer::releaseReservedIndexSpace() {
713 GeometryPoolState& poolState = fGeoPoolStateStack.back();
714 const GeometrySrcState& geoSrc = this->getGeomSrc();
715
716 GrAssert(kReserved_GeometrySrcType == geoSrc.fIndexSrc);
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000717
718 // Similar to releaseReservedVertexSpace we return any unused portion at
719 // the tail
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000720 size_t reservedIndexBytes = sizeof(uint16_t) * geoSrc.fIndexCount;
721 fIndexPool.putBack(reservedIndexBytes - poolState.fUsedPoolIndexBytes);
722 poolState.fUsedPoolIndexBytes = 0;
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000723 poolState.fPoolIndexBuffer = NULL;
724 poolState.fPoolStartIndex = 0;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000725}
726
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000727void GrInOrderDrawBuffer::onSetVertexSourceToArray(const void* vertexArray,
728 int vertexCount) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000729
730 GeometryPoolState& poolState = fGeoPoolStateStack.back();
731 GrAssert(0 == poolState.fUsedPoolVertexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000732#if GR_DEBUG
733 bool success =
734#endif
bsalomon@google.come79c8152012-03-29 19:07:12 +0000735 fVertexPool.appendVertices(this->getVertexLayout(),
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000736 vertexCount,
737 vertexArray,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000738 &poolState.fPoolVertexBuffer,
739 &poolState.fPoolStartVertex);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000740 GR_DEBUGASSERT(success);
741}
742
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000743void GrInOrderDrawBuffer::onSetIndexSourceToArray(const void* indexArray,
744 int indexCount) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000745 GeometryPoolState& poolState = fGeoPoolStateStack.back();
746 GrAssert(0 == poolState.fUsedPoolIndexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000747#if GR_DEBUG
748 bool success =
749#endif
750 fIndexPool.appendIndices(indexCount,
751 indexArray,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000752 &poolState.fPoolIndexBuffer,
753 &poolState.fPoolStartIndex);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000754 GR_DEBUGASSERT(success);
reed@google.comac10a2d2010-12-22 21:39:39 +0000755}
756
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000757void GrInOrderDrawBuffer::releaseVertexArray() {
758 // When the client provides an array as the vertex source we handled it
759 // by copying their array into reserved space.
760 this->GrInOrderDrawBuffer::releaseReservedVertexSpace();
761}
762
763void GrInOrderDrawBuffer::releaseIndexArray() {
764 // When the client provides an array as the index source we handled it
765 // by copying their array into reserved space.
766 this->GrInOrderDrawBuffer::releaseReservedIndexSpace();
767}
768
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000769void GrInOrderDrawBuffer::geometrySourceWillPush() {
770 GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
771 poolState.fUsedPoolVertexBytes = 0;
772 poolState.fUsedPoolIndexBytes = 0;
bsalomon@google.com934c5702012-03-20 21:17:58 +0000773 this->resetDrawTracking();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000774#if GR_DEBUG
775 poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0;
776 poolState.fPoolStartVertex = ~0;
777 poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0;
778 poolState.fPoolStartIndex = ~0;
779#endif
780}
781
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000782void GrInOrderDrawBuffer::geometrySourceWillPop(
783 const GeometrySrcState& restoredState) {
784 GrAssert(fGeoPoolStateStack.count() > 1);
785 fGeoPoolStateStack.pop_back();
786 GeometryPoolState& poolState = fGeoPoolStateStack.back();
787 // we have to assume that any slack we had in our vertex/index data
788 // is now unreleasable because data may have been appended later in the
789 // pool.
790 if (kReserved_GeometrySrcType == restoredState.fVertexSrc ||
791 kArray_GeometrySrcType == restoredState.fVertexSrc) {
792 poolState.fUsedPoolVertexBytes =
793 VertexSize(restoredState.fVertexLayout) *
794 restoredState.fVertexCount;
795 }
796 if (kReserved_GeometrySrcType == restoredState.fIndexSrc ||
797 kArray_GeometrySrcType == restoredState.fIndexSrc) {
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000798 poolState.fUsedPoolIndexBytes = sizeof(uint16_t) *
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000799 restoredState.fIndexCount;
800 }
bsalomon@google.com934c5702012-03-20 21:17:58 +0000801 this->resetDrawTracking();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000802}
803
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000804bool GrInOrderDrawBuffer::needsNewState() const {
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000805 // we should have recorded a default state in reset()
806 GrAssert(!fStates.empty());
807 return fStates.back() != this->getDrawState();
reed@google.comac10a2d2010-12-22 21:39:39 +0000808}
809
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000810bool GrInOrderDrawBuffer::needsNewClip() const {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000811 if (this->getDrawState().isClipState()) {
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000812 if (fClipSet && fClips.back() != fClip) {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000813 return true;
814 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000815 }
816 return false;
817}
bsalomon@google.comd302f142011-03-03 13:54:13 +0000818
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000819void GrInOrderDrawBuffer::recordClip() {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000820 fClips.push_back() = fClip;
821 fClipSet = false;
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000822 fCmds.push_back(kSetClip_Cmd);
823}
824
825void GrInOrderDrawBuffer::recordDefaultClip() {
826 fClips.push_back() = GrClip();
827 fCmds.push_back(kSetClip_Cmd);
828}
829
830void GrInOrderDrawBuffer::recordState() {
831 fStates.push_back(this->getDrawState());
832 fCmds.push_back(kSetState_Cmd);
833}
834
835void GrInOrderDrawBuffer::recordDefaultState() {
836 fStates.push_back(GrDrawState());
837 fCmds.push_back(kSetState_Cmd);
838}
839
840GrInOrderDrawBuffer::Draw* GrInOrderDrawBuffer::recordDraw() {
841 fCmds.push_back(kDraw_Cmd);
842 return &fDraws.push_back();
843}
844
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000845GrInOrderDrawBuffer::StencilPath* GrInOrderDrawBuffer::recordStencilPath() {
846 fCmds.push_back(kStencilPath_Cmd);
847 return &fStencilPaths.push_back();
848}
849
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000850GrInOrderDrawBuffer::Clear* GrInOrderDrawBuffer::recordClear() {
851 fCmds.push_back(kClear_Cmd);
852 return &fClears.push_back();
reed@google.comac10a2d2010-12-22 21:39:39 +0000853}
bsalomon@google.comd302f142011-03-03 13:54:13 +0000854
bsalomon@google.comdea2f8d2011-08-01 15:51:05 +0000855void GrInOrderDrawBuffer::clipWillBeSet(const GrClip& newClip) {
856 INHERITED::clipWillBeSet(newClip);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000857 fClipSet = true;
858}