blob: 3d78da398cc65067a6d3f422b8df01f2aa7624cb [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)
bsalomon@google.com92669012011-09-27 19:10:05 +000033 , fIndexPool(*indexPool) {
bsalomon@google.com18c9c192011-09-22 21:01:31 +000034
35 fCaps = gpu->getCaps();
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
40 GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
41 poolState.fUsedPoolVertexBytes = 0;
42 poolState.fUsedPoolIndexBytes = 0;
43#if GR_DEBUG
44 poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0;
45 poolState.fPoolStartVertex = ~0;
46 poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0;
47 poolState.fPoolStartIndex = ~0;
48#endif
reed@google.comac10a2d2010-12-22 21:39:39 +000049}
50
51GrInOrderDrawBuffer::~GrInOrderDrawBuffer() {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000052 this->reset();
53 GrSafeUnref(fQuadIndexBuffer);
reed@google.comac10a2d2010-12-22 21:39:39 +000054}
55
56void GrInOrderDrawBuffer::initializeDrawStateAndClip(const GrDrawTarget& target) {
57 this->copyDrawState(target);
58 this->setClip(target.getClip());
59}
60
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000061void GrInOrderDrawBuffer::setQuadIndexBuffer(const GrIndexBuffer* indexBuffer) {
62 bool newIdxBuffer = fQuadIndexBuffer != indexBuffer;
63 if (newIdxBuffer) {
64 GrSafeUnref(fQuadIndexBuffer);
65 fQuadIndexBuffer = indexBuffer;
66 GrSafeRef(fQuadIndexBuffer);
67 fCurrQuad = 0;
68 fMaxQuads = (NULL == indexBuffer) ? 0 : indexBuffer->maxQuads();
69 } else {
bsalomon@google.comd302f142011-03-03 13:54:13 +000070 GrAssert((NULL == indexBuffer && 0 == fMaxQuads) ||
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000071 (indexBuffer->maxQuads() == fMaxQuads));
72 }
73}
74
bsalomon@google.comd302f142011-03-03 13:54:13 +000075void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000076 const GrMatrix* matrix,
bsalomon@google.comffca4002011-02-22 20:34:01 +000077 StageBitfield stageEnableBitfield,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000078 const GrRect* srcRects[],
79 const GrMatrix* srcMatrices[]) {
bsalomon@google.comd302f142011-03-03 13:54:13 +000080
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000081 GrAssert(!(NULL == fQuadIndexBuffer && fCurrQuad));
82 GrAssert(!(fDraws.empty() && fCurrQuad));
83 GrAssert(!(0 != fMaxQuads && NULL == fQuadIndexBuffer));
84
85 // if we have a quad IB then either append to the previous run of
86 // rects or start a new run
87 if (fMaxQuads) {
bsalomon@google.comd302f142011-03-03 13:54:13 +000088
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000089 bool appendToPreviousDraw = false;
bsalomon@google.comffca4002011-02-22 20:34:01 +000090 GrVertexLayout layout = GetRectVertexLayout(stageEnableBitfield, srcRects);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000091 AutoReleaseGeometry geo(this, layout, 4, 0);
bsalomon@google.com6513cd02011-08-05 20:12:30 +000092 if (!geo.succeeded()) {
93 GrPrintf("Failed to get space for vertices!\n");
94 return;
95 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000096 AutoViewMatrixRestore avmr(this);
97 GrMatrix combinedMatrix = this->getViewMatrix();
98 this->setViewMatrix(GrMatrix::I());
99 if (NULL != matrix) {
100 combinedMatrix.preConcat(*matrix);
101 }
102
103 SetRectVertices(rect, &combinedMatrix, srcRects, srcMatrices, layout, geo.vertices());
104
105 // we don't want to miss an opportunity to batch rects together
106 // simply because the clip has changed if the clip doesn't affect
107 // the rect.
108 bool disabledClip = false;
109 if (this->isClipState() && fClip.isRect()) {
bsalomon@google.comd302f142011-03-03 13:54:13 +0000110
bsalomon@google.com0b50b2e2011-03-08 21:07:21 +0000111 GrRect clipRect = fClip.getRect(0);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000112 // If the clip rect touches the edge of the viewport, extended it
113 // out (close) to infinity to avoid bogus intersections.
bsalomon@google.comd302f142011-03-03 13:54:13 +0000114 // We might consider a more exact clip to viewport if this
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000115 // conservative test fails.
116 const GrRenderTarget* target = this->getRenderTarget();
117 if (0 >= clipRect.fLeft) {
118 clipRect.fLeft = GR_ScalarMin;
119 }
120 if (target->width() <= clipRect.fRight) {
121 clipRect.fRight = GR_ScalarMax;
122 }
123 if (0 >= clipRect.top()) {
124 clipRect.fTop = GR_ScalarMin;
125 }
126 if (target->height() <= clipRect.fBottom) {
127 clipRect.fBottom = GR_ScalarMax;
128 }
129 int stride = VertexSize(layout);
130 bool insideClip = true;
131 for (int v = 0; v < 4; ++v) {
132 const GrPoint& p = *GetVertexPoint(geo.vertices(), v, stride);
133 if (!clipRect.contains(p)) {
134 insideClip = false;
135 break;
136 }
137 }
138 if (insideClip) {
139 this->disableState(kClip_StateBit);
140 disabledClip = true;
141 }
142 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000143 if (!needsNewClip() && !needsNewState() && fCurrQuad > 0 &&
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000144 fCurrQuad < fMaxQuads && layout == fLastRectVertexLayout) {
145
146 int vsize = VertexSize(layout);
bsalomon@google.comd302f142011-03-03 13:54:13 +0000147
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000148 Draw& lastDraw = fDraws.back();
149
150 GrAssert(lastDraw.fIndexBuffer == fQuadIndexBuffer);
151 GrAssert(kTriangles_PrimitiveType == lastDraw.fPrimitiveType);
152 GrAssert(0 == lastDraw.fVertexCount % 4);
153 GrAssert(0 == lastDraw.fIndexCount % 6);
154 GrAssert(0 == lastDraw.fStartIndex);
155
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000156 GeometryPoolState& poolState = fGeoPoolStateStack.back();
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000157 bool clearSinceLastDraw =
158 fClears.count() &&
159 fClears.back().fBeforeDrawIdx == fDraws.count();
160
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000161 appendToPreviousDraw =
162 !clearSinceLastDraw &&
163 lastDraw.fVertexBuffer == poolState.fPoolVertexBuffer &&
164 (fCurrQuad * 4 + lastDraw.fStartVertex) == poolState.fPoolStartVertex;
165
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000166 if (appendToPreviousDraw) {
167 lastDraw.fVertexCount += 4;
168 lastDraw.fIndexCount += 6;
169 fCurrQuad += 1;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000170 // we reserved above, so we should be the first
171 // use of this vertex reserveation.
172 GrAssert(0 == poolState.fUsedPoolVertexBytes);
173 poolState.fUsedPoolVertexBytes = 4 * vsize;
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000174 }
175 }
176 if (!appendToPreviousDraw) {
177 this->setIndexSourceToBuffer(fQuadIndexBuffer);
178 drawIndexed(kTriangles_PrimitiveType, 0, 0, 4, 6);
179 fCurrQuad = 1;
180 fLastRectVertexLayout = layout;
181 }
182 if (disabledClip) {
183 this->enableState(kClip_StateBit);
184 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000185 } else {
bsalomon@google.comffca4002011-02-22 20:34:01 +0000186 INHERITED::drawRect(rect, matrix, stageEnableBitfield, srcRects, srcMatrices);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000187 }
188}
189
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000190void GrInOrderDrawBuffer::onDrawIndexed(GrPrimitiveType primitiveType,
191 int startVertex,
192 int startIndex,
193 int vertexCount,
194 int indexCount) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000195
196 if (!vertexCount || !indexCount) {
197 return;
198 }
199
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000200 fCurrQuad = 0;
201
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000202 GeometryPoolState& poolState = fGeoPoolStateStack.back();
203
reed@google.comac10a2d2010-12-22 21:39:39 +0000204 Draw& draw = fDraws.push_back();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000205 draw.fPrimitiveType = primitiveType;
reed@google.comac10a2d2010-12-22 21:39:39 +0000206 draw.fStartVertex = startVertex;
207 draw.fStartIndex = startIndex;
208 draw.fVertexCount = vertexCount;
209 draw.fIndexCount = indexCount;
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000210
211 draw.fClipChanged = this->needsNewClip();
212 if (draw.fClipChanged) {
213 this->pushClip();
214 }
215
216 draw.fStateChanged = this->needsNewState();
217 if (draw.fStateChanged) {
218 this->pushState();
219 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000220
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000221 draw.fVertexLayout = this->getGeomSrc().fVertexLayout;
222 switch (this->getGeomSrc().fVertexSrc) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000223 case kBuffer_GeometrySrcType:
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000224 draw.fVertexBuffer = this->getGeomSrc().fVertexBuffer;
reed@google.comac10a2d2010-12-22 21:39:39 +0000225 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000226 case kReserved_GeometrySrcType: // fallthrough
227 case kArray_GeometrySrcType: {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000228 size_t vertexBytes = (vertexCount + startVertex) *
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000229 VertexSize(this->getGeomSrc().fVertexLayout);
230 poolState.fUsedPoolVertexBytes =
231 GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
232 draw.fVertexBuffer = poolState.fPoolVertexBuffer;
233 draw.fStartVertex += poolState.fPoolStartVertex;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000234 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000235 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000236 default:
237 GrCrash("unknown geom src type");
reed@google.comac10a2d2010-12-22 21:39:39 +0000238 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000239 draw.fVertexBuffer->ref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000240
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000241 switch (this->getGeomSrc().fIndexSrc) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000242 case kBuffer_GeometrySrcType:
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000243 draw.fIndexBuffer = this->getGeomSrc().fIndexBuffer;
reed@google.comac10a2d2010-12-22 21:39:39 +0000244 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000245 case kReserved_GeometrySrcType: // fallthrough
246 case kArray_GeometrySrcType: {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000247 size_t indexBytes = (indexCount + startIndex) * sizeof(uint16_t);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000248 poolState.fUsedPoolIndexBytes =
249 GrMax(poolState.fUsedPoolIndexBytes, indexBytes);
250 draw.fIndexBuffer = poolState.fPoolIndexBuffer;
251 draw.fStartIndex += poolState.fPoolStartVertex;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000252 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000253 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000254 default:
255 GrCrash("unknown geom src type");
reed@google.comac10a2d2010-12-22 21:39:39 +0000256 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000257 draw.fIndexBuffer->ref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000258}
259
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000260void GrInOrderDrawBuffer::onDrawNonIndexed(GrPrimitiveType primitiveType,
261 int startVertex,
262 int vertexCount) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000263 if (!vertexCount) {
264 return;
265 }
266
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000267 fCurrQuad = 0;
268
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000269 GeometryPoolState& poolState = fGeoPoolStateStack.back();
270
reed@google.comac10a2d2010-12-22 21:39:39 +0000271 Draw& draw = fDraws.push_back();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000272 draw.fPrimitiveType = primitiveType;
reed@google.comac10a2d2010-12-22 21:39:39 +0000273 draw.fStartVertex = startVertex;
274 draw.fStartIndex = 0;
275 draw.fVertexCount = vertexCount;
276 draw.fIndexCount = 0;
277
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000278 draw.fClipChanged = this->needsNewClip();
279 if (draw.fClipChanged) {
280 this->pushClip();
281 }
282
283 draw.fStateChanged = this->needsNewState();
284 if (draw.fStateChanged) {
285 this->pushState();
286 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000287
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000288 draw.fVertexLayout = this->getGeomSrc().fVertexLayout;
289 switch (this->getGeomSrc().fVertexSrc) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000290 case kBuffer_GeometrySrcType:
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000291 draw.fVertexBuffer = this->getGeomSrc().fVertexBuffer;
reed@google.comac10a2d2010-12-22 21:39:39 +0000292 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000293 case kReserved_GeometrySrcType: // fallthrough
294 case kArray_GeometrySrcType: {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000295 size_t vertexBytes = (vertexCount + startVertex) *
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000296 VertexSize(this->getGeomSrc().fVertexLayout);
297 poolState.fUsedPoolVertexBytes =
298 GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
299 draw.fVertexBuffer = poolState.fPoolVertexBuffer;
300 draw.fStartVertex += poolState.fPoolStartVertex;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000301 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000302 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000303 default:
304 GrCrash("unknown geom src type");
reed@google.comac10a2d2010-12-22 21:39:39 +0000305 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000306 draw.fVertexBuffer->ref();
307 draw.fIndexBuffer = NULL;
reed@google.comac10a2d2010-12-22 21:39:39 +0000308}
309
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000310void GrInOrderDrawBuffer::clear(const GrIRect* rect, GrColor color) {
311 GrIRect r;
312 if (NULL == rect) {
313 // We could do something smart and remove previous draws and clears to
314 // the current render target. If we get that smart we have to make sure
315 // those draws aren't read before this clear (render-to-texture).
316 r.setLTRB(0, 0,
317 this->getRenderTarget()->width(),
318 this->getRenderTarget()->height());
319 rect = &r;
320 }
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000321 Clear& clr = fClears.push_back();
322 clr.fColor = color;
323 clr.fBeforeDrawIdx = fDraws.count();
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000324 clr.fRect = *rect;
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000325}
326
reed@google.comac10a2d2010-12-22 21:39:39 +0000327void GrInOrderDrawBuffer::reset() {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000328 GrAssert(1 == fGeoPoolStateStack.count());
329 this->resetVertexSource();
330 this->resetIndexSource();
reed@google.comac10a2d2010-12-22 21:39:39 +0000331 uint32_t numStates = fStates.count();
332 for (uint32_t i = 0; i < numStates; ++i) {
bsalomon@google.com1da07462011-03-10 14:51:57 +0000333 const DrState& dstate = this->accessSavedDrawState(fStates[i]);
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000334 for (int s = 0; s < kNumStages; ++s) {
bsalomon@google.com1da07462011-03-10 14:51:57 +0000335 GrSafeUnref(dstate.fTextures[s]);
reed@google.comac10a2d2010-12-22 21:39:39 +0000336 }
bsalomon@google.com1da07462011-03-10 14:51:57 +0000337 GrSafeUnref(dstate.fRenderTarget);
reed@google.comac10a2d2010-12-22 21:39:39 +0000338 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000339 int numDraws = fDraws.count();
340 for (int d = 0; d < numDraws; ++d) {
341 // we always have a VB, but not always an IB
342 GrAssert(NULL != fDraws[d].fVertexBuffer);
343 fDraws[d].fVertexBuffer->unref();
344 GrSafeUnref(fDraws[d].fIndexBuffer);
345 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000346 fDraws.reset();
347 fStates.reset();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000348
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000349 fClears.reset();
350
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000351 fVertexPool.reset();
352 fIndexPool.reset();
353
reed@google.comac10a2d2010-12-22 21:39:39 +0000354 fClips.reset();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000355
356 fCurrQuad = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000357}
358
359void GrInOrderDrawBuffer::playback(GrDrawTarget* target) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000360 GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fVertexSrc);
361 GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fIndexSrc);
reed@google.comac10a2d2010-12-22 21:39:39 +0000362 GrAssert(NULL != target);
363 GrAssert(target != this); // not considered and why?
364
bsalomon@google.com898d9e52011-04-26 13:22:33 +0000365 int numDraws = fDraws.count();
reed@google.comac10a2d2010-12-22 21:39:39 +0000366 if (!numDraws) {
367 return;
368 }
369
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000370 fVertexPool.unlock();
371 fIndexPool.unlock();
reed@google.comac10a2d2010-12-22 21:39:39 +0000372
373 GrDrawTarget::AutoStateRestore asr(target);
374 GrDrawTarget::AutoClipRestore acr(target);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000375 AutoGeometryPush agp(target);
reed@google.comac10a2d2010-12-22 21:39:39 +0000376
bsalomon@google.com6a77cc52011-04-28 17:33:34 +0000377 int currState = ~0;
378 int currClip = ~0;
379 int currClear = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000380
bsalomon@google.com898d9e52011-04-26 13:22:33 +0000381 for (int i = 0; i < numDraws; ++i) {
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000382 while (currClear < fClears.count() &&
383 i == fClears[currClear].fBeforeDrawIdx) {
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000384 target->clear(&fClears[currClear].fRect, fClears[currClear].fColor);
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000385 ++currClear;
386 }
387
reed@google.comac10a2d2010-12-22 21:39:39 +0000388 const Draw& draw = fDraws[i];
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000389 if (draw.fStateChanged) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000390 ++currState;
391 target->restoreDrawState(fStates[currState]);
392 }
393 if (draw.fClipChanged) {
394 ++currClip;
395 target->setClip(fClips[currClip]);
396 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000397
398 target->setVertexSourceToBuffer(draw.fVertexLayout, draw.fVertexBuffer);
399
reed@google.comac10a2d2010-12-22 21:39:39 +0000400 if (draw.fIndexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000401 target->setIndexSourceToBuffer(draw.fIndexBuffer);
402 }
403
404 if (draw.fIndexCount) {
405 target->drawIndexed(draw.fPrimitiveType,
reed@google.comac10a2d2010-12-22 21:39:39 +0000406 draw.fStartVertex,
407 draw.fStartIndex,
408 draw.fVertexCount,
409 draw.fIndexCount);
410 } else {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000411 target->drawNonIndexed(draw.fPrimitiveType,
reed@google.comac10a2d2010-12-22 21:39:39 +0000412 draw.fStartVertex,
413 draw.fVertexCount);
414 }
415 }
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000416 while (currClear < fClears.count()) {
417 GrAssert(fDraws.count() == fClears[currClear].fBeforeDrawIdx);
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000418 target->clear(&fClears[currClear].fRect, fClears[currClear].fColor);
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000419 ++currClear;
420 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000421}
422
423bool GrInOrderDrawBuffer::geometryHints(GrVertexLayout vertexLayout,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000424 int* vertexCount,
425 int* indexCount) const {
426 // we will recommend a flush if the data could fit in a single
427 // preallocated buffer but none are left and it can't fit
428 // in the current buffer (which may not be prealloced).
reed@google.comac10a2d2010-12-22 21:39:39 +0000429 bool flush = false;
430 if (NULL != indexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000431 int32_t currIndices = fIndexPool.currentBufferIndices();
432 if (*indexCount > currIndices &&
433 (!fIndexPool.preallocatedBuffersRemaining() &&
434 *indexCount <= fIndexPool.preallocatedBufferIndices())) {
435
436 flush = true;
437 }
438 *indexCount = currIndices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000439 }
440 if (NULL != vertexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000441 int32_t currVertices = fVertexPool.currentBufferVertices(vertexLayout);
442 if (*vertexCount > currVertices &&
443 (!fVertexPool.preallocatedBuffersRemaining() &&
444 *vertexCount <= fVertexPool.preallocatedBufferVertices(vertexLayout))) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000445
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000446 flush = true;
reed@google.comac10a2d2010-12-22 21:39:39 +0000447 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000448 *vertexCount = currVertices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000449 }
450 return flush;
451}
452
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000453bool GrInOrderDrawBuffer::onReserveVertexSpace(GrVertexLayout vertexLayout,
454 int vertexCount,
455 void** vertices) {
456 GeometryPoolState& poolState = fGeoPoolStateStack.back();
457 GrAssert(vertexCount > 0);
458 GrAssert(NULL != vertices);
459 GrAssert(0 == poolState.fUsedPoolVertexBytes);
460
461 *vertices = fVertexPool.makeSpace(vertexLayout,
462 vertexCount,
463 &poolState.fPoolVertexBuffer,
464 &poolState.fPoolStartVertex);
465 return NULL != *vertices;
466}
467
468bool GrInOrderDrawBuffer::onReserveIndexSpace(int indexCount, void** indices) {
469 GeometryPoolState& poolState = fGeoPoolStateStack.back();
470 GrAssert(indexCount > 0);
471 GrAssert(NULL != indices);
472 GrAssert(0 == poolState.fUsedPoolIndexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000473
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000474 *indices = fIndexPool.makeSpace(indexCount,
475 &poolState.fPoolIndexBuffer,
476 &poolState.fPoolStartIndex);
477 return NULL != *indices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000478}
479
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000480void GrInOrderDrawBuffer::releaseReservedVertexSpace() {
481 GeometryPoolState& poolState = fGeoPoolStateStack.back();
482 const GeometrySrcState& geoSrc = this->getGeomSrc();
483
484 GrAssert(kReserved_GeometrySrcType == geoSrc.fVertexSrc);
485
486 size_t reservedVertexBytes = VertexSize(geoSrc.fVertexLayout) *
487 geoSrc.fVertexCount;
488 fVertexPool.putBack(reservedVertexBytes -
489 poolState.fUsedPoolVertexBytes);
490 poolState.fUsedPoolVertexBytes = 0;
491 poolState.fPoolVertexBuffer = 0;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000492}
493
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000494void GrInOrderDrawBuffer::releaseReservedIndexSpace() {
495 GeometryPoolState& poolState = fGeoPoolStateStack.back();
496 const GeometrySrcState& geoSrc = this->getGeomSrc();
497
498 GrAssert(kReserved_GeometrySrcType == geoSrc.fIndexSrc);
499
500 size_t reservedIndexBytes = sizeof(uint16_t) * geoSrc.fIndexCount;
501 fIndexPool.putBack(reservedIndexBytes - poolState.fUsedPoolIndexBytes);
502 poolState.fUsedPoolIndexBytes = 0;
503 poolState.fPoolStartVertex = 0;
504}
505
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000506void GrInOrderDrawBuffer::onSetVertexSourceToArray(const void* vertexArray,
507 int vertexCount) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000508
509 GeometryPoolState& poolState = fGeoPoolStateStack.back();
510 GrAssert(0 == poolState.fUsedPoolVertexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000511#if GR_DEBUG
512 bool success =
513#endif
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000514 fVertexPool.appendVertices(this->getGeomSrc().fVertexLayout,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000515 vertexCount,
516 vertexArray,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000517 &poolState.fPoolVertexBuffer,
518 &poolState.fPoolStartVertex);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000519 GR_DEBUGASSERT(success);
520}
521
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000522void GrInOrderDrawBuffer::onSetIndexSourceToArray(const void* indexArray,
523 int indexCount) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000524 GeometryPoolState& poolState = fGeoPoolStateStack.back();
525 GrAssert(0 == poolState.fUsedPoolIndexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000526#if GR_DEBUG
527 bool success =
528#endif
529 fIndexPool.appendIndices(indexCount,
530 indexArray,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000531 &poolState.fPoolIndexBuffer,
532 &poolState.fPoolStartIndex);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000533 GR_DEBUGASSERT(success);
reed@google.comac10a2d2010-12-22 21:39:39 +0000534}
535
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000536void GrInOrderDrawBuffer::geometrySourceWillPush() {
537 GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
538 poolState.fUsedPoolVertexBytes = 0;
539 poolState.fUsedPoolIndexBytes = 0;
540#if GR_DEBUG
541 poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0;
542 poolState.fPoolStartVertex = ~0;
543 poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0;
544 poolState.fPoolStartIndex = ~0;
545#endif
546}
547
548void GrInOrderDrawBuffer::releaseVertexArray() {
549 GeometryPoolState& poolState = fGeoPoolStateStack.back();
550 const GeometrySrcState& geoSrc = this->getGeomSrc();
551
552 size_t reservedVertexBytes = VertexSize(geoSrc.fVertexLayout) *
553 geoSrc.fVertexCount;
554 fVertexPool.putBack(reservedVertexBytes - poolState.fUsedPoolVertexBytes);
555
556 poolState.fUsedPoolVertexBytes = 0;
557}
558
559void GrInOrderDrawBuffer::releaseIndexArray() {
560 GeometryPoolState& poolState = fGeoPoolStateStack.back();
561 const GeometrySrcState& geoSrc = this->getGeomSrc();
562
563 size_t reservedIndexBytes = sizeof(uint16_t) * geoSrc.fIndexCount;
564 fIndexPool.putBack(reservedIndexBytes - poolState.fUsedPoolIndexBytes);
565
566 poolState.fUsedPoolIndexBytes = 0;
567}
568
569void GrInOrderDrawBuffer::geometrySourceWillPop(
570 const GeometrySrcState& restoredState) {
571 GrAssert(fGeoPoolStateStack.count() > 1);
572 fGeoPoolStateStack.pop_back();
573 GeometryPoolState& poolState = fGeoPoolStateStack.back();
574 // we have to assume that any slack we had in our vertex/index data
575 // is now unreleasable because data may have been appended later in the
576 // pool.
577 if (kReserved_GeometrySrcType == restoredState.fVertexSrc ||
578 kArray_GeometrySrcType == restoredState.fVertexSrc) {
579 poolState.fUsedPoolVertexBytes =
580 VertexSize(restoredState.fVertexLayout) *
581 restoredState.fVertexCount;
582 }
583 if (kReserved_GeometrySrcType == restoredState.fIndexSrc ||
584 kArray_GeometrySrcType == restoredState.fIndexSrc) {
585 poolState.fUsedPoolVertexBytes = sizeof(uint16_t) *
586 restoredState.fIndexCount;
587 }
588}
589
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000590bool GrInOrderDrawBuffer::needsNewState() const {
591 if (fStates.empty()) {
592 return true;
593 } else {
594 const DrState& old = this->accessSavedDrawState(fStates.back());
595 return old != fCurrDrawState;
596 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000597}
598
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000599void GrInOrderDrawBuffer::pushState() {
600 for (int s = 0; s < kNumStages; ++s) {
601 GrSafeRef(fCurrDrawState.fTextures[s]);
602 }
bsalomon@google.com1da07462011-03-10 14:51:57 +0000603 GrSafeRef(fCurrDrawState.fRenderTarget);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000604 this->saveCurrentDrawState(&fStates.push_back());
605 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000606
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000607bool GrInOrderDrawBuffer::needsNewClip() const {
608 if (fCurrDrawState.fFlagBits & kClip_StateBit) {
609 if (fClips.empty() || (fClipSet && fClips.back() != fClip)) {
610 return true;
611 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000612 }
613 return false;
614}
bsalomon@google.comd302f142011-03-03 13:54:13 +0000615
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000616void GrInOrderDrawBuffer::pushClip() {
617 fClips.push_back() = fClip;
618 fClipSet = false;
reed@google.comac10a2d2010-12-22 21:39:39 +0000619}
bsalomon@google.comd302f142011-03-03 13:54:13 +0000620
bsalomon@google.comdea2f8d2011-08-01 15:51:05 +0000621void GrInOrderDrawBuffer::clipWillBeSet(const GrClip& newClip) {
622 INHERITED::clipWillBeSet(newClip);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000623 fClipSet = true;
624}
bsalomon@google.com471d4712011-08-23 15:45:25 +0000625
626bool GrInOrderDrawBuffer::willUseHWAALines() const {
bsalomon@google.com18c9c192011-09-22 21:01:31 +0000627 return this->getCaps().fHWAALineSupport &&
bsalomon@google.com471d4712011-08-23 15:45:25 +0000628 CanUseHWAALines(this->getGeomSrc().fVertexLayout, fCurrDrawState);
629}
630