blob: db208462250b985ee8ff12cf680404c433804de4 [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.com471d4712011-08-23 15:45:25 +000018GrInOrderDrawBuffer::GrInOrderDrawBuffer(const GrGpu* gpu,
19 GrVertexBufferAllocPool* vertexPool,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000020 GrIndexBufferAllocPool* indexPool)
bsalomon@google.com4b90c622011-09-28 17:52:15 +000021 : fClipSet(true)
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000022 , fLastRectVertexLayout(0)
23 , fQuadIndexBuffer(NULL)
24 , fMaxQuads(0)
25 , fCurrQuad(0)
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000026 , fVertexPool(*vertexPool)
bsalomon@google.com92669012011-09-27 19:10:05 +000027 , fIndexPool(*indexPool) {
bsalomon@google.com18c9c192011-09-22 21:01:31 +000028
29 fCaps = gpu->getCaps();
30
bsalomon@google.com1c13c962011-02-14 16:51:21 +000031 GrAssert(NULL != vertexPool);
32 GrAssert(NULL != indexPool);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000033
34 GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
35 poolState.fUsedPoolVertexBytes = 0;
36 poolState.fUsedPoolIndexBytes = 0;
37#if GR_DEBUG
38 poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0;
39 poolState.fPoolStartVertex = ~0;
40 poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0;
41 poolState.fPoolStartIndex = ~0;
42#endif
reed@google.comac10a2d2010-12-22 21:39:39 +000043}
44
45GrInOrderDrawBuffer::~GrInOrderDrawBuffer() {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000046 this->reset();
47 GrSafeUnref(fQuadIndexBuffer);
reed@google.comac10a2d2010-12-22 21:39:39 +000048}
49
50void GrInOrderDrawBuffer::initializeDrawStateAndClip(const GrDrawTarget& target) {
51 this->copyDrawState(target);
52 this->setClip(target.getClip());
53}
54
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000055void GrInOrderDrawBuffer::setQuadIndexBuffer(const GrIndexBuffer* indexBuffer) {
56 bool newIdxBuffer = fQuadIndexBuffer != indexBuffer;
57 if (newIdxBuffer) {
58 GrSafeUnref(fQuadIndexBuffer);
59 fQuadIndexBuffer = indexBuffer;
60 GrSafeRef(fQuadIndexBuffer);
61 fCurrQuad = 0;
62 fMaxQuads = (NULL == indexBuffer) ? 0 : indexBuffer->maxQuads();
63 } else {
bsalomon@google.comd302f142011-03-03 13:54:13 +000064 GrAssert((NULL == indexBuffer && 0 == fMaxQuads) ||
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000065 (indexBuffer->maxQuads() == fMaxQuads));
66 }
67}
68
bsalomon@google.comd302f142011-03-03 13:54:13 +000069void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000070 const GrMatrix* matrix,
bsalomon@google.comffca4002011-02-22 20:34:01 +000071 StageBitfield stageEnableBitfield,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000072 const GrRect* srcRects[],
73 const GrMatrix* srcMatrices[]) {
bsalomon@google.comd302f142011-03-03 13:54:13 +000074
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000075 GrAssert(!(NULL == fQuadIndexBuffer && fCurrQuad));
76 GrAssert(!(fDraws.empty() && fCurrQuad));
77 GrAssert(!(0 != fMaxQuads && NULL == fQuadIndexBuffer));
78
79 // if we have a quad IB then either append to the previous run of
80 // rects or start a new run
81 if (fMaxQuads) {
bsalomon@google.comd302f142011-03-03 13:54:13 +000082
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000083 bool appendToPreviousDraw = false;
bsalomon@google.comffca4002011-02-22 20:34:01 +000084 GrVertexLayout layout = GetRectVertexLayout(stageEnableBitfield, srcRects);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000085 AutoReleaseGeometry geo(this, layout, 4, 0);
bsalomon@google.com6513cd02011-08-05 20:12:30 +000086 if (!geo.succeeded()) {
87 GrPrintf("Failed to get space for vertices!\n");
88 return;
89 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000090 AutoViewMatrixRestore avmr(this);
91 GrMatrix combinedMatrix = this->getViewMatrix();
92 this->setViewMatrix(GrMatrix::I());
93 if (NULL != matrix) {
94 combinedMatrix.preConcat(*matrix);
95 }
96
97 SetRectVertices(rect, &combinedMatrix, srcRects, srcMatrices, layout, geo.vertices());
98
99 // we don't want to miss an opportunity to batch rects together
100 // simply because the clip has changed if the clip doesn't affect
101 // the rect.
102 bool disabledClip = false;
103 if (this->isClipState() && fClip.isRect()) {
bsalomon@google.comd302f142011-03-03 13:54:13 +0000104
bsalomon@google.com0b50b2e2011-03-08 21:07:21 +0000105 GrRect clipRect = fClip.getRect(0);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000106 // If the clip rect touches the edge of the viewport, extended it
107 // out (close) to infinity to avoid bogus intersections.
bsalomon@google.comd302f142011-03-03 13:54:13 +0000108 // We might consider a more exact clip to viewport if this
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000109 // conservative test fails.
110 const GrRenderTarget* target = this->getRenderTarget();
111 if (0 >= clipRect.fLeft) {
112 clipRect.fLeft = GR_ScalarMin;
113 }
114 if (target->width() <= clipRect.fRight) {
115 clipRect.fRight = GR_ScalarMax;
116 }
117 if (0 >= clipRect.top()) {
118 clipRect.fTop = GR_ScalarMin;
119 }
120 if (target->height() <= clipRect.fBottom) {
121 clipRect.fBottom = GR_ScalarMax;
122 }
123 int stride = VertexSize(layout);
124 bool insideClip = true;
125 for (int v = 0; v < 4; ++v) {
126 const GrPoint& p = *GetVertexPoint(geo.vertices(), v, stride);
127 if (!clipRect.contains(p)) {
128 insideClip = false;
129 break;
130 }
131 }
132 if (insideClip) {
133 this->disableState(kClip_StateBit);
134 disabledClip = true;
135 }
136 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000137 if (!needsNewClip() && !needsNewState() && fCurrQuad > 0 &&
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000138 fCurrQuad < fMaxQuads && layout == fLastRectVertexLayout) {
139
140 int vsize = VertexSize(layout);
bsalomon@google.comd302f142011-03-03 13:54:13 +0000141
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000142 Draw& lastDraw = fDraws.back();
143
144 GrAssert(lastDraw.fIndexBuffer == fQuadIndexBuffer);
145 GrAssert(kTriangles_PrimitiveType == lastDraw.fPrimitiveType);
146 GrAssert(0 == lastDraw.fVertexCount % 4);
147 GrAssert(0 == lastDraw.fIndexCount % 6);
148 GrAssert(0 == lastDraw.fStartIndex);
149
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000150 GeometryPoolState& poolState = fGeoPoolStateStack.back();
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000151 bool clearSinceLastDraw =
152 fClears.count() &&
153 fClears.back().fBeforeDrawIdx == fDraws.count();
154
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000155 appendToPreviousDraw =
156 !clearSinceLastDraw &&
157 lastDraw.fVertexBuffer == poolState.fPoolVertexBuffer &&
158 (fCurrQuad * 4 + lastDraw.fStartVertex) == poolState.fPoolStartVertex;
159
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000160 if (appendToPreviousDraw) {
161 lastDraw.fVertexCount += 4;
162 lastDraw.fIndexCount += 6;
163 fCurrQuad += 1;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000164 // we reserved above, so we should be the first
165 // use of this vertex reserveation.
166 GrAssert(0 == poolState.fUsedPoolVertexBytes);
167 poolState.fUsedPoolVertexBytes = 4 * vsize;
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000168 }
169 }
170 if (!appendToPreviousDraw) {
171 this->setIndexSourceToBuffer(fQuadIndexBuffer);
172 drawIndexed(kTriangles_PrimitiveType, 0, 0, 4, 6);
173 fCurrQuad = 1;
174 fLastRectVertexLayout = layout;
175 }
176 if (disabledClip) {
177 this->enableState(kClip_StateBit);
178 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000179 } else {
bsalomon@google.comffca4002011-02-22 20:34:01 +0000180 INHERITED::drawRect(rect, matrix, stageEnableBitfield, srcRects, srcMatrices);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000181 }
182}
183
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000184void GrInOrderDrawBuffer::onDrawIndexed(GrPrimitiveType primitiveType,
185 int startVertex,
186 int startIndex,
187 int vertexCount,
188 int indexCount) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000189
190 if (!vertexCount || !indexCount) {
191 return;
192 }
193
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000194 fCurrQuad = 0;
195
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000196 GeometryPoolState& poolState = fGeoPoolStateStack.back();
197
reed@google.comac10a2d2010-12-22 21:39:39 +0000198 Draw& draw = fDraws.push_back();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000199 draw.fPrimitiveType = primitiveType;
reed@google.comac10a2d2010-12-22 21:39:39 +0000200 draw.fStartVertex = startVertex;
201 draw.fStartIndex = startIndex;
202 draw.fVertexCount = vertexCount;
203 draw.fIndexCount = indexCount;
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000204
205 draw.fClipChanged = this->needsNewClip();
206 if (draw.fClipChanged) {
207 this->pushClip();
208 }
209
210 draw.fStateChanged = this->needsNewState();
211 if (draw.fStateChanged) {
212 this->pushState();
213 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000214
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000215 draw.fVertexLayout = this->getGeomSrc().fVertexLayout;
216 switch (this->getGeomSrc().fVertexSrc) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000217 case kBuffer_GeometrySrcType:
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000218 draw.fVertexBuffer = this->getGeomSrc().fVertexBuffer;
reed@google.comac10a2d2010-12-22 21:39:39 +0000219 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000220 case kReserved_GeometrySrcType: // fallthrough
221 case kArray_GeometrySrcType: {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000222 size_t vertexBytes = (vertexCount + startVertex) *
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000223 VertexSize(this->getGeomSrc().fVertexLayout);
224 poolState.fUsedPoolVertexBytes =
225 GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
226 draw.fVertexBuffer = poolState.fPoolVertexBuffer;
227 draw.fStartVertex += poolState.fPoolStartVertex;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000228 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000229 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000230 default:
231 GrCrash("unknown geom src type");
reed@google.comac10a2d2010-12-22 21:39:39 +0000232 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000233 draw.fVertexBuffer->ref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000234
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000235 switch (this->getGeomSrc().fIndexSrc) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000236 case kBuffer_GeometrySrcType:
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000237 draw.fIndexBuffer = this->getGeomSrc().fIndexBuffer;
reed@google.comac10a2d2010-12-22 21:39:39 +0000238 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000239 case kReserved_GeometrySrcType: // fallthrough
240 case kArray_GeometrySrcType: {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000241 size_t indexBytes = (indexCount + startIndex) * sizeof(uint16_t);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000242 poolState.fUsedPoolIndexBytes =
243 GrMax(poolState.fUsedPoolIndexBytes, indexBytes);
244 draw.fIndexBuffer = poolState.fPoolIndexBuffer;
245 draw.fStartIndex += poolState.fPoolStartVertex;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000246 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000247 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000248 default:
249 GrCrash("unknown geom src type");
reed@google.comac10a2d2010-12-22 21:39:39 +0000250 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000251 draw.fIndexBuffer->ref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000252}
253
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000254void GrInOrderDrawBuffer::onDrawNonIndexed(GrPrimitiveType primitiveType,
255 int startVertex,
256 int vertexCount) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000257 if (!vertexCount) {
258 return;
259 }
260
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000261 fCurrQuad = 0;
262
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000263 GeometryPoolState& poolState = fGeoPoolStateStack.back();
264
reed@google.comac10a2d2010-12-22 21:39:39 +0000265 Draw& draw = fDraws.push_back();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000266 draw.fPrimitiveType = primitiveType;
reed@google.comac10a2d2010-12-22 21:39:39 +0000267 draw.fStartVertex = startVertex;
268 draw.fStartIndex = 0;
269 draw.fVertexCount = vertexCount;
270 draw.fIndexCount = 0;
271
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000272 draw.fClipChanged = this->needsNewClip();
273 if (draw.fClipChanged) {
274 this->pushClip();
275 }
276
277 draw.fStateChanged = this->needsNewState();
278 if (draw.fStateChanged) {
279 this->pushState();
280 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000281
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000282 draw.fVertexLayout = this->getGeomSrc().fVertexLayout;
283 switch (this->getGeomSrc().fVertexSrc) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000284 case kBuffer_GeometrySrcType:
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000285 draw.fVertexBuffer = this->getGeomSrc().fVertexBuffer;
reed@google.comac10a2d2010-12-22 21:39:39 +0000286 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000287 case kReserved_GeometrySrcType: // fallthrough
288 case kArray_GeometrySrcType: {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000289 size_t vertexBytes = (vertexCount + startVertex) *
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000290 VertexSize(this->getGeomSrc().fVertexLayout);
291 poolState.fUsedPoolVertexBytes =
292 GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
293 draw.fVertexBuffer = poolState.fPoolVertexBuffer;
294 draw.fStartVertex += poolState.fPoolStartVertex;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000295 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000296 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000297 default:
298 GrCrash("unknown geom src type");
reed@google.comac10a2d2010-12-22 21:39:39 +0000299 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000300 draw.fVertexBuffer->ref();
301 draw.fIndexBuffer = NULL;
reed@google.comac10a2d2010-12-22 21:39:39 +0000302}
303
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000304void GrInOrderDrawBuffer::clear(const GrIRect* rect, GrColor color) {
305 GrIRect r;
306 if (NULL == rect) {
307 // We could do something smart and remove previous draws and clears to
308 // the current render target. If we get that smart we have to make sure
309 // those draws aren't read before this clear (render-to-texture).
310 r.setLTRB(0, 0,
311 this->getRenderTarget()->width(),
312 this->getRenderTarget()->height());
313 rect = &r;
314 }
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000315 Clear& clr = fClears.push_back();
316 clr.fColor = color;
317 clr.fBeforeDrawIdx = fDraws.count();
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000318 clr.fRect = *rect;
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000319}
320
reed@google.comac10a2d2010-12-22 21:39:39 +0000321void GrInOrderDrawBuffer::reset() {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000322 GrAssert(1 == fGeoPoolStateStack.count());
323 this->resetVertexSource();
324 this->resetIndexSource();
reed@google.comac10a2d2010-12-22 21:39:39 +0000325 uint32_t numStates = fStates.count();
326 for (uint32_t i = 0; i < numStates; ++i) {
tomhudson@google.com93813632011-10-27 20:21:16 +0000327 const GrDrawState& dstate = this->accessSavedDrawState(fStates[i]);
328 for (int s = 0; s < GrDrawState::kNumStages; ++s) {
bsalomon@google.com1da07462011-03-10 14:51:57 +0000329 GrSafeUnref(dstate.fTextures[s]);
reed@google.comac10a2d2010-12-22 21:39:39 +0000330 }
bsalomon@google.com1da07462011-03-10 14:51:57 +0000331 GrSafeUnref(dstate.fRenderTarget);
reed@google.comac10a2d2010-12-22 21:39:39 +0000332 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000333 int numDraws = fDraws.count();
334 for (int d = 0; d < numDraws; ++d) {
335 // we always have a VB, but not always an IB
336 GrAssert(NULL != fDraws[d].fVertexBuffer);
337 fDraws[d].fVertexBuffer->unref();
338 GrSafeUnref(fDraws[d].fIndexBuffer);
339 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000340 fDraws.reset();
341 fStates.reset();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000342
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000343 fClears.reset();
344
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000345 fVertexPool.reset();
346 fIndexPool.reset();
347
reed@google.comac10a2d2010-12-22 21:39:39 +0000348 fClips.reset();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000349
350 fCurrQuad = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000351}
352
353void GrInOrderDrawBuffer::playback(GrDrawTarget* target) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000354 GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fVertexSrc);
355 GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fIndexSrc);
reed@google.comac10a2d2010-12-22 21:39:39 +0000356 GrAssert(NULL != target);
357 GrAssert(target != this); // not considered and why?
358
bsalomon@google.com898d9e52011-04-26 13:22:33 +0000359 int numDraws = fDraws.count();
reed@google.comac10a2d2010-12-22 21:39:39 +0000360 if (!numDraws) {
361 return;
362 }
363
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000364 fVertexPool.unlock();
365 fIndexPool.unlock();
reed@google.comac10a2d2010-12-22 21:39:39 +0000366
367 GrDrawTarget::AutoStateRestore asr(target);
368 GrDrawTarget::AutoClipRestore acr(target);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000369 AutoGeometryPush agp(target);
reed@google.comac10a2d2010-12-22 21:39:39 +0000370
bsalomon@google.com6a77cc52011-04-28 17:33:34 +0000371 int currState = ~0;
372 int currClip = ~0;
373 int currClear = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000374
bsalomon@google.com898d9e52011-04-26 13:22:33 +0000375 for (int i = 0; i < numDraws; ++i) {
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000376 while (currClear < fClears.count() &&
377 i == fClears[currClear].fBeforeDrawIdx) {
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000378 target->clear(&fClears[currClear].fRect, fClears[currClear].fColor);
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000379 ++currClear;
380 }
381
reed@google.comac10a2d2010-12-22 21:39:39 +0000382 const Draw& draw = fDraws[i];
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000383 if (draw.fStateChanged) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000384 ++currState;
385 target->restoreDrawState(fStates[currState]);
386 }
387 if (draw.fClipChanged) {
388 ++currClip;
389 target->setClip(fClips[currClip]);
390 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000391
392 target->setVertexSourceToBuffer(draw.fVertexLayout, draw.fVertexBuffer);
393
reed@google.comac10a2d2010-12-22 21:39:39 +0000394 if (draw.fIndexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000395 target->setIndexSourceToBuffer(draw.fIndexBuffer);
396 }
397
398 if (draw.fIndexCount) {
399 target->drawIndexed(draw.fPrimitiveType,
reed@google.comac10a2d2010-12-22 21:39:39 +0000400 draw.fStartVertex,
401 draw.fStartIndex,
402 draw.fVertexCount,
403 draw.fIndexCount);
404 } else {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000405 target->drawNonIndexed(draw.fPrimitiveType,
reed@google.comac10a2d2010-12-22 21:39:39 +0000406 draw.fStartVertex,
407 draw.fVertexCount);
408 }
409 }
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000410 while (currClear < fClears.count()) {
411 GrAssert(fDraws.count() == fClears[currClear].fBeforeDrawIdx);
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000412 target->clear(&fClears[currClear].fRect, fClears[currClear].fColor);
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000413 ++currClear;
414 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000415}
416
417bool GrInOrderDrawBuffer::geometryHints(GrVertexLayout vertexLayout,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000418 int* vertexCount,
419 int* indexCount) const {
420 // we will recommend a flush if the data could fit in a single
421 // preallocated buffer but none are left and it can't fit
422 // in the current buffer (which may not be prealloced).
reed@google.comac10a2d2010-12-22 21:39:39 +0000423 bool flush = false;
424 if (NULL != indexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000425 int32_t currIndices = fIndexPool.currentBufferIndices();
426 if (*indexCount > currIndices &&
427 (!fIndexPool.preallocatedBuffersRemaining() &&
428 *indexCount <= fIndexPool.preallocatedBufferIndices())) {
429
430 flush = true;
431 }
432 *indexCount = currIndices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000433 }
434 if (NULL != vertexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000435 int32_t currVertices = fVertexPool.currentBufferVertices(vertexLayout);
436 if (*vertexCount > currVertices &&
437 (!fVertexPool.preallocatedBuffersRemaining() &&
438 *vertexCount <= fVertexPool.preallocatedBufferVertices(vertexLayout))) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000439
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000440 flush = true;
reed@google.comac10a2d2010-12-22 21:39:39 +0000441 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000442 *vertexCount = currVertices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000443 }
444 return flush;
445}
446
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000447bool GrInOrderDrawBuffer::onReserveVertexSpace(GrVertexLayout vertexLayout,
448 int vertexCount,
449 void** vertices) {
450 GeometryPoolState& poolState = fGeoPoolStateStack.back();
451 GrAssert(vertexCount > 0);
452 GrAssert(NULL != vertices);
453 GrAssert(0 == poolState.fUsedPoolVertexBytes);
454
455 *vertices = fVertexPool.makeSpace(vertexLayout,
456 vertexCount,
457 &poolState.fPoolVertexBuffer,
458 &poolState.fPoolStartVertex);
459 return NULL != *vertices;
460}
461
462bool GrInOrderDrawBuffer::onReserveIndexSpace(int indexCount, void** indices) {
463 GeometryPoolState& poolState = fGeoPoolStateStack.back();
464 GrAssert(indexCount > 0);
465 GrAssert(NULL != indices);
466 GrAssert(0 == poolState.fUsedPoolIndexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000467
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000468 *indices = fIndexPool.makeSpace(indexCount,
469 &poolState.fPoolIndexBuffer,
470 &poolState.fPoolStartIndex);
471 return NULL != *indices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000472}
473
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000474void GrInOrderDrawBuffer::releaseReservedVertexSpace() {
475 GeometryPoolState& poolState = fGeoPoolStateStack.back();
476 const GeometrySrcState& geoSrc = this->getGeomSrc();
477
478 GrAssert(kReserved_GeometrySrcType == geoSrc.fVertexSrc);
479
480 size_t reservedVertexBytes = VertexSize(geoSrc.fVertexLayout) *
481 geoSrc.fVertexCount;
482 fVertexPool.putBack(reservedVertexBytes -
483 poolState.fUsedPoolVertexBytes);
484 poolState.fUsedPoolVertexBytes = 0;
485 poolState.fPoolVertexBuffer = 0;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000486}
487
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000488void GrInOrderDrawBuffer::releaseReservedIndexSpace() {
489 GeometryPoolState& poolState = fGeoPoolStateStack.back();
490 const GeometrySrcState& geoSrc = this->getGeomSrc();
491
492 GrAssert(kReserved_GeometrySrcType == geoSrc.fIndexSrc);
493
494 size_t reservedIndexBytes = sizeof(uint16_t) * geoSrc.fIndexCount;
495 fIndexPool.putBack(reservedIndexBytes - poolState.fUsedPoolIndexBytes);
496 poolState.fUsedPoolIndexBytes = 0;
497 poolState.fPoolStartVertex = 0;
498}
499
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000500void GrInOrderDrawBuffer::onSetVertexSourceToArray(const void* vertexArray,
501 int vertexCount) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000502
503 GeometryPoolState& poolState = fGeoPoolStateStack.back();
504 GrAssert(0 == poolState.fUsedPoolVertexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000505#if GR_DEBUG
506 bool success =
507#endif
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000508 fVertexPool.appendVertices(this->getGeomSrc().fVertexLayout,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000509 vertexCount,
510 vertexArray,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000511 &poolState.fPoolVertexBuffer,
512 &poolState.fPoolStartVertex);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000513 GR_DEBUGASSERT(success);
514}
515
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000516void GrInOrderDrawBuffer::onSetIndexSourceToArray(const void* indexArray,
517 int indexCount) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000518 GeometryPoolState& poolState = fGeoPoolStateStack.back();
519 GrAssert(0 == poolState.fUsedPoolIndexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000520#if GR_DEBUG
521 bool success =
522#endif
523 fIndexPool.appendIndices(indexCount,
524 indexArray,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000525 &poolState.fPoolIndexBuffer,
526 &poolState.fPoolStartIndex);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000527 GR_DEBUGASSERT(success);
reed@google.comac10a2d2010-12-22 21:39:39 +0000528}
529
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000530void GrInOrderDrawBuffer::geometrySourceWillPush() {
531 GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
532 poolState.fUsedPoolVertexBytes = 0;
533 poolState.fUsedPoolIndexBytes = 0;
534#if GR_DEBUG
535 poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0;
536 poolState.fPoolStartVertex = ~0;
537 poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0;
538 poolState.fPoolStartIndex = ~0;
539#endif
540}
541
542void GrInOrderDrawBuffer::releaseVertexArray() {
543 GeometryPoolState& poolState = fGeoPoolStateStack.back();
544 const GeometrySrcState& geoSrc = this->getGeomSrc();
545
546 size_t reservedVertexBytes = VertexSize(geoSrc.fVertexLayout) *
547 geoSrc.fVertexCount;
548 fVertexPool.putBack(reservedVertexBytes - poolState.fUsedPoolVertexBytes);
549
550 poolState.fUsedPoolVertexBytes = 0;
551}
552
553void GrInOrderDrawBuffer::releaseIndexArray() {
554 GeometryPoolState& poolState = fGeoPoolStateStack.back();
555 const GeometrySrcState& geoSrc = this->getGeomSrc();
556
557 size_t reservedIndexBytes = sizeof(uint16_t) * geoSrc.fIndexCount;
558 fIndexPool.putBack(reservedIndexBytes - poolState.fUsedPoolIndexBytes);
559
560 poolState.fUsedPoolIndexBytes = 0;
561}
562
563void GrInOrderDrawBuffer::geometrySourceWillPop(
564 const GeometrySrcState& restoredState) {
565 GrAssert(fGeoPoolStateStack.count() > 1);
566 fGeoPoolStateStack.pop_back();
567 GeometryPoolState& poolState = fGeoPoolStateStack.back();
568 // we have to assume that any slack we had in our vertex/index data
569 // is now unreleasable because data may have been appended later in the
570 // pool.
571 if (kReserved_GeometrySrcType == restoredState.fVertexSrc ||
572 kArray_GeometrySrcType == restoredState.fVertexSrc) {
573 poolState.fUsedPoolVertexBytes =
574 VertexSize(restoredState.fVertexLayout) *
575 restoredState.fVertexCount;
576 }
577 if (kReserved_GeometrySrcType == restoredState.fIndexSrc ||
578 kArray_GeometrySrcType == restoredState.fIndexSrc) {
579 poolState.fUsedPoolVertexBytes = sizeof(uint16_t) *
580 restoredState.fIndexCount;
581 }
582}
583
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000584bool GrInOrderDrawBuffer::needsNewState() const {
585 if (fStates.empty()) {
586 return true;
587 } else {
tomhudson@google.com93813632011-10-27 20:21:16 +0000588 const GrDrawState& old = this->accessSavedDrawState(fStates.back());
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000589 return old != fCurrDrawState;
590 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000591}
592
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000593void GrInOrderDrawBuffer::pushState() {
tomhudson@google.com93813632011-10-27 20:21:16 +0000594 for (int s = 0; s < GrDrawState::kNumStages; ++s) {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000595 GrSafeRef(fCurrDrawState.fTextures[s]);
596 }
bsalomon@google.com1da07462011-03-10 14:51:57 +0000597 GrSafeRef(fCurrDrawState.fRenderTarget);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000598 this->saveCurrentDrawState(&fStates.push_back());
599 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000600
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000601bool GrInOrderDrawBuffer::needsNewClip() const {
602 if (fCurrDrawState.fFlagBits & kClip_StateBit) {
603 if (fClips.empty() || (fClipSet && fClips.back() != fClip)) {
604 return true;
605 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000606 }
607 return false;
608}
bsalomon@google.comd302f142011-03-03 13:54:13 +0000609
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000610void GrInOrderDrawBuffer::pushClip() {
611 fClips.push_back() = fClip;
612 fClipSet = false;
reed@google.comac10a2d2010-12-22 21:39:39 +0000613}
bsalomon@google.comd302f142011-03-03 13:54:13 +0000614
bsalomon@google.comdea2f8d2011-08-01 15:51:05 +0000615void GrInOrderDrawBuffer::clipWillBeSet(const GrClip& newClip) {
616 INHERITED::clipWillBeSet(newClip);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000617 fClipSet = true;
618}