blob: 2ea12e1ccb2a0aeda9f089cc7db564b42f13f166 [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,
26 GrIndexBufferAllocPool* indexPool) :
bsalomon@google.coma55847b2011-04-20 15:47:04 +000027 fDraws(&fDrawStorage),
28 fStates(&fStateStorage),
bsalomon@google.com0b335c12011-04-25 19:17:44 +000029 fClears(&fClearStorage),
bsalomon@google.coma55847b2011-04-20 15:47:04 +000030 fClips(&fClipStorage),
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000031 fClipSet(true),
32
33 fLastRectVertexLayout(0),
34 fQuadIndexBuffer(NULL),
35 fMaxQuads(0),
36 fCurrQuad(0),
37
bsalomon@google.com1c13c962011-02-14 16:51:21 +000038 fVertexPool(*vertexPool),
39 fCurrPoolVertexBuffer(NULL),
40 fCurrPoolStartVertex(0),
41 fIndexPool(*indexPool),
42 fCurrPoolIndexBuffer(NULL),
43 fCurrPoolStartIndex(0),
reed@google.comac10a2d2010-12-22 21:39:39 +000044 fReservedVertexBytes(0),
45 fReservedIndexBytes(0),
46 fUsedReservedVertexBytes(0),
47 fUsedReservedIndexBytes(0) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +000048 GrAssert(NULL != vertexPool);
49 GrAssert(NULL != indexPool);
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);
93 AutoViewMatrixRestore avmr(this);
94 GrMatrix combinedMatrix = this->getViewMatrix();
95 this->setViewMatrix(GrMatrix::I());
96 if (NULL != matrix) {
97 combinedMatrix.preConcat(*matrix);
98 }
99
100 SetRectVertices(rect, &combinedMatrix, srcRects, srcMatrices, layout, geo.vertices());
101
102 // we don't want to miss an opportunity to batch rects together
103 // simply because the clip has changed if the clip doesn't affect
104 // the rect.
105 bool disabledClip = false;
106 if (this->isClipState() && fClip.isRect()) {
bsalomon@google.comd302f142011-03-03 13:54:13 +0000107
bsalomon@google.com0b50b2e2011-03-08 21:07:21 +0000108 GrRect clipRect = fClip.getRect(0);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000109 // If the clip rect touches the edge of the viewport, extended it
110 // out (close) to infinity to avoid bogus intersections.
bsalomon@google.comd302f142011-03-03 13:54:13 +0000111 // We might consider a more exact clip to viewport if this
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000112 // conservative test fails.
113 const GrRenderTarget* target = this->getRenderTarget();
114 if (0 >= clipRect.fLeft) {
115 clipRect.fLeft = GR_ScalarMin;
116 }
117 if (target->width() <= clipRect.fRight) {
118 clipRect.fRight = GR_ScalarMax;
119 }
120 if (0 >= clipRect.top()) {
121 clipRect.fTop = GR_ScalarMin;
122 }
123 if (target->height() <= clipRect.fBottom) {
124 clipRect.fBottom = GR_ScalarMax;
125 }
126 int stride = VertexSize(layout);
127 bool insideClip = true;
128 for (int v = 0; v < 4; ++v) {
129 const GrPoint& p = *GetVertexPoint(geo.vertices(), v, stride);
130 if (!clipRect.contains(p)) {
131 insideClip = false;
132 break;
133 }
134 }
135 if (insideClip) {
136 this->disableState(kClip_StateBit);
137 disabledClip = true;
138 }
139 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000140 if (!needsNewClip() && !needsNewState() && fCurrQuad > 0 &&
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000141 fCurrQuad < fMaxQuads && layout == fLastRectVertexLayout) {
142
143 int vsize = VertexSize(layout);
bsalomon@google.comd302f142011-03-03 13:54:13 +0000144
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000145 Draw& lastDraw = fDraws.back();
146
147 GrAssert(lastDraw.fIndexBuffer == fQuadIndexBuffer);
148 GrAssert(kTriangles_PrimitiveType == lastDraw.fPrimitiveType);
149 GrAssert(0 == lastDraw.fVertexCount % 4);
150 GrAssert(0 == lastDraw.fIndexCount % 6);
151 GrAssert(0 == lastDraw.fStartIndex);
152
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000153 bool clearSinceLastDraw =
154 fClears.count() &&
155 fClears.back().fBeforeDrawIdx == fDraws.count();
156
157 appendToPreviousDraw = !clearSinceLastDraw &&
158 lastDraw.fVertexBuffer == fCurrPoolVertexBuffer &&
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000159 (fCurrQuad * 4 + lastDraw.fStartVertex) == fCurrPoolStartVertex;
160 if (appendToPreviousDraw) {
161 lastDraw.fVertexCount += 4;
162 lastDraw.fIndexCount += 6;
163 fCurrQuad += 1;
164 GrAssert(0 == fUsedReservedVertexBytes);
165 fUsedReservedVertexBytes = 4 * vsize;
166 }
167 }
168 if (!appendToPreviousDraw) {
169 this->setIndexSourceToBuffer(fQuadIndexBuffer);
170 drawIndexed(kTriangles_PrimitiveType, 0, 0, 4, 6);
171 fCurrQuad = 1;
172 fLastRectVertexLayout = layout;
173 }
174 if (disabledClip) {
175 this->enableState(kClip_StateBit);
176 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000177 } else {
bsalomon@google.comffca4002011-02-22 20:34:01 +0000178 INHERITED::drawRect(rect, matrix, stageEnableBitfield, srcRects, srcMatrices);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000179 }
180}
181
bsalomon@google.comffca4002011-02-22 20:34:01 +0000182void GrInOrderDrawBuffer::drawIndexed(GrPrimitiveType primitiveType,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000183 int startVertex,
184 int startIndex,
185 int vertexCount,
186 int indexCount) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000187
188 if (!vertexCount || !indexCount) {
189 return;
190 }
191
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000192 fCurrQuad = 0;
193
reed@google.comac10a2d2010-12-22 21:39:39 +0000194 Draw& draw = fDraws.push_back();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000195 draw.fPrimitiveType = primitiveType;
reed@google.comac10a2d2010-12-22 21:39:39 +0000196 draw.fStartVertex = startVertex;
197 draw.fStartIndex = startIndex;
198 draw.fVertexCount = vertexCount;
199 draw.fIndexCount = indexCount;
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000200
201 draw.fClipChanged = this->needsNewClip();
202 if (draw.fClipChanged) {
203 this->pushClip();
204 }
205
206 draw.fStateChanged = this->needsNewState();
207 if (draw.fStateChanged) {
208 this->pushState();
209 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000210
211 draw.fVertexLayout = fGeometrySrc.fVertexLayout;
212 switch (fGeometrySrc.fVertexSrc) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000213 case kBuffer_GeometrySrcType:
reed@google.comac10a2d2010-12-22 21:39:39 +0000214 draw.fVertexBuffer = fGeometrySrc.fVertexBuffer;
215 break;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000216 case kReserved_GeometrySrcType: {
217 size_t vertexBytes = (vertexCount + startVertex) *
218 VertexSize(fGeometrySrc.fVertexLayout);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000219 fUsedReservedVertexBytes = GrMax(fUsedReservedVertexBytes, vertexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000220 } // fallthrough
221 case kArray_GeometrySrcType:
222 draw.fVertexBuffer = fCurrPoolVertexBuffer;
223 draw.fStartVertex += fCurrPoolStartVertex;
224 break;
225 default:
226 GrCrash("unknown geom src type");
reed@google.comac10a2d2010-12-22 21:39:39 +0000227 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000228 draw.fVertexBuffer->ref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000229
230 switch (fGeometrySrc.fIndexSrc) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000231 case kBuffer_GeometrySrcType:
reed@google.comac10a2d2010-12-22 21:39:39 +0000232 draw.fIndexBuffer = fGeometrySrc.fIndexBuffer;
233 break;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000234 case kReserved_GeometrySrcType: {
235 size_t indexBytes = (indexCount + startIndex) * sizeof(uint16_t);
236 fUsedReservedIndexBytes = GrMax(fUsedReservedIndexBytes, indexBytes);
237 } // fallthrough
238 case kArray_GeometrySrcType:
239 draw.fIndexBuffer = fCurrPoolIndexBuffer;
240 draw.fStartIndex += fCurrPoolStartVertex;
241 break;
242 default:
243 GrCrash("unknown geom src type");
reed@google.comac10a2d2010-12-22 21:39:39 +0000244 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000245 draw.fIndexBuffer->ref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000246}
247
bsalomon@google.comffca4002011-02-22 20:34:01 +0000248void GrInOrderDrawBuffer::drawNonIndexed(GrPrimitiveType primitiveType,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000249 int startVertex,
250 int vertexCount) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000251 if (!vertexCount) {
252 return;
253 }
254
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000255 fCurrQuad = 0;
256
reed@google.comac10a2d2010-12-22 21:39:39 +0000257 Draw& draw = fDraws.push_back();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000258 draw.fPrimitiveType = primitiveType;
reed@google.comac10a2d2010-12-22 21:39:39 +0000259 draw.fStartVertex = startVertex;
260 draw.fStartIndex = 0;
261 draw.fVertexCount = vertexCount;
262 draw.fIndexCount = 0;
263
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000264 draw.fClipChanged = this->needsNewClip();
265 if (draw.fClipChanged) {
266 this->pushClip();
267 }
268
269 draw.fStateChanged = this->needsNewState();
270 if (draw.fStateChanged) {
271 this->pushState();
272 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000273
274 draw.fVertexLayout = fGeometrySrc.fVertexLayout;
275 switch (fGeometrySrc.fVertexSrc) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000276 case kBuffer_GeometrySrcType:
reed@google.comac10a2d2010-12-22 21:39:39 +0000277 draw.fVertexBuffer = fGeometrySrc.fVertexBuffer;
278 break;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000279 case kReserved_GeometrySrcType: {
280 size_t vertexBytes = (vertexCount + startVertex) *
281 VertexSize(fGeometrySrc.fVertexLayout);
282 fUsedReservedVertexBytes = GrMax(fUsedReservedVertexBytes,
283 vertexBytes);
284 } // fallthrough
285 case kArray_GeometrySrcType:
286 draw.fVertexBuffer = fCurrPoolVertexBuffer;
287 draw.fStartVertex += fCurrPoolStartVertex;
288 break;
289 default:
290 GrCrash("unknown geom src type");
reed@google.comac10a2d2010-12-22 21:39:39 +0000291 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000292 draw.fVertexBuffer->ref();
293 draw.fIndexBuffer = NULL;
reed@google.comac10a2d2010-12-22 21:39:39 +0000294}
295
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000296void GrInOrderDrawBuffer::clear(const GrIRect* rect, GrColor color) {
297 GrIRect r;
298 if (NULL == rect) {
299 // We could do something smart and remove previous draws and clears to
300 // the current render target. If we get that smart we have to make sure
301 // those draws aren't read before this clear (render-to-texture).
302 r.setLTRB(0, 0,
303 this->getRenderTarget()->width(),
304 this->getRenderTarget()->height());
305 rect = &r;
306 }
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000307 Clear& clr = fClears.push_back();
308 clr.fColor = color;
309 clr.fBeforeDrawIdx = fDraws.count();
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000310 clr.fRect = *rect;
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000311}
312
reed@google.comac10a2d2010-12-22 21:39:39 +0000313void GrInOrderDrawBuffer::reset() {
314 GrAssert(!fReservedGeometry.fLocked);
315 uint32_t numStates = fStates.count();
316 for (uint32_t i = 0; i < numStates; ++i) {
bsalomon@google.com1da07462011-03-10 14:51:57 +0000317 const DrState& dstate = this->accessSavedDrawState(fStates[i]);
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000318 for (int s = 0; s < kNumStages; ++s) {
bsalomon@google.com1da07462011-03-10 14:51:57 +0000319 GrSafeUnref(dstate.fTextures[s]);
reed@google.comac10a2d2010-12-22 21:39:39 +0000320 }
bsalomon@google.com1da07462011-03-10 14:51:57 +0000321 GrSafeUnref(dstate.fRenderTarget);
reed@google.comac10a2d2010-12-22 21:39:39 +0000322 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000323 int numDraws = fDraws.count();
324 for (int d = 0; d < numDraws; ++d) {
325 // we always have a VB, but not always an IB
326 GrAssert(NULL != fDraws[d].fVertexBuffer);
327 fDraws[d].fVertexBuffer->unref();
328 GrSafeUnref(fDraws[d].fIndexBuffer);
329 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000330 fDraws.reset();
331 fStates.reset();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000332
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000333 fClears.reset();
334
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000335 fVertexPool.reset();
336 fIndexPool.reset();
337
reed@google.comac10a2d2010-12-22 21:39:39 +0000338 fClips.reset();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000339
340 fCurrQuad = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000341}
342
343void GrInOrderDrawBuffer::playback(GrDrawTarget* target) {
reed@google.com0ebe81a2011-04-04 20:06:59 +0000344 GrAssert(!fReservedGeometry.fLocked);
reed@google.comac10a2d2010-12-22 21:39:39 +0000345 GrAssert(NULL != target);
346 GrAssert(target != this); // not considered and why?
347
bsalomon@google.com898d9e52011-04-26 13:22:33 +0000348 int numDraws = fDraws.count();
reed@google.comac10a2d2010-12-22 21:39:39 +0000349 if (!numDraws) {
350 return;
351 }
352
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000353 fVertexPool.unlock();
354 fIndexPool.unlock();
reed@google.comac10a2d2010-12-22 21:39:39 +0000355
356 GrDrawTarget::AutoStateRestore asr(target);
357 GrDrawTarget::AutoClipRestore acr(target);
358 // important to not mess with reserve/lock geometry in the target with this
359 // on the stack.
360 GrDrawTarget::AutoGeometrySrcRestore agsr(target);
361
362 uint32_t currState = ~0;
363 uint32_t currClip = ~0;
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000364 uint32_t currClear = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000365
bsalomon@google.com898d9e52011-04-26 13:22:33 +0000366 for (int i = 0; i < numDraws; ++i) {
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000367 while (currClear < fClears.count() &&
368 i == fClears[currClear].fBeforeDrawIdx) {
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000369 target->clear(&fClears[currClear].fRect, fClears[currClear].fColor);
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000370 ++currClear;
371 }
372
reed@google.comac10a2d2010-12-22 21:39:39 +0000373 const Draw& draw = fDraws[i];
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000374 if (draw.fStateChanged) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000375 ++currState;
376 target->restoreDrawState(fStates[currState]);
377 }
378 if (draw.fClipChanged) {
379 ++currClip;
380 target->setClip(fClips[currClip]);
381 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000382
383 target->setVertexSourceToBuffer(draw.fVertexLayout, draw.fVertexBuffer);
384
reed@google.comac10a2d2010-12-22 21:39:39 +0000385 if (draw.fIndexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000386 target->setIndexSourceToBuffer(draw.fIndexBuffer);
387 }
388
389 if (draw.fIndexCount) {
390 target->drawIndexed(draw.fPrimitiveType,
reed@google.comac10a2d2010-12-22 21:39:39 +0000391 draw.fStartVertex,
392 draw.fStartIndex,
393 draw.fVertexCount,
394 draw.fIndexCount);
395 } else {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000396 target->drawNonIndexed(draw.fPrimitiveType,
reed@google.comac10a2d2010-12-22 21:39:39 +0000397 draw.fStartVertex,
398 draw.fVertexCount);
399 }
400 }
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000401 while (currClear < fClears.count()) {
402 GrAssert(fDraws.count() == fClears[currClear].fBeforeDrawIdx);
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000403 target->clear(&fClears[currClear].fRect, fClears[currClear].fColor);
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000404 ++currClear;
405 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000406}
407
408bool GrInOrderDrawBuffer::geometryHints(GrVertexLayout vertexLayout,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000409 int* vertexCount,
410 int* indexCount) const {
411 // we will recommend a flush if the data could fit in a single
412 // preallocated buffer but none are left and it can't fit
413 // in the current buffer (which may not be prealloced).
reed@google.comac10a2d2010-12-22 21:39:39 +0000414 bool flush = false;
415 if (NULL != indexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000416 int32_t currIndices = fIndexPool.currentBufferIndices();
417 if (*indexCount > currIndices &&
418 (!fIndexPool.preallocatedBuffersRemaining() &&
419 *indexCount <= fIndexPool.preallocatedBufferIndices())) {
420
421 flush = true;
422 }
423 *indexCount = currIndices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000424 }
425 if (NULL != vertexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000426 int32_t currVertices = fVertexPool.currentBufferVertices(vertexLayout);
427 if (*vertexCount > currVertices &&
428 (!fVertexPool.preallocatedBuffersRemaining() &&
429 *vertexCount <= fVertexPool.preallocatedBufferVertices(vertexLayout))) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000430
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000431 flush = true;
reed@google.comac10a2d2010-12-22 21:39:39 +0000432 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000433 *vertexCount = currVertices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000434 }
435 return flush;
436}
437
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000438bool GrInOrderDrawBuffer::onAcquireGeometry(GrVertexLayout vertexLayout,
439 void** vertices,
440 void** indices) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000441 GrAssert(!fReservedGeometry.fLocked);
reed@google.comac10a2d2010-12-22 21:39:39 +0000442 if (fReservedGeometry.fVertexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000443 GrAssert(NULL != vertices);
444 GrAssert(0 == fReservedVertexBytes);
445 GrAssert(0 == fUsedReservedVertexBytes);
446
reed@google.comac10a2d2010-12-22 21:39:39 +0000447 fReservedVertexBytes = VertexSize(vertexLayout) *
448 fReservedGeometry.fVertexCount;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000449 *vertices = fVertexPool.makeSpace(vertexLayout,
450 fReservedGeometry.fVertexCount,
451 &fCurrPoolVertexBuffer,
452 &fCurrPoolStartVertex);
453 if (NULL == *vertices) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000454 return false;
455 }
456 }
457 if (fReservedGeometry.fIndexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000458 GrAssert(NULL != indices);
459 GrAssert(0 == fReservedIndexBytes);
460 GrAssert(0 == fUsedReservedIndexBytes);
461
462 *indices = fIndexPool.makeSpace(fReservedGeometry.fIndexCount,
463 &fCurrPoolIndexBuffer,
464 &fCurrPoolStartIndex);
465 if (NULL == *indices) {
466 fVertexPool.putBack(fReservedVertexBytes);
467 fReservedVertexBytes = 0;
468 fCurrPoolVertexBuffer = NULL;
reed@google.comac10a2d2010-12-22 21:39:39 +0000469 return false;
470 }
471 }
472 return true;
473}
474
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000475void GrInOrderDrawBuffer::onReleaseGeometry() {
reed@google.comac10a2d2010-12-22 21:39:39 +0000476 GrAssert(fUsedReservedVertexBytes <= fReservedVertexBytes);
477 GrAssert(fUsedReservedIndexBytes <= fReservedIndexBytes);
478
479 size_t vertexSlack = fReservedVertexBytes - fUsedReservedVertexBytes;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000480 fVertexPool.putBack(vertexSlack);
reed@google.comac10a2d2010-12-22 21:39:39 +0000481
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000482 size_t indexSlack = fReservedIndexBytes - fUsedReservedIndexBytes;
483 fIndexPool.putBack(indexSlack);
reed@google.comac10a2d2010-12-22 21:39:39 +0000484
reed@google.comac10a2d2010-12-22 21:39:39 +0000485 fReservedVertexBytes = 0;
486 fReservedIndexBytes = 0;
487 fUsedReservedVertexBytes = 0;
488 fUsedReservedIndexBytes = 0;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000489 fCurrPoolVertexBuffer = 0;
490 fCurrPoolStartVertex = 0;
491
492}
493
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000494void GrInOrderDrawBuffer::onSetVertexSourceToArray(const void* vertexArray,
495 int vertexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000496 GrAssert(!fReservedGeometry.fLocked || !fReservedGeometry.fVertexCount);
497#if GR_DEBUG
498 bool success =
499#endif
500 fVertexPool.appendVertices(fGeometrySrc.fVertexLayout,
501 vertexCount,
502 vertexArray,
503 &fCurrPoolVertexBuffer,
504 &fCurrPoolStartVertex);
505 GR_DEBUGASSERT(success);
506}
507
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000508void GrInOrderDrawBuffer::onSetIndexSourceToArray(const void* indexArray,
509 int indexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000510 GrAssert(!fReservedGeometry.fLocked || !fReservedGeometry.fIndexCount);
511#if GR_DEBUG
512 bool success =
513#endif
514 fIndexPool.appendIndices(indexCount,
515 indexArray,
516 &fCurrPoolIndexBuffer,
517 &fCurrPoolStartIndex);
518 GR_DEBUGASSERT(success);
reed@google.comac10a2d2010-12-22 21:39:39 +0000519}
520
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000521bool GrInOrderDrawBuffer::needsNewState() const {
522 if (fStates.empty()) {
523 return true;
524 } else {
525 const DrState& old = this->accessSavedDrawState(fStates.back());
526 return old != fCurrDrawState;
527 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000528}
529
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000530void GrInOrderDrawBuffer::pushState() {
531 for (int s = 0; s < kNumStages; ++s) {
532 GrSafeRef(fCurrDrawState.fTextures[s]);
533 }
bsalomon@google.com1da07462011-03-10 14:51:57 +0000534 GrSafeRef(fCurrDrawState.fRenderTarget);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000535 this->saveCurrentDrawState(&fStates.push_back());
536 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000537
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000538bool GrInOrderDrawBuffer::needsNewClip() const {
539 if (fCurrDrawState.fFlagBits & kClip_StateBit) {
540 if (fClips.empty() || (fClipSet && fClips.back() != fClip)) {
541 return true;
542 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000543 }
544 return false;
545}
bsalomon@google.comd302f142011-03-03 13:54:13 +0000546
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000547void GrInOrderDrawBuffer::pushClip() {
548 fClips.push_back() = fClip;
549 fClipSet = false;
reed@google.comac10a2d2010-12-22 21:39:39 +0000550}
bsalomon@google.comd302f142011-03-03 13:54:13 +0000551
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000552void GrInOrderDrawBuffer::clipWillBeSet(const GrClip& newClip) {
553 fClipSet = true;
554}