blob: 9519655bfbb9fa99f1137123cfaa35b518e208a1 [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.com18c9c192011-09-22 21:01:31 +000021 : fDraws(&fDrawStorage)
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000022 , fStates(&fStateStorage)
23 , fClears(&fClearStorage)
24 , fClips(&fClipStorage)
25 , fClipSet(true)
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000026
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000027 , fLastRectVertexLayout(0)
28 , fQuadIndexBuffer(NULL)
29 , fMaxQuads(0)
30 , fCurrQuad(0)
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000031
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000032 , fVertexPool(*vertexPool)
33 , fIndexPool(*indexPool)
34 , fGeoPoolStateStack(&fGeoStackStorage) {
bsalomon@google.com18c9c192011-09-22 21:01:31 +000035
36 fCaps = gpu->getCaps();
37
bsalomon@google.com1c13c962011-02-14 16:51:21 +000038 GrAssert(NULL != vertexPool);
39 GrAssert(NULL != indexPool);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000040
41 GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
42 poolState.fUsedPoolVertexBytes = 0;
43 poolState.fUsedPoolIndexBytes = 0;
44#if GR_DEBUG
45 poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0;
46 poolState.fPoolStartVertex = ~0;
47 poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0;
48 poolState.fPoolStartIndex = ~0;
49#endif
reed@google.comac10a2d2010-12-22 21:39:39 +000050}
51
52GrInOrderDrawBuffer::~GrInOrderDrawBuffer() {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000053 this->reset();
54 GrSafeUnref(fQuadIndexBuffer);
reed@google.comac10a2d2010-12-22 21:39:39 +000055}
56
57void GrInOrderDrawBuffer::initializeDrawStateAndClip(const GrDrawTarget& target) {
58 this->copyDrawState(target);
59 this->setClip(target.getClip());
60}
61
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000062void GrInOrderDrawBuffer::setQuadIndexBuffer(const GrIndexBuffer* indexBuffer) {
63 bool newIdxBuffer = fQuadIndexBuffer != indexBuffer;
64 if (newIdxBuffer) {
65 GrSafeUnref(fQuadIndexBuffer);
66 fQuadIndexBuffer = indexBuffer;
67 GrSafeRef(fQuadIndexBuffer);
68 fCurrQuad = 0;
69 fMaxQuads = (NULL == indexBuffer) ? 0 : indexBuffer->maxQuads();
70 } else {
bsalomon@google.comd302f142011-03-03 13:54:13 +000071 GrAssert((NULL == indexBuffer && 0 == fMaxQuads) ||
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000072 (indexBuffer->maxQuads() == fMaxQuads));
73 }
74}
75
bsalomon@google.comd302f142011-03-03 13:54:13 +000076void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000077 const GrMatrix* matrix,
bsalomon@google.comffca4002011-02-22 20:34:01 +000078 StageBitfield stageEnableBitfield,
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
86 // if we have a quad IB then either append to the previous run of
87 // rects or start a new run
88 if (fMaxQuads) {
bsalomon@google.comd302f142011-03-03 13:54:13 +000089
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000090 bool appendToPreviousDraw = false;
bsalomon@google.comffca4002011-02-22 20:34:01 +000091 GrVertexLayout layout = GetRectVertexLayout(stageEnableBitfield, srcRects);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000092 AutoReleaseGeometry geo(this, layout, 4, 0);
bsalomon@google.com6513cd02011-08-05 20:12:30 +000093 if (!geo.succeeded()) {
94 GrPrintf("Failed to get space for vertices!\n");
95 return;
96 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000097 AutoViewMatrixRestore avmr(this);
98 GrMatrix combinedMatrix = this->getViewMatrix();
99 this->setViewMatrix(GrMatrix::I());
100 if (NULL != matrix) {
101 combinedMatrix.preConcat(*matrix);
102 }
103
104 SetRectVertices(rect, &combinedMatrix, srcRects, srcMatrices, layout, geo.vertices());
105
106 // we don't want to miss an opportunity to batch rects together
107 // simply because the clip has changed if the clip doesn't affect
108 // the rect.
109 bool disabledClip = false;
110 if (this->isClipState() && fClip.isRect()) {
bsalomon@google.comd302f142011-03-03 13:54:13 +0000111
bsalomon@google.com0b50b2e2011-03-08 21:07:21 +0000112 GrRect clipRect = fClip.getRect(0);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000113 // If the clip rect touches the edge of the viewport, extended it
114 // out (close) to infinity to avoid bogus intersections.
bsalomon@google.comd302f142011-03-03 13:54:13 +0000115 // We might consider a more exact clip to viewport if this
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000116 // conservative test fails.
117 const GrRenderTarget* target = this->getRenderTarget();
118 if (0 >= clipRect.fLeft) {
119 clipRect.fLeft = GR_ScalarMin;
120 }
121 if (target->width() <= clipRect.fRight) {
122 clipRect.fRight = GR_ScalarMax;
123 }
124 if (0 >= clipRect.top()) {
125 clipRect.fTop = GR_ScalarMin;
126 }
127 if (target->height() <= clipRect.fBottom) {
128 clipRect.fBottom = GR_ScalarMax;
129 }
130 int stride = VertexSize(layout);
131 bool insideClip = true;
132 for (int v = 0; v < 4; ++v) {
133 const GrPoint& p = *GetVertexPoint(geo.vertices(), v, stride);
134 if (!clipRect.contains(p)) {
135 insideClip = false;
136 break;
137 }
138 }
139 if (insideClip) {
140 this->disableState(kClip_StateBit);
141 disabledClip = true;
142 }
143 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000144 if (!needsNewClip() && !needsNewState() && fCurrQuad > 0 &&
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000145 fCurrQuad < fMaxQuads && layout == fLastRectVertexLayout) {
146
147 int vsize = VertexSize(layout);
bsalomon@google.comd302f142011-03-03 13:54:13 +0000148
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000149 Draw& lastDraw = fDraws.back();
150
151 GrAssert(lastDraw.fIndexBuffer == fQuadIndexBuffer);
152 GrAssert(kTriangles_PrimitiveType == lastDraw.fPrimitiveType);
153 GrAssert(0 == lastDraw.fVertexCount % 4);
154 GrAssert(0 == lastDraw.fIndexCount % 6);
155 GrAssert(0 == lastDraw.fStartIndex);
156
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000157 GeometryPoolState& poolState = fGeoPoolStateStack.back();
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000158 bool clearSinceLastDraw =
159 fClears.count() &&
160 fClears.back().fBeforeDrawIdx == fDraws.count();
161
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000162 appendToPreviousDraw =
163 !clearSinceLastDraw &&
164 lastDraw.fVertexBuffer == poolState.fPoolVertexBuffer &&
165 (fCurrQuad * 4 + lastDraw.fStartVertex) == poolState.fPoolStartVertex;
166
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000167 if (appendToPreviousDraw) {
168 lastDraw.fVertexCount += 4;
169 lastDraw.fIndexCount += 6;
170 fCurrQuad += 1;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000171 // we reserved above, so we should be the first
172 // use of this vertex reserveation.
173 GrAssert(0 == poolState.fUsedPoolVertexBytes);
174 poolState.fUsedPoolVertexBytes = 4 * vsize;
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000175 }
176 }
177 if (!appendToPreviousDraw) {
178 this->setIndexSourceToBuffer(fQuadIndexBuffer);
179 drawIndexed(kTriangles_PrimitiveType, 0, 0, 4, 6);
180 fCurrQuad = 1;
181 fLastRectVertexLayout = layout;
182 }
183 if (disabledClip) {
184 this->enableState(kClip_StateBit);
185 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000186 } else {
bsalomon@google.comffca4002011-02-22 20:34:01 +0000187 INHERITED::drawRect(rect, matrix, stageEnableBitfield, srcRects, srcMatrices);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000188 }
189}
190
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000191void GrInOrderDrawBuffer::onDrawIndexed(GrPrimitiveType primitiveType,
192 int startVertex,
193 int startIndex,
194 int vertexCount,
195 int indexCount) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000196
197 if (!vertexCount || !indexCount) {
198 return;
199 }
200
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000201 fCurrQuad = 0;
202
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000203 GeometryPoolState& poolState = fGeoPoolStateStack.back();
204
reed@google.comac10a2d2010-12-22 21:39:39 +0000205 Draw& draw = fDraws.push_back();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000206 draw.fPrimitiveType = primitiveType;
reed@google.comac10a2d2010-12-22 21:39:39 +0000207 draw.fStartVertex = startVertex;
208 draw.fStartIndex = startIndex;
209 draw.fVertexCount = vertexCount;
210 draw.fIndexCount = indexCount;
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000211
212 draw.fClipChanged = this->needsNewClip();
213 if (draw.fClipChanged) {
214 this->pushClip();
215 }
216
217 draw.fStateChanged = this->needsNewState();
218 if (draw.fStateChanged) {
219 this->pushState();
220 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000221
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000222 draw.fVertexLayout = this->getGeomSrc().fVertexLayout;
223 switch (this->getGeomSrc().fVertexSrc) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000224 case kBuffer_GeometrySrcType:
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000225 draw.fVertexBuffer = this->getGeomSrc().fVertexBuffer;
reed@google.comac10a2d2010-12-22 21:39:39 +0000226 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000227 case kReserved_GeometrySrcType: // fallthrough
228 case kArray_GeometrySrcType: {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000229 size_t vertexBytes = (vertexCount + startVertex) *
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000230 VertexSize(this->getGeomSrc().fVertexLayout);
231 poolState.fUsedPoolVertexBytes =
232 GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
233 draw.fVertexBuffer = poolState.fPoolVertexBuffer;
234 draw.fStartVertex += poolState.fPoolStartVertex;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000235 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000236 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000237 default:
238 GrCrash("unknown geom src type");
reed@google.comac10a2d2010-12-22 21:39:39 +0000239 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000240 draw.fVertexBuffer->ref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000241
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000242 switch (this->getGeomSrc().fIndexSrc) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000243 case kBuffer_GeometrySrcType:
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000244 draw.fIndexBuffer = this->getGeomSrc().fIndexBuffer;
reed@google.comac10a2d2010-12-22 21:39:39 +0000245 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000246 case kReserved_GeometrySrcType: // fallthrough
247 case kArray_GeometrySrcType: {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000248 size_t indexBytes = (indexCount + startIndex) * sizeof(uint16_t);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000249 poolState.fUsedPoolIndexBytes =
250 GrMax(poolState.fUsedPoolIndexBytes, indexBytes);
251 draw.fIndexBuffer = poolState.fPoolIndexBuffer;
252 draw.fStartIndex += poolState.fPoolStartVertex;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000253 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000254 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000255 default:
256 GrCrash("unknown geom src type");
reed@google.comac10a2d2010-12-22 21:39:39 +0000257 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000258 draw.fIndexBuffer->ref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000259}
260
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000261void GrInOrderDrawBuffer::onDrawNonIndexed(GrPrimitiveType primitiveType,
262 int startVertex,
263 int vertexCount) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000264 if (!vertexCount) {
265 return;
266 }
267
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000268 fCurrQuad = 0;
269
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000270 GeometryPoolState& poolState = fGeoPoolStateStack.back();
271
reed@google.comac10a2d2010-12-22 21:39:39 +0000272 Draw& draw = fDraws.push_back();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000273 draw.fPrimitiveType = primitiveType;
reed@google.comac10a2d2010-12-22 21:39:39 +0000274 draw.fStartVertex = startVertex;
275 draw.fStartIndex = 0;
276 draw.fVertexCount = vertexCount;
277 draw.fIndexCount = 0;
278
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000279 draw.fClipChanged = this->needsNewClip();
280 if (draw.fClipChanged) {
281 this->pushClip();
282 }
283
284 draw.fStateChanged = this->needsNewState();
285 if (draw.fStateChanged) {
286 this->pushState();
287 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000288
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000289 draw.fVertexLayout = this->getGeomSrc().fVertexLayout;
290 switch (this->getGeomSrc().fVertexSrc) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000291 case kBuffer_GeometrySrcType:
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000292 draw.fVertexBuffer = this->getGeomSrc().fVertexBuffer;
reed@google.comac10a2d2010-12-22 21:39:39 +0000293 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000294 case kReserved_GeometrySrcType: // fallthrough
295 case kArray_GeometrySrcType: {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000296 size_t vertexBytes = (vertexCount + startVertex) *
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000297 VertexSize(this->getGeomSrc().fVertexLayout);
298 poolState.fUsedPoolVertexBytes =
299 GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
300 draw.fVertexBuffer = poolState.fPoolVertexBuffer;
301 draw.fStartVertex += poolState.fPoolStartVertex;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000302 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000303 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000304 default:
305 GrCrash("unknown geom src type");
reed@google.comac10a2d2010-12-22 21:39:39 +0000306 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000307 draw.fVertexBuffer->ref();
308 draw.fIndexBuffer = NULL;
reed@google.comac10a2d2010-12-22 21:39:39 +0000309}
310
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000311void GrInOrderDrawBuffer::clear(const GrIRect* rect, GrColor color) {
312 GrIRect r;
313 if (NULL == rect) {
314 // We could do something smart and remove previous draws and clears to
315 // the current render target. If we get that smart we have to make sure
316 // those draws aren't read before this clear (render-to-texture).
317 r.setLTRB(0, 0,
318 this->getRenderTarget()->width(),
319 this->getRenderTarget()->height());
320 rect = &r;
321 }
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000322 Clear& clr = fClears.push_back();
323 clr.fColor = color;
324 clr.fBeforeDrawIdx = fDraws.count();
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000325 clr.fRect = *rect;
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000326}
327
reed@google.comac10a2d2010-12-22 21:39:39 +0000328void GrInOrderDrawBuffer::reset() {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000329 GrAssert(1 == fGeoPoolStateStack.count());
330 this->resetVertexSource();
331 this->resetIndexSource();
reed@google.comac10a2d2010-12-22 21:39:39 +0000332 uint32_t numStates = fStates.count();
333 for (uint32_t i = 0; i < numStates; ++i) {
bsalomon@google.com1da07462011-03-10 14:51:57 +0000334 const DrState& dstate = this->accessSavedDrawState(fStates[i]);
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000335 for (int s = 0; s < kNumStages; ++s) {
bsalomon@google.com1da07462011-03-10 14:51:57 +0000336 GrSafeUnref(dstate.fTextures[s]);
reed@google.comac10a2d2010-12-22 21:39:39 +0000337 }
bsalomon@google.com1da07462011-03-10 14:51:57 +0000338 GrSafeUnref(dstate.fRenderTarget);
reed@google.comac10a2d2010-12-22 21:39:39 +0000339 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000340 int numDraws = fDraws.count();
341 for (int d = 0; d < numDraws; ++d) {
342 // we always have a VB, but not always an IB
343 GrAssert(NULL != fDraws[d].fVertexBuffer);
344 fDraws[d].fVertexBuffer->unref();
345 GrSafeUnref(fDraws[d].fIndexBuffer);
346 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000347 fDraws.reset();
348 fStates.reset();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000349
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000350 fClears.reset();
351
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000352 fVertexPool.reset();
353 fIndexPool.reset();
354
reed@google.comac10a2d2010-12-22 21:39:39 +0000355 fClips.reset();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000356
357 fCurrQuad = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000358}
359
360void GrInOrderDrawBuffer::playback(GrDrawTarget* target) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000361 GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fVertexSrc);
362 GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fIndexSrc);
reed@google.comac10a2d2010-12-22 21:39:39 +0000363 GrAssert(NULL != target);
364 GrAssert(target != this); // not considered and why?
365
bsalomon@google.com898d9e52011-04-26 13:22:33 +0000366 int numDraws = fDraws.count();
reed@google.comac10a2d2010-12-22 21:39:39 +0000367 if (!numDraws) {
368 return;
369 }
370
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000371 fVertexPool.unlock();
372 fIndexPool.unlock();
reed@google.comac10a2d2010-12-22 21:39:39 +0000373
374 GrDrawTarget::AutoStateRestore asr(target);
375 GrDrawTarget::AutoClipRestore acr(target);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000376 AutoGeometryPush agp(target);
reed@google.comac10a2d2010-12-22 21:39:39 +0000377
bsalomon@google.com6a77cc52011-04-28 17:33:34 +0000378 int currState = ~0;
379 int currClip = ~0;
380 int currClear = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000381
bsalomon@google.com898d9e52011-04-26 13:22:33 +0000382 for (int i = 0; i < numDraws; ++i) {
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000383 while (currClear < fClears.count() &&
384 i == fClears[currClear].fBeforeDrawIdx) {
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000385 target->clear(&fClears[currClear].fRect, fClears[currClear].fColor);
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000386 ++currClear;
387 }
388
reed@google.comac10a2d2010-12-22 21:39:39 +0000389 const Draw& draw = fDraws[i];
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000390 if (draw.fStateChanged) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000391 ++currState;
392 target->restoreDrawState(fStates[currState]);
393 }
394 if (draw.fClipChanged) {
395 ++currClip;
396 target->setClip(fClips[currClip]);
397 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000398
399 target->setVertexSourceToBuffer(draw.fVertexLayout, draw.fVertexBuffer);
400
reed@google.comac10a2d2010-12-22 21:39:39 +0000401 if (draw.fIndexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000402 target->setIndexSourceToBuffer(draw.fIndexBuffer);
403 }
404
405 if (draw.fIndexCount) {
406 target->drawIndexed(draw.fPrimitiveType,
reed@google.comac10a2d2010-12-22 21:39:39 +0000407 draw.fStartVertex,
408 draw.fStartIndex,
409 draw.fVertexCount,
410 draw.fIndexCount);
411 } else {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000412 target->drawNonIndexed(draw.fPrimitiveType,
reed@google.comac10a2d2010-12-22 21:39:39 +0000413 draw.fStartVertex,
414 draw.fVertexCount);
415 }
416 }
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000417 while (currClear < fClears.count()) {
418 GrAssert(fDraws.count() == fClears[currClear].fBeforeDrawIdx);
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000419 target->clear(&fClears[currClear].fRect, fClears[currClear].fColor);
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000420 ++currClear;
421 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000422}
423
424bool GrInOrderDrawBuffer::geometryHints(GrVertexLayout vertexLayout,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000425 int* vertexCount,
426 int* indexCount) const {
427 // we will recommend a flush if the data could fit in a single
428 // preallocated buffer but none are left and it can't fit
429 // in the current buffer (which may not be prealloced).
reed@google.comac10a2d2010-12-22 21:39:39 +0000430 bool flush = false;
431 if (NULL != indexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000432 int32_t currIndices = fIndexPool.currentBufferIndices();
433 if (*indexCount > currIndices &&
434 (!fIndexPool.preallocatedBuffersRemaining() &&
435 *indexCount <= fIndexPool.preallocatedBufferIndices())) {
436
437 flush = true;
438 }
439 *indexCount = currIndices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000440 }
441 if (NULL != vertexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000442 int32_t currVertices = fVertexPool.currentBufferVertices(vertexLayout);
443 if (*vertexCount > currVertices &&
444 (!fVertexPool.preallocatedBuffersRemaining() &&
445 *vertexCount <= fVertexPool.preallocatedBufferVertices(vertexLayout))) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000446
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000447 flush = true;
reed@google.comac10a2d2010-12-22 21:39:39 +0000448 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000449 *vertexCount = currVertices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000450 }
451 return flush;
452}
453
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000454bool GrInOrderDrawBuffer::onReserveVertexSpace(GrVertexLayout vertexLayout,
455 int vertexCount,
456 void** vertices) {
457 GeometryPoolState& poolState = fGeoPoolStateStack.back();
458 GrAssert(vertexCount > 0);
459 GrAssert(NULL != vertices);
460 GrAssert(0 == poolState.fUsedPoolVertexBytes);
461
462 *vertices = fVertexPool.makeSpace(vertexLayout,
463 vertexCount,
464 &poolState.fPoolVertexBuffer,
465 &poolState.fPoolStartVertex);
466 return NULL != *vertices;
467}
468
469bool GrInOrderDrawBuffer::onReserveIndexSpace(int indexCount, void** indices) {
470 GeometryPoolState& poolState = fGeoPoolStateStack.back();
471 GrAssert(indexCount > 0);
472 GrAssert(NULL != indices);
473 GrAssert(0 == poolState.fUsedPoolIndexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000474
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000475 *indices = fIndexPool.makeSpace(indexCount,
476 &poolState.fPoolIndexBuffer,
477 &poolState.fPoolStartIndex);
478 return NULL != *indices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000479}
480
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000481void GrInOrderDrawBuffer::releaseReservedVertexSpace() {
482 GeometryPoolState& poolState = fGeoPoolStateStack.back();
483 const GeometrySrcState& geoSrc = this->getGeomSrc();
484
485 GrAssert(kReserved_GeometrySrcType == geoSrc.fVertexSrc);
486
487 size_t reservedVertexBytes = VertexSize(geoSrc.fVertexLayout) *
488 geoSrc.fVertexCount;
489 fVertexPool.putBack(reservedVertexBytes -
490 poolState.fUsedPoolVertexBytes);
491 poolState.fUsedPoolVertexBytes = 0;
492 poolState.fPoolVertexBuffer = 0;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000493}
494
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000495void GrInOrderDrawBuffer::releaseReservedIndexSpace() {
496 GeometryPoolState& poolState = fGeoPoolStateStack.back();
497 const GeometrySrcState& geoSrc = this->getGeomSrc();
498
499 GrAssert(kReserved_GeometrySrcType == geoSrc.fIndexSrc);
500
501 size_t reservedIndexBytes = sizeof(uint16_t) * geoSrc.fIndexCount;
502 fIndexPool.putBack(reservedIndexBytes - poolState.fUsedPoolIndexBytes);
503 poolState.fUsedPoolIndexBytes = 0;
504 poolState.fPoolStartVertex = 0;
505}
506
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000507void GrInOrderDrawBuffer::onSetVertexSourceToArray(const void* vertexArray,
508 int vertexCount) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000509
510 GeometryPoolState& poolState = fGeoPoolStateStack.back();
511 GrAssert(0 == poolState.fUsedPoolVertexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000512#if GR_DEBUG
513 bool success =
514#endif
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000515 fVertexPool.appendVertices(this->getGeomSrc().fVertexLayout,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000516 vertexCount,
517 vertexArray,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000518 &poolState.fPoolVertexBuffer,
519 &poolState.fPoolStartVertex);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000520 GR_DEBUGASSERT(success);
521}
522
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000523void GrInOrderDrawBuffer::onSetIndexSourceToArray(const void* indexArray,
524 int indexCount) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000525 GeometryPoolState& poolState = fGeoPoolStateStack.back();
526 GrAssert(0 == poolState.fUsedPoolIndexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000527#if GR_DEBUG
528 bool success =
529#endif
530 fIndexPool.appendIndices(indexCount,
531 indexArray,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000532 &poolState.fPoolIndexBuffer,
533 &poolState.fPoolStartIndex);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000534 GR_DEBUGASSERT(success);
reed@google.comac10a2d2010-12-22 21:39:39 +0000535}
536
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000537void GrInOrderDrawBuffer::geometrySourceWillPush() {
538 GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
539 poolState.fUsedPoolVertexBytes = 0;
540 poolState.fUsedPoolIndexBytes = 0;
541#if GR_DEBUG
542 poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0;
543 poolState.fPoolStartVertex = ~0;
544 poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0;
545 poolState.fPoolStartIndex = ~0;
546#endif
547}
548
549void GrInOrderDrawBuffer::releaseVertexArray() {
550 GeometryPoolState& poolState = fGeoPoolStateStack.back();
551 const GeometrySrcState& geoSrc = this->getGeomSrc();
552
553 size_t reservedVertexBytes = VertexSize(geoSrc.fVertexLayout) *
554 geoSrc.fVertexCount;
555 fVertexPool.putBack(reservedVertexBytes - poolState.fUsedPoolVertexBytes);
556
557 poolState.fUsedPoolVertexBytes = 0;
558}
559
560void GrInOrderDrawBuffer::releaseIndexArray() {
561 GeometryPoolState& poolState = fGeoPoolStateStack.back();
562 const GeometrySrcState& geoSrc = this->getGeomSrc();
563
564 size_t reservedIndexBytes = sizeof(uint16_t) * geoSrc.fIndexCount;
565 fIndexPool.putBack(reservedIndexBytes - poolState.fUsedPoolIndexBytes);
566
567 poolState.fUsedPoolIndexBytes = 0;
568}
569
570void GrInOrderDrawBuffer::geometrySourceWillPop(
571 const GeometrySrcState& restoredState) {
572 GrAssert(fGeoPoolStateStack.count() > 1);
573 fGeoPoolStateStack.pop_back();
574 GeometryPoolState& poolState = fGeoPoolStateStack.back();
575 // we have to assume that any slack we had in our vertex/index data
576 // is now unreleasable because data may have been appended later in the
577 // pool.
578 if (kReserved_GeometrySrcType == restoredState.fVertexSrc ||
579 kArray_GeometrySrcType == restoredState.fVertexSrc) {
580 poolState.fUsedPoolVertexBytes =
581 VertexSize(restoredState.fVertexLayout) *
582 restoredState.fVertexCount;
583 }
584 if (kReserved_GeometrySrcType == restoredState.fIndexSrc ||
585 kArray_GeometrySrcType == restoredState.fIndexSrc) {
586 poolState.fUsedPoolVertexBytes = sizeof(uint16_t) *
587 restoredState.fIndexCount;
588 }
589}
590
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000591bool GrInOrderDrawBuffer::needsNewState() const {
592 if (fStates.empty()) {
593 return true;
594 } else {
595 const DrState& old = this->accessSavedDrawState(fStates.back());
596 return old != fCurrDrawState;
597 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000598}
599
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000600void GrInOrderDrawBuffer::pushState() {
601 for (int s = 0; s < kNumStages; ++s) {
602 GrSafeRef(fCurrDrawState.fTextures[s]);
603 }
bsalomon@google.com1da07462011-03-10 14:51:57 +0000604 GrSafeRef(fCurrDrawState.fRenderTarget);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000605 this->saveCurrentDrawState(&fStates.push_back());
606 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000607
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000608bool GrInOrderDrawBuffer::needsNewClip() const {
609 if (fCurrDrawState.fFlagBits & kClip_StateBit) {
610 if (fClips.empty() || (fClipSet && fClips.back() != fClip)) {
611 return true;
612 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000613 }
614 return false;
615}
bsalomon@google.comd302f142011-03-03 13:54:13 +0000616
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000617void GrInOrderDrawBuffer::pushClip() {
618 fClips.push_back() = fClip;
619 fClipSet = false;
reed@google.comac10a2d2010-12-22 21:39:39 +0000620}
bsalomon@google.comd302f142011-03-03 13:54:13 +0000621
bsalomon@google.comdea2f8d2011-08-01 15:51:05 +0000622void GrInOrderDrawBuffer::clipWillBeSet(const GrClip& newClip) {
623 INHERITED::clipWillBeSet(newClip);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000624 fClipSet = true;
625}
bsalomon@google.com471d4712011-08-23 15:45:25 +0000626
627bool GrInOrderDrawBuffer::willUseHWAALines() const {
bsalomon@google.com18c9c192011-09-22 21:01:31 +0000628 return this->getCaps().fHWAALineSupport &&
bsalomon@google.com471d4712011-08-23 15:45:25 +0000629 CanUseHWAALines(this->getGeomSrc().fVertexLayout, fCurrDrawState);
630}
631