blob: e562300dd9430ff686f2da6f91cee33b996beda5 [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.com641f8b12012-07-31 19:15:58 +0000128 if (drawState->isClipState()) {
129
130 GrRect devClipRect;
131 bool isIntersectionOfRects = false;
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000132
robertphillips@google.com641f8b12012-07-31 19:15:58 +0000133 fClip->fClipStack->getConservativeBounds(-fClip->fOrigin.fX,
134 -fClip->fOrigin.fY,
135 drawState->getRenderTarget()->width(),
136 drawState->getRenderTarget()->height(),
137 &devClipRect,
138 &isIntersectionOfRects);
robertphillips@google.coma6f11c42012-07-23 17:39:44 +0000139
robertphillips@google.com641f8b12012-07-31 19:15:58 +0000140 if (isIntersectionOfRects) {
141 // If the clip rect touches the edge of the viewport, extended it
142 // out (close) to infinity to avoid bogus intersections.
143 // We might consider a more exact clip to viewport if this
144 // conservative test fails.
145 const GrRenderTarget* target = drawState->getRenderTarget();
146 if (0 >= devClipRect.fLeft) {
147 devClipRect.fLeft = GR_ScalarMin;
148 }
149 if (target->width() <= devClipRect.fRight) {
150 devClipRect.fRight = GR_ScalarMax;
151 }
152 if (0 >= devClipRect.top()) {
153 devClipRect.fTop = GR_ScalarMin;
154 }
155 if (target->height() <= devClipRect.fBottom) {
156 devClipRect.fBottom = GR_ScalarMax;
157 }
158 int stride = VertexSize(layout);
159 bool insideClip = true;
160 for (int v = 0; v < 4; ++v) {
161 const GrPoint& p = *GetVertexPoint(geo.vertices(), v, stride);
162 if (!devClipRect.contains(p)) {
163 insideClip = false;
164 break;
165 }
166 }
167 if (insideClip) {
168 drawState->disableState(GrDrawState::kClip_StateBit);
169 disabledClip = true;
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000170 }
171 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000172 }
robertphillips@google.com641f8b12012-07-31 19:15:58 +0000173
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000174 if (!this->needsNewClip() &&
175 !this->needsNewState() &&
176 fCurrQuad > 0 &&
177 fCurrQuad < fMaxQuads &&
178 layout == fLastRectVertexLayout) {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000179
180 int vsize = VertexSize(layout);
bsalomon@google.comd302f142011-03-03 13:54:13 +0000181
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000182 Draw& lastDraw = fDraws.back();
183
184 GrAssert(lastDraw.fIndexBuffer == fQuadIndexBuffer);
bsalomon@google.com47059542012-06-06 20:51:20 +0000185 GrAssert(kTriangles_GrPrimitiveType == lastDraw.fPrimitiveType);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000186 GrAssert(0 == lastDraw.fVertexCount % 4);
187 GrAssert(0 == lastDraw.fIndexCount % 6);
188 GrAssert(0 == lastDraw.fStartIndex);
189
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000190 GeometryPoolState& poolState = fGeoPoolStateStack.back();
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000191
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000192 appendToPreviousDraw =
193 kDraw_Cmd != fCmds.back() &&
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000194 lastDraw.fVertexBuffer == poolState.fPoolVertexBuffer &&
195 (fCurrQuad * 4 + lastDraw.fStartVertex) == poolState.fPoolStartVertex;
196
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000197 if (appendToPreviousDraw) {
198 lastDraw.fVertexCount += 4;
199 lastDraw.fIndexCount += 6;
200 fCurrQuad += 1;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000201 // we reserved above, so we should be the first
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000202 // use of this vertex reservation.
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000203 GrAssert(0 == poolState.fUsedPoolVertexBytes);
204 poolState.fUsedPoolVertexBytes = 4 * vsize;
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000205 }
206 }
207 if (!appendToPreviousDraw) {
208 this->setIndexSourceToBuffer(fQuadIndexBuffer);
bsalomon@google.com47059542012-06-06 20:51:20 +0000209 this->drawIndexed(kTriangles_GrPrimitiveType, 0, 0, 4, 6);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000210 fCurrQuad = 1;
211 fLastRectVertexLayout = layout;
212 }
213 if (disabledClip) {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000214 drawState->enableState(GrDrawState::kClip_StateBit);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000215 }
bsalomon@google.com934c5702012-03-20 21:17:58 +0000216 fInstancedDrawTracker.reset();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000217 } else {
bsalomon@google.come3d32162012-07-20 13:37:06 +0000218 INHERITED::drawRect(rect, matrix, srcRects, srcMatrices);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000219 }
220}
221
bsalomon@google.com934c5702012-03-20 21:17:58 +0000222void GrInOrderDrawBuffer::drawIndexedInstances(GrPrimitiveType type,
223 int instanceCount,
224 int verticesPerInstance,
225 int indicesPerInstance) {
226 if (!verticesPerInstance || !indicesPerInstance) {
227 return;
228 }
229
230 const GeometrySrcState& geomSrc = this->getGeomSrc();
231
232 // we only attempt to concat the case when reserved verts are used with
233 // an index buffer.
234 if (kReserved_GeometrySrcType == geomSrc.fVertexSrc &&
235 kBuffer_GeometrySrcType == geomSrc.fIndexSrc) {
236
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000237 if (this->needsNewClip()) {
238 this->recordClip();
239 }
240 if (this->needsNewState()) {
241 this->recordState();
242 }
243
bsalomon@google.com934c5702012-03-20 21:17:58 +0000244 Draw* draw = NULL;
245 // if the last draw used the same indices/vertices per shape then we
246 // may be able to append to it.
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000247 if (kDraw_Cmd == fCmds.back() &&
248 verticesPerInstance == fInstancedDrawTracker.fVerticesPerInstance &&
bsalomon@google.com934c5702012-03-20 21:17:58 +0000249 indicesPerInstance == fInstancedDrawTracker.fIndicesPerInstance) {
250 GrAssert(fDraws.count());
251 draw = &fDraws.back();
252 }
253
bsalomon@google.com934c5702012-03-20 21:17:58 +0000254 GeometryPoolState& poolState = fGeoPoolStateStack.back();
255 const GrVertexBuffer* vertexBuffer = poolState.fPoolVertexBuffer;
256
257 // Check whether the draw is compatible with this draw in order to
258 // append
259 if (NULL == draw ||
bsalomon@google.com934c5702012-03-20 21:17:58 +0000260 draw->fIndexBuffer != geomSrc.fIndexBuffer ||
261 draw->fPrimitiveType != type ||
262 draw->fVertexBuffer != vertexBuffer) {
263
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000264 draw = this->recordDraw();
bsalomon@google.com934c5702012-03-20 21:17:58 +0000265 draw->fIndexBuffer = geomSrc.fIndexBuffer;
266 geomSrc.fIndexBuffer->ref();
267 draw->fVertexBuffer = vertexBuffer;
268 vertexBuffer->ref();
269 draw->fPrimitiveType = type;
270 draw->fStartIndex = 0;
271 draw->fIndexCount = 0;
272 draw->fStartVertex = poolState.fPoolStartVertex;
273 draw->fVertexCount = 0;
274 draw->fVertexLayout = geomSrc.fVertexLayout;
275 } else {
276 GrAssert(!(draw->fIndexCount % indicesPerInstance));
277 GrAssert(!(draw->fVertexCount % verticesPerInstance));
278 GrAssert(poolState.fPoolStartVertex == draw->fStartVertex +
279 draw->fVertexCount);
280 }
281
282 // how many instances can be in a single draw
283 int maxInstancesPerDraw = this->indexCountInCurrentSource() /
284 indicesPerInstance;
285 if (!maxInstancesPerDraw) {
286 return;
287 }
288 // how many instances should be concat'ed onto draw
289 int instancesToConcat = maxInstancesPerDraw - draw->fVertexCount /
290 verticesPerInstance;
291 if (maxInstancesPerDraw > instanceCount) {
292 maxInstancesPerDraw = instanceCount;
293 if (instancesToConcat > instanceCount) {
294 instancesToConcat = instanceCount;
295 }
296 }
297
298 // update the amount of reserved data actually referenced in draws
299 size_t vertexBytes = instanceCount * verticesPerInstance *
300 VertexSize(draw->fVertexLayout);
301 poolState.fUsedPoolVertexBytes =
302 GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
303
304 while (instanceCount) {
305 if (!instancesToConcat) {
306 int startVertex = draw->fStartVertex + draw->fVertexCount;
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000307 draw = this->recordDraw();
bsalomon@google.com934c5702012-03-20 21:17:58 +0000308 draw->fIndexBuffer = geomSrc.fIndexBuffer;
309 geomSrc.fIndexBuffer->ref();
310 draw->fVertexBuffer = vertexBuffer;
311 vertexBuffer->ref();
312 draw->fPrimitiveType = type;
313 draw->fStartIndex = 0;
314 draw->fStartVertex = startVertex;
315 draw->fVertexCount = 0;
316 draw->fVertexLayout = geomSrc.fVertexLayout;
317 instancesToConcat = maxInstancesPerDraw;
318 }
319 draw->fVertexCount += instancesToConcat * verticesPerInstance;
320 draw->fIndexCount += instancesToConcat * indicesPerInstance;
321 instanceCount -= instancesToConcat;
322 instancesToConcat = 0;
323 }
324
325 // update draw tracking for next draw
326 fCurrQuad = 0;
327 fInstancedDrawTracker.fVerticesPerInstance = verticesPerInstance;
328 fInstancedDrawTracker.fIndicesPerInstance = indicesPerInstance;
329 } else {
330 this->INHERITED::drawIndexedInstances(type,
331 instanceCount,
332 verticesPerInstance,
333 indicesPerInstance);
334 }
335
336}
337
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000338void GrInOrderDrawBuffer::onDrawIndexed(GrPrimitiveType primitiveType,
339 int startVertex,
340 int startIndex,
341 int vertexCount,
342 int indexCount) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000343
344 if (!vertexCount || !indexCount) {
345 return;
346 }
347
bsalomon@google.com934c5702012-03-20 21:17:58 +0000348 this->resetDrawTracking();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000349
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000350 GeometryPoolState& poolState = fGeoPoolStateStack.back();
351
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000352 if (this->needsNewClip()) {
353 this->recordClip();
354 }
355 if (this->needsNewState()) {
356 this->recordState();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000357 }
358
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000359 Draw* draw = this->recordDraw();
reed@google.comac10a2d2010-12-22 21:39:39 +0000360
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000361 draw->fPrimitiveType = primitiveType;
362 draw->fStartVertex = startVertex;
363 draw->fStartIndex = startIndex;
364 draw->fVertexCount = vertexCount;
365 draw->fIndexCount = indexCount;
366
367 draw->fVertexLayout = this->getVertexLayout();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000368 switch (this->getGeomSrc().fVertexSrc) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000369 case kBuffer_GeometrySrcType:
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000370 draw->fVertexBuffer = this->getGeomSrc().fVertexBuffer;
reed@google.comac10a2d2010-12-22 21:39:39 +0000371 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000372 case kReserved_GeometrySrcType: // fallthrough
373 case kArray_GeometrySrcType: {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000374 size_t vertexBytes = (vertexCount + startVertex) *
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000375 VertexSize(draw->fVertexLayout);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000376 poolState.fUsedPoolVertexBytes =
377 GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000378 draw->fVertexBuffer = poolState.fPoolVertexBuffer;
379 draw->fStartVertex += poolState.fPoolStartVertex;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000380 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000381 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000382 default:
383 GrCrash("unknown geom src type");
reed@google.comac10a2d2010-12-22 21:39:39 +0000384 }
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000385 draw->fVertexBuffer->ref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000386
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000387 switch (this->getGeomSrc().fIndexSrc) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000388 case kBuffer_GeometrySrcType:
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000389 draw->fIndexBuffer = this->getGeomSrc().fIndexBuffer;
reed@google.comac10a2d2010-12-22 21:39:39 +0000390 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000391 case kReserved_GeometrySrcType: // fallthrough
392 case kArray_GeometrySrcType: {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000393 size_t indexBytes = (indexCount + startIndex) * sizeof(uint16_t);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000394 poolState.fUsedPoolIndexBytes =
395 GrMax(poolState.fUsedPoolIndexBytes, indexBytes);
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000396 draw->fIndexBuffer = poolState.fPoolIndexBuffer;
397 draw->fStartIndex += poolState.fPoolStartIndex;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000398 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000399 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000400 default:
401 GrCrash("unknown geom src type");
reed@google.comac10a2d2010-12-22 21:39:39 +0000402 }
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000403 draw->fIndexBuffer->ref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000404}
405
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000406void GrInOrderDrawBuffer::onDrawNonIndexed(GrPrimitiveType primitiveType,
407 int startVertex,
408 int vertexCount) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000409 if (!vertexCount) {
410 return;
411 }
412
bsalomon@google.com934c5702012-03-20 21:17:58 +0000413 this->resetDrawTracking();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000414
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000415 GeometryPoolState& poolState = fGeoPoolStateStack.back();
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000416 if (this->needsNewClip()) {
417 this->recordClip();
418 }
419 if (this->needsNewState()) {
420 this->recordState();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000421 }
422
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000423 Draw* draw = this->recordDraw();
424 draw->fPrimitiveType = primitiveType;
425 draw->fStartVertex = startVertex;
426 draw->fStartIndex = 0;
427 draw->fVertexCount = vertexCount;
428 draw->fIndexCount = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000429
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000430 draw->fVertexLayout = this->getVertexLayout();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000431 switch (this->getGeomSrc().fVertexSrc) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000432 case kBuffer_GeometrySrcType:
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000433 draw->fVertexBuffer = this->getGeomSrc().fVertexBuffer;
reed@google.comac10a2d2010-12-22 21:39:39 +0000434 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000435 case kReserved_GeometrySrcType: // fallthrough
436 case kArray_GeometrySrcType: {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000437 size_t vertexBytes = (vertexCount + startVertex) *
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000438 VertexSize(draw->fVertexLayout);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000439 poolState.fUsedPoolVertexBytes =
440 GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000441 draw->fVertexBuffer = poolState.fPoolVertexBuffer;
442 draw->fStartVertex += poolState.fPoolStartVertex;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000443 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000444 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000445 default:
446 GrCrash("unknown geom src type");
reed@google.comac10a2d2010-12-22 21:39:39 +0000447 }
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000448 draw->fVertexBuffer->ref();
449 draw->fIndexBuffer = NULL;
reed@google.comac10a2d2010-12-22 21:39:39 +0000450}
451
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000452void GrInOrderDrawBuffer::onStencilPath(const GrPath* path, GrPathFill fill) {
453 if (this->needsNewClip()) {
454 this->recordClip();
455 }
456 // Only compare the subset of GrDrawState relevant to path stenciling?
457 if (this->needsNewState()) {
458 this->recordState();
459 }
460 StencilPath* sp = this->recordStencilPath();
461 sp->fPath.reset(path);
462 path->ref();
463 sp->fFill = fill;
bsalomon@google.com64aef2b2012-06-11 15:36:13 +0000464}
465
robertphillips@google.comc82a8b72012-06-21 20:15:48 +0000466void GrInOrderDrawBuffer::clear(const GrIRect* rect,
467 GrColor color,
468 GrRenderTarget* renderTarget) {
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000469 GrIRect r;
bsalomon@google.com1b3ce472012-08-17 13:43:08 +0000470 if (NULL == renderTarget) {
471 renderTarget = this->drawState()->getRenderTarget();
472 GrAssert(NULL != renderTarget);
473 }
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000474 if (NULL == rect) {
475 // We could do something smart and remove previous draws and clears to
476 // the current render target. If we get that smart we have to make sure
477 // those draws aren't read before this clear (render-to-texture).
bsalomon@google.com1b3ce472012-08-17 13:43:08 +0000478 r.setLTRB(0, 0, renderTarget->width(), renderTarget->height());
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000479 rect = &r;
480 }
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000481 Clear* clr = this->recordClear();
482 clr->fColor = color;
483 clr->fRect = *rect;
484 clr->fRenderTarget = renderTarget;
bsalomon@google.com1b3ce472012-08-17 13:43:08 +0000485 renderTarget->ref();
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000486}
487
reed@google.comac10a2d2010-12-22 21:39:39 +0000488void GrInOrderDrawBuffer::reset() {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000489 GrAssert(1 == fGeoPoolStateStack.count());
490 this->resetVertexSource();
491 this->resetIndexSource();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000492 int numDraws = fDraws.count();
493 for (int d = 0; d < numDraws; ++d) {
494 // we always have a VB, but not always an IB
495 GrAssert(NULL != fDraws[d].fVertexBuffer);
496 fDraws[d].fVertexBuffer->unref();
497 GrSafeUnref(fDraws[d].fIndexBuffer);
498 }
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000499 fCmds.reset();
reed@google.comac10a2d2010-12-22 21:39:39 +0000500 fDraws.reset();
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000501 fStencilPaths.reset();
reed@google.comac10a2d2010-12-22 21:39:39 +0000502 fStates.reset();
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000503 fClears.reset();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000504 fVertexPool.reset();
505 fIndexPool.reset();
reed@google.comac10a2d2010-12-22 21:39:39 +0000506 fClips.reset();
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000507 fClipOrigins.reset();
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000508 fClipSet = true;
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000509
bsalomon@google.com934c5702012-03-20 21:17:58 +0000510 this->resetDrawTracking();
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000511
512 // we start off with a default clip and state so that we don't have
513 // to do count checks on fClips, fStates, or fCmds before checking their
514 // last entry.
515 this->recordDefaultState();
516 this->recordDefaultClip();
reed@google.comac10a2d2010-12-22 21:39:39 +0000517}
518
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000519bool GrInOrderDrawBuffer::playback(GrDrawTarget* target) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000520 GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fVertexSrc);
521 GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fIndexSrc);
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000522
reed@google.comac10a2d2010-12-22 21:39:39 +0000523 GrAssert(NULL != target);
524 GrAssert(target != this); // not considered and why?
525
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000526 int numCmds = fCmds.count();
527 GrAssert(numCmds >= 2);
528 if (2 == numCmds) {
529 GrAssert(kSetState_Cmd == fCmds[0]);
530 GrAssert(kSetClip_Cmd == fCmds[1]);
531 return false;
reed@google.comac10a2d2010-12-22 21:39:39 +0000532 }
533
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000534 fVertexPool.unlock();
535 fIndexPool.unlock();
reed@google.comac10a2d2010-12-22 21:39:39 +0000536
reed@google.comac10a2d2010-12-22 21:39:39 +0000537 GrDrawTarget::AutoClipRestore acr(target);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000538 AutoGeometryPush agp(target);
bsalomon@google.coma5d056a2012-03-27 15:59:58 +0000539 GrDrawState* prevDrawState = target->drawState();
540 prevDrawState->ref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000541
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000542 GrClipData clipData;
543
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000544 int currState = 0;
545 int currClip = 0;
546 int currClear = 0;
547 int currDraw = 0;
548 int currStencilPath = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000549
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000550 for (int c = 0; c < numCmds; ++c) {
551 switch (fCmds[c]) {
552 case kDraw_Cmd: {
553 const Draw& draw = fDraws[currDraw];
554 target->setVertexSourceToBuffer(draw.fVertexLayout, draw.fVertexBuffer);
555 if (draw.fIndexCount) {
556 target->setIndexSourceToBuffer(draw.fIndexBuffer);
557 }
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000558
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000559 if (draw.fIndexCount) {
560 target->drawIndexed(draw.fPrimitiveType,
561 draw.fStartVertex,
562 draw.fStartIndex,
563 draw.fVertexCount,
564 draw.fIndexCount);
565 } else {
566 target->drawNonIndexed(draw.fPrimitiveType,
567 draw.fStartVertex,
568 draw.fVertexCount);
569 }
570 ++currDraw;
571 break;
572 }
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000573 case kStencilPath_Cmd: {
574 const StencilPath& sp = fStencilPaths[currStencilPath];
575 target->stencilPath(sp.fPath.get(), sp.fFill);
576 ++currStencilPath;
577 break;
578 }
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000579 case kSetState_Cmd:
580 target->setDrawState(&fStates[currState]);
581 ++currState;
582 break;
583 case kSetClip_Cmd:
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000584 clipData.fClipStack = &fClips[currClip];
585 clipData.fOrigin = fClipOrigins[currClip];
586 target->setClip(&clipData);
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000587 ++currClip;
588 break;
589 case kClear_Cmd:
590 target->clear(&fClears[currClear].fRect,
591 fClears[currClear].fColor,
592 fClears[currClear].fRenderTarget);
593 ++currClear;
594 break;
reed@google.comac10a2d2010-12-22 21:39:39 +0000595 }
596 }
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000597 // we should have consumed all the states, clips, etc.
598 GrAssert(fStates.count() == currState);
599 GrAssert(fClips.count() == currClip);
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000600 GrAssert(fClipOrigins.count() == currClip);
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000601 GrAssert(fClears.count() == currClear);
602 GrAssert(fDraws.count() == currDraw);
603
bsalomon@google.coma5d056a2012-03-27 15:59:58 +0000604 target->setDrawState(prevDrawState);
605 prevDrawState->unref();
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000606 return true;
reed@google.comac10a2d2010-12-22 21:39:39 +0000607}
608
bsalomon@google.com97805382012-03-13 14:32:07 +0000609void GrInOrderDrawBuffer::setAutoFlushTarget(GrDrawTarget* target) {
610 GrSafeAssign(fAutoFlushTarget, target);
611}
612
613void GrInOrderDrawBuffer::willReserveVertexAndIndexSpace(
614 GrVertexLayout vertexLayout,
615 int vertexCount,
616 int indexCount) {
617 if (NULL != fAutoFlushTarget) {
618 // We use geometryHints() to know whether to flush the draw buffer. We
619 // can't flush if we are inside an unbalanced pushGeometrySource.
620 // Moreover, flushing blows away vertex and index data that was
621 // previously reserved. So if the vertex or index data is pulled from
622 // reserved space and won't be released by this request then we can't
623 // flush.
624 bool insideGeoPush = fGeoPoolStateStack.count() > 1;
625
626 bool unreleasedVertexSpace =
627 !vertexCount &&
628 kReserved_GeometrySrcType == this->getGeomSrc().fVertexSrc;
629
630 bool unreleasedIndexSpace =
631 !indexCount &&
632 kReserved_GeometrySrcType == this->getGeomSrc().fIndexSrc;
633
634 // we don't want to finalize any reserved geom on the target since
635 // we don't know that the client has finished writing to it.
636 bool targetHasReservedGeom =
637 fAutoFlushTarget->hasReservedVerticesOrIndices();
638
639 int vcount = vertexCount;
640 int icount = indexCount;
641
642 if (!insideGeoPush &&
643 !unreleasedVertexSpace &&
644 !unreleasedIndexSpace &&
645 !targetHasReservedGeom &&
646 this->geometryHints(vertexLayout, &vcount, &icount)) {
647
648 this->flushTo(fAutoFlushTarget);
649 }
650 }
651}
652
reed@google.comac10a2d2010-12-22 21:39:39 +0000653bool GrInOrderDrawBuffer::geometryHints(GrVertexLayout vertexLayout,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000654 int* vertexCount,
655 int* indexCount) const {
656 // we will recommend a flush if the data could fit in a single
657 // preallocated buffer but none are left and it can't fit
658 // in the current buffer (which may not be prealloced).
reed@google.comac10a2d2010-12-22 21:39:39 +0000659 bool flush = false;
660 if (NULL != indexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000661 int32_t currIndices = fIndexPool.currentBufferIndices();
662 if (*indexCount > currIndices &&
663 (!fIndexPool.preallocatedBuffersRemaining() &&
664 *indexCount <= fIndexPool.preallocatedBufferIndices())) {
665
666 flush = true;
667 }
668 *indexCount = currIndices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000669 }
670 if (NULL != vertexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000671 int32_t currVertices = fVertexPool.currentBufferVertices(vertexLayout);
672 if (*vertexCount > currVertices &&
673 (!fVertexPool.preallocatedBuffersRemaining() &&
674 *vertexCount <= fVertexPool.preallocatedBufferVertices(vertexLayout))) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000675
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000676 flush = true;
reed@google.comac10a2d2010-12-22 21:39:39 +0000677 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000678 *vertexCount = currVertices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000679 }
680 return flush;
681}
682
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000683bool GrInOrderDrawBuffer::onReserveVertexSpace(GrVertexLayout vertexLayout,
684 int vertexCount,
685 void** vertices) {
686 GeometryPoolState& poolState = fGeoPoolStateStack.back();
687 GrAssert(vertexCount > 0);
688 GrAssert(NULL != vertices);
689 GrAssert(0 == poolState.fUsedPoolVertexBytes);
690
691 *vertices = fVertexPool.makeSpace(vertexLayout,
692 vertexCount,
693 &poolState.fPoolVertexBuffer,
694 &poolState.fPoolStartVertex);
695 return NULL != *vertices;
696}
697
698bool GrInOrderDrawBuffer::onReserveIndexSpace(int indexCount, void** indices) {
699 GeometryPoolState& poolState = fGeoPoolStateStack.back();
700 GrAssert(indexCount > 0);
701 GrAssert(NULL != indices);
702 GrAssert(0 == poolState.fUsedPoolIndexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000703
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000704 *indices = fIndexPool.makeSpace(indexCount,
705 &poolState.fPoolIndexBuffer,
706 &poolState.fPoolStartIndex);
707 return NULL != *indices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000708}
709
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000710void GrInOrderDrawBuffer::releaseReservedVertexSpace() {
711 GeometryPoolState& poolState = fGeoPoolStateStack.back();
712 const GeometrySrcState& geoSrc = this->getGeomSrc();
bsalomon@google.comd57d71a2012-08-16 16:26:33 +0000713
714 // If we get a release vertex space call then our current source should either be reserved
715 // or array (which we copied into reserved space).
716 GrAssert(kReserved_GeometrySrcType == geoSrc.fVertexSrc ||
717 kArray_GeometrySrcType == geoSrc.fVertexSrc);
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000718
719 // When the caller reserved vertex buffer space we gave it back a pointer
720 // provided by the vertex buffer pool. At each draw we tracked the largest
721 // offset into the pool's pointer that was referenced. Now we return to the
722 // pool any portion at the tail of the allocation that no draw referenced.
723 size_t reservedVertexBytes = VertexSize(geoSrc.fVertexLayout) *
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000724 geoSrc.fVertexCount;
725 fVertexPool.putBack(reservedVertexBytes -
726 poolState.fUsedPoolVertexBytes);
727 poolState.fUsedPoolVertexBytes = 0;
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000728 poolState.fPoolVertexBuffer = NULL;
729 poolState.fPoolStartVertex = 0;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000730}
731
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000732void GrInOrderDrawBuffer::releaseReservedIndexSpace() {
733 GeometryPoolState& poolState = fGeoPoolStateStack.back();
734 const GeometrySrcState& geoSrc = this->getGeomSrc();
735
bsalomon@google.comd57d71a2012-08-16 16:26:33 +0000736 // If we get a release index space call then our current source should either be reserved
737 // or array (which we copied into reserved space).
738 GrAssert(kReserved_GeometrySrcType == geoSrc.fIndexSrc ||
739 kArray_GeometrySrcType == geoSrc.fIndexSrc);
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000740
741 // Similar to releaseReservedVertexSpace we return any unused portion at
742 // the tail
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000743 size_t reservedIndexBytes = sizeof(uint16_t) * geoSrc.fIndexCount;
744 fIndexPool.putBack(reservedIndexBytes - poolState.fUsedPoolIndexBytes);
745 poolState.fUsedPoolIndexBytes = 0;
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000746 poolState.fPoolIndexBuffer = NULL;
747 poolState.fPoolStartIndex = 0;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000748}
749
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000750void GrInOrderDrawBuffer::onSetVertexSourceToArray(const void* vertexArray,
751 int vertexCount) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000752
753 GeometryPoolState& poolState = fGeoPoolStateStack.back();
754 GrAssert(0 == poolState.fUsedPoolVertexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000755#if GR_DEBUG
756 bool success =
757#endif
bsalomon@google.come79c8152012-03-29 19:07:12 +0000758 fVertexPool.appendVertices(this->getVertexLayout(),
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000759 vertexCount,
760 vertexArray,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000761 &poolState.fPoolVertexBuffer,
762 &poolState.fPoolStartVertex);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000763 GR_DEBUGASSERT(success);
764}
765
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000766void GrInOrderDrawBuffer::onSetIndexSourceToArray(const void* indexArray,
767 int indexCount) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000768 GeometryPoolState& poolState = fGeoPoolStateStack.back();
769 GrAssert(0 == poolState.fUsedPoolIndexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000770#if GR_DEBUG
771 bool success =
772#endif
773 fIndexPool.appendIndices(indexCount,
774 indexArray,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000775 &poolState.fPoolIndexBuffer,
776 &poolState.fPoolStartIndex);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000777 GR_DEBUGASSERT(success);
reed@google.comac10a2d2010-12-22 21:39:39 +0000778}
779
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000780void GrInOrderDrawBuffer::releaseVertexArray() {
781 // When the client provides an array as the vertex source we handled it
782 // by copying their array into reserved space.
783 this->GrInOrderDrawBuffer::releaseReservedVertexSpace();
784}
785
786void GrInOrderDrawBuffer::releaseIndexArray() {
787 // When the client provides an array as the index source we handled it
788 // by copying their array into reserved space.
789 this->GrInOrderDrawBuffer::releaseReservedIndexSpace();
790}
791
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000792void GrInOrderDrawBuffer::geometrySourceWillPush() {
793 GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
794 poolState.fUsedPoolVertexBytes = 0;
795 poolState.fUsedPoolIndexBytes = 0;
bsalomon@google.com934c5702012-03-20 21:17:58 +0000796 this->resetDrawTracking();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000797#if GR_DEBUG
798 poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0;
799 poolState.fPoolStartVertex = ~0;
800 poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0;
801 poolState.fPoolStartIndex = ~0;
802#endif
803}
804
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000805void GrInOrderDrawBuffer::geometrySourceWillPop(
806 const GeometrySrcState& restoredState) {
807 GrAssert(fGeoPoolStateStack.count() > 1);
808 fGeoPoolStateStack.pop_back();
809 GeometryPoolState& poolState = fGeoPoolStateStack.back();
810 // we have to assume that any slack we had in our vertex/index data
811 // is now unreleasable because data may have been appended later in the
812 // pool.
813 if (kReserved_GeometrySrcType == restoredState.fVertexSrc ||
814 kArray_GeometrySrcType == restoredState.fVertexSrc) {
815 poolState.fUsedPoolVertexBytes =
816 VertexSize(restoredState.fVertexLayout) *
817 restoredState.fVertexCount;
818 }
819 if (kReserved_GeometrySrcType == restoredState.fIndexSrc ||
820 kArray_GeometrySrcType == restoredState.fIndexSrc) {
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000821 poolState.fUsedPoolIndexBytes = sizeof(uint16_t) *
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000822 restoredState.fIndexCount;
823 }
bsalomon@google.com934c5702012-03-20 21:17:58 +0000824 this->resetDrawTracking();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000825}
826
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000827bool GrInOrderDrawBuffer::needsNewState() const {
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000828 // we should have recorded a default state in reset()
829 GrAssert(!fStates.empty());
830 return fStates.back() != this->getDrawState();
reed@google.comac10a2d2010-12-22 21:39:39 +0000831}
832
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000833bool GrInOrderDrawBuffer::needsNewClip() const {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000834 if (this->getDrawState().isClipState()) {
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000835 if (fClipSet &&
836 (fClips.back() != *fClip->fClipStack ||
837 fClipOrigins.back() != fClip->fOrigin)) {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000838 return true;
839 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000840 }
841 return false;
842}
bsalomon@google.comd302f142011-03-03 13:54:13 +0000843
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000844void GrInOrderDrawBuffer::recordClip() {
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000845 fClips.push_back() = *fClip->fClipStack;
846 fClipOrigins.push_back() = fClip->fOrigin;
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000847 fClipSet = false;
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000848 fCmds.push_back(kSetClip_Cmd);
849}
850
851void GrInOrderDrawBuffer::recordDefaultClip() {
robertphillips@google.com641f8b12012-07-31 19:15:58 +0000852 fClips.push_back() = SkClipStack();
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000853 fClipOrigins.push_back() = SkIPoint::Make(0, 0);
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000854 fCmds.push_back(kSetClip_Cmd);
855}
856
857void GrInOrderDrawBuffer::recordState() {
858 fStates.push_back(this->getDrawState());
859 fCmds.push_back(kSetState_Cmd);
860}
861
862void GrInOrderDrawBuffer::recordDefaultState() {
863 fStates.push_back(GrDrawState());
864 fCmds.push_back(kSetState_Cmd);
865}
866
867GrInOrderDrawBuffer::Draw* GrInOrderDrawBuffer::recordDraw() {
868 fCmds.push_back(kDraw_Cmd);
869 return &fDraws.push_back();
870}
871
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000872GrInOrderDrawBuffer::StencilPath* GrInOrderDrawBuffer::recordStencilPath() {
873 fCmds.push_back(kStencilPath_Cmd);
874 return &fStencilPaths.push_back();
875}
876
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000877GrInOrderDrawBuffer::Clear* GrInOrderDrawBuffer::recordClear() {
878 fCmds.push_back(kClear_Cmd);
879 return &fClears.push_back();
reed@google.comac10a2d2010-12-22 21:39:39 +0000880}
bsalomon@google.comd302f142011-03-03 13:54:13 +0000881
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000882void GrInOrderDrawBuffer::clipWillBeSet(const GrClipData* newClipData) {
883 INHERITED::clipWillBeSet(newClipData);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000884 fClipSet = true;
885}