blob: d5d03cd5cf0a00a93f3c5380dfa12c4ae9c23a3e [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.comd302f142011-03-03 13:54:13 +0000127
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000128 if (drawState->isClipState() && fClip->fClipStack->isRect()) {
129
130 GrClip::Iter iter(*fClip->fClipStack, GrClip::Iter::kBottom_IterStart);
robertphillips@google.coma6f11c42012-07-23 17:39:44 +0000131 const GrClip::Iter::Clip* clip = iter.next();
132 GrAssert(NULL != clip && NULL != clip->fRect);
133
134 GrRect clipRect = *clip->fRect;
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000135 // If the clip rect touches the edge of the viewport, extended it
136 // out (close) to infinity to avoid bogus intersections.
bsalomon@google.comd302f142011-03-03 13:54:13 +0000137 // We might consider a more exact clip to viewport if this
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000138 // conservative test fails.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000139 const GrRenderTarget* target = drawState->getRenderTarget();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000140 if (0 >= clipRect.fLeft) {
141 clipRect.fLeft = GR_ScalarMin;
142 }
143 if (target->width() <= clipRect.fRight) {
144 clipRect.fRight = GR_ScalarMax;
145 }
146 if (0 >= clipRect.top()) {
147 clipRect.fTop = GR_ScalarMin;
148 }
149 if (target->height() <= clipRect.fBottom) {
150 clipRect.fBottom = GR_ScalarMax;
151 }
152 int stride = VertexSize(layout);
153 bool insideClip = true;
154 for (int v = 0; v < 4; ++v) {
155 const GrPoint& p = *GetVertexPoint(geo.vertices(), v, stride);
156 if (!clipRect.contains(p)) {
157 insideClip = false;
158 break;
159 }
160 }
161 if (insideClip) {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000162 drawState->disableState(GrDrawState::kClip_StateBit);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000163 disabledClip = true;
164 }
165 }
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000166 if (!this->needsNewClip() &&
167 !this->needsNewState() &&
168 fCurrQuad > 0 &&
169 fCurrQuad < fMaxQuads &&
170 layout == fLastRectVertexLayout) {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000171
172 int vsize = VertexSize(layout);
bsalomon@google.comd302f142011-03-03 13:54:13 +0000173
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000174 Draw& lastDraw = fDraws.back();
175
176 GrAssert(lastDraw.fIndexBuffer == fQuadIndexBuffer);
bsalomon@google.com47059542012-06-06 20:51:20 +0000177 GrAssert(kTriangles_GrPrimitiveType == lastDraw.fPrimitiveType);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000178 GrAssert(0 == lastDraw.fVertexCount % 4);
179 GrAssert(0 == lastDraw.fIndexCount % 6);
180 GrAssert(0 == lastDraw.fStartIndex);
181
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000182 GeometryPoolState& poolState = fGeoPoolStateStack.back();
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000183
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000184 appendToPreviousDraw =
185 kDraw_Cmd != fCmds.back() &&
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000186 lastDraw.fVertexBuffer == poolState.fPoolVertexBuffer &&
187 (fCurrQuad * 4 + lastDraw.fStartVertex) == poolState.fPoolStartVertex;
188
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000189 if (appendToPreviousDraw) {
190 lastDraw.fVertexCount += 4;
191 lastDraw.fIndexCount += 6;
192 fCurrQuad += 1;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000193 // we reserved above, so we should be the first
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000194 // use of this vertex reservation.
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000195 GrAssert(0 == poolState.fUsedPoolVertexBytes);
196 poolState.fUsedPoolVertexBytes = 4 * vsize;
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000197 }
198 }
199 if (!appendToPreviousDraw) {
200 this->setIndexSourceToBuffer(fQuadIndexBuffer);
bsalomon@google.com47059542012-06-06 20:51:20 +0000201 this->drawIndexed(kTriangles_GrPrimitiveType, 0, 0, 4, 6);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000202 fCurrQuad = 1;
203 fLastRectVertexLayout = layout;
204 }
205 if (disabledClip) {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000206 drawState->enableState(GrDrawState::kClip_StateBit);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000207 }
bsalomon@google.com934c5702012-03-20 21:17:58 +0000208 fInstancedDrawTracker.reset();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000209 } else {
bsalomon@google.come3d32162012-07-20 13:37:06 +0000210 INHERITED::drawRect(rect, matrix, srcRects, srcMatrices);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000211 }
212}
213
bsalomon@google.com934c5702012-03-20 21:17:58 +0000214void GrInOrderDrawBuffer::drawIndexedInstances(GrPrimitiveType type,
215 int instanceCount,
216 int verticesPerInstance,
217 int indicesPerInstance) {
218 if (!verticesPerInstance || !indicesPerInstance) {
219 return;
220 }
221
222 const GeometrySrcState& geomSrc = this->getGeomSrc();
223
224 // we only attempt to concat the case when reserved verts are used with
225 // an index buffer.
226 if (kReserved_GeometrySrcType == geomSrc.fVertexSrc &&
227 kBuffer_GeometrySrcType == geomSrc.fIndexSrc) {
228
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000229 if (this->needsNewClip()) {
230 this->recordClip();
231 }
232 if (this->needsNewState()) {
233 this->recordState();
234 }
235
bsalomon@google.com934c5702012-03-20 21:17:58 +0000236 Draw* draw = NULL;
237 // if the last draw used the same indices/vertices per shape then we
238 // may be able to append to it.
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000239 if (kDraw_Cmd == fCmds.back() &&
240 verticesPerInstance == fInstancedDrawTracker.fVerticesPerInstance &&
bsalomon@google.com934c5702012-03-20 21:17:58 +0000241 indicesPerInstance == fInstancedDrawTracker.fIndicesPerInstance) {
242 GrAssert(fDraws.count());
243 draw = &fDraws.back();
244 }
245
bsalomon@google.com934c5702012-03-20 21:17:58 +0000246 GeometryPoolState& poolState = fGeoPoolStateStack.back();
247 const GrVertexBuffer* vertexBuffer = poolState.fPoolVertexBuffer;
248
249 // Check whether the draw is compatible with this draw in order to
250 // append
251 if (NULL == draw ||
bsalomon@google.com934c5702012-03-20 21:17:58 +0000252 draw->fIndexBuffer != geomSrc.fIndexBuffer ||
253 draw->fPrimitiveType != type ||
254 draw->fVertexBuffer != vertexBuffer) {
255
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000256 draw = this->recordDraw();
bsalomon@google.com934c5702012-03-20 21:17:58 +0000257 draw->fIndexBuffer = geomSrc.fIndexBuffer;
258 geomSrc.fIndexBuffer->ref();
259 draw->fVertexBuffer = vertexBuffer;
260 vertexBuffer->ref();
261 draw->fPrimitiveType = type;
262 draw->fStartIndex = 0;
263 draw->fIndexCount = 0;
264 draw->fStartVertex = poolState.fPoolStartVertex;
265 draw->fVertexCount = 0;
266 draw->fVertexLayout = geomSrc.fVertexLayout;
267 } else {
268 GrAssert(!(draw->fIndexCount % indicesPerInstance));
269 GrAssert(!(draw->fVertexCount % verticesPerInstance));
270 GrAssert(poolState.fPoolStartVertex == draw->fStartVertex +
271 draw->fVertexCount);
272 }
273
274 // how many instances can be in a single draw
275 int maxInstancesPerDraw = this->indexCountInCurrentSource() /
276 indicesPerInstance;
277 if (!maxInstancesPerDraw) {
278 return;
279 }
280 // how many instances should be concat'ed onto draw
281 int instancesToConcat = maxInstancesPerDraw - draw->fVertexCount /
282 verticesPerInstance;
283 if (maxInstancesPerDraw > instanceCount) {
284 maxInstancesPerDraw = instanceCount;
285 if (instancesToConcat > instanceCount) {
286 instancesToConcat = instanceCount;
287 }
288 }
289
290 // update the amount of reserved data actually referenced in draws
291 size_t vertexBytes = instanceCount * verticesPerInstance *
292 VertexSize(draw->fVertexLayout);
293 poolState.fUsedPoolVertexBytes =
294 GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
295
296 while (instanceCount) {
297 if (!instancesToConcat) {
298 int startVertex = draw->fStartVertex + draw->fVertexCount;
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000299 draw = this->recordDraw();
bsalomon@google.com934c5702012-03-20 21:17:58 +0000300 draw->fIndexBuffer = geomSrc.fIndexBuffer;
301 geomSrc.fIndexBuffer->ref();
302 draw->fVertexBuffer = vertexBuffer;
303 vertexBuffer->ref();
304 draw->fPrimitiveType = type;
305 draw->fStartIndex = 0;
306 draw->fStartVertex = startVertex;
307 draw->fVertexCount = 0;
308 draw->fVertexLayout = geomSrc.fVertexLayout;
309 instancesToConcat = maxInstancesPerDraw;
310 }
311 draw->fVertexCount += instancesToConcat * verticesPerInstance;
312 draw->fIndexCount += instancesToConcat * indicesPerInstance;
313 instanceCount -= instancesToConcat;
314 instancesToConcat = 0;
315 }
316
317 // update draw tracking for next draw
318 fCurrQuad = 0;
319 fInstancedDrawTracker.fVerticesPerInstance = verticesPerInstance;
320 fInstancedDrawTracker.fIndicesPerInstance = indicesPerInstance;
321 } else {
322 this->INHERITED::drawIndexedInstances(type,
323 instanceCount,
324 verticesPerInstance,
325 indicesPerInstance);
326 }
327
328}
329
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000330void GrInOrderDrawBuffer::onDrawIndexed(GrPrimitiveType primitiveType,
331 int startVertex,
332 int startIndex,
333 int vertexCount,
334 int indexCount) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000335
336 if (!vertexCount || !indexCount) {
337 return;
338 }
339
bsalomon@google.com934c5702012-03-20 21:17:58 +0000340 this->resetDrawTracking();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000341
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000342 GeometryPoolState& poolState = fGeoPoolStateStack.back();
343
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000344 if (this->needsNewClip()) {
345 this->recordClip();
346 }
347 if (this->needsNewState()) {
348 this->recordState();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000349 }
350
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000351 Draw* draw = this->recordDraw();
reed@google.comac10a2d2010-12-22 21:39:39 +0000352
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000353 draw->fPrimitiveType = primitiveType;
354 draw->fStartVertex = startVertex;
355 draw->fStartIndex = startIndex;
356 draw->fVertexCount = vertexCount;
357 draw->fIndexCount = indexCount;
358
359 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.coma4f6b102012-06-26 21:04:22 +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.coma4f6b102012-06-26 21:04:22 +0000367 VertexSize(draw->fVertexLayout);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000368 poolState.fUsedPoolVertexBytes =
369 GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000370 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.coma4f6b102012-06-26 21:04:22 +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.coma4f6b102012-06-26 21:04:22 +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);
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000388 draw->fIndexBuffer = poolState.fPoolIndexBuffer;
389 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.coma4f6b102012-06-26 21:04:22 +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();
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000408 if (this->needsNewClip()) {
409 this->recordClip();
410 }
411 if (this->needsNewState()) {
412 this->recordState();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000413 }
414
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000415 Draw* draw = this->recordDraw();
416 draw->fPrimitiveType = primitiveType;
417 draw->fStartVertex = startVertex;
418 draw->fStartIndex = 0;
419 draw->fVertexCount = vertexCount;
420 draw->fIndexCount = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000421
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000422 draw->fVertexLayout = this->getVertexLayout();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000423 switch (this->getGeomSrc().fVertexSrc) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000424 case kBuffer_GeometrySrcType:
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000425 draw->fVertexBuffer = this->getGeomSrc().fVertexBuffer;
reed@google.comac10a2d2010-12-22 21:39:39 +0000426 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000427 case kReserved_GeometrySrcType: // fallthrough
428 case kArray_GeometrySrcType: {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000429 size_t vertexBytes = (vertexCount + startVertex) *
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000430 VertexSize(draw->fVertexLayout);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000431 poolState.fUsedPoolVertexBytes =
432 GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000433 draw->fVertexBuffer = poolState.fPoolVertexBuffer;
434 draw->fStartVertex += poolState.fPoolStartVertex;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000435 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000436 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000437 default:
438 GrCrash("unknown geom src type");
reed@google.comac10a2d2010-12-22 21:39:39 +0000439 }
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000440 draw->fVertexBuffer->ref();
441 draw->fIndexBuffer = NULL;
reed@google.comac10a2d2010-12-22 21:39:39 +0000442}
443
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000444void GrInOrderDrawBuffer::onStencilPath(const GrPath* path, GrPathFill fill) {
445 if (this->needsNewClip()) {
446 this->recordClip();
447 }
448 // Only compare the subset of GrDrawState relevant to path stenciling?
449 if (this->needsNewState()) {
450 this->recordState();
451 }
452 StencilPath* sp = this->recordStencilPath();
453 sp->fPath.reset(path);
454 path->ref();
455 sp->fFill = fill;
bsalomon@google.com64aef2b2012-06-11 15:36:13 +0000456}
457
robertphillips@google.comc82a8b72012-06-21 20:15:48 +0000458void GrInOrderDrawBuffer::clear(const GrIRect* rect,
459 GrColor color,
460 GrRenderTarget* renderTarget) {
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000461 GrIRect r;
462 if (NULL == rect) {
463 // We could do something smart and remove previous draws and clears to
464 // the current render target. If we get that smart we have to make sure
465 // those draws aren't read before this clear (render-to-texture).
466 r.setLTRB(0, 0,
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000467 this->getDrawState().getRenderTarget()->width(),
468 this->getDrawState().getRenderTarget()->height());
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000469 rect = &r;
470 }
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000471 Clear* clr = this->recordClear();
472 clr->fColor = color;
473 clr->fRect = *rect;
474 clr->fRenderTarget = renderTarget;
475 GrSafeRef(clr->fRenderTarget);
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000476}
477
reed@google.comac10a2d2010-12-22 21:39:39 +0000478void GrInOrderDrawBuffer::reset() {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000479 GrAssert(1 == fGeoPoolStateStack.count());
480 this->resetVertexSource();
481 this->resetIndexSource();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000482 int numDraws = fDraws.count();
483 for (int d = 0; d < numDraws; ++d) {
484 // we always have a VB, but not always an IB
485 GrAssert(NULL != fDraws[d].fVertexBuffer);
486 fDraws[d].fVertexBuffer->unref();
487 GrSafeUnref(fDraws[d].fIndexBuffer);
488 }
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000489 fCmds.reset();
reed@google.comac10a2d2010-12-22 21:39:39 +0000490 fDraws.reset();
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000491 fStencilPaths.reset();
reed@google.comac10a2d2010-12-22 21:39:39 +0000492 fStates.reset();
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000493 fClears.reset();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000494 fVertexPool.reset();
495 fIndexPool.reset();
reed@google.comac10a2d2010-12-22 21:39:39 +0000496 fClips.reset();
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000497 fClipOrigins.reset();
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000498 fClipSet = true;
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000499
bsalomon@google.com934c5702012-03-20 21:17:58 +0000500 this->resetDrawTracking();
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000501
502 // we start off with a default clip and state so that we don't have
503 // to do count checks on fClips, fStates, or fCmds before checking their
504 // last entry.
505 this->recordDefaultState();
506 this->recordDefaultClip();
reed@google.comac10a2d2010-12-22 21:39:39 +0000507}
508
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000509bool GrInOrderDrawBuffer::playback(GrDrawTarget* target) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000510 GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fVertexSrc);
511 GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fIndexSrc);
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000512
reed@google.comac10a2d2010-12-22 21:39:39 +0000513 GrAssert(NULL != target);
514 GrAssert(target != this); // not considered and why?
515
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000516 int numCmds = fCmds.count();
517 GrAssert(numCmds >= 2);
518 if (2 == numCmds) {
519 GrAssert(kSetState_Cmd == fCmds[0]);
520 GrAssert(kSetClip_Cmd == fCmds[1]);
521 return false;
reed@google.comac10a2d2010-12-22 21:39:39 +0000522 }
523
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000524 fVertexPool.unlock();
525 fIndexPool.unlock();
reed@google.comac10a2d2010-12-22 21:39:39 +0000526
reed@google.comac10a2d2010-12-22 21:39:39 +0000527 GrDrawTarget::AutoClipRestore acr(target);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000528 AutoGeometryPush agp(target);
bsalomon@google.coma5d056a2012-03-27 15:59:58 +0000529 GrDrawState* prevDrawState = target->drawState();
530 prevDrawState->ref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000531
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000532 GrClipData clipData;
533
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000534 int currState = 0;
535 int currClip = 0;
536 int currClear = 0;
537 int currDraw = 0;
538 int currStencilPath = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000539
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000540 for (int c = 0; c < numCmds; ++c) {
541 switch (fCmds[c]) {
542 case kDraw_Cmd: {
543 const Draw& draw = fDraws[currDraw];
544 target->setVertexSourceToBuffer(draw.fVertexLayout, draw.fVertexBuffer);
545 if (draw.fIndexCount) {
546 target->setIndexSourceToBuffer(draw.fIndexBuffer);
547 }
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000548
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000549 if (draw.fIndexCount) {
550 target->drawIndexed(draw.fPrimitiveType,
551 draw.fStartVertex,
552 draw.fStartIndex,
553 draw.fVertexCount,
554 draw.fIndexCount);
555 } else {
556 target->drawNonIndexed(draw.fPrimitiveType,
557 draw.fStartVertex,
558 draw.fVertexCount);
559 }
560 ++currDraw;
561 break;
562 }
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000563 case kStencilPath_Cmd: {
564 const StencilPath& sp = fStencilPaths[currStencilPath];
565 target->stencilPath(sp.fPath.get(), sp.fFill);
566 ++currStencilPath;
567 break;
568 }
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000569 case kSetState_Cmd:
570 target->setDrawState(&fStates[currState]);
571 ++currState;
572 break;
573 case kSetClip_Cmd:
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000574 clipData.fClipStack = &fClips[currClip];
575 clipData.fOrigin = fClipOrigins[currClip];
576 target->setClip(&clipData);
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000577 ++currClip;
578 break;
579 case kClear_Cmd:
580 target->clear(&fClears[currClear].fRect,
581 fClears[currClear].fColor,
582 fClears[currClear].fRenderTarget);
583 ++currClear;
584 break;
reed@google.comac10a2d2010-12-22 21:39:39 +0000585 }
586 }
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000587 // we should have consumed all the states, clips, etc.
588 GrAssert(fStates.count() == currState);
589 GrAssert(fClips.count() == currClip);
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000590 GrAssert(fClipOrigins.count() == currClip);
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000591 GrAssert(fClears.count() == currClear);
592 GrAssert(fDraws.count() == currDraw);
593
bsalomon@google.coma5d056a2012-03-27 15:59:58 +0000594 target->setDrawState(prevDrawState);
595 prevDrawState->unref();
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000596 return true;
reed@google.comac10a2d2010-12-22 21:39:39 +0000597}
598
bsalomon@google.com97805382012-03-13 14:32:07 +0000599void GrInOrderDrawBuffer::setAutoFlushTarget(GrDrawTarget* target) {
600 GrSafeAssign(fAutoFlushTarget, target);
601}
602
603void GrInOrderDrawBuffer::willReserveVertexAndIndexSpace(
604 GrVertexLayout vertexLayout,
605 int vertexCount,
606 int indexCount) {
607 if (NULL != fAutoFlushTarget) {
608 // We use geometryHints() to know whether to flush the draw buffer. We
609 // can't flush if we are inside an unbalanced pushGeometrySource.
610 // Moreover, flushing blows away vertex and index data that was
611 // previously reserved. So if the vertex or index data is pulled from
612 // reserved space and won't be released by this request then we can't
613 // flush.
614 bool insideGeoPush = fGeoPoolStateStack.count() > 1;
615
616 bool unreleasedVertexSpace =
617 !vertexCount &&
618 kReserved_GeometrySrcType == this->getGeomSrc().fVertexSrc;
619
620 bool unreleasedIndexSpace =
621 !indexCount &&
622 kReserved_GeometrySrcType == this->getGeomSrc().fIndexSrc;
623
624 // we don't want to finalize any reserved geom on the target since
625 // we don't know that the client has finished writing to it.
626 bool targetHasReservedGeom =
627 fAutoFlushTarget->hasReservedVerticesOrIndices();
628
629 int vcount = vertexCount;
630 int icount = indexCount;
631
632 if (!insideGeoPush &&
633 !unreleasedVertexSpace &&
634 !unreleasedIndexSpace &&
635 !targetHasReservedGeom &&
636 this->geometryHints(vertexLayout, &vcount, &icount)) {
637
638 this->flushTo(fAutoFlushTarget);
639 }
640 }
641}
642
reed@google.comac10a2d2010-12-22 21:39:39 +0000643bool GrInOrderDrawBuffer::geometryHints(GrVertexLayout vertexLayout,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000644 int* vertexCount,
645 int* indexCount) const {
646 // we will recommend a flush if the data could fit in a single
647 // preallocated buffer but none are left and it can't fit
648 // in the current buffer (which may not be prealloced).
reed@google.comac10a2d2010-12-22 21:39:39 +0000649 bool flush = false;
650 if (NULL != indexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000651 int32_t currIndices = fIndexPool.currentBufferIndices();
652 if (*indexCount > currIndices &&
653 (!fIndexPool.preallocatedBuffersRemaining() &&
654 *indexCount <= fIndexPool.preallocatedBufferIndices())) {
655
656 flush = true;
657 }
658 *indexCount = currIndices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000659 }
660 if (NULL != vertexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000661 int32_t currVertices = fVertexPool.currentBufferVertices(vertexLayout);
662 if (*vertexCount > currVertices &&
663 (!fVertexPool.preallocatedBuffersRemaining() &&
664 *vertexCount <= fVertexPool.preallocatedBufferVertices(vertexLayout))) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000665
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000666 flush = true;
reed@google.comac10a2d2010-12-22 21:39:39 +0000667 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000668 *vertexCount = currVertices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000669 }
670 return flush;
671}
672
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000673bool GrInOrderDrawBuffer::onReserveVertexSpace(GrVertexLayout vertexLayout,
674 int vertexCount,
675 void** vertices) {
676 GeometryPoolState& poolState = fGeoPoolStateStack.back();
677 GrAssert(vertexCount > 0);
678 GrAssert(NULL != vertices);
679 GrAssert(0 == poolState.fUsedPoolVertexBytes);
680
681 *vertices = fVertexPool.makeSpace(vertexLayout,
682 vertexCount,
683 &poolState.fPoolVertexBuffer,
684 &poolState.fPoolStartVertex);
685 return NULL != *vertices;
686}
687
688bool GrInOrderDrawBuffer::onReserveIndexSpace(int indexCount, void** indices) {
689 GeometryPoolState& poolState = fGeoPoolStateStack.back();
690 GrAssert(indexCount > 0);
691 GrAssert(NULL != indices);
692 GrAssert(0 == poolState.fUsedPoolIndexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000693
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000694 *indices = fIndexPool.makeSpace(indexCount,
695 &poolState.fPoolIndexBuffer,
696 &poolState.fPoolStartIndex);
697 return NULL != *indices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000698}
699
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000700void GrInOrderDrawBuffer::releaseReservedVertexSpace() {
701 GeometryPoolState& poolState = fGeoPoolStateStack.back();
702 const GeometrySrcState& geoSrc = this->getGeomSrc();
703
704 GrAssert(kReserved_GeometrySrcType == geoSrc.fVertexSrc);
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000705
706 // When the caller reserved vertex buffer space we gave it back a pointer
707 // provided by the vertex buffer pool. At each draw we tracked the largest
708 // offset into the pool's pointer that was referenced. Now we return to the
709 // pool any portion at the tail of the allocation that no draw referenced.
710 size_t reservedVertexBytes = VertexSize(geoSrc.fVertexLayout) *
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000711 geoSrc.fVertexCount;
712 fVertexPool.putBack(reservedVertexBytes -
713 poolState.fUsedPoolVertexBytes);
714 poolState.fUsedPoolVertexBytes = 0;
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000715 poolState.fPoolVertexBuffer = NULL;
716 poolState.fPoolStartVertex = 0;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000717}
718
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000719void GrInOrderDrawBuffer::releaseReservedIndexSpace() {
720 GeometryPoolState& poolState = fGeoPoolStateStack.back();
721 const GeometrySrcState& geoSrc = this->getGeomSrc();
722
723 GrAssert(kReserved_GeometrySrcType == geoSrc.fIndexSrc);
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000724
725 // Similar to releaseReservedVertexSpace we return any unused portion at
726 // the tail
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000727 size_t reservedIndexBytes = sizeof(uint16_t) * geoSrc.fIndexCount;
728 fIndexPool.putBack(reservedIndexBytes - poolState.fUsedPoolIndexBytes);
729 poolState.fUsedPoolIndexBytes = 0;
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000730 poolState.fPoolIndexBuffer = NULL;
731 poolState.fPoolStartIndex = 0;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000732}
733
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000734void GrInOrderDrawBuffer::onSetVertexSourceToArray(const void* vertexArray,
735 int vertexCount) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000736
737 GeometryPoolState& poolState = fGeoPoolStateStack.back();
738 GrAssert(0 == poolState.fUsedPoolVertexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000739#if GR_DEBUG
740 bool success =
741#endif
bsalomon@google.come79c8152012-03-29 19:07:12 +0000742 fVertexPool.appendVertices(this->getVertexLayout(),
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000743 vertexCount,
744 vertexArray,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000745 &poolState.fPoolVertexBuffer,
746 &poolState.fPoolStartVertex);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000747 GR_DEBUGASSERT(success);
748}
749
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000750void GrInOrderDrawBuffer::onSetIndexSourceToArray(const void* indexArray,
751 int indexCount) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000752 GeometryPoolState& poolState = fGeoPoolStateStack.back();
753 GrAssert(0 == poolState.fUsedPoolIndexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000754#if GR_DEBUG
755 bool success =
756#endif
757 fIndexPool.appendIndices(indexCount,
758 indexArray,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000759 &poolState.fPoolIndexBuffer,
760 &poolState.fPoolStartIndex);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000761 GR_DEBUGASSERT(success);
reed@google.comac10a2d2010-12-22 21:39:39 +0000762}
763
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000764void GrInOrderDrawBuffer::releaseVertexArray() {
765 // When the client provides an array as the vertex source we handled it
766 // by copying their array into reserved space.
767 this->GrInOrderDrawBuffer::releaseReservedVertexSpace();
768}
769
770void GrInOrderDrawBuffer::releaseIndexArray() {
771 // When the client provides an array as the index source we handled it
772 // by copying their array into reserved space.
773 this->GrInOrderDrawBuffer::releaseReservedIndexSpace();
774}
775
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000776void GrInOrderDrawBuffer::geometrySourceWillPush() {
777 GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
778 poolState.fUsedPoolVertexBytes = 0;
779 poolState.fUsedPoolIndexBytes = 0;
bsalomon@google.com934c5702012-03-20 21:17:58 +0000780 this->resetDrawTracking();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000781#if GR_DEBUG
782 poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0;
783 poolState.fPoolStartVertex = ~0;
784 poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0;
785 poolState.fPoolStartIndex = ~0;
786#endif
787}
788
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000789void GrInOrderDrawBuffer::geometrySourceWillPop(
790 const GeometrySrcState& restoredState) {
791 GrAssert(fGeoPoolStateStack.count() > 1);
792 fGeoPoolStateStack.pop_back();
793 GeometryPoolState& poolState = fGeoPoolStateStack.back();
794 // we have to assume that any slack we had in our vertex/index data
795 // is now unreleasable because data may have been appended later in the
796 // pool.
797 if (kReserved_GeometrySrcType == restoredState.fVertexSrc ||
798 kArray_GeometrySrcType == restoredState.fVertexSrc) {
799 poolState.fUsedPoolVertexBytes =
800 VertexSize(restoredState.fVertexLayout) *
801 restoredState.fVertexCount;
802 }
803 if (kReserved_GeometrySrcType == restoredState.fIndexSrc ||
804 kArray_GeometrySrcType == restoredState.fIndexSrc) {
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000805 poolState.fUsedPoolIndexBytes = sizeof(uint16_t) *
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000806 restoredState.fIndexCount;
807 }
bsalomon@google.com934c5702012-03-20 21:17:58 +0000808 this->resetDrawTracking();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000809}
810
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000811bool GrInOrderDrawBuffer::needsNewState() const {
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000812 // we should have recorded a default state in reset()
813 GrAssert(!fStates.empty());
814 return fStates.back() != this->getDrawState();
reed@google.comac10a2d2010-12-22 21:39:39 +0000815}
816
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000817bool GrInOrderDrawBuffer::needsNewClip() const {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000818 if (this->getDrawState().isClipState()) {
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000819 if (fClipSet &&
820 (fClips.back() != *fClip->fClipStack ||
821 fClipOrigins.back() != fClip->fOrigin)) {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000822 return true;
823 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000824 }
825 return false;
826}
bsalomon@google.comd302f142011-03-03 13:54:13 +0000827
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000828void GrInOrderDrawBuffer::recordClip() {
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000829 fClips.push_back() = *fClip->fClipStack;
830 fClipOrigins.push_back() = fClip->fOrigin;
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000831 fClipSet = false;
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000832 fCmds.push_back(kSetClip_Cmd);
833}
834
835void GrInOrderDrawBuffer::recordDefaultClip() {
836 fClips.push_back() = GrClip();
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000837 fClipOrigins.push_back() = SkIPoint::Make(0, 0);
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000838 fCmds.push_back(kSetClip_Cmd);
839}
840
841void GrInOrderDrawBuffer::recordState() {
842 fStates.push_back(this->getDrawState());
843 fCmds.push_back(kSetState_Cmd);
844}
845
846void GrInOrderDrawBuffer::recordDefaultState() {
847 fStates.push_back(GrDrawState());
848 fCmds.push_back(kSetState_Cmd);
849}
850
851GrInOrderDrawBuffer::Draw* GrInOrderDrawBuffer::recordDraw() {
852 fCmds.push_back(kDraw_Cmd);
853 return &fDraws.push_back();
854}
855
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000856GrInOrderDrawBuffer::StencilPath* GrInOrderDrawBuffer::recordStencilPath() {
857 fCmds.push_back(kStencilPath_Cmd);
858 return &fStencilPaths.push_back();
859}
860
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000861GrInOrderDrawBuffer::Clear* GrInOrderDrawBuffer::recordClear() {
862 fCmds.push_back(kClear_Cmd);
863 return &fClears.push_back();
reed@google.comac10a2d2010-12-22 21:39:39 +0000864}
bsalomon@google.comd302f142011-03-03 13:54:13 +0000865
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000866void GrInOrderDrawBuffer::clipWillBeSet(const GrClipData* newClipData) {
867 INHERITED::clipWillBeSet(newClipData);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000868 fClipSet = true;
869}