blob: 85af430fbf17c22b92c91283dda5659f580c9516 [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.com471d4712011-08-23 15:45:25 +000021 : fGpu(gpu)
22 , fDraws(&fDrawStorage)
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000023 , fStates(&fStateStorage)
24 , fClears(&fClearStorage)
25 , fClips(&fClipStorage)
26 , fClipSet(true)
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000027
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000028 , fLastRectVertexLayout(0)
29 , fQuadIndexBuffer(NULL)
30 , fMaxQuads(0)
31 , fCurrQuad(0)
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000032
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000033 , fVertexPool(*vertexPool)
34 , fIndexPool(*indexPool)
35 , fGeoPoolStateStack(&fGeoStackStorage) {
36
bsalomon@google.com1c13c962011-02-14 16:51:21 +000037 GrAssert(NULL != vertexPool);
38 GrAssert(NULL != indexPool);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000039
bsalomon@google.com471d4712011-08-23 15:45:25 +000040 gpu->ref();
41
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000042 GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
43 poolState.fUsedPoolVertexBytes = 0;
44 poolState.fUsedPoolIndexBytes = 0;
45#if GR_DEBUG
46 poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0;
47 poolState.fPoolStartVertex = ~0;
48 poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0;
49 poolState.fPoolStartIndex = ~0;
50#endif
reed@google.comac10a2d2010-12-22 21:39:39 +000051}
52
53GrInOrderDrawBuffer::~GrInOrderDrawBuffer() {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000054 this->reset();
55 GrSafeUnref(fQuadIndexBuffer);
bsalomon@google.com471d4712011-08-23 15:45:25 +000056 fGpu->unref();
reed@google.comac10a2d2010-12-22 21:39:39 +000057}
58
59void GrInOrderDrawBuffer::initializeDrawStateAndClip(const GrDrawTarget& target) {
60 this->copyDrawState(target);
61 this->setClip(target.getClip());
62}
63
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000064void GrInOrderDrawBuffer::setQuadIndexBuffer(const GrIndexBuffer* indexBuffer) {
65 bool newIdxBuffer = fQuadIndexBuffer != indexBuffer;
66 if (newIdxBuffer) {
67 GrSafeUnref(fQuadIndexBuffer);
68 fQuadIndexBuffer = indexBuffer;
69 GrSafeRef(fQuadIndexBuffer);
70 fCurrQuad = 0;
71 fMaxQuads = (NULL == indexBuffer) ? 0 : indexBuffer->maxQuads();
72 } else {
bsalomon@google.comd302f142011-03-03 13:54:13 +000073 GrAssert((NULL == indexBuffer && 0 == fMaxQuads) ||
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000074 (indexBuffer->maxQuads() == fMaxQuads));
75 }
76}
77
bsalomon@google.comd302f142011-03-03 13:54:13 +000078void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000079 const GrMatrix* matrix,
bsalomon@google.comffca4002011-02-22 20:34:01 +000080 StageBitfield stageEnableBitfield,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000081 const GrRect* srcRects[],
82 const GrMatrix* srcMatrices[]) {
bsalomon@google.comd302f142011-03-03 13:54:13 +000083
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000084 GrAssert(!(NULL == fQuadIndexBuffer && fCurrQuad));
85 GrAssert(!(fDraws.empty() && fCurrQuad));
86 GrAssert(!(0 != fMaxQuads && NULL == fQuadIndexBuffer));
87
88 // 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.comffca4002011-02-22 20:34:01 +000093 GrVertexLayout layout = GetRectVertexLayout(stageEnableBitfield, 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.com86afc2a2011-02-16 16:12:19 +000099 AutoViewMatrixRestore avmr(this);
100 GrMatrix combinedMatrix = this->getViewMatrix();
101 this->setViewMatrix(GrMatrix::I());
102 if (NULL != matrix) {
103 combinedMatrix.preConcat(*matrix);
104 }
105
106 SetRectVertices(rect, &combinedMatrix, srcRects, srcMatrices, layout, geo.vertices());
107
108 // we don't want to miss an opportunity to batch rects together
109 // simply because the clip has changed if the clip doesn't affect
110 // the rect.
111 bool disabledClip = false;
112 if (this->isClipState() && fClip.isRect()) {
bsalomon@google.comd302f142011-03-03 13:54:13 +0000113
bsalomon@google.com0b50b2e2011-03-08 21:07:21 +0000114 GrRect clipRect = fClip.getRect(0);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000115 // If the clip rect touches the edge of the viewport, extended it
116 // out (close) to infinity to avoid bogus intersections.
bsalomon@google.comd302f142011-03-03 13:54:13 +0000117 // We might consider a more exact clip to viewport if this
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000118 // conservative test fails.
119 const GrRenderTarget* target = this->getRenderTarget();
120 if (0 >= clipRect.fLeft) {
121 clipRect.fLeft = GR_ScalarMin;
122 }
123 if (target->width() <= clipRect.fRight) {
124 clipRect.fRight = GR_ScalarMax;
125 }
126 if (0 >= clipRect.top()) {
127 clipRect.fTop = GR_ScalarMin;
128 }
129 if (target->height() <= clipRect.fBottom) {
130 clipRect.fBottom = GR_ScalarMax;
131 }
132 int stride = VertexSize(layout);
133 bool insideClip = true;
134 for (int v = 0; v < 4; ++v) {
135 const GrPoint& p = *GetVertexPoint(geo.vertices(), v, stride);
136 if (!clipRect.contains(p)) {
137 insideClip = false;
138 break;
139 }
140 }
141 if (insideClip) {
142 this->disableState(kClip_StateBit);
143 disabledClip = true;
144 }
145 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000146 if (!needsNewClip() && !needsNewState() && fCurrQuad > 0 &&
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000147 fCurrQuad < fMaxQuads && layout == fLastRectVertexLayout) {
148
149 int vsize = VertexSize(layout);
bsalomon@google.comd302f142011-03-03 13:54:13 +0000150
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000151 Draw& lastDraw = fDraws.back();
152
153 GrAssert(lastDraw.fIndexBuffer == fQuadIndexBuffer);
154 GrAssert(kTriangles_PrimitiveType == lastDraw.fPrimitiveType);
155 GrAssert(0 == lastDraw.fVertexCount % 4);
156 GrAssert(0 == lastDraw.fIndexCount % 6);
157 GrAssert(0 == lastDraw.fStartIndex);
158
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000159 GeometryPoolState& poolState = fGeoPoolStateStack.back();
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000160 bool clearSinceLastDraw =
161 fClears.count() &&
162 fClears.back().fBeforeDrawIdx == fDraws.count();
163
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000164 appendToPreviousDraw =
165 !clearSinceLastDraw &&
166 lastDraw.fVertexBuffer == poolState.fPoolVertexBuffer &&
167 (fCurrQuad * 4 + lastDraw.fStartVertex) == poolState.fPoolStartVertex;
168
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000169 if (appendToPreviousDraw) {
170 lastDraw.fVertexCount += 4;
171 lastDraw.fIndexCount += 6;
172 fCurrQuad += 1;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000173 // we reserved above, so we should be the first
174 // use of this vertex reserveation.
175 GrAssert(0 == poolState.fUsedPoolVertexBytes);
176 poolState.fUsedPoolVertexBytes = 4 * vsize;
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000177 }
178 }
179 if (!appendToPreviousDraw) {
180 this->setIndexSourceToBuffer(fQuadIndexBuffer);
181 drawIndexed(kTriangles_PrimitiveType, 0, 0, 4, 6);
182 fCurrQuad = 1;
183 fLastRectVertexLayout = layout;
184 }
185 if (disabledClip) {
186 this->enableState(kClip_StateBit);
187 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000188 } else {
bsalomon@google.comffca4002011-02-22 20:34:01 +0000189 INHERITED::drawRect(rect, matrix, stageEnableBitfield, srcRects, srcMatrices);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000190 }
191}
192
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000193void GrInOrderDrawBuffer::onDrawIndexed(GrPrimitiveType primitiveType,
194 int startVertex,
195 int startIndex,
196 int vertexCount,
197 int indexCount) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000198
199 if (!vertexCount || !indexCount) {
200 return;
201 }
202
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000203 fCurrQuad = 0;
204
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000205 GeometryPoolState& poolState = fGeoPoolStateStack.back();
206
reed@google.comac10a2d2010-12-22 21:39:39 +0000207 Draw& draw = fDraws.push_back();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000208 draw.fPrimitiveType = primitiveType;
reed@google.comac10a2d2010-12-22 21:39:39 +0000209 draw.fStartVertex = startVertex;
210 draw.fStartIndex = startIndex;
211 draw.fVertexCount = vertexCount;
212 draw.fIndexCount = indexCount;
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000213
214 draw.fClipChanged = this->needsNewClip();
215 if (draw.fClipChanged) {
216 this->pushClip();
217 }
218
219 draw.fStateChanged = this->needsNewState();
220 if (draw.fStateChanged) {
221 this->pushState();
222 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000223
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000224 draw.fVertexLayout = this->getGeomSrc().fVertexLayout;
225 switch (this->getGeomSrc().fVertexSrc) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000226 case kBuffer_GeometrySrcType:
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000227 draw.fVertexBuffer = this->getGeomSrc().fVertexBuffer;
reed@google.comac10a2d2010-12-22 21:39:39 +0000228 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000229 case kReserved_GeometrySrcType: // fallthrough
230 case kArray_GeometrySrcType: {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000231 size_t vertexBytes = (vertexCount + startVertex) *
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000232 VertexSize(this->getGeomSrc().fVertexLayout);
233 poolState.fUsedPoolVertexBytes =
234 GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
235 draw.fVertexBuffer = poolState.fPoolVertexBuffer;
236 draw.fStartVertex += poolState.fPoolStartVertex;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000237 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000238 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000239 default:
240 GrCrash("unknown geom src type");
reed@google.comac10a2d2010-12-22 21:39:39 +0000241 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000242 draw.fVertexBuffer->ref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000243
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000244 switch (this->getGeomSrc().fIndexSrc) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000245 case kBuffer_GeometrySrcType:
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000246 draw.fIndexBuffer = this->getGeomSrc().fIndexBuffer;
reed@google.comac10a2d2010-12-22 21:39:39 +0000247 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000248 case kReserved_GeometrySrcType: // fallthrough
249 case kArray_GeometrySrcType: {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000250 size_t indexBytes = (indexCount + startIndex) * sizeof(uint16_t);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000251 poolState.fUsedPoolIndexBytes =
252 GrMax(poolState.fUsedPoolIndexBytes, indexBytes);
253 draw.fIndexBuffer = poolState.fPoolIndexBuffer;
254 draw.fStartIndex += poolState.fPoolStartVertex;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000255 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000256 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000257 default:
258 GrCrash("unknown geom src type");
reed@google.comac10a2d2010-12-22 21:39:39 +0000259 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000260 draw.fIndexBuffer->ref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000261}
262
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000263void GrInOrderDrawBuffer::onDrawNonIndexed(GrPrimitiveType primitiveType,
264 int startVertex,
265 int vertexCount) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000266 if (!vertexCount) {
267 return;
268 }
269
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000270 fCurrQuad = 0;
271
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000272 GeometryPoolState& poolState = fGeoPoolStateStack.back();
273
reed@google.comac10a2d2010-12-22 21:39:39 +0000274 Draw& draw = fDraws.push_back();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000275 draw.fPrimitiveType = primitiveType;
reed@google.comac10a2d2010-12-22 21:39:39 +0000276 draw.fStartVertex = startVertex;
277 draw.fStartIndex = 0;
278 draw.fVertexCount = vertexCount;
279 draw.fIndexCount = 0;
280
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000281 draw.fClipChanged = this->needsNewClip();
282 if (draw.fClipChanged) {
283 this->pushClip();
284 }
285
286 draw.fStateChanged = this->needsNewState();
287 if (draw.fStateChanged) {
288 this->pushState();
289 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000290
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000291 draw.fVertexLayout = this->getGeomSrc().fVertexLayout;
292 switch (this->getGeomSrc().fVertexSrc) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000293 case kBuffer_GeometrySrcType:
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000294 draw.fVertexBuffer = this->getGeomSrc().fVertexBuffer;
reed@google.comac10a2d2010-12-22 21:39:39 +0000295 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000296 case kReserved_GeometrySrcType: // fallthrough
297 case kArray_GeometrySrcType: {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000298 size_t vertexBytes = (vertexCount + startVertex) *
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000299 VertexSize(this->getGeomSrc().fVertexLayout);
300 poolState.fUsedPoolVertexBytes =
301 GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
302 draw.fVertexBuffer = poolState.fPoolVertexBuffer;
303 draw.fStartVertex += poolState.fPoolStartVertex;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000304 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000305 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000306 default:
307 GrCrash("unknown geom src type");
reed@google.comac10a2d2010-12-22 21:39:39 +0000308 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000309 draw.fVertexBuffer->ref();
310 draw.fIndexBuffer = NULL;
reed@google.comac10a2d2010-12-22 21:39:39 +0000311}
312
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000313void GrInOrderDrawBuffer::clear(const GrIRect* rect, GrColor color) {
314 GrIRect r;
315 if (NULL == rect) {
316 // We could do something smart and remove previous draws and clears to
317 // the current render target. If we get that smart we have to make sure
318 // those draws aren't read before this clear (render-to-texture).
319 r.setLTRB(0, 0,
320 this->getRenderTarget()->width(),
321 this->getRenderTarget()->height());
322 rect = &r;
323 }
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000324 Clear& clr = fClears.push_back();
325 clr.fColor = color;
326 clr.fBeforeDrawIdx = fDraws.count();
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000327 clr.fRect = *rect;
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000328}
329
reed@google.comac10a2d2010-12-22 21:39:39 +0000330void GrInOrderDrawBuffer::reset() {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000331 GrAssert(1 == fGeoPoolStateStack.count());
332 this->resetVertexSource();
333 this->resetIndexSource();
reed@google.comac10a2d2010-12-22 21:39:39 +0000334 uint32_t numStates = fStates.count();
335 for (uint32_t i = 0; i < numStates; ++i) {
bsalomon@google.com1da07462011-03-10 14:51:57 +0000336 const DrState& dstate = this->accessSavedDrawState(fStates[i]);
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000337 for (int s = 0; s < kNumStages; ++s) {
bsalomon@google.com1da07462011-03-10 14:51:57 +0000338 GrSafeUnref(dstate.fTextures[s]);
reed@google.comac10a2d2010-12-22 21:39:39 +0000339 }
bsalomon@google.com1da07462011-03-10 14:51:57 +0000340 GrSafeUnref(dstate.fRenderTarget);
reed@google.comac10a2d2010-12-22 21:39:39 +0000341 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000342 int numDraws = fDraws.count();
343 for (int d = 0; d < numDraws; ++d) {
344 // we always have a VB, but not always an IB
345 GrAssert(NULL != fDraws[d].fVertexBuffer);
346 fDraws[d].fVertexBuffer->unref();
347 GrSafeUnref(fDraws[d].fIndexBuffer);
348 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000349 fDraws.reset();
350 fStates.reset();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000351
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000352 fClears.reset();
353
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000354 fVertexPool.reset();
355 fIndexPool.reset();
356
reed@google.comac10a2d2010-12-22 21:39:39 +0000357 fClips.reset();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000358
359 fCurrQuad = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000360}
361
362void GrInOrderDrawBuffer::playback(GrDrawTarget* target) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000363 GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fVertexSrc);
364 GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fIndexSrc);
reed@google.comac10a2d2010-12-22 21:39:39 +0000365 GrAssert(NULL != target);
366 GrAssert(target != this); // not considered and why?
367
bsalomon@google.com898d9e52011-04-26 13:22:33 +0000368 int numDraws = fDraws.count();
reed@google.comac10a2d2010-12-22 21:39:39 +0000369 if (!numDraws) {
370 return;
371 }
372
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000373 fVertexPool.unlock();
374 fIndexPool.unlock();
reed@google.comac10a2d2010-12-22 21:39:39 +0000375
376 GrDrawTarget::AutoStateRestore asr(target);
377 GrDrawTarget::AutoClipRestore acr(target);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000378 AutoGeometryPush agp(target);
reed@google.comac10a2d2010-12-22 21:39:39 +0000379
bsalomon@google.com6a77cc52011-04-28 17:33:34 +0000380 int currState = ~0;
381 int currClip = ~0;
382 int currClear = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000383
bsalomon@google.com898d9e52011-04-26 13:22:33 +0000384 for (int i = 0; i < numDraws; ++i) {
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000385 while (currClear < fClears.count() &&
386 i == fClears[currClear].fBeforeDrawIdx) {
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000387 target->clear(&fClears[currClear].fRect, fClears[currClear].fColor);
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000388 ++currClear;
389 }
390
reed@google.comac10a2d2010-12-22 21:39:39 +0000391 const Draw& draw = fDraws[i];
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000392 if (draw.fStateChanged) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000393 ++currState;
394 target->restoreDrawState(fStates[currState]);
395 }
396 if (draw.fClipChanged) {
397 ++currClip;
398 target->setClip(fClips[currClip]);
399 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000400
401 target->setVertexSourceToBuffer(draw.fVertexLayout, draw.fVertexBuffer);
402
reed@google.comac10a2d2010-12-22 21:39:39 +0000403 if (draw.fIndexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000404 target->setIndexSourceToBuffer(draw.fIndexBuffer);
405 }
406
407 if (draw.fIndexCount) {
408 target->drawIndexed(draw.fPrimitiveType,
reed@google.comac10a2d2010-12-22 21:39:39 +0000409 draw.fStartVertex,
410 draw.fStartIndex,
411 draw.fVertexCount,
412 draw.fIndexCount);
413 } else {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000414 target->drawNonIndexed(draw.fPrimitiveType,
reed@google.comac10a2d2010-12-22 21:39:39 +0000415 draw.fStartVertex,
416 draw.fVertexCount);
417 }
418 }
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000419 while (currClear < fClears.count()) {
420 GrAssert(fDraws.count() == fClears[currClear].fBeforeDrawIdx);
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000421 target->clear(&fClears[currClear].fRect, fClears[currClear].fColor);
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000422 ++currClear;
423 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000424}
425
426bool GrInOrderDrawBuffer::geometryHints(GrVertexLayout vertexLayout,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000427 int* vertexCount,
428 int* indexCount) const {
429 // we will recommend a flush if the data could fit in a single
430 // preallocated buffer but none are left and it can't fit
431 // in the current buffer (which may not be prealloced).
reed@google.comac10a2d2010-12-22 21:39:39 +0000432 bool flush = false;
433 if (NULL != indexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000434 int32_t currIndices = fIndexPool.currentBufferIndices();
435 if (*indexCount > currIndices &&
436 (!fIndexPool.preallocatedBuffersRemaining() &&
437 *indexCount <= fIndexPool.preallocatedBufferIndices())) {
438
439 flush = true;
440 }
441 *indexCount = currIndices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000442 }
443 if (NULL != vertexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000444 int32_t currVertices = fVertexPool.currentBufferVertices(vertexLayout);
445 if (*vertexCount > currVertices &&
446 (!fVertexPool.preallocatedBuffersRemaining() &&
447 *vertexCount <= fVertexPool.preallocatedBufferVertices(vertexLayout))) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000448
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000449 flush = true;
reed@google.comac10a2d2010-12-22 21:39:39 +0000450 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000451 *vertexCount = currVertices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000452 }
453 return flush;
454}
455
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000456bool GrInOrderDrawBuffer::onReserveVertexSpace(GrVertexLayout vertexLayout,
457 int vertexCount,
458 void** vertices) {
459 GeometryPoolState& poolState = fGeoPoolStateStack.back();
460 GrAssert(vertexCount > 0);
461 GrAssert(NULL != vertices);
462 GrAssert(0 == poolState.fUsedPoolVertexBytes);
463
464 *vertices = fVertexPool.makeSpace(vertexLayout,
465 vertexCount,
466 &poolState.fPoolVertexBuffer,
467 &poolState.fPoolStartVertex);
468 return NULL != *vertices;
469}
470
471bool GrInOrderDrawBuffer::onReserveIndexSpace(int indexCount, void** indices) {
472 GeometryPoolState& poolState = fGeoPoolStateStack.back();
473 GrAssert(indexCount > 0);
474 GrAssert(NULL != indices);
475 GrAssert(0 == poolState.fUsedPoolIndexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000476
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000477 *indices = fIndexPool.makeSpace(indexCount,
478 &poolState.fPoolIndexBuffer,
479 &poolState.fPoolStartIndex);
480 return NULL != *indices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000481}
482
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000483void GrInOrderDrawBuffer::releaseReservedVertexSpace() {
484 GeometryPoolState& poolState = fGeoPoolStateStack.back();
485 const GeometrySrcState& geoSrc = this->getGeomSrc();
486
487 GrAssert(kReserved_GeometrySrcType == geoSrc.fVertexSrc);
488
489 size_t reservedVertexBytes = VertexSize(geoSrc.fVertexLayout) *
490 geoSrc.fVertexCount;
491 fVertexPool.putBack(reservedVertexBytes -
492 poolState.fUsedPoolVertexBytes);
493 poolState.fUsedPoolVertexBytes = 0;
494 poolState.fPoolVertexBuffer = 0;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000495}
496
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000497void GrInOrderDrawBuffer::releaseReservedIndexSpace() {
498 GeometryPoolState& poolState = fGeoPoolStateStack.back();
499 const GeometrySrcState& geoSrc = this->getGeomSrc();
500
501 GrAssert(kReserved_GeometrySrcType == geoSrc.fIndexSrc);
502
503 size_t reservedIndexBytes = sizeof(uint16_t) * geoSrc.fIndexCount;
504 fIndexPool.putBack(reservedIndexBytes - poolState.fUsedPoolIndexBytes);
505 poolState.fUsedPoolIndexBytes = 0;
506 poolState.fPoolStartVertex = 0;
507}
508
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000509void GrInOrderDrawBuffer::onSetVertexSourceToArray(const void* vertexArray,
510 int vertexCount) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000511
512 GeometryPoolState& poolState = fGeoPoolStateStack.back();
513 GrAssert(0 == poolState.fUsedPoolVertexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000514#if GR_DEBUG
515 bool success =
516#endif
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000517 fVertexPool.appendVertices(this->getGeomSrc().fVertexLayout,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000518 vertexCount,
519 vertexArray,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000520 &poolState.fPoolVertexBuffer,
521 &poolState.fPoolStartVertex);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000522 GR_DEBUGASSERT(success);
523}
524
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000525void GrInOrderDrawBuffer::onSetIndexSourceToArray(const void* indexArray,
526 int indexCount) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000527 GeometryPoolState& poolState = fGeoPoolStateStack.back();
528 GrAssert(0 == poolState.fUsedPoolIndexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000529#if GR_DEBUG
530 bool success =
531#endif
532 fIndexPool.appendIndices(indexCount,
533 indexArray,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000534 &poolState.fPoolIndexBuffer,
535 &poolState.fPoolStartIndex);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000536 GR_DEBUGASSERT(success);
reed@google.comac10a2d2010-12-22 21:39:39 +0000537}
538
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000539void GrInOrderDrawBuffer::geometrySourceWillPush() {
540 GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
541 poolState.fUsedPoolVertexBytes = 0;
542 poolState.fUsedPoolIndexBytes = 0;
543#if GR_DEBUG
544 poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0;
545 poolState.fPoolStartVertex = ~0;
546 poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0;
547 poolState.fPoolStartIndex = ~0;
548#endif
549}
550
551void GrInOrderDrawBuffer::releaseVertexArray() {
552 GeometryPoolState& poolState = fGeoPoolStateStack.back();
553 const GeometrySrcState& geoSrc = this->getGeomSrc();
554
555 size_t reservedVertexBytes = VertexSize(geoSrc.fVertexLayout) *
556 geoSrc.fVertexCount;
557 fVertexPool.putBack(reservedVertexBytes - poolState.fUsedPoolVertexBytes);
558
559 poolState.fUsedPoolVertexBytes = 0;
560}
561
562void GrInOrderDrawBuffer::releaseIndexArray() {
563 GeometryPoolState& poolState = fGeoPoolStateStack.back();
564 const GeometrySrcState& geoSrc = this->getGeomSrc();
565
566 size_t reservedIndexBytes = sizeof(uint16_t) * geoSrc.fIndexCount;
567 fIndexPool.putBack(reservedIndexBytes - poolState.fUsedPoolIndexBytes);
568
569 poolState.fUsedPoolIndexBytes = 0;
570}
571
572void GrInOrderDrawBuffer::geometrySourceWillPop(
573 const GeometrySrcState& restoredState) {
574 GrAssert(fGeoPoolStateStack.count() > 1);
575 fGeoPoolStateStack.pop_back();
576 GeometryPoolState& poolState = fGeoPoolStateStack.back();
577 // we have to assume that any slack we had in our vertex/index data
578 // is now unreleasable because data may have been appended later in the
579 // pool.
580 if (kReserved_GeometrySrcType == restoredState.fVertexSrc ||
581 kArray_GeometrySrcType == restoredState.fVertexSrc) {
582 poolState.fUsedPoolVertexBytes =
583 VertexSize(restoredState.fVertexLayout) *
584 restoredState.fVertexCount;
585 }
586 if (kReserved_GeometrySrcType == restoredState.fIndexSrc ||
587 kArray_GeometrySrcType == restoredState.fIndexSrc) {
588 poolState.fUsedPoolVertexBytes = sizeof(uint16_t) *
589 restoredState.fIndexCount;
590 }
591}
592
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000593bool GrInOrderDrawBuffer::needsNewState() const {
594 if (fStates.empty()) {
595 return true;
596 } else {
597 const DrState& old = this->accessSavedDrawState(fStates.back());
598 return old != fCurrDrawState;
599 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000600}
601
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000602void GrInOrderDrawBuffer::pushState() {
603 for (int s = 0; s < kNumStages; ++s) {
604 GrSafeRef(fCurrDrawState.fTextures[s]);
605 }
bsalomon@google.com1da07462011-03-10 14:51:57 +0000606 GrSafeRef(fCurrDrawState.fRenderTarget);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000607 this->saveCurrentDrawState(&fStates.push_back());
608 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000609
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000610bool GrInOrderDrawBuffer::needsNewClip() const {
611 if (fCurrDrawState.fFlagBits & kClip_StateBit) {
612 if (fClips.empty() || (fClipSet && fClips.back() != fClip)) {
613 return true;
614 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000615 }
616 return false;
617}
bsalomon@google.comd302f142011-03-03 13:54:13 +0000618
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000619void GrInOrderDrawBuffer::pushClip() {
620 fClips.push_back() = fClip;
621 fClipSet = false;
reed@google.comac10a2d2010-12-22 21:39:39 +0000622}
bsalomon@google.comd302f142011-03-03 13:54:13 +0000623
bsalomon@google.comdea2f8d2011-08-01 15:51:05 +0000624void GrInOrderDrawBuffer::clipWillBeSet(const GrClip& newClip) {
625 INHERITED::clipWillBeSet(newClip);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000626 fClipSet = true;
627}
bsalomon@google.com471d4712011-08-23 15:45:25 +0000628
629bool GrInOrderDrawBuffer::willUseHWAALines() const {
630 return fGpu->supportsHWAALines() &&
631 CanUseHWAALines(this->getGeomSrc().fVertexLayout, fCurrDrawState);
632}
633