blob: cbe153cb7deccaf55bc2cae9bcb71430e5237a7c [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"
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +000012#include "GrRenderTarget.h"
reed@google.comac10a2d2010-12-22 21:39:39 +000013#include "GrTexture.h"
bsalomon@google.com1c13c962011-02-14 16:51:21 +000014#include "GrBufferAllocPool.h"
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000015#include "GrIndexBuffer.h"
16#include "GrVertexBuffer.h"
reed@google.comac10a2d2010-12-22 21:39:39 +000017#include "GrGpu.h"
18
bsalomon@google.com471d4712011-08-23 15:45:25 +000019GrInOrderDrawBuffer::GrInOrderDrawBuffer(const GrGpu* gpu,
20 GrVertexBufferAllocPool* vertexPool,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000021 GrIndexBufferAllocPool* indexPool)
bsalomon@google.com4b90c622011-09-28 17:52:15 +000022 : fClipSet(true)
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000023 , fLastRectVertexLayout(0)
24 , fQuadIndexBuffer(NULL)
25 , fMaxQuads(0)
26 , fCurrQuad(0)
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000027 , fVertexPool(*vertexPool)
bsalomon@google.com92669012011-09-27 19:10:05 +000028 , fIndexPool(*indexPool) {
bsalomon@google.com18c9c192011-09-22 21:01:31 +000029
30 fCaps = gpu->getCaps();
31
bsalomon@google.com1c13c962011-02-14 16:51:21 +000032 GrAssert(NULL != vertexPool);
33 GrAssert(NULL != indexPool);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000034
35 GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
36 poolState.fUsedPoolVertexBytes = 0;
37 poolState.fUsedPoolIndexBytes = 0;
38#if GR_DEBUG
39 poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0;
40 poolState.fPoolStartVertex = ~0;
41 poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0;
42 poolState.fPoolStartIndex = ~0;
43#endif
reed@google.comac10a2d2010-12-22 21:39:39 +000044}
45
46GrInOrderDrawBuffer::~GrInOrderDrawBuffer() {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000047 this->reset();
bsalomon@google.com4a018bb2011-10-28 19:50:21 +000048 // This must be called by before the GrDrawTarget destructor
49 this->releaseGeometry();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000050 GrSafeUnref(fQuadIndexBuffer);
reed@google.comac10a2d2010-12-22 21:39:39 +000051}
52
53void GrInOrderDrawBuffer::initializeDrawStateAndClip(const GrDrawTarget& target) {
54 this->copyDrawState(target);
55 this->setClip(target.getClip());
56}
57
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000058void GrInOrderDrawBuffer::setQuadIndexBuffer(const GrIndexBuffer* indexBuffer) {
59 bool newIdxBuffer = fQuadIndexBuffer != indexBuffer;
60 if (newIdxBuffer) {
61 GrSafeUnref(fQuadIndexBuffer);
62 fQuadIndexBuffer = indexBuffer;
63 GrSafeRef(fQuadIndexBuffer);
64 fCurrQuad = 0;
65 fMaxQuads = (NULL == indexBuffer) ? 0 : indexBuffer->maxQuads();
66 } else {
bsalomon@google.comd302f142011-03-03 13:54:13 +000067 GrAssert((NULL == indexBuffer && 0 == fMaxQuads) ||
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000068 (indexBuffer->maxQuads() == fMaxQuads));
69 }
70}
71
bsalomon@google.comd302f142011-03-03 13:54:13 +000072void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000073 const GrMatrix* matrix,
bsalomon@google.com39ee0ff2011-12-06 15:32:52 +000074 StageMask stageMask,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000075 const GrRect* srcRects[],
76 const GrMatrix* srcMatrices[]) {
bsalomon@google.comd302f142011-03-03 13:54:13 +000077
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000078 GrAssert(!(NULL == fQuadIndexBuffer && fCurrQuad));
79 GrAssert(!(fDraws.empty() && fCurrQuad));
80 GrAssert(!(0 != fMaxQuads && NULL == fQuadIndexBuffer));
81
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +000082 GrDrawState* drawState = this->drawState();
83
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000084 // if we have a quad IB then either append to the previous run of
85 // rects or start a new run
86 if (fMaxQuads) {
bsalomon@google.comd302f142011-03-03 13:54:13 +000087
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000088 bool appendToPreviousDraw = false;
bsalomon@google.com39ee0ff2011-12-06 15:32:52 +000089 GrVertexLayout layout = GetRectVertexLayout(stageMask, srcRects);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000090 AutoReleaseGeometry geo(this, layout, 4, 0);
bsalomon@google.com6513cd02011-08-05 20:12:30 +000091 if (!geo.succeeded()) {
92 GrPrintf("Failed to get space for vertices!\n");
93 return;
94 }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +000095 GrMatrix combinedMatrix = drawState->getViewMatrix();
96 GrDrawState::AutoViewMatrixRestore avmr(drawState, GrMatrix::I());
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000097 if (NULL != matrix) {
98 combinedMatrix.preConcat(*matrix);
99 }
100
101 SetRectVertices(rect, &combinedMatrix, srcRects, srcMatrices, layout, geo.vertices());
102
103 // we don't want to miss an opportunity to batch rects together
104 // simply because the clip has changed if the clip doesn't affect
105 // the rect.
106 bool disabledClip = false;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000107 if (drawState->isClipState() && fClip.isRect()) {
bsalomon@google.comd302f142011-03-03 13:54:13 +0000108
bsalomon@google.com0b50b2e2011-03-08 21:07:21 +0000109 GrRect clipRect = fClip.getRect(0);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000110 // If the clip rect touches the edge of the viewport, extended it
111 // out (close) to infinity to avoid bogus intersections.
bsalomon@google.comd302f142011-03-03 13:54:13 +0000112 // We might consider a more exact clip to viewport if this
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000113 // conservative test fails.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000114 const GrRenderTarget* target = drawState->getRenderTarget();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000115 if (0 >= clipRect.fLeft) {
116 clipRect.fLeft = GR_ScalarMin;
117 }
118 if (target->width() <= clipRect.fRight) {
119 clipRect.fRight = GR_ScalarMax;
120 }
121 if (0 >= clipRect.top()) {
122 clipRect.fTop = GR_ScalarMin;
123 }
124 if (target->height() <= clipRect.fBottom) {
125 clipRect.fBottom = GR_ScalarMax;
126 }
127 int stride = VertexSize(layout);
128 bool insideClip = true;
129 for (int v = 0; v < 4; ++v) {
130 const GrPoint& p = *GetVertexPoint(geo.vertices(), v, stride);
131 if (!clipRect.contains(p)) {
132 insideClip = false;
133 break;
134 }
135 }
136 if (insideClip) {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000137 drawState->disableState(GrDrawState::kClip_StateBit);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000138 disabledClip = true;
139 }
140 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000141 if (!needsNewClip() && !needsNewState() && fCurrQuad > 0 &&
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000142 fCurrQuad < fMaxQuads && layout == fLastRectVertexLayout) {
143
144 int vsize = VertexSize(layout);
bsalomon@google.comd302f142011-03-03 13:54:13 +0000145
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000146 Draw& lastDraw = fDraws.back();
147
148 GrAssert(lastDraw.fIndexBuffer == fQuadIndexBuffer);
149 GrAssert(kTriangles_PrimitiveType == lastDraw.fPrimitiveType);
150 GrAssert(0 == lastDraw.fVertexCount % 4);
151 GrAssert(0 == lastDraw.fIndexCount % 6);
152 GrAssert(0 == lastDraw.fStartIndex);
153
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000154 GeometryPoolState& poolState = fGeoPoolStateStack.back();
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000155 bool clearSinceLastDraw =
156 fClears.count() &&
157 fClears.back().fBeforeDrawIdx == fDraws.count();
158
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000159 appendToPreviousDraw =
160 !clearSinceLastDraw &&
161 lastDraw.fVertexBuffer == poolState.fPoolVertexBuffer &&
162 (fCurrQuad * 4 + lastDraw.fStartVertex) == poolState.fPoolStartVertex;
163
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000164 if (appendToPreviousDraw) {
165 lastDraw.fVertexCount += 4;
166 lastDraw.fIndexCount += 6;
167 fCurrQuad += 1;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000168 // we reserved above, so we should be the first
169 // use of this vertex reserveation.
170 GrAssert(0 == poolState.fUsedPoolVertexBytes);
171 poolState.fUsedPoolVertexBytes = 4 * vsize;
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000172 }
173 }
174 if (!appendToPreviousDraw) {
175 this->setIndexSourceToBuffer(fQuadIndexBuffer);
176 drawIndexed(kTriangles_PrimitiveType, 0, 0, 4, 6);
177 fCurrQuad = 1;
178 fLastRectVertexLayout = layout;
179 }
180 if (disabledClip) {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000181 drawState->enableState(GrDrawState::kClip_StateBit);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000182 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000183 } else {
bsalomon@google.com39ee0ff2011-12-06 15:32:52 +0000184 INHERITED::drawRect(rect, matrix, stageMask, srcRects, srcMatrices);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000185 }
186}
187
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000188void GrInOrderDrawBuffer::onDrawIndexed(GrPrimitiveType primitiveType,
189 int startVertex,
190 int startIndex,
191 int vertexCount,
192 int indexCount) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000193
194 if (!vertexCount || !indexCount) {
195 return;
196 }
197
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000198 fCurrQuad = 0;
199
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000200 GeometryPoolState& poolState = fGeoPoolStateStack.back();
201
reed@google.comac10a2d2010-12-22 21:39:39 +0000202 Draw& draw = fDraws.push_back();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000203 draw.fPrimitiveType = primitiveType;
reed@google.comac10a2d2010-12-22 21:39:39 +0000204 draw.fStartVertex = startVertex;
205 draw.fStartIndex = startIndex;
206 draw.fVertexCount = vertexCount;
207 draw.fIndexCount = indexCount;
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000208
209 draw.fClipChanged = this->needsNewClip();
210 if (draw.fClipChanged) {
211 this->pushClip();
212 }
213
214 draw.fStateChanged = this->needsNewState();
215 if (draw.fStateChanged) {
216 this->pushState();
217 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000218
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000219 draw.fVertexLayout = this->getGeomSrc().fVertexLayout;
220 switch (this->getGeomSrc().fVertexSrc) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000221 case kBuffer_GeometrySrcType:
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000222 draw.fVertexBuffer = this->getGeomSrc().fVertexBuffer;
reed@google.comac10a2d2010-12-22 21:39:39 +0000223 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000224 case kReserved_GeometrySrcType: // fallthrough
225 case kArray_GeometrySrcType: {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000226 size_t vertexBytes = (vertexCount + startVertex) *
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000227 VertexSize(this->getGeomSrc().fVertexLayout);
228 poolState.fUsedPoolVertexBytes =
229 GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
230 draw.fVertexBuffer = poolState.fPoolVertexBuffer;
231 draw.fStartVertex += poolState.fPoolStartVertex;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000232 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000233 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000234 default:
235 GrCrash("unknown geom src type");
reed@google.comac10a2d2010-12-22 21:39:39 +0000236 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000237 draw.fVertexBuffer->ref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000238
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000239 switch (this->getGeomSrc().fIndexSrc) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000240 case kBuffer_GeometrySrcType:
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000241 draw.fIndexBuffer = this->getGeomSrc().fIndexBuffer;
reed@google.comac10a2d2010-12-22 21:39:39 +0000242 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000243 case kReserved_GeometrySrcType: // fallthrough
244 case kArray_GeometrySrcType: {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000245 size_t indexBytes = (indexCount + startIndex) * sizeof(uint16_t);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000246 poolState.fUsedPoolIndexBytes =
247 GrMax(poolState.fUsedPoolIndexBytes, indexBytes);
248 draw.fIndexBuffer = poolState.fPoolIndexBuffer;
249 draw.fStartIndex += poolState.fPoolStartVertex;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000250 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000251 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000252 default:
253 GrCrash("unknown geom src type");
reed@google.comac10a2d2010-12-22 21:39:39 +0000254 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000255 draw.fIndexBuffer->ref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000256}
257
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000258void GrInOrderDrawBuffer::onDrawNonIndexed(GrPrimitiveType primitiveType,
259 int startVertex,
260 int vertexCount) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000261 if (!vertexCount) {
262 return;
263 }
264
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000265 fCurrQuad = 0;
266
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000267 GeometryPoolState& poolState = fGeoPoolStateStack.back();
268
reed@google.comac10a2d2010-12-22 21:39:39 +0000269 Draw& draw = fDraws.push_back();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000270 draw.fPrimitiveType = primitiveType;
reed@google.comac10a2d2010-12-22 21:39:39 +0000271 draw.fStartVertex = startVertex;
272 draw.fStartIndex = 0;
273 draw.fVertexCount = vertexCount;
274 draw.fIndexCount = 0;
275
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000276 draw.fClipChanged = this->needsNewClip();
277 if (draw.fClipChanged) {
278 this->pushClip();
279 }
280
281 draw.fStateChanged = this->needsNewState();
282 if (draw.fStateChanged) {
283 this->pushState();
284 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000285
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000286 draw.fVertexLayout = this->getGeomSrc().fVertexLayout;
287 switch (this->getGeomSrc().fVertexSrc) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000288 case kBuffer_GeometrySrcType:
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000289 draw.fVertexBuffer = this->getGeomSrc().fVertexBuffer;
reed@google.comac10a2d2010-12-22 21:39:39 +0000290 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000291 case kReserved_GeometrySrcType: // fallthrough
292 case kArray_GeometrySrcType: {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000293 size_t vertexBytes = (vertexCount + startVertex) *
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000294 VertexSize(this->getGeomSrc().fVertexLayout);
295 poolState.fUsedPoolVertexBytes =
296 GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
297 draw.fVertexBuffer = poolState.fPoolVertexBuffer;
298 draw.fStartVertex += poolState.fPoolStartVertex;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000299 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000300 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000301 default:
302 GrCrash("unknown geom src type");
reed@google.comac10a2d2010-12-22 21:39:39 +0000303 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000304 draw.fVertexBuffer->ref();
305 draw.fIndexBuffer = NULL;
reed@google.comac10a2d2010-12-22 21:39:39 +0000306}
307
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000308void GrInOrderDrawBuffer::clear(const GrIRect* rect, GrColor color) {
309 GrIRect r;
310 if (NULL == rect) {
311 // We could do something smart and remove previous draws and clears to
312 // the current render target. If we get that smart we have to make sure
313 // those draws aren't read before this clear (render-to-texture).
314 r.setLTRB(0, 0,
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000315 this->getDrawState().getRenderTarget()->width(),
316 this->getDrawState().getRenderTarget()->height());
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000317 rect = &r;
318 }
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000319 Clear& clr = fClears.push_back();
320 clr.fColor = color;
321 clr.fBeforeDrawIdx = fDraws.count();
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000322 clr.fRect = *rect;
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000323}
324
reed@google.comac10a2d2010-12-22 21:39:39 +0000325void GrInOrderDrawBuffer::reset() {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000326 GrAssert(1 == fGeoPoolStateStack.count());
327 this->resetVertexSource();
328 this->resetIndexSource();
reed@google.comac10a2d2010-12-22 21:39:39 +0000329 uint32_t numStates = fStates.count();
330 for (uint32_t i = 0; i < numStates; ++i) {
tomhudson@google.com93813632011-10-27 20:21:16 +0000331 const GrDrawState& dstate = this->accessSavedDrawState(fStates[i]);
332 for (int s = 0; s < GrDrawState::kNumStages; ++s) {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000333 GrSafeUnref(dstate.getTexture(s));
reed@google.comac10a2d2010-12-22 21:39:39 +0000334 }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000335 GrSafeUnref(dstate.getRenderTarget());
reed@google.comac10a2d2010-12-22 21:39:39 +0000336 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000337 int numDraws = fDraws.count();
338 for (int d = 0; d < numDraws; ++d) {
339 // we always have a VB, but not always an IB
340 GrAssert(NULL != fDraws[d].fVertexBuffer);
341 fDraws[d].fVertexBuffer->unref();
342 GrSafeUnref(fDraws[d].fIndexBuffer);
343 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000344 fDraws.reset();
345 fStates.reset();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000346
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000347 fClears.reset();
348
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000349 fVertexPool.reset();
350 fIndexPool.reset();
351
reed@google.comac10a2d2010-12-22 21:39:39 +0000352 fClips.reset();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000353
354 fCurrQuad = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000355}
356
357void GrInOrderDrawBuffer::playback(GrDrawTarget* target) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000358 GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fVertexSrc);
359 GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fIndexSrc);
reed@google.comac10a2d2010-12-22 21:39:39 +0000360 GrAssert(NULL != target);
361 GrAssert(target != this); // not considered and why?
362
bsalomon@google.com898d9e52011-04-26 13:22:33 +0000363 int numDraws = fDraws.count();
reed@google.comac10a2d2010-12-22 21:39:39 +0000364 if (!numDraws) {
365 return;
366 }
367
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000368 fVertexPool.unlock();
369 fIndexPool.unlock();
reed@google.comac10a2d2010-12-22 21:39:39 +0000370
371 GrDrawTarget::AutoStateRestore asr(target);
372 GrDrawTarget::AutoClipRestore acr(target);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000373 AutoGeometryPush agp(target);
reed@google.comac10a2d2010-12-22 21:39:39 +0000374
bsalomon@google.com6a77cc52011-04-28 17:33:34 +0000375 int currState = ~0;
376 int currClip = ~0;
377 int currClear = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000378
bsalomon@google.com898d9e52011-04-26 13:22:33 +0000379 for (int i = 0; i < numDraws; ++i) {
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000380 while (currClear < fClears.count() &&
381 i == fClears[currClear].fBeforeDrawIdx) {
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000382 target->clear(&fClears[currClear].fRect, fClears[currClear].fColor);
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000383 ++currClear;
384 }
385
reed@google.comac10a2d2010-12-22 21:39:39 +0000386 const Draw& draw = fDraws[i];
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000387 if (draw.fStateChanged) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000388 ++currState;
389 target->restoreDrawState(fStates[currState]);
390 }
391 if (draw.fClipChanged) {
392 ++currClip;
393 target->setClip(fClips[currClip]);
394 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000395
396 target->setVertexSourceToBuffer(draw.fVertexLayout, draw.fVertexBuffer);
397
reed@google.comac10a2d2010-12-22 21:39:39 +0000398 if (draw.fIndexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000399 target->setIndexSourceToBuffer(draw.fIndexBuffer);
400 }
401
402 if (draw.fIndexCount) {
403 target->drawIndexed(draw.fPrimitiveType,
reed@google.comac10a2d2010-12-22 21:39:39 +0000404 draw.fStartVertex,
405 draw.fStartIndex,
406 draw.fVertexCount,
407 draw.fIndexCount);
408 } else {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000409 target->drawNonIndexed(draw.fPrimitiveType,
reed@google.comac10a2d2010-12-22 21:39:39 +0000410 draw.fStartVertex,
411 draw.fVertexCount);
412 }
413 }
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000414 while (currClear < fClears.count()) {
415 GrAssert(fDraws.count() == fClears[currClear].fBeforeDrawIdx);
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000416 target->clear(&fClears[currClear].fRect, fClears[currClear].fColor);
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000417 ++currClear;
418 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000419}
420
421bool GrInOrderDrawBuffer::geometryHints(GrVertexLayout vertexLayout,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000422 int* vertexCount,
423 int* indexCount) const {
424 // we will recommend a flush if the data could fit in a single
425 // preallocated buffer but none are left and it can't fit
426 // in the current buffer (which may not be prealloced).
reed@google.comac10a2d2010-12-22 21:39:39 +0000427 bool flush = false;
428 if (NULL != indexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000429 int32_t currIndices = fIndexPool.currentBufferIndices();
430 if (*indexCount > currIndices &&
431 (!fIndexPool.preallocatedBuffersRemaining() &&
432 *indexCount <= fIndexPool.preallocatedBufferIndices())) {
433
434 flush = true;
435 }
436 *indexCount = currIndices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000437 }
438 if (NULL != vertexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000439 int32_t currVertices = fVertexPool.currentBufferVertices(vertexLayout);
440 if (*vertexCount > currVertices &&
441 (!fVertexPool.preallocatedBuffersRemaining() &&
442 *vertexCount <= fVertexPool.preallocatedBufferVertices(vertexLayout))) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000443
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000444 flush = true;
reed@google.comac10a2d2010-12-22 21:39:39 +0000445 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000446 *vertexCount = currVertices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000447 }
448 return flush;
449}
450
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000451bool GrInOrderDrawBuffer::onReserveVertexSpace(GrVertexLayout vertexLayout,
452 int vertexCount,
453 void** vertices) {
454 GeometryPoolState& poolState = fGeoPoolStateStack.back();
455 GrAssert(vertexCount > 0);
456 GrAssert(NULL != vertices);
457 GrAssert(0 == poolState.fUsedPoolVertexBytes);
458
459 *vertices = fVertexPool.makeSpace(vertexLayout,
460 vertexCount,
461 &poolState.fPoolVertexBuffer,
462 &poolState.fPoolStartVertex);
463 return NULL != *vertices;
464}
465
466bool GrInOrderDrawBuffer::onReserveIndexSpace(int indexCount, void** indices) {
467 GeometryPoolState& poolState = fGeoPoolStateStack.back();
468 GrAssert(indexCount > 0);
469 GrAssert(NULL != indices);
470 GrAssert(0 == poolState.fUsedPoolIndexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000471
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000472 *indices = fIndexPool.makeSpace(indexCount,
473 &poolState.fPoolIndexBuffer,
474 &poolState.fPoolStartIndex);
475 return NULL != *indices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000476}
477
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000478void GrInOrderDrawBuffer::releaseReservedVertexSpace() {
479 GeometryPoolState& poolState = fGeoPoolStateStack.back();
480 const GeometrySrcState& geoSrc = this->getGeomSrc();
481
482 GrAssert(kReserved_GeometrySrcType == geoSrc.fVertexSrc);
483
484 size_t reservedVertexBytes = VertexSize(geoSrc.fVertexLayout) *
485 geoSrc.fVertexCount;
486 fVertexPool.putBack(reservedVertexBytes -
487 poolState.fUsedPoolVertexBytes);
488 poolState.fUsedPoolVertexBytes = 0;
489 poolState.fPoolVertexBuffer = 0;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000490}
491
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000492void GrInOrderDrawBuffer::releaseReservedIndexSpace() {
493 GeometryPoolState& poolState = fGeoPoolStateStack.back();
494 const GeometrySrcState& geoSrc = this->getGeomSrc();
495
496 GrAssert(kReserved_GeometrySrcType == geoSrc.fIndexSrc);
497
498 size_t reservedIndexBytes = sizeof(uint16_t) * geoSrc.fIndexCount;
499 fIndexPool.putBack(reservedIndexBytes - poolState.fUsedPoolIndexBytes);
500 poolState.fUsedPoolIndexBytes = 0;
501 poolState.fPoolStartVertex = 0;
502}
503
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000504void GrInOrderDrawBuffer::onSetVertexSourceToArray(const void* vertexArray,
505 int vertexCount) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000506
507 GeometryPoolState& poolState = fGeoPoolStateStack.back();
508 GrAssert(0 == poolState.fUsedPoolVertexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000509#if GR_DEBUG
510 bool success =
511#endif
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000512 fVertexPool.appendVertices(this->getGeomSrc().fVertexLayout,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000513 vertexCount,
514 vertexArray,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000515 &poolState.fPoolVertexBuffer,
516 &poolState.fPoolStartVertex);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000517 GR_DEBUGASSERT(success);
518}
519
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000520void GrInOrderDrawBuffer::onSetIndexSourceToArray(const void* indexArray,
521 int indexCount) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000522 GeometryPoolState& poolState = fGeoPoolStateStack.back();
523 GrAssert(0 == poolState.fUsedPoolIndexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000524#if GR_DEBUG
525 bool success =
526#endif
527 fIndexPool.appendIndices(indexCount,
528 indexArray,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000529 &poolState.fPoolIndexBuffer,
530 &poolState.fPoolStartIndex);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000531 GR_DEBUGASSERT(success);
reed@google.comac10a2d2010-12-22 21:39:39 +0000532}
533
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000534void GrInOrderDrawBuffer::geometrySourceWillPush() {
535 GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
536 poolState.fUsedPoolVertexBytes = 0;
537 poolState.fUsedPoolIndexBytes = 0;
538#if GR_DEBUG
539 poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0;
540 poolState.fPoolStartVertex = ~0;
541 poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0;
542 poolState.fPoolStartIndex = ~0;
543#endif
544}
545
546void GrInOrderDrawBuffer::releaseVertexArray() {
547 GeometryPoolState& poolState = fGeoPoolStateStack.back();
548 const GeometrySrcState& geoSrc = this->getGeomSrc();
549
550 size_t reservedVertexBytes = VertexSize(geoSrc.fVertexLayout) *
551 geoSrc.fVertexCount;
552 fVertexPool.putBack(reservedVertexBytes - poolState.fUsedPoolVertexBytes);
553
554 poolState.fUsedPoolVertexBytes = 0;
555}
556
557void GrInOrderDrawBuffer::releaseIndexArray() {
558 GeometryPoolState& poolState = fGeoPoolStateStack.back();
559 const GeometrySrcState& geoSrc = this->getGeomSrc();
560
561 size_t reservedIndexBytes = sizeof(uint16_t) * geoSrc.fIndexCount;
562 fIndexPool.putBack(reservedIndexBytes - poolState.fUsedPoolIndexBytes);
563
564 poolState.fUsedPoolIndexBytes = 0;
565}
566
567void GrInOrderDrawBuffer::geometrySourceWillPop(
568 const GeometrySrcState& restoredState) {
569 GrAssert(fGeoPoolStateStack.count() > 1);
570 fGeoPoolStateStack.pop_back();
571 GeometryPoolState& poolState = fGeoPoolStateStack.back();
572 // we have to assume that any slack we had in our vertex/index data
573 // is now unreleasable because data may have been appended later in the
574 // pool.
575 if (kReserved_GeometrySrcType == restoredState.fVertexSrc ||
576 kArray_GeometrySrcType == restoredState.fVertexSrc) {
577 poolState.fUsedPoolVertexBytes =
578 VertexSize(restoredState.fVertexLayout) *
579 restoredState.fVertexCount;
580 }
581 if (kReserved_GeometrySrcType == restoredState.fIndexSrc ||
582 kArray_GeometrySrcType == restoredState.fIndexSrc) {
583 poolState.fUsedPoolVertexBytes = sizeof(uint16_t) *
584 restoredState.fIndexCount;
585 }
586}
587
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000588bool GrInOrderDrawBuffer::needsNewState() const {
589 if (fStates.empty()) {
590 return true;
591 } else {
tomhudson@google.com93813632011-10-27 20:21:16 +0000592 const GrDrawState& old = this->accessSavedDrawState(fStates.back());
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000593 return old != fCurrDrawState;
594 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000595}
596
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000597void GrInOrderDrawBuffer::pushState() {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000598 const GrDrawState& drawState = this->getDrawState();
tomhudson@google.com93813632011-10-27 20:21:16 +0000599 for (int s = 0; s < GrDrawState::kNumStages; ++s) {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000600 GrSafeRef(drawState.getTexture(s));
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000601 }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000602 GrSafeRef(drawState.getRenderTarget());
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000603 this->saveCurrentDrawState(&fStates.push_back());
604 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000605
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000606bool GrInOrderDrawBuffer::needsNewClip() const {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000607 if (this->getDrawState().isClipState()) {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000608 if (fClips.empty() || (fClipSet && fClips.back() != fClip)) {
609 return true;
610 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000611 }
612 return false;
613}
bsalomon@google.comd302f142011-03-03 13:54:13 +0000614
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000615void GrInOrderDrawBuffer::pushClip() {
616 fClips.push_back() = fClip;
617 fClipSet = false;
reed@google.comac10a2d2010-12-22 21:39:39 +0000618}
bsalomon@google.comd302f142011-03-03 13:54:13 +0000619
bsalomon@google.comdea2f8d2011-08-01 15:51:05 +0000620void GrInOrderDrawBuffer::clipWillBeSet(const GrClip& newClip) {
621 INHERITED::clipWillBeSet(newClip);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000622 fClipSet = true;
623}