blob: 24efb37fc58db70e04716a7b28e08586cdaef784 [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
bsalomon@google.com0b50b2e2011-03-08 21:07:21 +0000129 GrRect clipRect = fClip.getRect(0);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000130 // If the clip rect touches the edge of the viewport, extended it
131 // out (close) to infinity to avoid bogus intersections.
bsalomon@google.comd302f142011-03-03 13:54:13 +0000132 // We might consider a more exact clip to viewport if this
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000133 // conservative test fails.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000134 const GrRenderTarget* target = drawState->getRenderTarget();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000135 if (0 >= clipRect.fLeft) {
136 clipRect.fLeft = GR_ScalarMin;
137 }
138 if (target->width() <= clipRect.fRight) {
139 clipRect.fRight = GR_ScalarMax;
140 }
141 if (0 >= clipRect.top()) {
142 clipRect.fTop = GR_ScalarMin;
143 }
144 if (target->height() <= clipRect.fBottom) {
145 clipRect.fBottom = GR_ScalarMax;
146 }
147 int stride = VertexSize(layout);
148 bool insideClip = true;
149 for (int v = 0; v < 4; ++v) {
150 const GrPoint& p = *GetVertexPoint(geo.vertices(), v, stride);
151 if (!clipRect.contains(p)) {
152 insideClip = false;
153 break;
154 }
155 }
156 if (insideClip) {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000157 drawState->disableState(GrDrawState::kClip_StateBit);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000158 disabledClip = true;
159 }
160 }
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000161 if (!this->needsNewClip() &&
162 !this->needsNewState() &&
163 fCurrQuad > 0 &&
164 fCurrQuad < fMaxQuads &&
165 layout == fLastRectVertexLayout) {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000166
167 int vsize = VertexSize(layout);
bsalomon@google.comd302f142011-03-03 13:54:13 +0000168
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000169 Draw& lastDraw = fDraws.back();
170
171 GrAssert(lastDraw.fIndexBuffer == fQuadIndexBuffer);
bsalomon@google.com47059542012-06-06 20:51:20 +0000172 GrAssert(kTriangles_GrPrimitiveType == lastDraw.fPrimitiveType);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000173 GrAssert(0 == lastDraw.fVertexCount % 4);
174 GrAssert(0 == lastDraw.fIndexCount % 6);
175 GrAssert(0 == lastDraw.fStartIndex);
176
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000177 GeometryPoolState& poolState = fGeoPoolStateStack.back();
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000178
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000179 appendToPreviousDraw =
180 kDraw_Cmd != fCmds.back() &&
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000181 lastDraw.fVertexBuffer == poolState.fPoolVertexBuffer &&
182 (fCurrQuad * 4 + lastDraw.fStartVertex) == poolState.fPoolStartVertex;
183
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000184 if (appendToPreviousDraw) {
185 lastDraw.fVertexCount += 4;
186 lastDraw.fIndexCount += 6;
187 fCurrQuad += 1;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000188 // we reserved above, so we should be the first
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000189 // use of this vertex reservation.
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000190 GrAssert(0 == poolState.fUsedPoolVertexBytes);
191 poolState.fUsedPoolVertexBytes = 4 * vsize;
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000192 }
193 }
194 if (!appendToPreviousDraw) {
195 this->setIndexSourceToBuffer(fQuadIndexBuffer);
bsalomon@google.com47059542012-06-06 20:51:20 +0000196 this->drawIndexed(kTriangles_GrPrimitiveType, 0, 0, 4, 6);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000197 fCurrQuad = 1;
198 fLastRectVertexLayout = layout;
199 }
200 if (disabledClip) {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000201 drawState->enableState(GrDrawState::kClip_StateBit);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000202 }
bsalomon@google.com934c5702012-03-20 21:17:58 +0000203 fInstancedDrawTracker.reset();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000204 } else {
bsalomon@google.come3d32162012-07-20 13:37:06 +0000205 INHERITED::drawRect(rect, matrix, srcRects, srcMatrices);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000206 }
207}
208
bsalomon@google.com934c5702012-03-20 21:17:58 +0000209void GrInOrderDrawBuffer::drawIndexedInstances(GrPrimitiveType type,
210 int instanceCount,
211 int verticesPerInstance,
212 int indicesPerInstance) {
213 if (!verticesPerInstance || !indicesPerInstance) {
214 return;
215 }
216
217 const GeometrySrcState& geomSrc = this->getGeomSrc();
218
219 // we only attempt to concat the case when reserved verts are used with
220 // an index buffer.
221 if (kReserved_GeometrySrcType == geomSrc.fVertexSrc &&
222 kBuffer_GeometrySrcType == geomSrc.fIndexSrc) {
223
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000224 if (this->needsNewClip()) {
225 this->recordClip();
226 }
227 if (this->needsNewState()) {
228 this->recordState();
229 }
230
bsalomon@google.com934c5702012-03-20 21:17:58 +0000231 Draw* draw = NULL;
232 // if the last draw used the same indices/vertices per shape then we
233 // may be able to append to it.
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000234 if (kDraw_Cmd == fCmds.back() &&
235 verticesPerInstance == fInstancedDrawTracker.fVerticesPerInstance &&
bsalomon@google.com934c5702012-03-20 21:17:58 +0000236 indicesPerInstance == fInstancedDrawTracker.fIndicesPerInstance) {
237 GrAssert(fDraws.count());
238 draw = &fDraws.back();
239 }
240
bsalomon@google.com934c5702012-03-20 21:17:58 +0000241 GeometryPoolState& poolState = fGeoPoolStateStack.back();
242 const GrVertexBuffer* vertexBuffer = poolState.fPoolVertexBuffer;
243
244 // Check whether the draw is compatible with this draw in order to
245 // append
246 if (NULL == draw ||
bsalomon@google.com934c5702012-03-20 21:17:58 +0000247 draw->fIndexBuffer != geomSrc.fIndexBuffer ||
248 draw->fPrimitiveType != type ||
249 draw->fVertexBuffer != vertexBuffer) {
250
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000251 draw = this->recordDraw();
bsalomon@google.com934c5702012-03-20 21:17:58 +0000252 draw->fIndexBuffer = geomSrc.fIndexBuffer;
253 geomSrc.fIndexBuffer->ref();
254 draw->fVertexBuffer = vertexBuffer;
255 vertexBuffer->ref();
256 draw->fPrimitiveType = type;
257 draw->fStartIndex = 0;
258 draw->fIndexCount = 0;
259 draw->fStartVertex = poolState.fPoolStartVertex;
260 draw->fVertexCount = 0;
261 draw->fVertexLayout = geomSrc.fVertexLayout;
262 } else {
263 GrAssert(!(draw->fIndexCount % indicesPerInstance));
264 GrAssert(!(draw->fVertexCount % verticesPerInstance));
265 GrAssert(poolState.fPoolStartVertex == draw->fStartVertex +
266 draw->fVertexCount);
267 }
268
269 // how many instances can be in a single draw
270 int maxInstancesPerDraw = this->indexCountInCurrentSource() /
271 indicesPerInstance;
272 if (!maxInstancesPerDraw) {
273 return;
274 }
275 // how many instances should be concat'ed onto draw
276 int instancesToConcat = maxInstancesPerDraw - draw->fVertexCount /
277 verticesPerInstance;
278 if (maxInstancesPerDraw > instanceCount) {
279 maxInstancesPerDraw = instanceCount;
280 if (instancesToConcat > instanceCount) {
281 instancesToConcat = instanceCount;
282 }
283 }
284
285 // update the amount of reserved data actually referenced in draws
286 size_t vertexBytes = instanceCount * verticesPerInstance *
287 VertexSize(draw->fVertexLayout);
288 poolState.fUsedPoolVertexBytes =
289 GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
290
291 while (instanceCount) {
292 if (!instancesToConcat) {
293 int startVertex = draw->fStartVertex + draw->fVertexCount;
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000294 draw = this->recordDraw();
bsalomon@google.com934c5702012-03-20 21:17:58 +0000295 draw->fIndexBuffer = geomSrc.fIndexBuffer;
296 geomSrc.fIndexBuffer->ref();
297 draw->fVertexBuffer = vertexBuffer;
298 vertexBuffer->ref();
299 draw->fPrimitiveType = type;
300 draw->fStartIndex = 0;
301 draw->fStartVertex = startVertex;
302 draw->fVertexCount = 0;
303 draw->fVertexLayout = geomSrc.fVertexLayout;
304 instancesToConcat = maxInstancesPerDraw;
305 }
306 draw->fVertexCount += instancesToConcat * verticesPerInstance;
307 draw->fIndexCount += instancesToConcat * indicesPerInstance;
308 instanceCount -= instancesToConcat;
309 instancesToConcat = 0;
310 }
311
312 // update draw tracking for next draw
313 fCurrQuad = 0;
314 fInstancedDrawTracker.fVerticesPerInstance = verticesPerInstance;
315 fInstancedDrawTracker.fIndicesPerInstance = indicesPerInstance;
316 } else {
317 this->INHERITED::drawIndexedInstances(type,
318 instanceCount,
319 verticesPerInstance,
320 indicesPerInstance);
321 }
322
323}
324
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000325void GrInOrderDrawBuffer::onDrawIndexed(GrPrimitiveType primitiveType,
326 int startVertex,
327 int startIndex,
328 int vertexCount,
329 int indexCount) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000330
331 if (!vertexCount || !indexCount) {
332 return;
333 }
334
bsalomon@google.com934c5702012-03-20 21:17:58 +0000335 this->resetDrawTracking();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000336
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000337 GeometryPoolState& poolState = fGeoPoolStateStack.back();
338
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000339 if (this->needsNewClip()) {
340 this->recordClip();
341 }
342 if (this->needsNewState()) {
343 this->recordState();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000344 }
345
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000346 Draw* draw = this->recordDraw();
reed@google.comac10a2d2010-12-22 21:39:39 +0000347
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000348 draw->fPrimitiveType = primitiveType;
349 draw->fStartVertex = startVertex;
350 draw->fStartIndex = startIndex;
351 draw->fVertexCount = vertexCount;
352 draw->fIndexCount = indexCount;
353
354 draw->fVertexLayout = this->getVertexLayout();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000355 switch (this->getGeomSrc().fVertexSrc) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000356 case kBuffer_GeometrySrcType:
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000357 draw->fVertexBuffer = this->getGeomSrc().fVertexBuffer;
reed@google.comac10a2d2010-12-22 21:39:39 +0000358 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000359 case kReserved_GeometrySrcType: // fallthrough
360 case kArray_GeometrySrcType: {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000361 size_t vertexBytes = (vertexCount + startVertex) *
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000362 VertexSize(draw->fVertexLayout);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000363 poolState.fUsedPoolVertexBytes =
364 GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000365 draw->fVertexBuffer = poolState.fPoolVertexBuffer;
366 draw->fStartVertex += poolState.fPoolStartVertex;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000367 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000368 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000369 default:
370 GrCrash("unknown geom src type");
reed@google.comac10a2d2010-12-22 21:39:39 +0000371 }
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000372 draw->fVertexBuffer->ref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000373
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000374 switch (this->getGeomSrc().fIndexSrc) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000375 case kBuffer_GeometrySrcType:
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000376 draw->fIndexBuffer = this->getGeomSrc().fIndexBuffer;
reed@google.comac10a2d2010-12-22 21:39:39 +0000377 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000378 case kReserved_GeometrySrcType: // fallthrough
379 case kArray_GeometrySrcType: {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000380 size_t indexBytes = (indexCount + startIndex) * sizeof(uint16_t);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000381 poolState.fUsedPoolIndexBytes =
382 GrMax(poolState.fUsedPoolIndexBytes, indexBytes);
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000383 draw->fIndexBuffer = poolState.fPoolIndexBuffer;
384 draw->fStartIndex += poolState.fPoolStartIndex;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000385 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000386 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000387 default:
388 GrCrash("unknown geom src type");
reed@google.comac10a2d2010-12-22 21:39:39 +0000389 }
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000390 draw->fIndexBuffer->ref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000391}
392
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000393void GrInOrderDrawBuffer::onDrawNonIndexed(GrPrimitiveType primitiveType,
394 int startVertex,
395 int vertexCount) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000396 if (!vertexCount) {
397 return;
398 }
399
bsalomon@google.com934c5702012-03-20 21:17:58 +0000400 this->resetDrawTracking();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000401
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000402 GeometryPoolState& poolState = fGeoPoolStateStack.back();
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000403 if (this->needsNewClip()) {
404 this->recordClip();
405 }
406 if (this->needsNewState()) {
407 this->recordState();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000408 }
409
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000410 Draw* draw = this->recordDraw();
411 draw->fPrimitiveType = primitiveType;
412 draw->fStartVertex = startVertex;
413 draw->fStartIndex = 0;
414 draw->fVertexCount = vertexCount;
415 draw->fIndexCount = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000416
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000417 draw->fVertexLayout = this->getVertexLayout();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000418 switch (this->getGeomSrc().fVertexSrc) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000419 case kBuffer_GeometrySrcType:
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000420 draw->fVertexBuffer = this->getGeomSrc().fVertexBuffer;
reed@google.comac10a2d2010-12-22 21:39:39 +0000421 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000422 case kReserved_GeometrySrcType: // fallthrough
423 case kArray_GeometrySrcType: {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000424 size_t vertexBytes = (vertexCount + startVertex) *
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000425 VertexSize(draw->fVertexLayout);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000426 poolState.fUsedPoolVertexBytes =
427 GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000428 draw->fVertexBuffer = poolState.fPoolVertexBuffer;
429 draw->fStartVertex += poolState.fPoolStartVertex;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000430 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000431 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000432 default:
433 GrCrash("unknown geom src type");
reed@google.comac10a2d2010-12-22 21:39:39 +0000434 }
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000435 draw->fVertexBuffer->ref();
436 draw->fIndexBuffer = NULL;
reed@google.comac10a2d2010-12-22 21:39:39 +0000437}
438
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000439void GrInOrderDrawBuffer::onStencilPath(const GrPath* path, GrPathFill fill) {
440 if (this->needsNewClip()) {
441 this->recordClip();
442 }
443 // Only compare the subset of GrDrawState relevant to path stenciling?
444 if (this->needsNewState()) {
445 this->recordState();
446 }
447 StencilPath* sp = this->recordStencilPath();
448 sp->fPath.reset(path);
449 path->ref();
450 sp->fFill = fill;
bsalomon@google.com64aef2b2012-06-11 15:36:13 +0000451}
452
robertphillips@google.comc82a8b72012-06-21 20:15:48 +0000453void GrInOrderDrawBuffer::clear(const GrIRect* rect,
454 GrColor color,
455 GrRenderTarget* renderTarget) {
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000456 GrIRect r;
457 if (NULL == rect) {
458 // We could do something smart and remove previous draws and clears to
459 // the current render target. If we get that smart we have to make sure
460 // those draws aren't read before this clear (render-to-texture).
461 r.setLTRB(0, 0,
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000462 this->getDrawState().getRenderTarget()->width(),
463 this->getDrawState().getRenderTarget()->height());
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000464 rect = &r;
465 }
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000466 Clear* clr = this->recordClear();
467 clr->fColor = color;
468 clr->fRect = *rect;
469 clr->fRenderTarget = renderTarget;
470 GrSafeRef(clr->fRenderTarget);
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000471}
472
reed@google.comac10a2d2010-12-22 21:39:39 +0000473void GrInOrderDrawBuffer::reset() {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000474 GrAssert(1 == fGeoPoolStateStack.count());
475 this->resetVertexSource();
476 this->resetIndexSource();
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 }
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000484 fCmds.reset();
reed@google.comac10a2d2010-12-22 21:39:39 +0000485 fDraws.reset();
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000486 fStencilPaths.reset();
reed@google.comac10a2d2010-12-22 21:39:39 +0000487 fStates.reset();
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000488 fClears.reset();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000489 fVertexPool.reset();
490 fIndexPool.reset();
reed@google.comac10a2d2010-12-22 21:39:39 +0000491 fClips.reset();
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000492 fClipSet = true;
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000493
bsalomon@google.com934c5702012-03-20 21:17:58 +0000494 this->resetDrawTracking();
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000495
496 // we start off with a default clip and state so that we don't have
497 // to do count checks on fClips, fStates, or fCmds before checking their
498 // last entry.
499 this->recordDefaultState();
500 this->recordDefaultClip();
reed@google.comac10a2d2010-12-22 21:39:39 +0000501}
502
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000503bool GrInOrderDrawBuffer::playback(GrDrawTarget* target) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000504 GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fVertexSrc);
505 GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fIndexSrc);
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000506
reed@google.comac10a2d2010-12-22 21:39:39 +0000507 GrAssert(NULL != target);
508 GrAssert(target != this); // not considered and why?
509
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000510 int numCmds = fCmds.count();
511 GrAssert(numCmds >= 2);
512 if (2 == numCmds) {
513 GrAssert(kSetState_Cmd == fCmds[0]);
514 GrAssert(kSetClip_Cmd == fCmds[1]);
515 return false;
reed@google.comac10a2d2010-12-22 21:39:39 +0000516 }
517
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000518 fVertexPool.unlock();
519 fIndexPool.unlock();
reed@google.comac10a2d2010-12-22 21:39:39 +0000520
reed@google.comac10a2d2010-12-22 21:39:39 +0000521 GrDrawTarget::AutoClipRestore acr(target);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000522 AutoGeometryPush agp(target);
bsalomon@google.coma5d056a2012-03-27 15:59:58 +0000523 GrDrawState* prevDrawState = target->drawState();
524 prevDrawState->ref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000525
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000526 int currState = 0;
527 int currClip = 0;
528 int currClear = 0;
529 int currDraw = 0;
530 int currStencilPath = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000531
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000532 for (int c = 0; c < numCmds; ++c) {
533 switch (fCmds[c]) {
534 case kDraw_Cmd: {
535 const Draw& draw = fDraws[currDraw];
536 target->setVertexSourceToBuffer(draw.fVertexLayout, draw.fVertexBuffer);
537 if (draw.fIndexCount) {
538 target->setIndexSourceToBuffer(draw.fIndexBuffer);
539 }
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000540
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000541 if (draw.fIndexCount) {
542 target->drawIndexed(draw.fPrimitiveType,
543 draw.fStartVertex,
544 draw.fStartIndex,
545 draw.fVertexCount,
546 draw.fIndexCount);
547 } else {
548 target->drawNonIndexed(draw.fPrimitiveType,
549 draw.fStartVertex,
550 draw.fVertexCount);
551 }
552 ++currDraw;
553 break;
554 }
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000555 case kStencilPath_Cmd: {
556 const StencilPath& sp = fStencilPaths[currStencilPath];
557 target->stencilPath(sp.fPath.get(), sp.fFill);
558 ++currStencilPath;
559 break;
560 }
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000561 case kSetState_Cmd:
562 target->setDrawState(&fStates[currState]);
563 ++currState;
564 break;
565 case kSetClip_Cmd:
566 target->setClip(fClips[currClip]);
567 ++currClip;
568 break;
569 case kClear_Cmd:
570 target->clear(&fClears[currClear].fRect,
571 fClears[currClear].fColor,
572 fClears[currClear].fRenderTarget);
573 ++currClear;
574 break;
reed@google.comac10a2d2010-12-22 21:39:39 +0000575 }
576 }
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000577 // we should have consumed all the states, clips, etc.
578 GrAssert(fStates.count() == currState);
579 GrAssert(fClips.count() == currClip);
580 GrAssert(fClears.count() == currClear);
581 GrAssert(fDraws.count() == currDraw);
582
bsalomon@google.coma5d056a2012-03-27 15:59:58 +0000583 target->setDrawState(prevDrawState);
584 prevDrawState->unref();
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000585 return true;
reed@google.comac10a2d2010-12-22 21:39:39 +0000586}
587
bsalomon@google.com97805382012-03-13 14:32:07 +0000588void GrInOrderDrawBuffer::setAutoFlushTarget(GrDrawTarget* target) {
589 GrSafeAssign(fAutoFlushTarget, target);
590}
591
592void GrInOrderDrawBuffer::willReserveVertexAndIndexSpace(
593 GrVertexLayout vertexLayout,
594 int vertexCount,
595 int indexCount) {
596 if (NULL != fAutoFlushTarget) {
597 // We use geometryHints() to know whether to flush the draw buffer. We
598 // can't flush if we are inside an unbalanced pushGeometrySource.
599 // Moreover, flushing blows away vertex and index data that was
600 // previously reserved. So if the vertex or index data is pulled from
601 // reserved space and won't be released by this request then we can't
602 // flush.
603 bool insideGeoPush = fGeoPoolStateStack.count() > 1;
604
605 bool unreleasedVertexSpace =
606 !vertexCount &&
607 kReserved_GeometrySrcType == this->getGeomSrc().fVertexSrc;
608
609 bool unreleasedIndexSpace =
610 !indexCount &&
611 kReserved_GeometrySrcType == this->getGeomSrc().fIndexSrc;
612
613 // we don't want to finalize any reserved geom on the target since
614 // we don't know that the client has finished writing to it.
615 bool targetHasReservedGeom =
616 fAutoFlushTarget->hasReservedVerticesOrIndices();
617
618 int vcount = vertexCount;
619 int icount = indexCount;
620
621 if (!insideGeoPush &&
622 !unreleasedVertexSpace &&
623 !unreleasedIndexSpace &&
624 !targetHasReservedGeom &&
625 this->geometryHints(vertexLayout, &vcount, &icount)) {
626
627 this->flushTo(fAutoFlushTarget);
628 }
629 }
630}
631
reed@google.comac10a2d2010-12-22 21:39:39 +0000632bool GrInOrderDrawBuffer::geometryHints(GrVertexLayout vertexLayout,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000633 int* vertexCount,
634 int* indexCount) const {
635 // we will recommend a flush if the data could fit in a single
636 // preallocated buffer but none are left and it can't fit
637 // in the current buffer (which may not be prealloced).
reed@google.comac10a2d2010-12-22 21:39:39 +0000638 bool flush = false;
639 if (NULL != indexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000640 int32_t currIndices = fIndexPool.currentBufferIndices();
641 if (*indexCount > currIndices &&
642 (!fIndexPool.preallocatedBuffersRemaining() &&
643 *indexCount <= fIndexPool.preallocatedBufferIndices())) {
644
645 flush = true;
646 }
647 *indexCount = currIndices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000648 }
649 if (NULL != vertexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000650 int32_t currVertices = fVertexPool.currentBufferVertices(vertexLayout);
651 if (*vertexCount > currVertices &&
652 (!fVertexPool.preallocatedBuffersRemaining() &&
653 *vertexCount <= fVertexPool.preallocatedBufferVertices(vertexLayout))) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000654
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000655 flush = true;
reed@google.comac10a2d2010-12-22 21:39:39 +0000656 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000657 *vertexCount = currVertices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000658 }
659 return flush;
660}
661
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000662bool GrInOrderDrawBuffer::onReserveVertexSpace(GrVertexLayout vertexLayout,
663 int vertexCount,
664 void** vertices) {
665 GeometryPoolState& poolState = fGeoPoolStateStack.back();
666 GrAssert(vertexCount > 0);
667 GrAssert(NULL != vertices);
668 GrAssert(0 == poolState.fUsedPoolVertexBytes);
669
670 *vertices = fVertexPool.makeSpace(vertexLayout,
671 vertexCount,
672 &poolState.fPoolVertexBuffer,
673 &poolState.fPoolStartVertex);
674 return NULL != *vertices;
675}
676
677bool GrInOrderDrawBuffer::onReserveIndexSpace(int indexCount, void** indices) {
678 GeometryPoolState& poolState = fGeoPoolStateStack.back();
679 GrAssert(indexCount > 0);
680 GrAssert(NULL != indices);
681 GrAssert(0 == poolState.fUsedPoolIndexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000682
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000683 *indices = fIndexPool.makeSpace(indexCount,
684 &poolState.fPoolIndexBuffer,
685 &poolState.fPoolStartIndex);
686 return NULL != *indices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000687}
688
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000689void GrInOrderDrawBuffer::releaseReservedVertexSpace() {
690 GeometryPoolState& poolState = fGeoPoolStateStack.back();
691 const GeometrySrcState& geoSrc = this->getGeomSrc();
692
693 GrAssert(kReserved_GeometrySrcType == geoSrc.fVertexSrc);
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000694
695 // When the caller reserved vertex buffer space we gave it back a pointer
696 // provided by the vertex buffer pool. At each draw we tracked the largest
697 // offset into the pool's pointer that was referenced. Now we return to the
698 // pool any portion at the tail of the allocation that no draw referenced.
699 size_t reservedVertexBytes = VertexSize(geoSrc.fVertexLayout) *
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000700 geoSrc.fVertexCount;
701 fVertexPool.putBack(reservedVertexBytes -
702 poolState.fUsedPoolVertexBytes);
703 poolState.fUsedPoolVertexBytes = 0;
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000704 poolState.fPoolVertexBuffer = NULL;
705 poolState.fPoolStartVertex = 0;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000706}
707
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000708void GrInOrderDrawBuffer::releaseReservedIndexSpace() {
709 GeometryPoolState& poolState = fGeoPoolStateStack.back();
710 const GeometrySrcState& geoSrc = this->getGeomSrc();
711
712 GrAssert(kReserved_GeometrySrcType == geoSrc.fIndexSrc);
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000713
714 // Similar to releaseReservedVertexSpace we return any unused portion at
715 // the tail
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000716 size_t reservedIndexBytes = sizeof(uint16_t) * geoSrc.fIndexCount;
717 fIndexPool.putBack(reservedIndexBytes - poolState.fUsedPoolIndexBytes);
718 poolState.fUsedPoolIndexBytes = 0;
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000719 poolState.fPoolIndexBuffer = NULL;
720 poolState.fPoolStartIndex = 0;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000721}
722
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000723void GrInOrderDrawBuffer::onSetVertexSourceToArray(const void* vertexArray,
724 int vertexCount) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000725
726 GeometryPoolState& poolState = fGeoPoolStateStack.back();
727 GrAssert(0 == poolState.fUsedPoolVertexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000728#if GR_DEBUG
729 bool success =
730#endif
bsalomon@google.come79c8152012-03-29 19:07:12 +0000731 fVertexPool.appendVertices(this->getVertexLayout(),
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000732 vertexCount,
733 vertexArray,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000734 &poolState.fPoolVertexBuffer,
735 &poolState.fPoolStartVertex);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000736 GR_DEBUGASSERT(success);
737}
738
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000739void GrInOrderDrawBuffer::onSetIndexSourceToArray(const void* indexArray,
740 int indexCount) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000741 GeometryPoolState& poolState = fGeoPoolStateStack.back();
742 GrAssert(0 == poolState.fUsedPoolIndexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000743#if GR_DEBUG
744 bool success =
745#endif
746 fIndexPool.appendIndices(indexCount,
747 indexArray,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000748 &poolState.fPoolIndexBuffer,
749 &poolState.fPoolStartIndex);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000750 GR_DEBUGASSERT(success);
reed@google.comac10a2d2010-12-22 21:39:39 +0000751}
752
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000753void GrInOrderDrawBuffer::releaseVertexArray() {
754 // When the client provides an array as the vertex source we handled it
755 // by copying their array into reserved space.
756 this->GrInOrderDrawBuffer::releaseReservedVertexSpace();
757}
758
759void GrInOrderDrawBuffer::releaseIndexArray() {
760 // When the client provides an array as the index source we handled it
761 // by copying their array into reserved space.
762 this->GrInOrderDrawBuffer::releaseReservedIndexSpace();
763}
764
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000765void GrInOrderDrawBuffer::geometrySourceWillPush() {
766 GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
767 poolState.fUsedPoolVertexBytes = 0;
768 poolState.fUsedPoolIndexBytes = 0;
bsalomon@google.com934c5702012-03-20 21:17:58 +0000769 this->resetDrawTracking();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000770#if GR_DEBUG
771 poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0;
772 poolState.fPoolStartVertex = ~0;
773 poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0;
774 poolState.fPoolStartIndex = ~0;
775#endif
776}
777
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000778void GrInOrderDrawBuffer::geometrySourceWillPop(
779 const GeometrySrcState& restoredState) {
780 GrAssert(fGeoPoolStateStack.count() > 1);
781 fGeoPoolStateStack.pop_back();
782 GeometryPoolState& poolState = fGeoPoolStateStack.back();
783 // we have to assume that any slack we had in our vertex/index data
784 // is now unreleasable because data may have been appended later in the
785 // pool.
786 if (kReserved_GeometrySrcType == restoredState.fVertexSrc ||
787 kArray_GeometrySrcType == restoredState.fVertexSrc) {
788 poolState.fUsedPoolVertexBytes =
789 VertexSize(restoredState.fVertexLayout) *
790 restoredState.fVertexCount;
791 }
792 if (kReserved_GeometrySrcType == restoredState.fIndexSrc ||
793 kArray_GeometrySrcType == restoredState.fIndexSrc) {
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000794 poolState.fUsedPoolIndexBytes = sizeof(uint16_t) *
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000795 restoredState.fIndexCount;
796 }
bsalomon@google.com934c5702012-03-20 21:17:58 +0000797 this->resetDrawTracking();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000798}
799
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000800bool GrInOrderDrawBuffer::needsNewState() const {
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000801 // we should have recorded a default state in reset()
802 GrAssert(!fStates.empty());
803 return fStates.back() != this->getDrawState();
reed@google.comac10a2d2010-12-22 21:39:39 +0000804}
805
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000806bool GrInOrderDrawBuffer::needsNewClip() const {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000807 if (this->getDrawState().isClipState()) {
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000808 if (fClipSet && fClips.back() != fClip) {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000809 return true;
810 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000811 }
812 return false;
813}
bsalomon@google.comd302f142011-03-03 13:54:13 +0000814
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000815void GrInOrderDrawBuffer::recordClip() {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000816 fClips.push_back() = fClip;
817 fClipSet = false;
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000818 fCmds.push_back(kSetClip_Cmd);
819}
820
821void GrInOrderDrawBuffer::recordDefaultClip() {
822 fClips.push_back() = GrClip();
823 fCmds.push_back(kSetClip_Cmd);
824}
825
826void GrInOrderDrawBuffer::recordState() {
827 fStates.push_back(this->getDrawState());
828 fCmds.push_back(kSetState_Cmd);
829}
830
831void GrInOrderDrawBuffer::recordDefaultState() {
832 fStates.push_back(GrDrawState());
833 fCmds.push_back(kSetState_Cmd);
834}
835
836GrInOrderDrawBuffer::Draw* GrInOrderDrawBuffer::recordDraw() {
837 fCmds.push_back(kDraw_Cmd);
838 return &fDraws.push_back();
839}
840
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000841GrInOrderDrawBuffer::StencilPath* GrInOrderDrawBuffer::recordStencilPath() {
842 fCmds.push_back(kStencilPath_Cmd);
843 return &fStencilPaths.push_back();
844}
845
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000846GrInOrderDrawBuffer::Clear* GrInOrderDrawBuffer::recordClear() {
847 fCmds.push_back(kClear_Cmd);
848 return &fClears.push_back();
reed@google.comac10a2d2010-12-22 21:39:39 +0000849}
bsalomon@google.comd302f142011-03-03 13:54:13 +0000850
bsalomon@google.comdea2f8d2011-08-01 15:51:05 +0000851void GrInOrderDrawBuffer::clipWillBeSet(const GrClip& newClip) {
852 INHERITED::clipWillBeSet(newClip);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000853 fClipSet = true;
854}