blob: 93acc12432ebec9ceae1b72e5e73e29056d3a912 [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
153 appendToPreviousDraw = lastDraw.fVertexBuffer == fCurrPoolVertexBuffer &&
154 (fCurrQuad * 4 + lastDraw.fStartVertex) == fCurrPoolStartVertex;
155 if (appendToPreviousDraw) {
156 lastDraw.fVertexCount += 4;
157 lastDraw.fIndexCount += 6;
158 fCurrQuad += 1;
159 GrAssert(0 == fUsedReservedVertexBytes);
160 fUsedReservedVertexBytes = 4 * vsize;
161 }
162 }
163 if (!appendToPreviousDraw) {
164 this->setIndexSourceToBuffer(fQuadIndexBuffer);
165 drawIndexed(kTriangles_PrimitiveType, 0, 0, 4, 6);
166 fCurrQuad = 1;
167 fLastRectVertexLayout = layout;
168 }
169 if (disabledClip) {
170 this->enableState(kClip_StateBit);
171 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000172 } else {
bsalomon@google.comffca4002011-02-22 20:34:01 +0000173 INHERITED::drawRect(rect, matrix, stageEnableBitfield, srcRects, srcMatrices);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000174 }
175}
176
bsalomon@google.comffca4002011-02-22 20:34:01 +0000177void GrInOrderDrawBuffer::drawIndexed(GrPrimitiveType primitiveType,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000178 int startVertex,
179 int startIndex,
180 int vertexCount,
181 int indexCount) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000182
183 if (!vertexCount || !indexCount) {
184 return;
185 }
186
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000187 fCurrQuad = 0;
188
reed@google.comac10a2d2010-12-22 21:39:39 +0000189 Draw& draw = fDraws.push_back();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000190 draw.fPrimitiveType = primitiveType;
reed@google.comac10a2d2010-12-22 21:39:39 +0000191 draw.fStartVertex = startVertex;
192 draw.fStartIndex = startIndex;
193 draw.fVertexCount = vertexCount;
194 draw.fIndexCount = indexCount;
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000195
196 draw.fClipChanged = this->needsNewClip();
197 if (draw.fClipChanged) {
198 this->pushClip();
199 }
200
201 draw.fStateChanged = this->needsNewState();
202 if (draw.fStateChanged) {
203 this->pushState();
204 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000205
206 draw.fVertexLayout = fGeometrySrc.fVertexLayout;
207 switch (fGeometrySrc.fVertexSrc) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000208 case kBuffer_GeometrySrcType:
reed@google.comac10a2d2010-12-22 21:39:39 +0000209 draw.fVertexBuffer = fGeometrySrc.fVertexBuffer;
210 break;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000211 case kReserved_GeometrySrcType: {
212 size_t vertexBytes = (vertexCount + startVertex) *
213 VertexSize(fGeometrySrc.fVertexLayout);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000214 fUsedReservedVertexBytes = GrMax(fUsedReservedVertexBytes, vertexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000215 } // fallthrough
216 case kArray_GeometrySrcType:
217 draw.fVertexBuffer = fCurrPoolVertexBuffer;
218 draw.fStartVertex += fCurrPoolStartVertex;
219 break;
220 default:
221 GrCrash("unknown geom src type");
reed@google.comac10a2d2010-12-22 21:39:39 +0000222 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000223 draw.fVertexBuffer->ref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000224
225 switch (fGeometrySrc.fIndexSrc) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000226 case kBuffer_GeometrySrcType:
reed@google.comac10a2d2010-12-22 21:39:39 +0000227 draw.fIndexBuffer = fGeometrySrc.fIndexBuffer;
228 break;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000229 case kReserved_GeometrySrcType: {
230 size_t indexBytes = (indexCount + startIndex) * sizeof(uint16_t);
231 fUsedReservedIndexBytes = GrMax(fUsedReservedIndexBytes, indexBytes);
232 } // fallthrough
233 case kArray_GeometrySrcType:
234 draw.fIndexBuffer = fCurrPoolIndexBuffer;
235 draw.fStartIndex += fCurrPoolStartVertex;
236 break;
237 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.fIndexBuffer->ref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000241}
242
bsalomon@google.comffca4002011-02-22 20:34:01 +0000243void GrInOrderDrawBuffer::drawNonIndexed(GrPrimitiveType primitiveType,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000244 int startVertex,
245 int vertexCount) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000246 if (!vertexCount) {
247 return;
248 }
249
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000250 fCurrQuad = 0;
251
reed@google.comac10a2d2010-12-22 21:39:39 +0000252 Draw& draw = fDraws.push_back();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000253 draw.fPrimitiveType = primitiveType;
reed@google.comac10a2d2010-12-22 21:39:39 +0000254 draw.fStartVertex = startVertex;
255 draw.fStartIndex = 0;
256 draw.fVertexCount = vertexCount;
257 draw.fIndexCount = 0;
258
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000259 draw.fClipChanged = this->needsNewClip();
260 if (draw.fClipChanged) {
261 this->pushClip();
262 }
263
264 draw.fStateChanged = this->needsNewState();
265 if (draw.fStateChanged) {
266 this->pushState();
267 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000268
269 draw.fVertexLayout = fGeometrySrc.fVertexLayout;
270 switch (fGeometrySrc.fVertexSrc) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000271 case kBuffer_GeometrySrcType:
reed@google.comac10a2d2010-12-22 21:39:39 +0000272 draw.fVertexBuffer = fGeometrySrc.fVertexBuffer;
273 break;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000274 case kReserved_GeometrySrcType: {
275 size_t vertexBytes = (vertexCount + startVertex) *
276 VertexSize(fGeometrySrc.fVertexLayout);
277 fUsedReservedVertexBytes = GrMax(fUsedReservedVertexBytes,
278 vertexBytes);
279 } // fallthrough
280 case kArray_GeometrySrcType:
281 draw.fVertexBuffer = fCurrPoolVertexBuffer;
282 draw.fStartVertex += fCurrPoolStartVertex;
283 break;
284 default:
285 GrCrash("unknown geom src type");
reed@google.comac10a2d2010-12-22 21:39:39 +0000286 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000287 draw.fVertexBuffer->ref();
288 draw.fIndexBuffer = NULL;
reed@google.comac10a2d2010-12-22 21:39:39 +0000289}
290
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000291void GrInOrderDrawBuffer::clear(GrColor color) {
292 Clear& clr = fClears.push_back();
293 clr.fColor = color;
294 clr.fBeforeDrawIdx = fDraws.count();
295
296 // We could do something smart and remove previous draws and clears to the
297 // current render target. If we get that smart we have to make sure those
298 // draws aren't read before this clear (render-to-texture).
299}
300
reed@google.comac10a2d2010-12-22 21:39:39 +0000301void GrInOrderDrawBuffer::reset() {
302 GrAssert(!fReservedGeometry.fLocked);
303 uint32_t numStates = fStates.count();
304 for (uint32_t i = 0; i < numStates; ++i) {
bsalomon@google.com1da07462011-03-10 14:51:57 +0000305 const DrState& dstate = this->accessSavedDrawState(fStates[i]);
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000306 for (int s = 0; s < kNumStages; ++s) {
bsalomon@google.com1da07462011-03-10 14:51:57 +0000307 GrSafeUnref(dstate.fTextures[s]);
reed@google.comac10a2d2010-12-22 21:39:39 +0000308 }
bsalomon@google.com1da07462011-03-10 14:51:57 +0000309 GrSafeUnref(dstate.fRenderTarget);
reed@google.comac10a2d2010-12-22 21:39:39 +0000310 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000311 int numDraws = fDraws.count();
312 for (int d = 0; d < numDraws; ++d) {
313 // we always have a VB, but not always an IB
314 GrAssert(NULL != fDraws[d].fVertexBuffer);
315 fDraws[d].fVertexBuffer->unref();
316 GrSafeUnref(fDraws[d].fIndexBuffer);
317 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000318 fDraws.reset();
319 fStates.reset();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000320
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000321 fClears.reset();
322
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000323 fVertexPool.reset();
324 fIndexPool.reset();
325
reed@google.comac10a2d2010-12-22 21:39:39 +0000326 fClips.reset();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000327
328 fCurrQuad = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000329}
330
331void GrInOrderDrawBuffer::playback(GrDrawTarget* target) {
reed@google.com0ebe81a2011-04-04 20:06:59 +0000332 GrAssert(!fReservedGeometry.fLocked);
reed@google.comac10a2d2010-12-22 21:39:39 +0000333 GrAssert(NULL != target);
334 GrAssert(target != this); // not considered and why?
335
336 uint32_t numDraws = fDraws.count();
337 if (!numDraws) {
338 return;
339 }
340
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000341 fVertexPool.unlock();
342 fIndexPool.unlock();
reed@google.comac10a2d2010-12-22 21:39:39 +0000343
344 GrDrawTarget::AutoStateRestore asr(target);
345 GrDrawTarget::AutoClipRestore acr(target);
346 // important to not mess with reserve/lock geometry in the target with this
347 // on the stack.
348 GrDrawTarget::AutoGeometrySrcRestore agsr(target);
349
350 uint32_t currState = ~0;
351 uint32_t currClip = ~0;
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000352 uint32_t currClear = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000353
354 for (uint32_t i = 0; i < numDraws; ++i) {
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000355 while (currClear < fClears.count() &&
356 i == fClears[currClear].fBeforeDrawIdx) {
357 target->clear(fClears[currClear].fColor);
358 ++currClear;
359 }
360
reed@google.comac10a2d2010-12-22 21:39:39 +0000361 const Draw& draw = fDraws[i];
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000362 if (draw.fStateChanged) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000363 ++currState;
364 target->restoreDrawState(fStates[currState]);
365 }
366 if (draw.fClipChanged) {
367 ++currClip;
368 target->setClip(fClips[currClip]);
369 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000370
371 target->setVertexSourceToBuffer(draw.fVertexLayout, draw.fVertexBuffer);
372
reed@google.comac10a2d2010-12-22 21:39:39 +0000373 if (draw.fIndexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000374 target->setIndexSourceToBuffer(draw.fIndexBuffer);
375 }
376
377 if (draw.fIndexCount) {
378 target->drawIndexed(draw.fPrimitiveType,
reed@google.comac10a2d2010-12-22 21:39:39 +0000379 draw.fStartVertex,
380 draw.fStartIndex,
381 draw.fVertexCount,
382 draw.fIndexCount);
383 } else {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000384 target->drawNonIndexed(draw.fPrimitiveType,
reed@google.comac10a2d2010-12-22 21:39:39 +0000385 draw.fStartVertex,
386 draw.fVertexCount);
387 }
388 }
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000389 while (currClear < fClears.count()) {
390 GrAssert(fDraws.count() == fClears[currClear].fBeforeDrawIdx);
391 target->clear(fClears[currClear].fColor);
392 ++currClear;
393 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000394}
395
396bool GrInOrderDrawBuffer::geometryHints(GrVertexLayout vertexLayout,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000397 int* vertexCount,
398 int* indexCount) const {
399 // we will recommend a flush if the data could fit in a single
400 // preallocated buffer but none are left and it can't fit
401 // in the current buffer (which may not be prealloced).
reed@google.comac10a2d2010-12-22 21:39:39 +0000402 bool flush = false;
403 if (NULL != indexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000404 int32_t currIndices = fIndexPool.currentBufferIndices();
405 if (*indexCount > currIndices &&
406 (!fIndexPool.preallocatedBuffersRemaining() &&
407 *indexCount <= fIndexPool.preallocatedBufferIndices())) {
408
409 flush = true;
410 }
411 *indexCount = currIndices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000412 }
413 if (NULL != vertexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000414 int32_t currVertices = fVertexPool.currentBufferVertices(vertexLayout);
415 if (*vertexCount > currVertices &&
416 (!fVertexPool.preallocatedBuffersRemaining() &&
417 *vertexCount <= fVertexPool.preallocatedBufferVertices(vertexLayout))) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000418
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000419 flush = true;
reed@google.comac10a2d2010-12-22 21:39:39 +0000420 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000421 *vertexCount = currVertices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000422 }
423 return flush;
424}
425
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000426bool GrInOrderDrawBuffer::onAcquireGeometry(GrVertexLayout vertexLayout,
427 void** vertices,
428 void** indices) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000429 GrAssert(!fReservedGeometry.fLocked);
reed@google.comac10a2d2010-12-22 21:39:39 +0000430 if (fReservedGeometry.fVertexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000431 GrAssert(NULL != vertices);
432 GrAssert(0 == fReservedVertexBytes);
433 GrAssert(0 == fUsedReservedVertexBytes);
434
reed@google.comac10a2d2010-12-22 21:39:39 +0000435 fReservedVertexBytes = VertexSize(vertexLayout) *
436 fReservedGeometry.fVertexCount;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000437 *vertices = fVertexPool.makeSpace(vertexLayout,
438 fReservedGeometry.fVertexCount,
439 &fCurrPoolVertexBuffer,
440 &fCurrPoolStartVertex);
441 if (NULL == *vertices) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000442 return false;
443 }
444 }
445 if (fReservedGeometry.fIndexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000446 GrAssert(NULL != indices);
447 GrAssert(0 == fReservedIndexBytes);
448 GrAssert(0 == fUsedReservedIndexBytes);
449
450 *indices = fIndexPool.makeSpace(fReservedGeometry.fIndexCount,
451 &fCurrPoolIndexBuffer,
452 &fCurrPoolStartIndex);
453 if (NULL == *indices) {
454 fVertexPool.putBack(fReservedVertexBytes);
455 fReservedVertexBytes = 0;
456 fCurrPoolVertexBuffer = NULL;
reed@google.comac10a2d2010-12-22 21:39:39 +0000457 return false;
458 }
459 }
460 return true;
461}
462
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000463void GrInOrderDrawBuffer::onReleaseGeometry() {
reed@google.comac10a2d2010-12-22 21:39:39 +0000464 GrAssert(fUsedReservedVertexBytes <= fReservedVertexBytes);
465 GrAssert(fUsedReservedIndexBytes <= fReservedIndexBytes);
466
467 size_t vertexSlack = fReservedVertexBytes - fUsedReservedVertexBytes;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000468 fVertexPool.putBack(vertexSlack);
reed@google.comac10a2d2010-12-22 21:39:39 +0000469
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000470 size_t indexSlack = fReservedIndexBytes - fUsedReservedIndexBytes;
471 fIndexPool.putBack(indexSlack);
reed@google.comac10a2d2010-12-22 21:39:39 +0000472
reed@google.comac10a2d2010-12-22 21:39:39 +0000473 fReservedVertexBytes = 0;
474 fReservedIndexBytes = 0;
475 fUsedReservedVertexBytes = 0;
476 fUsedReservedIndexBytes = 0;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000477 fCurrPoolVertexBuffer = 0;
478 fCurrPoolStartVertex = 0;
479
480}
481
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000482void GrInOrderDrawBuffer::onSetVertexSourceToArray(const void* vertexArray,
483 int vertexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000484 GrAssert(!fReservedGeometry.fLocked || !fReservedGeometry.fVertexCount);
485#if GR_DEBUG
486 bool success =
487#endif
488 fVertexPool.appendVertices(fGeometrySrc.fVertexLayout,
489 vertexCount,
490 vertexArray,
491 &fCurrPoolVertexBuffer,
492 &fCurrPoolStartVertex);
493 GR_DEBUGASSERT(success);
494}
495
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000496void GrInOrderDrawBuffer::onSetIndexSourceToArray(const void* indexArray,
497 int indexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000498 GrAssert(!fReservedGeometry.fLocked || !fReservedGeometry.fIndexCount);
499#if GR_DEBUG
500 bool success =
501#endif
502 fIndexPool.appendIndices(indexCount,
503 indexArray,
504 &fCurrPoolIndexBuffer,
505 &fCurrPoolStartIndex);
506 GR_DEBUGASSERT(success);
reed@google.comac10a2d2010-12-22 21:39:39 +0000507}
508
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000509bool GrInOrderDrawBuffer::needsNewState() const {
510 if (fStates.empty()) {
511 return true;
512 } else {
513 const DrState& old = this->accessSavedDrawState(fStates.back());
514 return old != fCurrDrawState;
515 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000516}
517
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000518void GrInOrderDrawBuffer::pushState() {
519 for (int s = 0; s < kNumStages; ++s) {
520 GrSafeRef(fCurrDrawState.fTextures[s]);
521 }
bsalomon@google.com1da07462011-03-10 14:51:57 +0000522 GrSafeRef(fCurrDrawState.fRenderTarget);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000523 this->saveCurrentDrawState(&fStates.push_back());
524 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000525
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000526bool GrInOrderDrawBuffer::needsNewClip() const {
527 if (fCurrDrawState.fFlagBits & kClip_StateBit) {
528 if (fClips.empty() || (fClipSet && fClips.back() != fClip)) {
529 return true;
530 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000531 }
532 return false;
533}
bsalomon@google.comd302f142011-03-03 13:54:13 +0000534
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000535void GrInOrderDrawBuffer::pushClip() {
536 fClips.push_back() = fClip;
537 fClipSet = false;
reed@google.comac10a2d2010-12-22 21:39:39 +0000538}
bsalomon@google.comd302f142011-03-03 13:54:13 +0000539
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000540void GrInOrderDrawBuffer::clipWillBeSet(const GrClip& newClip) {
541 fClipSet = true;
542}