blob: ae6d0f24b7a77f534f2ac66f874f2db38ccadfaa [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);
robertphillips@google.com8b129aa2012-10-05 15:37:00 +000094
95 // When we batch rects we store the color at each vertex in order
96 // to allow batching when only the draw color is changing (the usual case)
97 layout |= kColor_VertexLayoutBit;
98
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000099 AutoReleaseGeometry geo(this, layout, 4, 0);
bsalomon@google.com6513cd02011-08-05 20:12:30 +0000100 if (!geo.succeeded()) {
101 GrPrintf("Failed to get space for vertices!\n");
102 return;
103 }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000104 GrMatrix combinedMatrix = drawState->getViewMatrix();
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000105 // We go to device space so that matrix changes allow us to concat
106 // rect draws. When the caller has provided explicit source rects
robertphillips@google.com8b129aa2012-10-05 15:37:00 +0000107 // then we don't want to modify the sampler matrices. Otherwise
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000108 // we have to account for the view matrix change in the sampler
109 // matrices.
bsalomon@google.come3d32162012-07-20 13:37:06 +0000110 uint32_t explicitCoordMask = 0;
111 if (srcRects) {
112 for (int s = 0; s < GrDrawState::kNumStages; ++s) {
113 if (srcRects[s]) {
114 explicitCoordMask |= (1 << s);
115 }
116 }
117 }
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000118 GrDrawState::AutoDeviceCoordDraw adcd(this->drawState(), explicitCoordMask);
bsalomon@google.come3d32162012-07-20 13:37:06 +0000119 if (!adcd.succeeded()) {
120 return;
121 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000122 if (NULL != matrix) {
123 combinedMatrix.preConcat(*matrix);
124 }
125
skia.committer@gmail.coma18ed032012-10-06 02:05:26 +0000126 SetRectVertices(rect, &combinedMatrix, srcRects, srcMatrices,
robertphillips@google.com8b129aa2012-10-05 15:37:00 +0000127 this->getDrawState().getColor(), layout, geo.vertices());
128
129 // Now that the paint's color is stored in the vertices set it to
130 // white so that the following code can batch all the rects regardless
131 // of paint color
bsalomon@google.com5b3e8902012-10-05 20:13:28 +0000132 GrDrawState::AutoColorRestore acr(this->drawState(), SK_ColorWHITE);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000133
134 // we don't want to miss an opportunity to batch rects together
135 // simply because the clip has changed if the clip doesn't affect
136 // the rect.
137 bool disabledClip = false;
bsalomon@google.comd302f142011-03-03 13:54:13 +0000138
robertphillips@google.com641f8b12012-07-31 19:15:58 +0000139 if (drawState->isClipState()) {
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000140
robertphillips@google.com641f8b12012-07-31 19:15:58 +0000141 GrRect devClipRect;
142 bool isIntersectionOfRects = false;
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000143
robertphillips@google.com641f8b12012-07-31 19:15:58 +0000144 fClip->fClipStack->getConservativeBounds(-fClip->fOrigin.fX,
145 -fClip->fOrigin.fY,
146 drawState->getRenderTarget()->width(),
147 drawState->getRenderTarget()->height(),
148 &devClipRect,
149 &isIntersectionOfRects);
robertphillips@google.coma6f11c42012-07-23 17:39:44 +0000150
robertphillips@google.com641f8b12012-07-31 19:15:58 +0000151 if (isIntersectionOfRects) {
152 // If the clip rect touches the edge of the viewport, extended it
153 // out (close) to infinity to avoid bogus intersections.
154 // We might consider a more exact clip to viewport if this
155 // conservative test fails.
156 const GrRenderTarget* target = drawState->getRenderTarget();
157 if (0 >= devClipRect.fLeft) {
158 devClipRect.fLeft = GR_ScalarMin;
159 }
160 if (target->width() <= devClipRect.fRight) {
161 devClipRect.fRight = GR_ScalarMax;
162 }
163 if (0 >= devClipRect.top()) {
164 devClipRect.fTop = GR_ScalarMin;
165 }
166 if (target->height() <= devClipRect.fBottom) {
167 devClipRect.fBottom = GR_ScalarMax;
168 }
169 int stride = VertexSize(layout);
170 bool insideClip = true;
171 for (int v = 0; v < 4; ++v) {
172 const GrPoint& p = *GetVertexPoint(geo.vertices(), v, stride);
173 if (!devClipRect.contains(p)) {
174 insideClip = false;
175 break;
176 }
177 }
178 if (insideClip) {
179 drawState->disableState(GrDrawState::kClip_StateBit);
180 disabledClip = true;
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000181 }
182 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000183 }
robertphillips@google.com641f8b12012-07-31 19:15:58 +0000184
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000185 if (!this->needsNewClip() &&
186 !this->needsNewState() &&
187 fCurrQuad > 0 &&
188 fCurrQuad < fMaxQuads &&
189 layout == fLastRectVertexLayout) {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000190
191 int vsize = VertexSize(layout);
bsalomon@google.comd302f142011-03-03 13:54:13 +0000192
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000193 Draw& lastDraw = fDraws.back();
194
195 GrAssert(lastDraw.fIndexBuffer == fQuadIndexBuffer);
bsalomon@google.com47059542012-06-06 20:51:20 +0000196 GrAssert(kTriangles_GrPrimitiveType == lastDraw.fPrimitiveType);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000197 GrAssert(0 == lastDraw.fVertexCount % 4);
198 GrAssert(0 == lastDraw.fIndexCount % 6);
199 GrAssert(0 == lastDraw.fStartIndex);
200
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000201 GeometryPoolState& poolState = fGeoPoolStateStack.back();
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000202
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000203 appendToPreviousDraw =
robertphillips@google.com837ec432012-10-04 17:57:05 +0000204 kDraw_Cmd == fCmds.back() &&
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000205 lastDraw.fVertexBuffer == poolState.fPoolVertexBuffer &&
206 (fCurrQuad * 4 + lastDraw.fStartVertex) == poolState.fPoolStartVertex;
207
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000208 if (appendToPreviousDraw) {
209 lastDraw.fVertexCount += 4;
210 lastDraw.fIndexCount += 6;
211 fCurrQuad += 1;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000212 // we reserved above, so we should be the first
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000213 // use of this vertex reservation.
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000214 GrAssert(0 == poolState.fUsedPoolVertexBytes);
215 poolState.fUsedPoolVertexBytes = 4 * vsize;
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000216 }
217 }
218 if (!appendToPreviousDraw) {
219 this->setIndexSourceToBuffer(fQuadIndexBuffer);
bsalomon@google.com47059542012-06-06 20:51:20 +0000220 this->drawIndexed(kTriangles_GrPrimitiveType, 0, 0, 4, 6);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000221 fCurrQuad = 1;
222 fLastRectVertexLayout = layout;
223 }
224 if (disabledClip) {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000225 drawState->enableState(GrDrawState::kClip_StateBit);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000226 }
bsalomon@google.com934c5702012-03-20 21:17:58 +0000227 fInstancedDrawTracker.reset();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000228 } else {
bsalomon@google.come3d32162012-07-20 13:37:06 +0000229 INHERITED::drawRect(rect, matrix, srcRects, srcMatrices);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000230 }
231}
232
bsalomon@google.com934c5702012-03-20 21:17:58 +0000233void GrInOrderDrawBuffer::drawIndexedInstances(GrPrimitiveType type,
234 int instanceCount,
235 int verticesPerInstance,
236 int indicesPerInstance) {
237 if (!verticesPerInstance || !indicesPerInstance) {
238 return;
239 }
240
241 const GeometrySrcState& geomSrc = this->getGeomSrc();
242
243 // we only attempt to concat the case when reserved verts are used with
244 // an index buffer.
245 if (kReserved_GeometrySrcType == geomSrc.fVertexSrc &&
246 kBuffer_GeometrySrcType == geomSrc.fIndexSrc) {
247
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000248 if (this->needsNewClip()) {
249 this->recordClip();
250 }
251 if (this->needsNewState()) {
252 this->recordState();
253 }
254
bsalomon@google.com934c5702012-03-20 21:17:58 +0000255 Draw* draw = NULL;
256 // if the last draw used the same indices/vertices per shape then we
257 // may be able to append to it.
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000258 if (kDraw_Cmd == fCmds.back() &&
259 verticesPerInstance == fInstancedDrawTracker.fVerticesPerInstance &&
bsalomon@google.com934c5702012-03-20 21:17:58 +0000260 indicesPerInstance == fInstancedDrawTracker.fIndicesPerInstance) {
261 GrAssert(fDraws.count());
262 draw = &fDraws.back();
263 }
264
bsalomon@google.com934c5702012-03-20 21:17:58 +0000265 GeometryPoolState& poolState = fGeoPoolStateStack.back();
266 const GrVertexBuffer* vertexBuffer = poolState.fPoolVertexBuffer;
267
268 // Check whether the draw is compatible with this draw in order to
269 // append
270 if (NULL == draw ||
bsalomon@google.com934c5702012-03-20 21:17:58 +0000271 draw->fIndexBuffer != geomSrc.fIndexBuffer ||
272 draw->fPrimitiveType != type ||
273 draw->fVertexBuffer != vertexBuffer) {
274
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000275 draw = this->recordDraw();
bsalomon@google.com934c5702012-03-20 21:17:58 +0000276 draw->fIndexBuffer = geomSrc.fIndexBuffer;
277 geomSrc.fIndexBuffer->ref();
278 draw->fVertexBuffer = vertexBuffer;
279 vertexBuffer->ref();
280 draw->fPrimitiveType = type;
281 draw->fStartIndex = 0;
282 draw->fIndexCount = 0;
283 draw->fStartVertex = poolState.fPoolStartVertex;
284 draw->fVertexCount = 0;
285 draw->fVertexLayout = geomSrc.fVertexLayout;
286 } else {
287 GrAssert(!(draw->fIndexCount % indicesPerInstance));
288 GrAssert(!(draw->fVertexCount % verticesPerInstance));
289 GrAssert(poolState.fPoolStartVertex == draw->fStartVertex +
290 draw->fVertexCount);
291 }
292
293 // how many instances can be in a single draw
294 int maxInstancesPerDraw = this->indexCountInCurrentSource() /
295 indicesPerInstance;
296 if (!maxInstancesPerDraw) {
297 return;
298 }
299 // how many instances should be concat'ed onto draw
300 int instancesToConcat = maxInstancesPerDraw - draw->fVertexCount /
301 verticesPerInstance;
302 if (maxInstancesPerDraw > instanceCount) {
303 maxInstancesPerDraw = instanceCount;
304 if (instancesToConcat > instanceCount) {
305 instancesToConcat = instanceCount;
306 }
307 }
308
309 // update the amount of reserved data actually referenced in draws
310 size_t vertexBytes = instanceCount * verticesPerInstance *
311 VertexSize(draw->fVertexLayout);
312 poolState.fUsedPoolVertexBytes =
313 GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
314
315 while (instanceCount) {
316 if (!instancesToConcat) {
317 int startVertex = draw->fStartVertex + draw->fVertexCount;
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000318 draw = this->recordDraw();
bsalomon@google.com934c5702012-03-20 21:17:58 +0000319 draw->fIndexBuffer = geomSrc.fIndexBuffer;
320 geomSrc.fIndexBuffer->ref();
321 draw->fVertexBuffer = vertexBuffer;
322 vertexBuffer->ref();
323 draw->fPrimitiveType = type;
324 draw->fStartIndex = 0;
325 draw->fStartVertex = startVertex;
326 draw->fVertexCount = 0;
327 draw->fVertexLayout = geomSrc.fVertexLayout;
328 instancesToConcat = maxInstancesPerDraw;
329 }
330 draw->fVertexCount += instancesToConcat * verticesPerInstance;
331 draw->fIndexCount += instancesToConcat * indicesPerInstance;
332 instanceCount -= instancesToConcat;
333 instancesToConcat = 0;
334 }
335
336 // update draw tracking for next draw
337 fCurrQuad = 0;
338 fInstancedDrawTracker.fVerticesPerInstance = verticesPerInstance;
339 fInstancedDrawTracker.fIndicesPerInstance = indicesPerInstance;
340 } else {
341 this->INHERITED::drawIndexedInstances(type,
342 instanceCount,
343 verticesPerInstance,
344 indicesPerInstance);
345 }
346
347}
348
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000349void GrInOrderDrawBuffer::onDrawIndexed(GrPrimitiveType primitiveType,
350 int startVertex,
351 int startIndex,
352 int vertexCount,
353 int indexCount) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000354
355 if (!vertexCount || !indexCount) {
356 return;
357 }
358
bsalomon@google.com934c5702012-03-20 21:17:58 +0000359 this->resetDrawTracking();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000360
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000361 GeometryPoolState& poolState = fGeoPoolStateStack.back();
362
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000363 if (this->needsNewClip()) {
364 this->recordClip();
365 }
366 if (this->needsNewState()) {
367 this->recordState();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000368 }
369
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000370 Draw* draw = this->recordDraw();
reed@google.comac10a2d2010-12-22 21:39:39 +0000371
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000372 draw->fPrimitiveType = primitiveType;
373 draw->fStartVertex = startVertex;
374 draw->fStartIndex = startIndex;
375 draw->fVertexCount = vertexCount;
376 draw->fIndexCount = indexCount;
377
378 draw->fVertexLayout = this->getVertexLayout();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000379 switch (this->getGeomSrc().fVertexSrc) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000380 case kBuffer_GeometrySrcType:
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000381 draw->fVertexBuffer = this->getGeomSrc().fVertexBuffer;
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 vertexBytes = (vertexCount + startVertex) *
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000386 VertexSize(draw->fVertexLayout);
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000387 poolState.fUsedPoolVertexBytes =
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000388 GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000389 draw->fVertexBuffer = poolState.fPoolVertexBuffer;
390 draw->fStartVertex += poolState.fPoolStartVertex;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000391 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000392 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000393 default:
394 GrCrash("unknown geom src type");
reed@google.comac10a2d2010-12-22 21:39:39 +0000395 }
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000396 draw->fVertexBuffer->ref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000397
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000398 switch (this->getGeomSrc().fIndexSrc) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000399 case kBuffer_GeometrySrcType:
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000400 draw->fIndexBuffer = this->getGeomSrc().fIndexBuffer;
reed@google.comac10a2d2010-12-22 21:39:39 +0000401 break;
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000402 case kReserved_GeometrySrcType: // fallthrough
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000403 case kArray_GeometrySrcType: {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000404 size_t indexBytes = (indexCount + startIndex) * sizeof(uint16_t);
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000405 poolState.fUsedPoolIndexBytes =
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000406 GrMax(poolState.fUsedPoolIndexBytes, indexBytes);
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000407 draw->fIndexBuffer = poolState.fPoolIndexBuffer;
408 draw->fStartIndex += poolState.fPoolStartIndex;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000409 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000410 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000411 default:
412 GrCrash("unknown geom src type");
reed@google.comac10a2d2010-12-22 21:39:39 +0000413 }
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000414 draw->fIndexBuffer->ref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000415}
416
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000417void GrInOrderDrawBuffer::onDrawNonIndexed(GrPrimitiveType primitiveType,
418 int startVertex,
419 int vertexCount) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000420 if (!vertexCount) {
421 return;
422 }
423
bsalomon@google.com934c5702012-03-20 21:17:58 +0000424 this->resetDrawTracking();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000425
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000426 GeometryPoolState& poolState = fGeoPoolStateStack.back();
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000427 if (this->needsNewClip()) {
428 this->recordClip();
429 }
430 if (this->needsNewState()) {
431 this->recordState();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000432 }
433
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000434 Draw* draw = this->recordDraw();
435 draw->fPrimitiveType = primitiveType;
436 draw->fStartVertex = startVertex;
437 draw->fStartIndex = 0;
438 draw->fVertexCount = vertexCount;
439 draw->fIndexCount = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000440
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000441 draw->fVertexLayout = this->getVertexLayout();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000442 switch (this->getGeomSrc().fVertexSrc) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000443 case kBuffer_GeometrySrcType:
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000444 draw->fVertexBuffer = this->getGeomSrc().fVertexBuffer;
reed@google.comac10a2d2010-12-22 21:39:39 +0000445 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000446 case kReserved_GeometrySrcType: // fallthrough
447 case kArray_GeometrySrcType: {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000448 size_t vertexBytes = (vertexCount + startVertex) *
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000449 VertexSize(draw->fVertexLayout);
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000450 poolState.fUsedPoolVertexBytes =
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000451 GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000452 draw->fVertexBuffer = poolState.fPoolVertexBuffer;
453 draw->fStartVertex += poolState.fPoolStartVertex;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000454 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000455 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000456 default:
457 GrCrash("unknown geom src type");
reed@google.comac10a2d2010-12-22 21:39:39 +0000458 }
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000459 draw->fVertexBuffer->ref();
460 draw->fIndexBuffer = NULL;
reed@google.comac10a2d2010-12-22 21:39:39 +0000461}
462
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000463void GrInOrderDrawBuffer::onStencilPath(const GrPath* path, GrPathFill fill) {
464 if (this->needsNewClip()) {
465 this->recordClip();
466 }
467 // Only compare the subset of GrDrawState relevant to path stenciling?
468 if (this->needsNewState()) {
469 this->recordState();
470 }
471 StencilPath* sp = this->recordStencilPath();
472 sp->fPath.reset(path);
473 path->ref();
474 sp->fFill = fill;
bsalomon@google.com64aef2b2012-06-11 15:36:13 +0000475}
476
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000477void GrInOrderDrawBuffer::clear(const GrIRect* rect,
robertphillips@google.comc82a8b72012-06-21 20:15:48 +0000478 GrColor color,
479 GrRenderTarget* renderTarget) {
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000480 GrIRect r;
bsalomon@google.com1b3ce472012-08-17 13:43:08 +0000481 if (NULL == renderTarget) {
482 renderTarget = this->drawState()->getRenderTarget();
483 GrAssert(NULL != renderTarget);
484 }
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000485 if (NULL == rect) {
486 // We could do something smart and remove previous draws and clears to
487 // the current render target. If we get that smart we have to make sure
488 // those draws aren't read before this clear (render-to-texture).
bsalomon@google.com1b3ce472012-08-17 13:43:08 +0000489 r.setLTRB(0, 0, renderTarget->width(), renderTarget->height());
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000490 rect = &r;
491 }
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000492 Clear* clr = this->recordClear();
493 clr->fColor = color;
494 clr->fRect = *rect;
495 clr->fRenderTarget = renderTarget;
bsalomon@google.com1b3ce472012-08-17 13:43:08 +0000496 renderTarget->ref();
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000497}
498
reed@google.comac10a2d2010-12-22 21:39:39 +0000499void GrInOrderDrawBuffer::reset() {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000500 GrAssert(1 == fGeoPoolStateStack.count());
501 this->resetVertexSource();
502 this->resetIndexSource();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000503 int numDraws = fDraws.count();
504 for (int d = 0; d < numDraws; ++d) {
505 // we always have a VB, but not always an IB
506 GrAssert(NULL != fDraws[d].fVertexBuffer);
507 fDraws[d].fVertexBuffer->unref();
508 GrSafeUnref(fDraws[d].fIndexBuffer);
509 }
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000510 fCmds.reset();
reed@google.comac10a2d2010-12-22 21:39:39 +0000511 fDraws.reset();
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000512 fStencilPaths.reset();
reed@google.comac10a2d2010-12-22 21:39:39 +0000513 fStates.reset();
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000514 fClears.reset();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000515 fVertexPool.reset();
516 fIndexPool.reset();
reed@google.comac10a2d2010-12-22 21:39:39 +0000517 fClips.reset();
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000518 fClipOrigins.reset();
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000519 fClipSet = true;
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000520
bsalomon@google.com934c5702012-03-20 21:17:58 +0000521 this->resetDrawTracking();
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000522
523 // we start off with a default clip and state so that we don't have
524 // to do count checks on fClips, fStates, or fCmds before checking their
525 // last entry.
526 this->recordDefaultState();
527 this->recordDefaultClip();
reed@google.comac10a2d2010-12-22 21:39:39 +0000528}
529
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000530bool GrInOrderDrawBuffer::playback(GrDrawTarget* target) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000531 GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fVertexSrc);
532 GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fIndexSrc);
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000533
reed@google.comac10a2d2010-12-22 21:39:39 +0000534 GrAssert(NULL != target);
535 GrAssert(target != this); // not considered and why?
536
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000537 int numCmds = fCmds.count();
538 GrAssert(numCmds >= 2);
539 if (2 == numCmds) {
540 GrAssert(kSetState_Cmd == fCmds[0]);
541 GrAssert(kSetClip_Cmd == fCmds[1]);
542 return false;
reed@google.comac10a2d2010-12-22 21:39:39 +0000543 }
544
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000545 fVertexPool.unlock();
546 fIndexPool.unlock();
reed@google.comac10a2d2010-12-22 21:39:39 +0000547
reed@google.comac10a2d2010-12-22 21:39:39 +0000548 GrDrawTarget::AutoClipRestore acr(target);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000549 AutoGeometryPush agp(target);
bsalomon@google.coma5d056a2012-03-27 15:59:58 +0000550 GrDrawState* prevDrawState = target->drawState();
551 prevDrawState->ref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000552
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000553 GrClipData clipData;
554
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000555 int currState = 0;
556 int currClip = 0;
557 int currClear = 0;
558 int currDraw = 0;
559 int currStencilPath = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000560
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000561 for (int c = 0; c < numCmds; ++c) {
562 switch (fCmds[c]) {
563 case kDraw_Cmd: {
564 const Draw& draw = fDraws[currDraw];
565 target->setVertexSourceToBuffer(draw.fVertexLayout, draw.fVertexBuffer);
566 if (draw.fIndexCount) {
567 target->setIndexSourceToBuffer(draw.fIndexBuffer);
568 }
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000569
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000570 if (draw.fIndexCount) {
571 target->drawIndexed(draw.fPrimitiveType,
572 draw.fStartVertex,
573 draw.fStartIndex,
574 draw.fVertexCount,
575 draw.fIndexCount);
576 } else {
577 target->drawNonIndexed(draw.fPrimitiveType,
578 draw.fStartVertex,
579 draw.fVertexCount);
580 }
581 ++currDraw;
582 break;
583 }
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000584 case kStencilPath_Cmd: {
585 const StencilPath& sp = fStencilPaths[currStencilPath];
586 target->stencilPath(sp.fPath.get(), sp.fFill);
587 ++currStencilPath;
588 break;
589 }
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000590 case kSetState_Cmd:
591 target->setDrawState(&fStates[currState]);
592 ++currState;
593 break;
594 case kSetClip_Cmd:
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000595 clipData.fClipStack = &fClips[currClip];
596 clipData.fOrigin = fClipOrigins[currClip];
597 target->setClip(&clipData);
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000598 ++currClip;
599 break;
600 case kClear_Cmd:
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000601 target->clear(&fClears[currClear].fRect,
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000602 fClears[currClear].fColor,
603 fClears[currClear].fRenderTarget);
604 ++currClear;
605 break;
reed@google.comac10a2d2010-12-22 21:39:39 +0000606 }
607 }
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000608 // we should have consumed all the states, clips, etc.
609 GrAssert(fStates.count() == currState);
610 GrAssert(fClips.count() == currClip);
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000611 GrAssert(fClipOrigins.count() == currClip);
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000612 GrAssert(fClears.count() == currClear);
613 GrAssert(fDraws.count() == currDraw);
614
bsalomon@google.coma5d056a2012-03-27 15:59:58 +0000615 target->setDrawState(prevDrawState);
616 prevDrawState->unref();
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000617 return true;
reed@google.comac10a2d2010-12-22 21:39:39 +0000618}
619
bsalomon@google.com97805382012-03-13 14:32:07 +0000620void GrInOrderDrawBuffer::setAutoFlushTarget(GrDrawTarget* target) {
621 GrSafeAssign(fAutoFlushTarget, target);
622}
623
624void GrInOrderDrawBuffer::willReserveVertexAndIndexSpace(
625 GrVertexLayout vertexLayout,
626 int vertexCount,
627 int indexCount) {
628 if (NULL != fAutoFlushTarget) {
629 // We use geometryHints() to know whether to flush the draw buffer. We
630 // can't flush if we are inside an unbalanced pushGeometrySource.
631 // Moreover, flushing blows away vertex and index data that was
632 // previously reserved. So if the vertex or index data is pulled from
633 // reserved space and won't be released by this request then we can't
634 // flush.
635 bool insideGeoPush = fGeoPoolStateStack.count() > 1;
636
637 bool unreleasedVertexSpace =
638 !vertexCount &&
639 kReserved_GeometrySrcType == this->getGeomSrc().fVertexSrc;
640
641 bool unreleasedIndexSpace =
642 !indexCount &&
643 kReserved_GeometrySrcType == this->getGeomSrc().fIndexSrc;
644
645 // we don't want to finalize any reserved geom on the target since
646 // we don't know that the client has finished writing to it.
647 bool targetHasReservedGeom =
648 fAutoFlushTarget->hasReservedVerticesOrIndices();
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000649
bsalomon@google.com97805382012-03-13 14:32:07 +0000650 int vcount = vertexCount;
651 int icount = indexCount;
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000652
bsalomon@google.com97805382012-03-13 14:32:07 +0000653 if (!insideGeoPush &&
654 !unreleasedVertexSpace &&
655 !unreleasedIndexSpace &&
656 !targetHasReservedGeom &&
657 this->geometryHints(vertexLayout, &vcount, &icount)) {
658
659 this->flushTo(fAutoFlushTarget);
660 }
661 }
662}
663
reed@google.comac10a2d2010-12-22 21:39:39 +0000664bool GrInOrderDrawBuffer::geometryHints(GrVertexLayout vertexLayout,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000665 int* vertexCount,
666 int* indexCount) const {
667 // we will recommend a flush if the data could fit in a single
668 // preallocated buffer but none are left and it can't fit
669 // in the current buffer (which may not be prealloced).
reed@google.comac10a2d2010-12-22 21:39:39 +0000670 bool flush = false;
671 if (NULL != indexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000672 int32_t currIndices = fIndexPool.currentBufferIndices();
673 if (*indexCount > currIndices &&
674 (!fIndexPool.preallocatedBuffersRemaining() &&
675 *indexCount <= fIndexPool.preallocatedBufferIndices())) {
676
677 flush = true;
678 }
679 *indexCount = currIndices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000680 }
681 if (NULL != vertexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000682 int32_t currVertices = fVertexPool.currentBufferVertices(vertexLayout);
683 if (*vertexCount > currVertices &&
684 (!fVertexPool.preallocatedBuffersRemaining() &&
685 *vertexCount <= fVertexPool.preallocatedBufferVertices(vertexLayout))) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000686
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000687 flush = true;
reed@google.comac10a2d2010-12-22 21:39:39 +0000688 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000689 *vertexCount = currVertices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000690 }
691 return flush;
692}
693
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000694bool GrInOrderDrawBuffer::onReserveVertexSpace(GrVertexLayout vertexLayout,
695 int vertexCount,
696 void** vertices) {
697 GeometryPoolState& poolState = fGeoPoolStateStack.back();
698 GrAssert(vertexCount > 0);
699 GrAssert(NULL != vertices);
700 GrAssert(0 == poolState.fUsedPoolVertexBytes);
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000701
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000702 *vertices = fVertexPool.makeSpace(vertexLayout,
703 vertexCount,
704 &poolState.fPoolVertexBuffer,
705 &poolState.fPoolStartVertex);
706 return NULL != *vertices;
707}
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000708
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000709bool GrInOrderDrawBuffer::onReserveIndexSpace(int indexCount, void** indices) {
710 GeometryPoolState& poolState = fGeoPoolStateStack.back();
711 GrAssert(indexCount > 0);
712 GrAssert(NULL != indices);
713 GrAssert(0 == poolState.fUsedPoolIndexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000714
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000715 *indices = fIndexPool.makeSpace(indexCount,
716 &poolState.fPoolIndexBuffer,
717 &poolState.fPoolStartIndex);
718 return NULL != *indices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000719}
720
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000721void GrInOrderDrawBuffer::releaseReservedVertexSpace() {
722 GeometryPoolState& poolState = fGeoPoolStateStack.back();
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000723 const GeometrySrcState& geoSrc = this->getGeomSrc();
bsalomon@google.comd57d71a2012-08-16 16:26:33 +0000724
725 // If we get a release vertex space call then our current source should either be reserved
726 // or array (which we copied into reserved space).
727 GrAssert(kReserved_GeometrySrcType == geoSrc.fVertexSrc ||
728 kArray_GeometrySrcType == geoSrc.fVertexSrc);
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000729
730 // When the caller reserved vertex buffer space we gave it back a pointer
731 // provided by the vertex buffer pool. At each draw we tracked the largest
732 // offset into the pool's pointer that was referenced. Now we return to the
733 // pool any portion at the tail of the allocation that no draw referenced.
734 size_t reservedVertexBytes = VertexSize(geoSrc.fVertexLayout) *
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000735 geoSrc.fVertexCount;
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000736 fVertexPool.putBack(reservedVertexBytes -
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000737 poolState.fUsedPoolVertexBytes);
738 poolState.fUsedPoolVertexBytes = 0;
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000739 poolState.fPoolVertexBuffer = NULL;
740 poolState.fPoolStartVertex = 0;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000741}
742
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000743void GrInOrderDrawBuffer::releaseReservedIndexSpace() {
744 GeometryPoolState& poolState = fGeoPoolStateStack.back();
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000745 const GeometrySrcState& geoSrc = this->getGeomSrc();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000746
bsalomon@google.comd57d71a2012-08-16 16:26:33 +0000747 // If we get a release index space call then our current source should either be reserved
748 // or array (which we copied into reserved space).
749 GrAssert(kReserved_GeometrySrcType == geoSrc.fIndexSrc ||
750 kArray_GeometrySrcType == geoSrc.fIndexSrc);
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000751
752 // Similar to releaseReservedVertexSpace we return any unused portion at
753 // the tail
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000754 size_t reservedIndexBytes = sizeof(uint16_t) * geoSrc.fIndexCount;
755 fIndexPool.putBack(reservedIndexBytes - poolState.fUsedPoolIndexBytes);
756 poolState.fUsedPoolIndexBytes = 0;
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000757 poolState.fPoolIndexBuffer = NULL;
758 poolState.fPoolStartIndex = 0;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000759}
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000760
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000761void GrInOrderDrawBuffer::onSetVertexSourceToArray(const void* vertexArray,
762 int vertexCount) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000763
764 GeometryPoolState& poolState = fGeoPoolStateStack.back();
765 GrAssert(0 == poolState.fUsedPoolVertexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000766#if GR_DEBUG
767 bool success =
768#endif
bsalomon@google.come79c8152012-03-29 19:07:12 +0000769 fVertexPool.appendVertices(this->getVertexLayout(),
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000770 vertexCount,
771 vertexArray,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000772 &poolState.fPoolVertexBuffer,
773 &poolState.fPoolStartVertex);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000774 GR_DEBUGASSERT(success);
775}
776
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000777void GrInOrderDrawBuffer::onSetIndexSourceToArray(const void* indexArray,
778 int indexCount) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000779 GeometryPoolState& poolState = fGeoPoolStateStack.back();
780 GrAssert(0 == poolState.fUsedPoolIndexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000781#if GR_DEBUG
782 bool success =
783#endif
784 fIndexPool.appendIndices(indexCount,
785 indexArray,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000786 &poolState.fPoolIndexBuffer,
787 &poolState.fPoolStartIndex);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000788 GR_DEBUGASSERT(success);
reed@google.comac10a2d2010-12-22 21:39:39 +0000789}
790
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000791void GrInOrderDrawBuffer::releaseVertexArray() {
792 // When the client provides an array as the vertex source we handled it
793 // by copying their array into reserved space.
794 this->GrInOrderDrawBuffer::releaseReservedVertexSpace();
795}
796
797void GrInOrderDrawBuffer::releaseIndexArray() {
798 // When the client provides an array as the index source we handled it
799 // by copying their array into reserved space.
800 this->GrInOrderDrawBuffer::releaseReservedIndexSpace();
801}
802
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000803void GrInOrderDrawBuffer::geometrySourceWillPush() {
804 GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
805 poolState.fUsedPoolVertexBytes = 0;
806 poolState.fUsedPoolIndexBytes = 0;
bsalomon@google.com934c5702012-03-20 21:17:58 +0000807 this->resetDrawTracking();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000808#if GR_DEBUG
809 poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0;
810 poolState.fPoolStartVertex = ~0;
811 poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0;
812 poolState.fPoolStartIndex = ~0;
813#endif
814}
815
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000816void GrInOrderDrawBuffer::geometrySourceWillPop(
817 const GeometrySrcState& restoredState) {
818 GrAssert(fGeoPoolStateStack.count() > 1);
819 fGeoPoolStateStack.pop_back();
820 GeometryPoolState& poolState = fGeoPoolStateStack.back();
821 // we have to assume that any slack we had in our vertex/index data
822 // is now unreleasable because data may have been appended later in the
823 // pool.
824 if (kReserved_GeometrySrcType == restoredState.fVertexSrc ||
825 kArray_GeometrySrcType == restoredState.fVertexSrc) {
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000826 poolState.fUsedPoolVertexBytes =
827 VertexSize(restoredState.fVertexLayout) *
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000828 restoredState.fVertexCount;
829 }
830 if (kReserved_GeometrySrcType == restoredState.fIndexSrc ||
831 kArray_GeometrySrcType == restoredState.fIndexSrc) {
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000832 poolState.fUsedPoolIndexBytes = sizeof(uint16_t) *
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000833 restoredState.fIndexCount;
834 }
bsalomon@google.com934c5702012-03-20 21:17:58 +0000835 this->resetDrawTracking();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000836}
837
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000838bool GrInOrderDrawBuffer::needsNewState() const {
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000839 // we should have recorded a default state in reset()
840 GrAssert(!fStates.empty());
841 return fStates.back() != this->getDrawState();
reed@google.comac10a2d2010-12-22 21:39:39 +0000842}
843
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000844bool GrInOrderDrawBuffer::needsNewClip() const {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000845 if (this->getDrawState().isClipState()) {
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000846 if (fClipSet &&
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000847 (fClips.back() != *fClip->fClipStack ||
848 fClipOrigins.back() != fClip->fOrigin)) {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000849 return true;
850 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000851 }
852 return false;
853}
bsalomon@google.comd302f142011-03-03 13:54:13 +0000854
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000855void GrInOrderDrawBuffer::recordClip() {
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000856 fClips.push_back() = *fClip->fClipStack;
857 fClipOrigins.push_back() = fClip->fOrigin;
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000858 fClipSet = false;
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000859 fCmds.push_back(kSetClip_Cmd);
860}
861
862void GrInOrderDrawBuffer::recordDefaultClip() {
robertphillips@google.com641f8b12012-07-31 19:15:58 +0000863 fClips.push_back() = SkClipStack();
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000864 fClipOrigins.push_back() = SkIPoint::Make(0, 0);
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000865 fCmds.push_back(kSetClip_Cmd);
866}
867
868void GrInOrderDrawBuffer::recordState() {
869 fStates.push_back(this->getDrawState());
870 fCmds.push_back(kSetState_Cmd);
871}
872
873void GrInOrderDrawBuffer::recordDefaultState() {
874 fStates.push_back(GrDrawState());
875 fCmds.push_back(kSetState_Cmd);
876}
877
878GrInOrderDrawBuffer::Draw* GrInOrderDrawBuffer::recordDraw() {
879 fCmds.push_back(kDraw_Cmd);
880 return &fDraws.push_back();
881}
882
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000883GrInOrderDrawBuffer::StencilPath* GrInOrderDrawBuffer::recordStencilPath() {
884 fCmds.push_back(kStencilPath_Cmd);
885 return &fStencilPaths.push_back();
886}
887
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000888GrInOrderDrawBuffer::Clear* GrInOrderDrawBuffer::recordClear() {
889 fCmds.push_back(kClear_Cmd);
890 return &fClears.push_back();
reed@google.comac10a2d2010-12-22 21:39:39 +0000891}
bsalomon@google.comd302f142011-03-03 13:54:13 +0000892
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000893void GrInOrderDrawBuffer::clipWillBeSet(const GrClipData* newClipData) {
894 INHERITED::clipWillBeSet(newClipData);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000895 fClipSet = true;
896}