blob: 340cff18f3e0469b364bedd5663173a2128df059 [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();
bsalomon@google.com4a018bb2011-10-28 19:50:21 +000047 // This must be called by before the GrDrawTarget destructor
48 this->releaseGeometry();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000049 GrSafeUnref(fQuadIndexBuffer);
reed@google.comac10a2d2010-12-22 21:39:39 +000050}
51
52void GrInOrderDrawBuffer::initializeDrawStateAndClip(const GrDrawTarget& target) {
53 this->copyDrawState(target);
54 this->setClip(target.getClip());
55}
56
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000057void GrInOrderDrawBuffer::setQuadIndexBuffer(const GrIndexBuffer* indexBuffer) {
58 bool newIdxBuffer = fQuadIndexBuffer != indexBuffer;
59 if (newIdxBuffer) {
60 GrSafeUnref(fQuadIndexBuffer);
61 fQuadIndexBuffer = indexBuffer;
62 GrSafeRef(fQuadIndexBuffer);
63 fCurrQuad = 0;
64 fMaxQuads = (NULL == indexBuffer) ? 0 : indexBuffer->maxQuads();
65 } else {
bsalomon@google.comd302f142011-03-03 13:54:13 +000066 GrAssert((NULL == indexBuffer && 0 == fMaxQuads) ||
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000067 (indexBuffer->maxQuads() == fMaxQuads));
68 }
69}
70
bsalomon@google.comd302f142011-03-03 13:54:13 +000071void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000072 const GrMatrix* matrix,
bsalomon@google.com39ee0ff2011-12-06 15:32:52 +000073 StageMask stageMask,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000074 const GrRect* srcRects[],
75 const GrMatrix* srcMatrices[]) {
bsalomon@google.comd302f142011-03-03 13:54:13 +000076
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000077 GrAssert(!(NULL == fQuadIndexBuffer && fCurrQuad));
78 GrAssert(!(fDraws.empty() && fCurrQuad));
79 GrAssert(!(0 != fMaxQuads && NULL == fQuadIndexBuffer));
80
81 // if we have a quad IB then either append to the previous run of
82 // rects or start a new run
83 if (fMaxQuads) {
bsalomon@google.comd302f142011-03-03 13:54:13 +000084
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000085 bool appendToPreviousDraw = false;
bsalomon@google.com39ee0ff2011-12-06 15:32:52 +000086 GrVertexLayout layout = GetRectVertexLayout(stageMask, srcRects);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000087 AutoReleaseGeometry geo(this, layout, 4, 0);
bsalomon@google.com6513cd02011-08-05 20:12:30 +000088 if (!geo.succeeded()) {
89 GrPrintf("Failed to get space for vertices!\n");
90 return;
91 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000092 AutoViewMatrixRestore avmr(this);
93 GrMatrix combinedMatrix = this->getViewMatrix();
94 this->setViewMatrix(GrMatrix::I());
95 if (NULL != matrix) {
96 combinedMatrix.preConcat(*matrix);
97 }
98
99 SetRectVertices(rect, &combinedMatrix, srcRects, srcMatrices, layout, geo.vertices());
100
101 // we don't want to miss an opportunity to batch rects together
102 // simply because the clip has changed if the clip doesn't affect
103 // the rect.
104 bool disabledClip = false;
105 if (this->isClipState() && fClip.isRect()) {
bsalomon@google.comd302f142011-03-03 13:54:13 +0000106
bsalomon@google.com0b50b2e2011-03-08 21:07:21 +0000107 GrRect clipRect = fClip.getRect(0);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000108 // If the clip rect touches the edge of the viewport, extended it
109 // out (close) to infinity to avoid bogus intersections.
bsalomon@google.comd302f142011-03-03 13:54:13 +0000110 // We might consider a more exact clip to viewport if this
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000111 // conservative test fails.
112 const GrRenderTarget* target = this->getRenderTarget();
113 if (0 >= clipRect.fLeft) {
114 clipRect.fLeft = GR_ScalarMin;
115 }
116 if (target->width() <= clipRect.fRight) {
117 clipRect.fRight = GR_ScalarMax;
118 }
119 if (0 >= clipRect.top()) {
120 clipRect.fTop = GR_ScalarMin;
121 }
122 if (target->height() <= clipRect.fBottom) {
123 clipRect.fBottom = GR_ScalarMax;
124 }
125 int stride = VertexSize(layout);
126 bool insideClip = true;
127 for (int v = 0; v < 4; ++v) {
128 const GrPoint& p = *GetVertexPoint(geo.vertices(), v, stride);
129 if (!clipRect.contains(p)) {
130 insideClip = false;
131 break;
132 }
133 }
134 if (insideClip) {
135 this->disableState(kClip_StateBit);
136 disabledClip = true;
137 }
138 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000139 if (!needsNewClip() && !needsNewState() && fCurrQuad > 0 &&
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000140 fCurrQuad < fMaxQuads && layout == fLastRectVertexLayout) {
141
142 int vsize = VertexSize(layout);
bsalomon@google.comd302f142011-03-03 13:54:13 +0000143
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000144 Draw& lastDraw = fDraws.back();
145
146 GrAssert(lastDraw.fIndexBuffer == fQuadIndexBuffer);
147 GrAssert(kTriangles_PrimitiveType == lastDraw.fPrimitiveType);
148 GrAssert(0 == lastDraw.fVertexCount % 4);
149 GrAssert(0 == lastDraw.fIndexCount % 6);
150 GrAssert(0 == lastDraw.fStartIndex);
151
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000152 GeometryPoolState& poolState = fGeoPoolStateStack.back();
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000153 bool clearSinceLastDraw =
154 fClears.count() &&
155 fClears.back().fBeforeDrawIdx == fDraws.count();
156
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000157 appendToPreviousDraw =
158 !clearSinceLastDraw &&
159 lastDraw.fVertexBuffer == poolState.fPoolVertexBuffer &&
160 (fCurrQuad * 4 + lastDraw.fStartVertex) == poolState.fPoolStartVertex;
161
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000162 if (appendToPreviousDraw) {
163 lastDraw.fVertexCount += 4;
164 lastDraw.fIndexCount += 6;
165 fCurrQuad += 1;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000166 // we reserved above, so we should be the first
167 // use of this vertex reserveation.
168 GrAssert(0 == poolState.fUsedPoolVertexBytes);
169 poolState.fUsedPoolVertexBytes = 4 * vsize;
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000170 }
171 }
172 if (!appendToPreviousDraw) {
173 this->setIndexSourceToBuffer(fQuadIndexBuffer);
174 drawIndexed(kTriangles_PrimitiveType, 0, 0, 4, 6);
175 fCurrQuad = 1;
176 fLastRectVertexLayout = layout;
177 }
178 if (disabledClip) {
179 this->enableState(kClip_StateBit);
180 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000181 } else {
bsalomon@google.com39ee0ff2011-12-06 15:32:52 +0000182 INHERITED::drawRect(rect, matrix, stageMask, srcRects, srcMatrices);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000183 }
184}
185
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000186void GrInOrderDrawBuffer::onDrawIndexed(GrPrimitiveType primitiveType,
187 int startVertex,
188 int startIndex,
189 int vertexCount,
190 int indexCount) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000191
192 if (!vertexCount || !indexCount) {
193 return;
194 }
195
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000196 fCurrQuad = 0;
197
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000198 GeometryPoolState& poolState = fGeoPoolStateStack.back();
199
reed@google.comac10a2d2010-12-22 21:39:39 +0000200 Draw& draw = fDraws.push_back();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000201 draw.fPrimitiveType = primitiveType;
reed@google.comac10a2d2010-12-22 21:39:39 +0000202 draw.fStartVertex = startVertex;
203 draw.fStartIndex = startIndex;
204 draw.fVertexCount = vertexCount;
205 draw.fIndexCount = indexCount;
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000206
207 draw.fClipChanged = this->needsNewClip();
208 if (draw.fClipChanged) {
209 this->pushClip();
210 }
211
212 draw.fStateChanged = this->needsNewState();
213 if (draw.fStateChanged) {
214 this->pushState();
215 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000216
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000217 draw.fVertexLayout = this->getGeomSrc().fVertexLayout;
218 switch (this->getGeomSrc().fVertexSrc) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000219 case kBuffer_GeometrySrcType:
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000220 draw.fVertexBuffer = this->getGeomSrc().fVertexBuffer;
reed@google.comac10a2d2010-12-22 21:39:39 +0000221 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000222 case kReserved_GeometrySrcType: // fallthrough
223 case kArray_GeometrySrcType: {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000224 size_t vertexBytes = (vertexCount + startVertex) *
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000225 VertexSize(this->getGeomSrc().fVertexLayout);
226 poolState.fUsedPoolVertexBytes =
227 GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
228 draw.fVertexBuffer = poolState.fPoolVertexBuffer;
229 draw.fStartVertex += poolState.fPoolStartVertex;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000230 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000231 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000232 default:
233 GrCrash("unknown geom src type");
reed@google.comac10a2d2010-12-22 21:39:39 +0000234 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000235 draw.fVertexBuffer->ref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000236
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000237 switch (this->getGeomSrc().fIndexSrc) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000238 case kBuffer_GeometrySrcType:
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000239 draw.fIndexBuffer = this->getGeomSrc().fIndexBuffer;
reed@google.comac10a2d2010-12-22 21:39:39 +0000240 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000241 case kReserved_GeometrySrcType: // fallthrough
242 case kArray_GeometrySrcType: {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000243 size_t indexBytes = (indexCount + startIndex) * sizeof(uint16_t);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000244 poolState.fUsedPoolIndexBytes =
245 GrMax(poolState.fUsedPoolIndexBytes, indexBytes);
246 draw.fIndexBuffer = poolState.fPoolIndexBuffer;
247 draw.fStartIndex += poolState.fPoolStartVertex;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000248 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000249 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000250 default:
251 GrCrash("unknown geom src type");
reed@google.comac10a2d2010-12-22 21:39:39 +0000252 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000253 draw.fIndexBuffer->ref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000254}
255
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000256void GrInOrderDrawBuffer::onDrawNonIndexed(GrPrimitiveType primitiveType,
257 int startVertex,
258 int vertexCount) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000259 if (!vertexCount) {
260 return;
261 }
262
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000263 fCurrQuad = 0;
264
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000265 GeometryPoolState& poolState = fGeoPoolStateStack.back();
266
reed@google.comac10a2d2010-12-22 21:39:39 +0000267 Draw& draw = fDraws.push_back();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000268 draw.fPrimitiveType = primitiveType;
reed@google.comac10a2d2010-12-22 21:39:39 +0000269 draw.fStartVertex = startVertex;
270 draw.fStartIndex = 0;
271 draw.fVertexCount = vertexCount;
272 draw.fIndexCount = 0;
273
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000274 draw.fClipChanged = this->needsNewClip();
275 if (draw.fClipChanged) {
276 this->pushClip();
277 }
278
279 draw.fStateChanged = this->needsNewState();
280 if (draw.fStateChanged) {
281 this->pushState();
282 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000283
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000284 draw.fVertexLayout = this->getGeomSrc().fVertexLayout;
285 switch (this->getGeomSrc().fVertexSrc) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000286 case kBuffer_GeometrySrcType:
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000287 draw.fVertexBuffer = this->getGeomSrc().fVertexBuffer;
reed@google.comac10a2d2010-12-22 21:39:39 +0000288 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000289 case kReserved_GeometrySrcType: // fallthrough
290 case kArray_GeometrySrcType: {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000291 size_t vertexBytes = (vertexCount + startVertex) *
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000292 VertexSize(this->getGeomSrc().fVertexLayout);
293 poolState.fUsedPoolVertexBytes =
294 GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
295 draw.fVertexBuffer = poolState.fPoolVertexBuffer;
296 draw.fStartVertex += poolState.fPoolStartVertex;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000297 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000298 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000299 default:
300 GrCrash("unknown geom src type");
reed@google.comac10a2d2010-12-22 21:39:39 +0000301 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000302 draw.fVertexBuffer->ref();
303 draw.fIndexBuffer = NULL;
reed@google.comac10a2d2010-12-22 21:39:39 +0000304}
305
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000306void GrInOrderDrawBuffer::clear(const GrIRect* rect, GrColor color) {
307 GrIRect r;
308 if (NULL == rect) {
309 // We could do something smart and remove previous draws and clears to
310 // the current render target. If we get that smart we have to make sure
311 // those draws aren't read before this clear (render-to-texture).
312 r.setLTRB(0, 0,
313 this->getRenderTarget()->width(),
314 this->getRenderTarget()->height());
315 rect = &r;
316 }
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000317 Clear& clr = fClears.push_back();
318 clr.fColor = color;
319 clr.fBeforeDrawIdx = fDraws.count();
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000320 clr.fRect = *rect;
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000321}
322
reed@google.comac10a2d2010-12-22 21:39:39 +0000323void GrInOrderDrawBuffer::reset() {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000324 GrAssert(1 == fGeoPoolStateStack.count());
325 this->resetVertexSource();
326 this->resetIndexSource();
reed@google.comac10a2d2010-12-22 21:39:39 +0000327 uint32_t numStates = fStates.count();
328 for (uint32_t i = 0; i < numStates; ++i) {
tomhudson@google.com93813632011-10-27 20:21:16 +0000329 const GrDrawState& dstate = this->accessSavedDrawState(fStates[i]);
330 for (int s = 0; s < GrDrawState::kNumStages; ++s) {
bsalomon@google.com1da07462011-03-10 14:51:57 +0000331 GrSafeUnref(dstate.fTextures[s]);
reed@google.comac10a2d2010-12-22 21:39:39 +0000332 }
bsalomon@google.com1da07462011-03-10 14:51:57 +0000333 GrSafeUnref(dstate.fRenderTarget);
reed@google.comac10a2d2010-12-22 21:39:39 +0000334 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000335 int numDraws = fDraws.count();
336 for (int d = 0; d < numDraws; ++d) {
337 // we always have a VB, but not always an IB
338 GrAssert(NULL != fDraws[d].fVertexBuffer);
339 fDraws[d].fVertexBuffer->unref();
340 GrSafeUnref(fDraws[d].fIndexBuffer);
341 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000342 fDraws.reset();
343 fStates.reset();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000344
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000345 fClears.reset();
346
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000347 fVertexPool.reset();
348 fIndexPool.reset();
349
reed@google.comac10a2d2010-12-22 21:39:39 +0000350 fClips.reset();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000351
352 fCurrQuad = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000353}
354
355void GrInOrderDrawBuffer::playback(GrDrawTarget* target) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000356 GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fVertexSrc);
357 GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fIndexSrc);
reed@google.comac10a2d2010-12-22 21:39:39 +0000358 GrAssert(NULL != target);
359 GrAssert(target != this); // not considered and why?
360
bsalomon@google.com898d9e52011-04-26 13:22:33 +0000361 int numDraws = fDraws.count();
reed@google.comac10a2d2010-12-22 21:39:39 +0000362 if (!numDraws) {
363 return;
364 }
365
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000366 fVertexPool.unlock();
367 fIndexPool.unlock();
reed@google.comac10a2d2010-12-22 21:39:39 +0000368
369 GrDrawTarget::AutoStateRestore asr(target);
370 GrDrawTarget::AutoClipRestore acr(target);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000371 AutoGeometryPush agp(target);
reed@google.comac10a2d2010-12-22 21:39:39 +0000372
bsalomon@google.com6a77cc52011-04-28 17:33:34 +0000373 int currState = ~0;
374 int currClip = ~0;
375 int currClear = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000376
bsalomon@google.com898d9e52011-04-26 13:22:33 +0000377 for (int i = 0; i < numDraws; ++i) {
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000378 while (currClear < fClears.count() &&
379 i == fClears[currClear].fBeforeDrawIdx) {
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000380 target->clear(&fClears[currClear].fRect, fClears[currClear].fColor);
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000381 ++currClear;
382 }
383
reed@google.comac10a2d2010-12-22 21:39:39 +0000384 const Draw& draw = fDraws[i];
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000385 if (draw.fStateChanged) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000386 ++currState;
387 target->restoreDrawState(fStates[currState]);
388 }
389 if (draw.fClipChanged) {
390 ++currClip;
391 target->setClip(fClips[currClip]);
392 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000393
394 target->setVertexSourceToBuffer(draw.fVertexLayout, draw.fVertexBuffer);
395
reed@google.comac10a2d2010-12-22 21:39:39 +0000396 if (draw.fIndexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000397 target->setIndexSourceToBuffer(draw.fIndexBuffer);
398 }
399
400 if (draw.fIndexCount) {
401 target->drawIndexed(draw.fPrimitiveType,
reed@google.comac10a2d2010-12-22 21:39:39 +0000402 draw.fStartVertex,
403 draw.fStartIndex,
404 draw.fVertexCount,
405 draw.fIndexCount);
406 } else {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000407 target->drawNonIndexed(draw.fPrimitiveType,
reed@google.comac10a2d2010-12-22 21:39:39 +0000408 draw.fStartVertex,
409 draw.fVertexCount);
410 }
411 }
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000412 while (currClear < fClears.count()) {
413 GrAssert(fDraws.count() == fClears[currClear].fBeforeDrawIdx);
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000414 target->clear(&fClears[currClear].fRect, fClears[currClear].fColor);
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000415 ++currClear;
416 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000417}
418
419bool GrInOrderDrawBuffer::geometryHints(GrVertexLayout vertexLayout,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000420 int* vertexCount,
421 int* indexCount) const {
422 // we will recommend a flush if the data could fit in a single
423 // preallocated buffer but none are left and it can't fit
424 // in the current buffer (which may not be prealloced).
reed@google.comac10a2d2010-12-22 21:39:39 +0000425 bool flush = false;
426 if (NULL != indexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000427 int32_t currIndices = fIndexPool.currentBufferIndices();
428 if (*indexCount > currIndices &&
429 (!fIndexPool.preallocatedBuffersRemaining() &&
430 *indexCount <= fIndexPool.preallocatedBufferIndices())) {
431
432 flush = true;
433 }
434 *indexCount = currIndices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000435 }
436 if (NULL != vertexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000437 int32_t currVertices = fVertexPool.currentBufferVertices(vertexLayout);
438 if (*vertexCount > currVertices &&
439 (!fVertexPool.preallocatedBuffersRemaining() &&
440 *vertexCount <= fVertexPool.preallocatedBufferVertices(vertexLayout))) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000441
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000442 flush = true;
reed@google.comac10a2d2010-12-22 21:39:39 +0000443 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000444 *vertexCount = currVertices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000445 }
446 return flush;
447}
448
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000449bool GrInOrderDrawBuffer::onReserveVertexSpace(GrVertexLayout vertexLayout,
450 int vertexCount,
451 void** vertices) {
452 GeometryPoolState& poolState = fGeoPoolStateStack.back();
453 GrAssert(vertexCount > 0);
454 GrAssert(NULL != vertices);
455 GrAssert(0 == poolState.fUsedPoolVertexBytes);
456
457 *vertices = fVertexPool.makeSpace(vertexLayout,
458 vertexCount,
459 &poolState.fPoolVertexBuffer,
460 &poolState.fPoolStartVertex);
461 return NULL != *vertices;
462}
463
464bool GrInOrderDrawBuffer::onReserveIndexSpace(int indexCount, void** indices) {
465 GeometryPoolState& poolState = fGeoPoolStateStack.back();
466 GrAssert(indexCount > 0);
467 GrAssert(NULL != indices);
468 GrAssert(0 == poolState.fUsedPoolIndexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000469
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000470 *indices = fIndexPool.makeSpace(indexCount,
471 &poolState.fPoolIndexBuffer,
472 &poolState.fPoolStartIndex);
473 return NULL != *indices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000474}
475
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000476void GrInOrderDrawBuffer::releaseReservedVertexSpace() {
477 GeometryPoolState& poolState = fGeoPoolStateStack.back();
478 const GeometrySrcState& geoSrc = this->getGeomSrc();
479
480 GrAssert(kReserved_GeometrySrcType == geoSrc.fVertexSrc);
481
482 size_t reservedVertexBytes = VertexSize(geoSrc.fVertexLayout) *
483 geoSrc.fVertexCount;
484 fVertexPool.putBack(reservedVertexBytes -
485 poolState.fUsedPoolVertexBytes);
486 poolState.fUsedPoolVertexBytes = 0;
487 poolState.fPoolVertexBuffer = 0;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000488}
489
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000490void GrInOrderDrawBuffer::releaseReservedIndexSpace() {
491 GeometryPoolState& poolState = fGeoPoolStateStack.back();
492 const GeometrySrcState& geoSrc = this->getGeomSrc();
493
494 GrAssert(kReserved_GeometrySrcType == geoSrc.fIndexSrc);
495
496 size_t reservedIndexBytes = sizeof(uint16_t) * geoSrc.fIndexCount;
497 fIndexPool.putBack(reservedIndexBytes - poolState.fUsedPoolIndexBytes);
498 poolState.fUsedPoolIndexBytes = 0;
499 poolState.fPoolStartVertex = 0;
500}
501
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000502void GrInOrderDrawBuffer::onSetVertexSourceToArray(const void* vertexArray,
503 int vertexCount) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000504
505 GeometryPoolState& poolState = fGeoPoolStateStack.back();
506 GrAssert(0 == poolState.fUsedPoolVertexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000507#if GR_DEBUG
508 bool success =
509#endif
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000510 fVertexPool.appendVertices(this->getGeomSrc().fVertexLayout,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000511 vertexCount,
512 vertexArray,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000513 &poolState.fPoolVertexBuffer,
514 &poolState.fPoolStartVertex);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000515 GR_DEBUGASSERT(success);
516}
517
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000518void GrInOrderDrawBuffer::onSetIndexSourceToArray(const void* indexArray,
519 int indexCount) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000520 GeometryPoolState& poolState = fGeoPoolStateStack.back();
521 GrAssert(0 == poolState.fUsedPoolIndexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000522#if GR_DEBUG
523 bool success =
524#endif
525 fIndexPool.appendIndices(indexCount,
526 indexArray,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000527 &poolState.fPoolIndexBuffer,
528 &poolState.fPoolStartIndex);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000529 GR_DEBUGASSERT(success);
reed@google.comac10a2d2010-12-22 21:39:39 +0000530}
531
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000532void GrInOrderDrawBuffer::geometrySourceWillPush() {
533 GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
534 poolState.fUsedPoolVertexBytes = 0;
535 poolState.fUsedPoolIndexBytes = 0;
536#if GR_DEBUG
537 poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0;
538 poolState.fPoolStartVertex = ~0;
539 poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0;
540 poolState.fPoolStartIndex = ~0;
541#endif
542}
543
544void GrInOrderDrawBuffer::releaseVertexArray() {
545 GeometryPoolState& poolState = fGeoPoolStateStack.back();
546 const GeometrySrcState& geoSrc = this->getGeomSrc();
547
548 size_t reservedVertexBytes = VertexSize(geoSrc.fVertexLayout) *
549 geoSrc.fVertexCount;
550 fVertexPool.putBack(reservedVertexBytes - poolState.fUsedPoolVertexBytes);
551
552 poolState.fUsedPoolVertexBytes = 0;
553}
554
555void GrInOrderDrawBuffer::releaseIndexArray() {
556 GeometryPoolState& poolState = fGeoPoolStateStack.back();
557 const GeometrySrcState& geoSrc = this->getGeomSrc();
558
559 size_t reservedIndexBytes = sizeof(uint16_t) * geoSrc.fIndexCount;
560 fIndexPool.putBack(reservedIndexBytes - poolState.fUsedPoolIndexBytes);
561
562 poolState.fUsedPoolIndexBytes = 0;
563}
564
565void GrInOrderDrawBuffer::geometrySourceWillPop(
566 const GeometrySrcState& restoredState) {
567 GrAssert(fGeoPoolStateStack.count() > 1);
568 fGeoPoolStateStack.pop_back();
569 GeometryPoolState& poolState = fGeoPoolStateStack.back();
570 // we have to assume that any slack we had in our vertex/index data
571 // is now unreleasable because data may have been appended later in the
572 // pool.
573 if (kReserved_GeometrySrcType == restoredState.fVertexSrc ||
574 kArray_GeometrySrcType == restoredState.fVertexSrc) {
575 poolState.fUsedPoolVertexBytes =
576 VertexSize(restoredState.fVertexLayout) *
577 restoredState.fVertexCount;
578 }
579 if (kReserved_GeometrySrcType == restoredState.fIndexSrc ||
580 kArray_GeometrySrcType == restoredState.fIndexSrc) {
581 poolState.fUsedPoolVertexBytes = sizeof(uint16_t) *
582 restoredState.fIndexCount;
583 }
584}
585
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000586bool GrInOrderDrawBuffer::needsNewState() const {
587 if (fStates.empty()) {
588 return true;
589 } else {
tomhudson@google.com93813632011-10-27 20:21:16 +0000590 const GrDrawState& old = this->accessSavedDrawState(fStates.back());
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000591 return old != fCurrDrawState;
592 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000593}
594
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000595void GrInOrderDrawBuffer::pushState() {
tomhudson@google.com93813632011-10-27 20:21:16 +0000596 for (int s = 0; s < GrDrawState::kNumStages; ++s) {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000597 GrSafeRef(fCurrDrawState.fTextures[s]);
598 }
bsalomon@google.com1da07462011-03-10 14:51:57 +0000599 GrSafeRef(fCurrDrawState.fRenderTarget);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000600 this->saveCurrentDrawState(&fStates.push_back());
601 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000602
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000603bool GrInOrderDrawBuffer::needsNewClip() const {
604 if (fCurrDrawState.fFlagBits & kClip_StateBit) {
605 if (fClips.empty() || (fClipSet && fClips.back() != fClip)) {
606 return true;
607 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000608 }
609 return false;
610}
bsalomon@google.comd302f142011-03-03 13:54:13 +0000611
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000612void GrInOrderDrawBuffer::pushClip() {
613 fClips.push_back() = fClip;
614 fClipSet = false;
reed@google.comac10a2d2010-12-22 21:39:39 +0000615}
bsalomon@google.comd302f142011-03-03 13:54:13 +0000616
bsalomon@google.comdea2f8d2011-08-01 15:51:05 +0000617void GrInOrderDrawBuffer::clipWillBeSet(const GrClip& newClip) {
618 INHERITED::clipWillBeSet(newClip);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000619 fClipSet = true;
620}