blob: a685620820dee8abd0179d0b587a85c7885a8b50 [file] [log] [blame]
reed@google.comac10a2d2010-12-22 21:39:39 +00001/*
bsalomon@google.com1da07462011-03-10 14:51:57 +00002 Copyright 2011 Google Inc.
reed@google.comac10a2d2010-12-22 21:39:39 +00003
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 */
16
17
18#include "GrInOrderDrawBuffer.h"
19#include "GrTexture.h"
bsalomon@google.com1c13c962011-02-14 16:51:21 +000020#include "GrBufferAllocPool.h"
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000021#include "GrIndexBuffer.h"
22#include "GrVertexBuffer.h"
reed@google.comac10a2d2010-12-22 21:39:39 +000023#include "GrGpu.h"
24
bsalomon@google.com1c13c962011-02-14 16:51:21 +000025GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrVertexBufferAllocPool* vertexPool,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000026 GrIndexBufferAllocPool* indexPool)
27 : fDraws(&fDrawStorage)
28 , fStates(&fStateStorage)
29 , fClears(&fClearStorage)
30 , fClips(&fClipStorage)
31 , fClipSet(true)
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000032
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000033 , fLastRectVertexLayout(0)
34 , fQuadIndexBuffer(NULL)
35 , fMaxQuads(0)
36 , fCurrQuad(0)
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000037
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000038 , fVertexPool(*vertexPool)
39 , fIndexPool(*indexPool)
40 , fGeoPoolStateStack(&fGeoStackStorage) {
41
bsalomon@google.com1c13c962011-02-14 16:51:21 +000042 GrAssert(NULL != vertexPool);
43 GrAssert(NULL != indexPool);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000044
45 GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
46 poolState.fUsedPoolVertexBytes = 0;
47 poolState.fUsedPoolIndexBytes = 0;
48#if GR_DEBUG
49 poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0;
50 poolState.fPoolStartVertex = ~0;
51 poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0;
52 poolState.fPoolStartIndex = ~0;
53#endif
reed@google.comac10a2d2010-12-22 21:39:39 +000054}
55
56GrInOrderDrawBuffer::~GrInOrderDrawBuffer() {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000057 this->reset();
58 GrSafeUnref(fQuadIndexBuffer);
reed@google.comac10a2d2010-12-22 21:39:39 +000059}
60
61void GrInOrderDrawBuffer::initializeDrawStateAndClip(const GrDrawTarget& target) {
62 this->copyDrawState(target);
63 this->setClip(target.getClip());
64}
65
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000066void GrInOrderDrawBuffer::setQuadIndexBuffer(const GrIndexBuffer* indexBuffer) {
67 bool newIdxBuffer = fQuadIndexBuffer != indexBuffer;
68 if (newIdxBuffer) {
69 GrSafeUnref(fQuadIndexBuffer);
70 fQuadIndexBuffer = indexBuffer;
71 GrSafeRef(fQuadIndexBuffer);
72 fCurrQuad = 0;
73 fMaxQuads = (NULL == indexBuffer) ? 0 : indexBuffer->maxQuads();
74 } else {
bsalomon@google.comd302f142011-03-03 13:54:13 +000075 GrAssert((NULL == indexBuffer && 0 == fMaxQuads) ||
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000076 (indexBuffer->maxQuads() == fMaxQuads));
77 }
78}
79
bsalomon@google.comd302f142011-03-03 13:54:13 +000080void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000081 const GrMatrix* matrix,
bsalomon@google.comffca4002011-02-22 20:34:01 +000082 StageBitfield stageEnableBitfield,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000083 const GrRect* srcRects[],
84 const GrMatrix* srcMatrices[]) {
bsalomon@google.comd302f142011-03-03 13:54:13 +000085
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000086 GrAssert(!(NULL == fQuadIndexBuffer && fCurrQuad));
87 GrAssert(!(fDraws.empty() && fCurrQuad));
88 GrAssert(!(0 != fMaxQuads && NULL == fQuadIndexBuffer));
89
90 // if we have a quad IB then either append to the previous run of
91 // rects or start a new run
92 if (fMaxQuads) {
bsalomon@google.comd302f142011-03-03 13:54:13 +000093
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000094 bool appendToPreviousDraw = false;
bsalomon@google.comffca4002011-02-22 20:34:01 +000095 GrVertexLayout layout = GetRectVertexLayout(stageEnableBitfield, srcRects);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000096 AutoReleaseGeometry geo(this, layout, 4, 0);
97 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.com86afc2a2011-02-16 16:12:19 +0000622void GrInOrderDrawBuffer::clipWillBeSet(const GrClip& newClip) {
623 fClipSet = true;
624}