blob: 39bf275560a1b1b2eff51f3c91354447d1dfddaf [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
epoger@google.comec3ed6a2011-07-28 14:26:00 +000010
reed@google.comac10a2d2010-12-22 21:39:39 +000011#include "GrInOrderDrawBuffer.h"
12#include "GrTexture.h"
bsalomon@google.com1c13c962011-02-14 16:51:21 +000013#include "GrBufferAllocPool.h"
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000014#include "GrIndexBuffer.h"
15#include "GrVertexBuffer.h"
reed@google.comac10a2d2010-12-22 21:39:39 +000016#include "GrGpu.h"
17
bsalomon@google.com1c13c962011-02-14 16:51:21 +000018GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrVertexBufferAllocPool* vertexPool,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000019 GrIndexBufferAllocPool* indexPool)
20 : fDraws(&fDrawStorage)
21 , fStates(&fStateStorage)
22 , fClears(&fClearStorage)
23 , fClips(&fClipStorage)
24 , fClipSet(true)
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000025
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000026 , fLastRectVertexLayout(0)
27 , fQuadIndexBuffer(NULL)
28 , fMaxQuads(0)
29 , fCurrQuad(0)
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000030
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000031 , fVertexPool(*vertexPool)
32 , fIndexPool(*indexPool)
33 , fGeoPoolStateStack(&fGeoStackStorage) {
34
bsalomon@google.com1c13c962011-02-14 16:51:21 +000035 GrAssert(NULL != vertexPool);
36 GrAssert(NULL != indexPool);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000037
38 GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
39 poolState.fUsedPoolVertexBytes = 0;
40 poolState.fUsedPoolIndexBytes = 0;
41#if GR_DEBUG
42 poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0;
43 poolState.fPoolStartVertex = ~0;
44 poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0;
45 poolState.fPoolStartIndex = ~0;
46#endif
reed@google.comac10a2d2010-12-22 21:39:39 +000047}
48
49GrInOrderDrawBuffer::~GrInOrderDrawBuffer() {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000050 this->reset();
51 GrSafeUnref(fQuadIndexBuffer);
reed@google.comac10a2d2010-12-22 21:39:39 +000052}
53
54void GrInOrderDrawBuffer::initializeDrawStateAndClip(const GrDrawTarget& target) {
55 this->copyDrawState(target);
56 this->setClip(target.getClip());
57}
58
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000059void GrInOrderDrawBuffer::setQuadIndexBuffer(const GrIndexBuffer* indexBuffer) {
60 bool newIdxBuffer = fQuadIndexBuffer != indexBuffer;
61 if (newIdxBuffer) {
62 GrSafeUnref(fQuadIndexBuffer);
63 fQuadIndexBuffer = indexBuffer;
64 GrSafeRef(fQuadIndexBuffer);
65 fCurrQuad = 0;
66 fMaxQuads = (NULL == indexBuffer) ? 0 : indexBuffer->maxQuads();
67 } else {
bsalomon@google.comd302f142011-03-03 13:54:13 +000068 GrAssert((NULL == indexBuffer && 0 == fMaxQuads) ||
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000069 (indexBuffer->maxQuads() == fMaxQuads));
70 }
71}
72
bsalomon@google.comd302f142011-03-03 13:54:13 +000073void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000074 const GrMatrix* matrix,
bsalomon@google.comffca4002011-02-22 20:34:01 +000075 StageBitfield stageEnableBitfield,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000076 const GrRect* srcRects[],
77 const GrMatrix* srcMatrices[]) {
bsalomon@google.comd302f142011-03-03 13:54:13 +000078
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000079 GrAssert(!(NULL == fQuadIndexBuffer && fCurrQuad));
80 GrAssert(!(fDraws.empty() && fCurrQuad));
81 GrAssert(!(0 != fMaxQuads && NULL == fQuadIndexBuffer));
82
83 // if we have a quad IB then either append to the previous run of
84 // rects or start a new run
85 if (fMaxQuads) {
bsalomon@google.comd302f142011-03-03 13:54:13 +000086
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000087 bool appendToPreviousDraw = false;
bsalomon@google.comffca4002011-02-22 20:34:01 +000088 GrVertexLayout layout = GetRectVertexLayout(stageEnableBitfield, srcRects);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000089 AutoReleaseGeometry geo(this, layout, 4, 0);
bsalomon@google.com6513cd02011-08-05 20:12:30 +000090 if (!geo.succeeded()) {
91 GrPrintf("Failed to get space for vertices!\n");
92 return;
93 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000094 AutoViewMatrixRestore avmr(this);
95 GrMatrix combinedMatrix = this->getViewMatrix();
96 this->setViewMatrix(GrMatrix::I());
97 if (NULL != matrix) {
98 combinedMatrix.preConcat(*matrix);
99 }
100
101 SetRectVertices(rect, &combinedMatrix, srcRects, srcMatrices, layout, geo.vertices());
102
103 // we don't want to miss an opportunity to batch rects together
104 // simply because the clip has changed if the clip doesn't affect
105 // the rect.
106 bool disabledClip = false;
107 if (this->isClipState() && fClip.isRect()) {
bsalomon@google.comd302f142011-03-03 13:54:13 +0000108
bsalomon@google.com0b50b2e2011-03-08 21:07:21 +0000109 GrRect clipRect = fClip.getRect(0);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000110 // If the clip rect touches the edge of the viewport, extended it
111 // out (close) to infinity to avoid bogus intersections.
bsalomon@google.comd302f142011-03-03 13:54:13 +0000112 // We might consider a more exact clip to viewport if this
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000113 // conservative test fails.
114 const GrRenderTarget* target = this->getRenderTarget();
115 if (0 >= clipRect.fLeft) {
116 clipRect.fLeft = GR_ScalarMin;
117 }
118 if (target->width() <= clipRect.fRight) {
119 clipRect.fRight = GR_ScalarMax;
120 }
121 if (0 >= clipRect.top()) {
122 clipRect.fTop = GR_ScalarMin;
123 }
124 if (target->height() <= clipRect.fBottom) {
125 clipRect.fBottom = GR_ScalarMax;
126 }
127 int stride = VertexSize(layout);
128 bool insideClip = true;
129 for (int v = 0; v < 4; ++v) {
130 const GrPoint& p = *GetVertexPoint(geo.vertices(), v, stride);
131 if (!clipRect.contains(p)) {
132 insideClip = false;
133 break;
134 }
135 }
136 if (insideClip) {
137 this->disableState(kClip_StateBit);
138 disabledClip = true;
139 }
140 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000141 if (!needsNewClip() && !needsNewState() && fCurrQuad > 0 &&
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000142 fCurrQuad < fMaxQuads && layout == fLastRectVertexLayout) {
143
144 int vsize = VertexSize(layout);
bsalomon@google.comd302f142011-03-03 13:54:13 +0000145
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000146 Draw& lastDraw = fDraws.back();
147
148 GrAssert(lastDraw.fIndexBuffer == fQuadIndexBuffer);
149 GrAssert(kTriangles_PrimitiveType == lastDraw.fPrimitiveType);
150 GrAssert(0 == lastDraw.fVertexCount % 4);
151 GrAssert(0 == lastDraw.fIndexCount % 6);
152 GrAssert(0 == lastDraw.fStartIndex);
153
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000154 GeometryPoolState& poolState = fGeoPoolStateStack.back();
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000155 bool clearSinceLastDraw =
156 fClears.count() &&
157 fClears.back().fBeforeDrawIdx == fDraws.count();
158
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000159 appendToPreviousDraw =
160 !clearSinceLastDraw &&
161 lastDraw.fVertexBuffer == poolState.fPoolVertexBuffer &&
162 (fCurrQuad * 4 + lastDraw.fStartVertex) == poolState.fPoolStartVertex;
163
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000164 if (appendToPreviousDraw) {
165 lastDraw.fVertexCount += 4;
166 lastDraw.fIndexCount += 6;
167 fCurrQuad += 1;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000168 // we reserved above, so we should be the first
169 // use of this vertex reserveation.
170 GrAssert(0 == poolState.fUsedPoolVertexBytes);
171 poolState.fUsedPoolVertexBytes = 4 * vsize;
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000172 }
173 }
174 if (!appendToPreviousDraw) {
175 this->setIndexSourceToBuffer(fQuadIndexBuffer);
176 drawIndexed(kTriangles_PrimitiveType, 0, 0, 4, 6);
177 fCurrQuad = 1;
178 fLastRectVertexLayout = layout;
179 }
180 if (disabledClip) {
181 this->enableState(kClip_StateBit);
182 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000183 } else {
bsalomon@google.comffca4002011-02-22 20:34:01 +0000184 INHERITED::drawRect(rect, matrix, stageEnableBitfield, srcRects, srcMatrices);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000185 }
186}
187
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000188void GrInOrderDrawBuffer::onDrawIndexed(GrPrimitiveType primitiveType,
189 int startVertex,
190 int startIndex,
191 int vertexCount,
192 int indexCount) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000193
194 if (!vertexCount || !indexCount) {
195 return;
196 }
197
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000198 fCurrQuad = 0;
199
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000200 GeometryPoolState& poolState = fGeoPoolStateStack.back();
201
reed@google.comac10a2d2010-12-22 21:39:39 +0000202 Draw& draw = fDraws.push_back();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000203 draw.fPrimitiveType = primitiveType;
reed@google.comac10a2d2010-12-22 21:39:39 +0000204 draw.fStartVertex = startVertex;
205 draw.fStartIndex = startIndex;
206 draw.fVertexCount = vertexCount;
207 draw.fIndexCount = indexCount;
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000208
209 draw.fClipChanged = this->needsNewClip();
210 if (draw.fClipChanged) {
211 this->pushClip();
212 }
213
214 draw.fStateChanged = this->needsNewState();
215 if (draw.fStateChanged) {
216 this->pushState();
217 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000218
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000219 draw.fVertexLayout = this->getGeomSrc().fVertexLayout;
220 switch (this->getGeomSrc().fVertexSrc) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000221 case kBuffer_GeometrySrcType:
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000222 draw.fVertexBuffer = this->getGeomSrc().fVertexBuffer;
reed@google.comac10a2d2010-12-22 21:39:39 +0000223 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000224 case kReserved_GeometrySrcType: // fallthrough
225 case kArray_GeometrySrcType: {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000226 size_t vertexBytes = (vertexCount + startVertex) *
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000227 VertexSize(this->getGeomSrc().fVertexLayout);
228 poolState.fUsedPoolVertexBytes =
229 GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
230 draw.fVertexBuffer = poolState.fPoolVertexBuffer;
231 draw.fStartVertex += poolState.fPoolStartVertex;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000232 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000233 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000234 default:
235 GrCrash("unknown geom src type");
reed@google.comac10a2d2010-12-22 21:39:39 +0000236 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000237 draw.fVertexBuffer->ref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000238
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000239 switch (this->getGeomSrc().fIndexSrc) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000240 case kBuffer_GeometrySrcType:
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000241 draw.fIndexBuffer = this->getGeomSrc().fIndexBuffer;
reed@google.comac10a2d2010-12-22 21:39:39 +0000242 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000243 case kReserved_GeometrySrcType: // fallthrough
244 case kArray_GeometrySrcType: {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000245 size_t indexBytes = (indexCount + startIndex) * sizeof(uint16_t);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000246 poolState.fUsedPoolIndexBytes =
247 GrMax(poolState.fUsedPoolIndexBytes, indexBytes);
248 draw.fIndexBuffer = poolState.fPoolIndexBuffer;
249 draw.fStartIndex += poolState.fPoolStartVertex;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000250 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000251 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000252 default:
253 GrCrash("unknown geom src type");
reed@google.comac10a2d2010-12-22 21:39:39 +0000254 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000255 draw.fIndexBuffer->ref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000256}
257
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000258void GrInOrderDrawBuffer::onDrawNonIndexed(GrPrimitiveType primitiveType,
259 int startVertex,
260 int vertexCount) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000261 if (!vertexCount) {
262 return;
263 }
264
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000265 fCurrQuad = 0;
266
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000267 GeometryPoolState& poolState = fGeoPoolStateStack.back();
268
reed@google.comac10a2d2010-12-22 21:39:39 +0000269 Draw& draw = fDraws.push_back();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000270 draw.fPrimitiveType = primitiveType;
reed@google.comac10a2d2010-12-22 21:39:39 +0000271 draw.fStartVertex = startVertex;
272 draw.fStartIndex = 0;
273 draw.fVertexCount = vertexCount;
274 draw.fIndexCount = 0;
275
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000276 draw.fClipChanged = this->needsNewClip();
277 if (draw.fClipChanged) {
278 this->pushClip();
279 }
280
281 draw.fStateChanged = this->needsNewState();
282 if (draw.fStateChanged) {
283 this->pushState();
284 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000285
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000286 draw.fVertexLayout = this->getGeomSrc().fVertexLayout;
287 switch (this->getGeomSrc().fVertexSrc) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000288 case kBuffer_GeometrySrcType:
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000289 draw.fVertexBuffer = this->getGeomSrc().fVertexBuffer;
reed@google.comac10a2d2010-12-22 21:39:39 +0000290 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000291 case kReserved_GeometrySrcType: // fallthrough
292 case kArray_GeometrySrcType: {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000293 size_t vertexBytes = (vertexCount + startVertex) *
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000294 VertexSize(this->getGeomSrc().fVertexLayout);
295 poolState.fUsedPoolVertexBytes =
296 GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
297 draw.fVertexBuffer = poolState.fPoolVertexBuffer;
298 draw.fStartVertex += poolState.fPoolStartVertex;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000299 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000300 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000301 default:
302 GrCrash("unknown geom src type");
reed@google.comac10a2d2010-12-22 21:39:39 +0000303 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000304 draw.fVertexBuffer->ref();
305 draw.fIndexBuffer = NULL;
reed@google.comac10a2d2010-12-22 21:39:39 +0000306}
307
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000308void GrInOrderDrawBuffer::clear(const GrIRect* rect, GrColor color) {
309 GrIRect r;
310 if (NULL == rect) {
311 // We could do something smart and remove previous draws and clears to
312 // the current render target. If we get that smart we have to make sure
313 // those draws aren't read before this clear (render-to-texture).
314 r.setLTRB(0, 0,
315 this->getRenderTarget()->width(),
316 this->getRenderTarget()->height());
317 rect = &r;
318 }
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000319 Clear& clr = fClears.push_back();
320 clr.fColor = color;
321 clr.fBeforeDrawIdx = fDraws.count();
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000322 clr.fRect = *rect;
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000323}
324
reed@google.comac10a2d2010-12-22 21:39:39 +0000325void GrInOrderDrawBuffer::reset() {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000326 GrAssert(1 == fGeoPoolStateStack.count());
327 this->resetVertexSource();
328 this->resetIndexSource();
reed@google.comac10a2d2010-12-22 21:39:39 +0000329 uint32_t numStates = fStates.count();
330 for (uint32_t i = 0; i < numStates; ++i) {
bsalomon@google.com1da07462011-03-10 14:51:57 +0000331 const DrState& dstate = this->accessSavedDrawState(fStates[i]);
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000332 for (int s = 0; s < kNumStages; ++s) {
bsalomon@google.com1da07462011-03-10 14:51:57 +0000333 GrSafeUnref(dstate.fTextures[s]);
reed@google.comac10a2d2010-12-22 21:39:39 +0000334 }
bsalomon@google.com1da07462011-03-10 14:51:57 +0000335 GrSafeUnref(dstate.fRenderTarget);
reed@google.comac10a2d2010-12-22 21:39:39 +0000336 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000337 int numDraws = fDraws.count();
338 for (int d = 0; d < numDraws; ++d) {
339 // we always have a VB, but not always an IB
340 GrAssert(NULL != fDraws[d].fVertexBuffer);
341 fDraws[d].fVertexBuffer->unref();
342 GrSafeUnref(fDraws[d].fIndexBuffer);
343 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000344 fDraws.reset();
345 fStates.reset();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000346
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000347 fClears.reset();
348
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000349 fVertexPool.reset();
350 fIndexPool.reset();
351
reed@google.comac10a2d2010-12-22 21:39:39 +0000352 fClips.reset();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000353
354 fCurrQuad = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000355}
356
357void GrInOrderDrawBuffer::playback(GrDrawTarget* target) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000358 GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fVertexSrc);
359 GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fIndexSrc);
reed@google.comac10a2d2010-12-22 21:39:39 +0000360 GrAssert(NULL != target);
361 GrAssert(target != this); // not considered and why?
362
bsalomon@google.com898d9e52011-04-26 13:22:33 +0000363 int numDraws = fDraws.count();
reed@google.comac10a2d2010-12-22 21:39:39 +0000364 if (!numDraws) {
365 return;
366 }
367
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000368 fVertexPool.unlock();
369 fIndexPool.unlock();
reed@google.comac10a2d2010-12-22 21:39:39 +0000370
371 GrDrawTarget::AutoStateRestore asr(target);
372 GrDrawTarget::AutoClipRestore acr(target);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000373 AutoGeometryPush agp(target);
reed@google.comac10a2d2010-12-22 21:39:39 +0000374
bsalomon@google.com6a77cc52011-04-28 17:33:34 +0000375 int currState = ~0;
376 int currClip = ~0;
377 int currClear = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000378
bsalomon@google.com898d9e52011-04-26 13:22:33 +0000379 for (int i = 0; i < numDraws; ++i) {
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000380 while (currClear < fClears.count() &&
381 i == fClears[currClear].fBeforeDrawIdx) {
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000382 target->clear(&fClears[currClear].fRect, fClears[currClear].fColor);
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000383 ++currClear;
384 }
385
reed@google.comac10a2d2010-12-22 21:39:39 +0000386 const Draw& draw = fDraws[i];
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000387 if (draw.fStateChanged) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000388 ++currState;
389 target->restoreDrawState(fStates[currState]);
390 }
391 if (draw.fClipChanged) {
392 ++currClip;
393 target->setClip(fClips[currClip]);
394 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000395
396 target->setVertexSourceToBuffer(draw.fVertexLayout, draw.fVertexBuffer);
397
reed@google.comac10a2d2010-12-22 21:39:39 +0000398 if (draw.fIndexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000399 target->setIndexSourceToBuffer(draw.fIndexBuffer);
400 }
401
402 if (draw.fIndexCount) {
403 target->drawIndexed(draw.fPrimitiveType,
reed@google.comac10a2d2010-12-22 21:39:39 +0000404 draw.fStartVertex,
405 draw.fStartIndex,
406 draw.fVertexCount,
407 draw.fIndexCount);
408 } else {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000409 target->drawNonIndexed(draw.fPrimitiveType,
reed@google.comac10a2d2010-12-22 21:39:39 +0000410 draw.fStartVertex,
411 draw.fVertexCount);
412 }
413 }
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000414 while (currClear < fClears.count()) {
415 GrAssert(fDraws.count() == fClears[currClear].fBeforeDrawIdx);
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000416 target->clear(&fClears[currClear].fRect, fClears[currClear].fColor);
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000417 ++currClear;
418 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000419}
420
421bool GrInOrderDrawBuffer::geometryHints(GrVertexLayout vertexLayout,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000422 int* vertexCount,
423 int* indexCount) const {
424 // we will recommend a flush if the data could fit in a single
425 // preallocated buffer but none are left and it can't fit
426 // in the current buffer (which may not be prealloced).
reed@google.comac10a2d2010-12-22 21:39:39 +0000427 bool flush = false;
428 if (NULL != indexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000429 int32_t currIndices = fIndexPool.currentBufferIndices();
430 if (*indexCount > currIndices &&
431 (!fIndexPool.preallocatedBuffersRemaining() &&
432 *indexCount <= fIndexPool.preallocatedBufferIndices())) {
433
434 flush = true;
435 }
436 *indexCount = currIndices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000437 }
438 if (NULL != vertexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000439 int32_t currVertices = fVertexPool.currentBufferVertices(vertexLayout);
440 if (*vertexCount > currVertices &&
441 (!fVertexPool.preallocatedBuffersRemaining() &&
442 *vertexCount <= fVertexPool.preallocatedBufferVertices(vertexLayout))) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000443
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000444 flush = true;
reed@google.comac10a2d2010-12-22 21:39:39 +0000445 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000446 *vertexCount = currVertices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000447 }
448 return flush;
449}
450
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000451bool GrInOrderDrawBuffer::onReserveVertexSpace(GrVertexLayout vertexLayout,
452 int vertexCount,
453 void** vertices) {
454 GeometryPoolState& poolState = fGeoPoolStateStack.back();
455 GrAssert(vertexCount > 0);
456 GrAssert(NULL != vertices);
457 GrAssert(0 == poolState.fUsedPoolVertexBytes);
458
459 *vertices = fVertexPool.makeSpace(vertexLayout,
460 vertexCount,
461 &poolState.fPoolVertexBuffer,
462 &poolState.fPoolStartVertex);
463 return NULL != *vertices;
464}
465
466bool GrInOrderDrawBuffer::onReserveIndexSpace(int indexCount, void** indices) {
467 GeometryPoolState& poolState = fGeoPoolStateStack.back();
468 GrAssert(indexCount > 0);
469 GrAssert(NULL != indices);
470 GrAssert(0 == poolState.fUsedPoolIndexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000471
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000472 *indices = fIndexPool.makeSpace(indexCount,
473 &poolState.fPoolIndexBuffer,
474 &poolState.fPoolStartIndex);
475 return NULL != *indices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000476}
477
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000478void GrInOrderDrawBuffer::releaseReservedVertexSpace() {
479 GeometryPoolState& poolState = fGeoPoolStateStack.back();
480 const GeometrySrcState& geoSrc = this->getGeomSrc();
481
482 GrAssert(kReserved_GeometrySrcType == geoSrc.fVertexSrc);
483
484 size_t reservedVertexBytes = VertexSize(geoSrc.fVertexLayout) *
485 geoSrc.fVertexCount;
486 fVertexPool.putBack(reservedVertexBytes -
487 poolState.fUsedPoolVertexBytes);
488 poolState.fUsedPoolVertexBytes = 0;
489 poolState.fPoolVertexBuffer = 0;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000490}
491
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000492void GrInOrderDrawBuffer::releaseReservedIndexSpace() {
493 GeometryPoolState& poolState = fGeoPoolStateStack.back();
494 const GeometrySrcState& geoSrc = this->getGeomSrc();
495
496 GrAssert(kReserved_GeometrySrcType == geoSrc.fIndexSrc);
497
498 size_t reservedIndexBytes = sizeof(uint16_t) * geoSrc.fIndexCount;
499 fIndexPool.putBack(reservedIndexBytes - poolState.fUsedPoolIndexBytes);
500 poolState.fUsedPoolIndexBytes = 0;
501 poolState.fPoolStartVertex = 0;
502}
503
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000504void GrInOrderDrawBuffer::onSetVertexSourceToArray(const void* vertexArray,
505 int vertexCount) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000506
507 GeometryPoolState& poolState = fGeoPoolStateStack.back();
508 GrAssert(0 == poolState.fUsedPoolVertexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000509#if GR_DEBUG
510 bool success =
511#endif
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000512 fVertexPool.appendVertices(this->getGeomSrc().fVertexLayout,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000513 vertexCount,
514 vertexArray,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000515 &poolState.fPoolVertexBuffer,
516 &poolState.fPoolStartVertex);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000517 GR_DEBUGASSERT(success);
518}
519
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000520void GrInOrderDrawBuffer::onSetIndexSourceToArray(const void* indexArray,
521 int indexCount) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000522 GeometryPoolState& poolState = fGeoPoolStateStack.back();
523 GrAssert(0 == poolState.fUsedPoolIndexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000524#if GR_DEBUG
525 bool success =
526#endif
527 fIndexPool.appendIndices(indexCount,
528 indexArray,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000529 &poolState.fPoolIndexBuffer,
530 &poolState.fPoolStartIndex);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000531 GR_DEBUGASSERT(success);
reed@google.comac10a2d2010-12-22 21:39:39 +0000532}
533
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000534void GrInOrderDrawBuffer::geometrySourceWillPush() {
535 GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
536 poolState.fUsedPoolVertexBytes = 0;
537 poolState.fUsedPoolIndexBytes = 0;
538#if GR_DEBUG
539 poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0;
540 poolState.fPoolStartVertex = ~0;
541 poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0;
542 poolState.fPoolStartIndex = ~0;
543#endif
544}
545
546void GrInOrderDrawBuffer::releaseVertexArray() {
547 GeometryPoolState& poolState = fGeoPoolStateStack.back();
548 const GeometrySrcState& geoSrc = this->getGeomSrc();
549
550 size_t reservedVertexBytes = VertexSize(geoSrc.fVertexLayout) *
551 geoSrc.fVertexCount;
552 fVertexPool.putBack(reservedVertexBytes - poolState.fUsedPoolVertexBytes);
553
554 poolState.fUsedPoolVertexBytes = 0;
555}
556
557void GrInOrderDrawBuffer::releaseIndexArray() {
558 GeometryPoolState& poolState = fGeoPoolStateStack.back();
559 const GeometrySrcState& geoSrc = this->getGeomSrc();
560
561 size_t reservedIndexBytes = sizeof(uint16_t) * geoSrc.fIndexCount;
562 fIndexPool.putBack(reservedIndexBytes - poolState.fUsedPoolIndexBytes);
563
564 poolState.fUsedPoolIndexBytes = 0;
565}
566
567void GrInOrderDrawBuffer::geometrySourceWillPop(
568 const GeometrySrcState& restoredState) {
569 GrAssert(fGeoPoolStateStack.count() > 1);
570 fGeoPoolStateStack.pop_back();
571 GeometryPoolState& poolState = fGeoPoolStateStack.back();
572 // we have to assume that any slack we had in our vertex/index data
573 // is now unreleasable because data may have been appended later in the
574 // pool.
575 if (kReserved_GeometrySrcType == restoredState.fVertexSrc ||
576 kArray_GeometrySrcType == restoredState.fVertexSrc) {
577 poolState.fUsedPoolVertexBytes =
578 VertexSize(restoredState.fVertexLayout) *
579 restoredState.fVertexCount;
580 }
581 if (kReserved_GeometrySrcType == restoredState.fIndexSrc ||
582 kArray_GeometrySrcType == restoredState.fIndexSrc) {
583 poolState.fUsedPoolVertexBytes = sizeof(uint16_t) *
584 restoredState.fIndexCount;
585 }
586}
587
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000588bool GrInOrderDrawBuffer::needsNewState() const {
589 if (fStates.empty()) {
590 return true;
591 } else {
592 const DrState& old = this->accessSavedDrawState(fStates.back());
593 return old != fCurrDrawState;
594 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000595}
596
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000597void GrInOrderDrawBuffer::pushState() {
598 for (int s = 0; s < kNumStages; ++s) {
599 GrSafeRef(fCurrDrawState.fTextures[s]);
600 }
bsalomon@google.com1da07462011-03-10 14:51:57 +0000601 GrSafeRef(fCurrDrawState.fRenderTarget);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000602 this->saveCurrentDrawState(&fStates.push_back());
603 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000604
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000605bool GrInOrderDrawBuffer::needsNewClip() const {
606 if (fCurrDrawState.fFlagBits & kClip_StateBit) {
607 if (fClips.empty() || (fClipSet && fClips.back() != fClip)) {
608 return true;
609 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000610 }
611 return false;
612}
bsalomon@google.comd302f142011-03-03 13:54:13 +0000613
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000614void GrInOrderDrawBuffer::pushClip() {
615 fClips.push_back() = fClip;
616 fClipSet = false;
reed@google.comac10a2d2010-12-22 21:39:39 +0000617}
bsalomon@google.comd302f142011-03-03 13:54:13 +0000618
bsalomon@google.comdea2f8d2011-08-01 15:51:05 +0000619void GrInOrderDrawBuffer::clipWillBeSet(const GrClip& newClip) {
620 INHERITED::clipWillBeSet(newClip);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000621 fClipSet = true;
622}