blob: 9d8f887d8367deea94eedab2bc9130a1ccdf35b8 [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
10#include "GrInOrderDrawBuffer.h"
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +000011#include "GrRenderTarget.h"
reed@google.comac10a2d2010-12-22 21:39:39 +000012#include "GrTexture.h"
bsalomon@google.com1c13c962011-02-14 16:51:21 +000013#include "GrBufferAllocPool.h"
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000014#include "GrIndexBuffer.h"
15#include "GrVertexBuffer.h"
reed@google.comac10a2d2010-12-22 21:39:39 +000016#include "GrGpu.h"
17
bsalomon@google.com471d4712011-08-23 15:45:25 +000018GrInOrderDrawBuffer::GrInOrderDrawBuffer(const GrGpu* gpu,
19 GrVertexBufferAllocPool* vertexPool,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000020 GrIndexBufferAllocPool* indexPool)
bsalomon@google.com97805382012-03-13 14:32:07 +000021 : fAutoFlushTarget(NULL)
22 , fClipSet(true)
robertphillips@google.com69705572012-03-21 19:46:50 +000023 , fVertexPool(*vertexPool)
24 , fIndexPool(*indexPool)
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000025 , fLastRectVertexLayout(0)
26 , fQuadIndexBuffer(NULL)
27 , fMaxQuads(0)
robertphillips@google.comc82a8b72012-06-21 20:15:48 +000028 , fCurrQuad(0)
29 , fFlushing(false) {
bsalomon@google.com18c9c192011-09-22 21:01:31 +000030
31 fCaps = gpu->getCaps();
32
bsalomon@google.com1c13c962011-02-14 16:51:21 +000033 GrAssert(NULL != vertexPool);
34 GrAssert(NULL != indexPool);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000035
36 GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
37 poolState.fUsedPoolVertexBytes = 0;
38 poolState.fUsedPoolIndexBytes = 0;
39#if GR_DEBUG
40 poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0;
41 poolState.fPoolStartVertex = ~0;
42 poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0;
43 poolState.fPoolStartIndex = ~0;
44#endif
bsalomon@google.com934c5702012-03-20 21:17:58 +000045 fInstancedDrawTracker.reset();
reed@google.comac10a2d2010-12-22 21:39:39 +000046}
47
48GrInOrderDrawBuffer::~GrInOrderDrawBuffer() {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000049 this->reset();
bsalomon@google.com4a018bb2011-10-28 19:50:21 +000050 // This must be called by before the GrDrawTarget destructor
51 this->releaseGeometry();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000052 GrSafeUnref(fQuadIndexBuffer);
bsalomon@google.com97805382012-03-13 14:32:07 +000053 GrSafeUnref(fAutoFlushTarget);
reed@google.comac10a2d2010-12-22 21:39:39 +000054}
55
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000056void GrInOrderDrawBuffer::setQuadIndexBuffer(const GrIndexBuffer* indexBuffer) {
57 bool newIdxBuffer = fQuadIndexBuffer != indexBuffer;
58 if (newIdxBuffer) {
59 GrSafeUnref(fQuadIndexBuffer);
60 fQuadIndexBuffer = indexBuffer;
61 GrSafeRef(fQuadIndexBuffer);
62 fCurrQuad = 0;
63 fMaxQuads = (NULL == indexBuffer) ? 0 : indexBuffer->maxQuads();
64 } else {
bsalomon@google.comd302f142011-03-03 13:54:13 +000065 GrAssert((NULL == indexBuffer && 0 == fMaxQuads) ||
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000066 (indexBuffer->maxQuads() == fMaxQuads));
67 }
68}
69
bsalomon@google.com934c5702012-03-20 21:17:58 +000070////////////////////////////////////////////////////////////////////////////////
71
72void GrInOrderDrawBuffer::resetDrawTracking() {
73 fCurrQuad = 0;
74 fInstancedDrawTracker.reset();
75}
76
bsalomon@google.comd302f142011-03-03 13:54:13 +000077void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000078 const GrMatrix* matrix,
bsalomon@google.com39ee0ff2011-12-06 15:32:52 +000079 StageMask stageMask,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000080 const GrRect* srcRects[],
81 const GrMatrix* srcMatrices[]) {
bsalomon@google.comd302f142011-03-03 13:54:13 +000082
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000083 GrAssert(!(NULL == fQuadIndexBuffer && fCurrQuad));
84 GrAssert(!(fDraws.empty() && fCurrQuad));
85 GrAssert(!(0 != fMaxQuads && NULL == fQuadIndexBuffer));
86
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +000087 GrDrawState* drawState = this->drawState();
88
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000089 // if we have a quad IB then either append to the previous run of
90 // rects or start a new run
91 if (fMaxQuads) {
bsalomon@google.comd302f142011-03-03 13:54:13 +000092
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000093 bool appendToPreviousDraw = false;
bsalomon@google.com39ee0ff2011-12-06 15:32:52 +000094 GrVertexLayout layout = GetRectVertexLayout(stageMask, srcRects);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000095 AutoReleaseGeometry geo(this, layout, 4, 0);
bsalomon@google.com6513cd02011-08-05 20:12:30 +000096 if (!geo.succeeded()) {
97 GrPrintf("Failed to get space for vertices!\n");
98 return;
99 }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000100 GrMatrix combinedMatrix = drawState->getViewMatrix();
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000101 // We go to device space so that matrix changes allow us to concat
102 // rect draws. When the caller has provided explicit source rects
103 // then we don't want to modify the sampler matrices. Otherwise we do
104 // we have to account for the view matrix change in the sampler
105 // matrices.
106 StageMask devCoordMask = (NULL == srcRects) ? stageMask : 0;
107 GrDrawTarget::AutoDeviceCoordDraw adcd(this, devCoordMask);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000108 if (NULL != matrix) {
109 combinedMatrix.preConcat(*matrix);
110 }
111
112 SetRectVertices(rect, &combinedMatrix, srcRects, srcMatrices, layout, geo.vertices());
113
114 // we don't want to miss an opportunity to batch rects together
115 // simply because the clip has changed if the clip doesn't affect
116 // the rect.
117 bool disabledClip = false;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000118 if (drawState->isClipState() && fClip.isRect()) {
bsalomon@google.comd302f142011-03-03 13:54:13 +0000119
bsalomon@google.com0b50b2e2011-03-08 21:07:21 +0000120 GrRect clipRect = fClip.getRect(0);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000121 // If the clip rect touches the edge of the viewport, extended it
122 // out (close) to infinity to avoid bogus intersections.
bsalomon@google.comd302f142011-03-03 13:54:13 +0000123 // We might consider a more exact clip to viewport if this
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000124 // conservative test fails.
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000125 const GrRenderTarget* target = drawState->getRenderTarget();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000126 if (0 >= clipRect.fLeft) {
127 clipRect.fLeft = GR_ScalarMin;
128 }
129 if (target->width() <= clipRect.fRight) {
130 clipRect.fRight = GR_ScalarMax;
131 }
132 if (0 >= clipRect.top()) {
133 clipRect.fTop = GR_ScalarMin;
134 }
135 if (target->height() <= clipRect.fBottom) {
136 clipRect.fBottom = GR_ScalarMax;
137 }
138 int stride = VertexSize(layout);
139 bool insideClip = true;
140 for (int v = 0; v < 4; ++v) {
141 const GrPoint& p = *GetVertexPoint(geo.vertices(), v, stride);
142 if (!clipRect.contains(p)) {
143 insideClip = false;
144 break;
145 }
146 }
147 if (insideClip) {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000148 drawState->disableState(GrDrawState::kClip_StateBit);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000149 disabledClip = true;
150 }
151 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000152 if (!needsNewClip() && !needsNewState() && fCurrQuad > 0 &&
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000153 fCurrQuad < fMaxQuads && layout == fLastRectVertexLayout) {
154
155 int vsize = VertexSize(layout);
bsalomon@google.comd302f142011-03-03 13:54:13 +0000156
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000157 Draw& lastDraw = fDraws.back();
158
159 GrAssert(lastDraw.fIndexBuffer == fQuadIndexBuffer);
bsalomon@google.com47059542012-06-06 20:51:20 +0000160 GrAssert(kTriangles_GrPrimitiveType == lastDraw.fPrimitiveType);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000161 GrAssert(0 == lastDraw.fVertexCount % 4);
162 GrAssert(0 == lastDraw.fIndexCount % 6);
163 GrAssert(0 == lastDraw.fStartIndex);
164
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000165 GeometryPoolState& poolState = fGeoPoolStateStack.back();
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000166 bool clearSinceLastDraw =
167 fClears.count() &&
168 fClears.back().fBeforeDrawIdx == fDraws.count();
169
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000170 appendToPreviousDraw =
171 !clearSinceLastDraw &&
172 lastDraw.fVertexBuffer == poolState.fPoolVertexBuffer &&
173 (fCurrQuad * 4 + lastDraw.fStartVertex) == poolState.fPoolStartVertex;
174
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000175 if (appendToPreviousDraw) {
176 lastDraw.fVertexCount += 4;
177 lastDraw.fIndexCount += 6;
178 fCurrQuad += 1;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000179 // we reserved above, so we should be the first
180 // use of this vertex reserveation.
181 GrAssert(0 == poolState.fUsedPoolVertexBytes);
182 poolState.fUsedPoolVertexBytes = 4 * vsize;
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000183 }
184 }
185 if (!appendToPreviousDraw) {
186 this->setIndexSourceToBuffer(fQuadIndexBuffer);
bsalomon@google.com47059542012-06-06 20:51:20 +0000187 this->drawIndexed(kTriangles_GrPrimitiveType, 0, 0, 4, 6);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000188 fCurrQuad = 1;
189 fLastRectVertexLayout = layout;
190 }
191 if (disabledClip) {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000192 drawState->enableState(GrDrawState::kClip_StateBit);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000193 }
bsalomon@google.com934c5702012-03-20 21:17:58 +0000194 fInstancedDrawTracker.reset();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000195 } else {
bsalomon@google.com39ee0ff2011-12-06 15:32:52 +0000196 INHERITED::drawRect(rect, matrix, stageMask, srcRects, srcMatrices);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000197 }
198}
199
bsalomon@google.com934c5702012-03-20 21:17:58 +0000200void GrInOrderDrawBuffer::drawIndexedInstances(GrPrimitiveType type,
201 int instanceCount,
202 int verticesPerInstance,
203 int indicesPerInstance) {
204 if (!verticesPerInstance || !indicesPerInstance) {
205 return;
206 }
207
208 const GeometrySrcState& geomSrc = this->getGeomSrc();
209
210 // we only attempt to concat the case when reserved verts are used with
211 // an index buffer.
212 if (kReserved_GeometrySrcType == geomSrc.fVertexSrc &&
213 kBuffer_GeometrySrcType == geomSrc.fIndexSrc) {
214
215 Draw* draw = NULL;
216 // if the last draw used the same indices/vertices per shape then we
217 // may be able to append to it.
218 if (verticesPerInstance == fInstancedDrawTracker.fVerticesPerInstance &&
219 indicesPerInstance == fInstancedDrawTracker.fIndicesPerInstance) {
220 GrAssert(fDraws.count());
221 draw = &fDraws.back();
222 }
223
224 bool clipChanged = this->needsNewClip();
225 bool stateChanged = this->needsNewState();
226 if (clipChanged) {
robertphillips@google.com49d9fd52012-05-23 11:44:08 +0000227 this->storeClip();
bsalomon@google.com934c5702012-03-20 21:17:58 +0000228 }
229 if (stateChanged) {
230 this->pushState();
231 }
232
233 GeometryPoolState& poolState = fGeoPoolStateStack.back();
234 const GrVertexBuffer* vertexBuffer = poolState.fPoolVertexBuffer;
235
236 // Check whether the draw is compatible with this draw in order to
237 // append
238 if (NULL == draw ||
239 clipChanged ||
240 stateChanged ||
241 draw->fIndexBuffer != geomSrc.fIndexBuffer ||
242 draw->fPrimitiveType != type ||
243 draw->fVertexBuffer != vertexBuffer) {
244
245 draw = &fDraws.push_back();
246 draw->fClipChanged = clipChanged;
247 draw->fStateChanged = stateChanged;
248 draw->fIndexBuffer = geomSrc.fIndexBuffer;
249 geomSrc.fIndexBuffer->ref();
250 draw->fVertexBuffer = vertexBuffer;
251 vertexBuffer->ref();
252 draw->fPrimitiveType = type;
253 draw->fStartIndex = 0;
254 draw->fIndexCount = 0;
255 draw->fStartVertex = poolState.fPoolStartVertex;
256 draw->fVertexCount = 0;
257 draw->fVertexLayout = geomSrc.fVertexLayout;
258 } else {
259 GrAssert(!(draw->fIndexCount % indicesPerInstance));
260 GrAssert(!(draw->fVertexCount % verticesPerInstance));
261 GrAssert(poolState.fPoolStartVertex == draw->fStartVertex +
262 draw->fVertexCount);
263 }
264
265 // how many instances can be in a single draw
266 int maxInstancesPerDraw = this->indexCountInCurrentSource() /
267 indicesPerInstance;
268 if (!maxInstancesPerDraw) {
269 return;
270 }
271 // how many instances should be concat'ed onto draw
272 int instancesToConcat = maxInstancesPerDraw - draw->fVertexCount /
273 verticesPerInstance;
274 if (maxInstancesPerDraw > instanceCount) {
275 maxInstancesPerDraw = instanceCount;
276 if (instancesToConcat > instanceCount) {
277 instancesToConcat = instanceCount;
278 }
279 }
280
281 // update the amount of reserved data actually referenced in draws
282 size_t vertexBytes = instanceCount * verticesPerInstance *
283 VertexSize(draw->fVertexLayout);
284 poolState.fUsedPoolVertexBytes =
285 GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
286
287 while (instanceCount) {
288 if (!instancesToConcat) {
289 int startVertex = draw->fStartVertex + draw->fVertexCount;
290 draw = &fDraws.push_back();
291 draw->fClipChanged = false;
292 draw->fStateChanged = false;
293 draw->fIndexBuffer = geomSrc.fIndexBuffer;
294 geomSrc.fIndexBuffer->ref();
295 draw->fVertexBuffer = vertexBuffer;
296 vertexBuffer->ref();
297 draw->fPrimitiveType = type;
298 draw->fStartIndex = 0;
299 draw->fStartVertex = startVertex;
300 draw->fVertexCount = 0;
301 draw->fVertexLayout = geomSrc.fVertexLayout;
302 instancesToConcat = maxInstancesPerDraw;
303 }
304 draw->fVertexCount += instancesToConcat * verticesPerInstance;
305 draw->fIndexCount += instancesToConcat * indicesPerInstance;
306 instanceCount -= instancesToConcat;
307 instancesToConcat = 0;
308 }
309
310 // update draw tracking for next draw
311 fCurrQuad = 0;
312 fInstancedDrawTracker.fVerticesPerInstance = verticesPerInstance;
313 fInstancedDrawTracker.fIndicesPerInstance = indicesPerInstance;
314 } else {
315 this->INHERITED::drawIndexedInstances(type,
316 instanceCount,
317 verticesPerInstance,
318 indicesPerInstance);
319 }
320
321}
322
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000323void GrInOrderDrawBuffer::onDrawIndexed(GrPrimitiveType primitiveType,
324 int startVertex,
325 int startIndex,
326 int vertexCount,
327 int indexCount) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000328
329 if (!vertexCount || !indexCount) {
330 return;
331 }
332
bsalomon@google.com934c5702012-03-20 21:17:58 +0000333 this->resetDrawTracking();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000334
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000335 GeometryPoolState& poolState = fGeoPoolStateStack.back();
336
reed@google.comac10a2d2010-12-22 21:39:39 +0000337 Draw& draw = fDraws.push_back();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000338 draw.fPrimitiveType = primitiveType;
reed@google.comac10a2d2010-12-22 21:39:39 +0000339 draw.fStartVertex = startVertex;
340 draw.fStartIndex = startIndex;
341 draw.fVertexCount = vertexCount;
342 draw.fIndexCount = indexCount;
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000343
344 draw.fClipChanged = this->needsNewClip();
345 if (draw.fClipChanged) {
robertphillips@google.com49d9fd52012-05-23 11:44:08 +0000346 this->storeClip();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000347 }
348
349 draw.fStateChanged = this->needsNewState();
350 if (draw.fStateChanged) {
351 this->pushState();
352 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000353
bsalomon@google.come79c8152012-03-29 19:07:12 +0000354 draw.fVertexLayout = this->getVertexLayout();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000355 switch (this->getGeomSrc().fVertexSrc) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000356 case kBuffer_GeometrySrcType:
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000357 draw.fVertexBuffer = this->getGeomSrc().fVertexBuffer;
reed@google.comac10a2d2010-12-22 21:39:39 +0000358 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000359 case kReserved_GeometrySrcType: // fallthrough
360 case kArray_GeometrySrcType: {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000361 size_t vertexBytes = (vertexCount + startVertex) *
bsalomon@google.come79c8152012-03-29 19:07:12 +0000362 VertexSize(draw.fVertexLayout);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000363 poolState.fUsedPoolVertexBytes =
364 GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
365 draw.fVertexBuffer = poolState.fPoolVertexBuffer;
366 draw.fStartVertex += poolState.fPoolStartVertex;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000367 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000368 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000369 default:
370 GrCrash("unknown geom src type");
reed@google.comac10a2d2010-12-22 21:39:39 +0000371 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000372 draw.fVertexBuffer->ref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000373
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000374 switch (this->getGeomSrc().fIndexSrc) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000375 case kBuffer_GeometrySrcType:
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000376 draw.fIndexBuffer = this->getGeomSrc().fIndexBuffer;
reed@google.comac10a2d2010-12-22 21:39:39 +0000377 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000378 case kReserved_GeometrySrcType: // fallthrough
379 case kArray_GeometrySrcType: {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000380 size_t indexBytes = (indexCount + startIndex) * sizeof(uint16_t);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000381 poolState.fUsedPoolIndexBytes =
382 GrMax(poolState.fUsedPoolIndexBytes, indexBytes);
383 draw.fIndexBuffer = poolState.fPoolIndexBuffer;
bsalomon@google.comd127ffe2012-02-24 20:11:52 +0000384 draw.fStartIndex += poolState.fPoolStartIndex;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000385 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000386 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000387 default:
388 GrCrash("unknown geom src type");
reed@google.comac10a2d2010-12-22 21:39:39 +0000389 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000390 draw.fIndexBuffer->ref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000391}
392
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000393void GrInOrderDrawBuffer::onDrawNonIndexed(GrPrimitiveType primitiveType,
394 int startVertex,
395 int vertexCount) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000396 if (!vertexCount) {
397 return;
398 }
399
bsalomon@google.com934c5702012-03-20 21:17:58 +0000400 this->resetDrawTracking();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000401
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000402 GeometryPoolState& poolState = fGeoPoolStateStack.back();
403
reed@google.comac10a2d2010-12-22 21:39:39 +0000404 Draw& draw = fDraws.push_back();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000405 draw.fPrimitiveType = primitiveType;
reed@google.comac10a2d2010-12-22 21:39:39 +0000406 draw.fStartVertex = startVertex;
407 draw.fStartIndex = 0;
408 draw.fVertexCount = vertexCount;
409 draw.fIndexCount = 0;
410
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000411 draw.fClipChanged = this->needsNewClip();
412 if (draw.fClipChanged) {
robertphillips@google.com49d9fd52012-05-23 11:44:08 +0000413 this->storeClip();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000414 }
415
416 draw.fStateChanged = this->needsNewState();
417 if (draw.fStateChanged) {
418 this->pushState();
419 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000420
bsalomon@google.come79c8152012-03-29 19:07:12 +0000421 draw.fVertexLayout = this->getVertexLayout();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000422 switch (this->getGeomSrc().fVertexSrc) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000423 case kBuffer_GeometrySrcType:
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000424 draw.fVertexBuffer = this->getGeomSrc().fVertexBuffer;
reed@google.comac10a2d2010-12-22 21:39:39 +0000425 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000426 case kReserved_GeometrySrcType: // fallthrough
427 case kArray_GeometrySrcType: {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000428 size_t vertexBytes = (vertexCount + startVertex) *
bsalomon@google.come79c8152012-03-29 19:07:12 +0000429 VertexSize(draw.fVertexLayout);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000430 poolState.fUsedPoolVertexBytes =
431 GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
432 draw.fVertexBuffer = poolState.fPoolVertexBuffer;
433 draw.fStartVertex += poolState.fPoolStartVertex;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000434 break;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000435 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000436 default:
437 GrCrash("unknown geom src type");
reed@google.comac10a2d2010-12-22 21:39:39 +0000438 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000439 draw.fVertexBuffer->ref();
440 draw.fIndexBuffer = NULL;
reed@google.comac10a2d2010-12-22 21:39:39 +0000441}
442
bsalomon@google.com64aef2b2012-06-11 15:36:13 +0000443void GrInOrderDrawBuffer::onStencilPath(const GrPath&, GrPathFill) {
444 GrCrash("Not implemented yet. Should not get here.");
445}
446
robertphillips@google.comc82a8b72012-06-21 20:15:48 +0000447void GrInOrderDrawBuffer::clear(const GrIRect* rect,
448 GrColor color,
449 GrRenderTarget* renderTarget) {
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000450 GrIRect r;
451 if (NULL == rect) {
452 // We could do something smart and remove previous draws and clears to
453 // the current render target. If we get that smart we have to make sure
454 // those draws aren't read before this clear (render-to-texture).
455 r.setLTRB(0, 0,
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000456 this->getDrawState().getRenderTarget()->width(),
457 this->getDrawState().getRenderTarget()->height());
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000458 rect = &r;
459 }
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000460 Clear& clr = fClears.push_back();
461 clr.fColor = color;
462 clr.fBeforeDrawIdx = fDraws.count();
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000463 clr.fRect = *rect;
robertphillips@google.comc82a8b72012-06-21 20:15:48 +0000464 clr.fRenderTarget = renderTarget;
465 GrSafeRef(clr.fRenderTarget);
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000466}
467
reed@google.comac10a2d2010-12-22 21:39:39 +0000468void GrInOrderDrawBuffer::reset() {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000469 GrAssert(1 == fGeoPoolStateStack.count());
470 this->resetVertexSource();
471 this->resetIndexSource();
robertphillips@google.comc077d1e2012-05-28 14:10:15 +0000472 uint32_t numStates = fStates.count();
473 for (uint32_t i = 0; i < numStates; ++i) {
474 for (int s = 0; s < GrDrawState::kNumStages; ++s) {
475 GrSafeUnref(fStates[i].getTexture(s));
476 }
477 GrSafeUnref(fStates[i].getRenderTarget());
robertphillips@google.com1942c052012-05-03 17:58:27 +0000478
robertphillips@google.comc077d1e2012-05-28 14:10:15 +0000479 // GrInOrderDrawBuffer is no longer managing the refs/unrefs
480 // for the stored GrDrawStates
481 fStates[i].disableBehavior(GrDrawState::kTexturesNeedRef_BehaviorBit);
482 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000483 int numDraws = fDraws.count();
484 for (int d = 0; d < numDraws; ++d) {
485 // we always have a VB, but not always an IB
486 GrAssert(NULL != fDraws[d].fVertexBuffer);
487 fDraws[d].fVertexBuffer->unref();
488 GrSafeUnref(fDraws[d].fIndexBuffer);
489 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000490 fDraws.reset();
491 fStates.reset();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000492
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000493 fClears.reset();
494
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000495 fVertexPool.reset();
496 fIndexPool.reset();
497
reed@google.comac10a2d2010-12-22 21:39:39 +0000498 fClips.reset();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000499
bsalomon@google.com934c5702012-03-20 21:17:58 +0000500 this->resetDrawTracking();
reed@google.comac10a2d2010-12-22 21:39:39 +0000501}
502
503void GrInOrderDrawBuffer::playback(GrDrawTarget* target) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000504 GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fVertexSrc);
505 GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fIndexSrc);
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000506
reed@google.comac10a2d2010-12-22 21:39:39 +0000507 GrAssert(NULL != target);
508 GrAssert(target != this); // not considered and why?
509
bsalomon@google.com898d9e52011-04-26 13:22:33 +0000510 int numDraws = fDraws.count();
reed@google.comac10a2d2010-12-22 21:39:39 +0000511 if (!numDraws) {
512 return;
513 }
514
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000515 fVertexPool.unlock();
516 fIndexPool.unlock();
reed@google.comac10a2d2010-12-22 21:39:39 +0000517
reed@google.comac10a2d2010-12-22 21:39:39 +0000518 GrDrawTarget::AutoClipRestore acr(target);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000519 AutoGeometryPush agp(target);
bsalomon@google.coma5d056a2012-03-27 15:59:58 +0000520 GrDrawState* prevDrawState = target->drawState();
521 prevDrawState->ref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000522
bsalomon@google.com6a77cc52011-04-28 17:33:34 +0000523 int currState = ~0;
524 int currClip = ~0;
525 int currClear = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +0000526
bsalomon@google.com898d9e52011-04-26 13:22:33 +0000527 for (int i = 0; i < numDraws; ++i) {
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000528 while (currClear < fClears.count() &&
529 i == fClears[currClear].fBeforeDrawIdx) {
robertphillips@google.comc82a8b72012-06-21 20:15:48 +0000530 target->clear(&fClears[currClear].fRect,
531 fClears[currClear].fColor,
532 fClears[currClear].fRenderTarget);
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000533 ++currClear;
534 }
535
reed@google.comac10a2d2010-12-22 21:39:39 +0000536 const Draw& draw = fDraws[i];
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000537 if (draw.fStateChanged) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000538 ++currState;
bsalomon@google.com873ea0c2012-03-30 15:55:32 +0000539 target->setDrawState(&fStates[currState]);
reed@google.comac10a2d2010-12-22 21:39:39 +0000540 }
541 if (draw.fClipChanged) {
542 ++currClip;
543 target->setClip(fClips[currClip]);
544 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000545
546 target->setVertexSourceToBuffer(draw.fVertexLayout, draw.fVertexBuffer);
547
reed@google.comac10a2d2010-12-22 21:39:39 +0000548 if (draw.fIndexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000549 target->setIndexSourceToBuffer(draw.fIndexBuffer);
550 }
551
552 if (draw.fIndexCount) {
553 target->drawIndexed(draw.fPrimitiveType,
reed@google.comac10a2d2010-12-22 21:39:39 +0000554 draw.fStartVertex,
555 draw.fStartIndex,
556 draw.fVertexCount,
557 draw.fIndexCount);
558 } else {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000559 target->drawNonIndexed(draw.fPrimitiveType,
reed@google.comac10a2d2010-12-22 21:39:39 +0000560 draw.fStartVertex,
561 draw.fVertexCount);
562 }
563 }
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000564 while (currClear < fClears.count()) {
565 GrAssert(fDraws.count() == fClears[currClear].fBeforeDrawIdx);
robertphillips@google.comc82a8b72012-06-21 20:15:48 +0000566 target->clear(&fClears[currClear].fRect,
567 fClears[currClear].fColor,
568 fClears[currClear].fRenderTarget);
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000569 ++currClear;
570 }
bsalomon@google.coma5d056a2012-03-27 15:59:58 +0000571 target->setDrawState(prevDrawState);
572 prevDrawState->unref();
reed@google.comac10a2d2010-12-22 21:39:39 +0000573}
574
bsalomon@google.com97805382012-03-13 14:32:07 +0000575void GrInOrderDrawBuffer::setAutoFlushTarget(GrDrawTarget* target) {
576 GrSafeAssign(fAutoFlushTarget, target);
577}
578
579void GrInOrderDrawBuffer::willReserveVertexAndIndexSpace(
580 GrVertexLayout vertexLayout,
581 int vertexCount,
582 int indexCount) {
583 if (NULL != fAutoFlushTarget) {
584 // We use geometryHints() to know whether to flush the draw buffer. We
585 // can't flush if we are inside an unbalanced pushGeometrySource.
586 // Moreover, flushing blows away vertex and index data that was
587 // previously reserved. So if the vertex or index data is pulled from
588 // reserved space and won't be released by this request then we can't
589 // flush.
590 bool insideGeoPush = fGeoPoolStateStack.count() > 1;
591
592 bool unreleasedVertexSpace =
593 !vertexCount &&
594 kReserved_GeometrySrcType == this->getGeomSrc().fVertexSrc;
595
596 bool unreleasedIndexSpace =
597 !indexCount &&
598 kReserved_GeometrySrcType == this->getGeomSrc().fIndexSrc;
599
600 // we don't want to finalize any reserved geom on the target since
601 // we don't know that the client has finished writing to it.
602 bool targetHasReservedGeom =
603 fAutoFlushTarget->hasReservedVerticesOrIndices();
604
605 int vcount = vertexCount;
606 int icount = indexCount;
607
608 if (!insideGeoPush &&
609 !unreleasedVertexSpace &&
610 !unreleasedIndexSpace &&
611 !targetHasReservedGeom &&
612 this->geometryHints(vertexLayout, &vcount, &icount)) {
613
614 this->flushTo(fAutoFlushTarget);
615 }
616 }
617}
618
reed@google.comac10a2d2010-12-22 21:39:39 +0000619bool GrInOrderDrawBuffer::geometryHints(GrVertexLayout vertexLayout,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000620 int* vertexCount,
621 int* indexCount) const {
622 // we will recommend a flush if the data could fit in a single
623 // preallocated buffer but none are left and it can't fit
624 // in the current buffer (which may not be prealloced).
reed@google.comac10a2d2010-12-22 21:39:39 +0000625 bool flush = false;
626 if (NULL != indexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000627 int32_t currIndices = fIndexPool.currentBufferIndices();
628 if (*indexCount > currIndices &&
629 (!fIndexPool.preallocatedBuffersRemaining() &&
630 *indexCount <= fIndexPool.preallocatedBufferIndices())) {
631
632 flush = true;
633 }
634 *indexCount = currIndices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000635 }
636 if (NULL != vertexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000637 int32_t currVertices = fVertexPool.currentBufferVertices(vertexLayout);
638 if (*vertexCount > currVertices &&
639 (!fVertexPool.preallocatedBuffersRemaining() &&
640 *vertexCount <= fVertexPool.preallocatedBufferVertices(vertexLayout))) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000641
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000642 flush = true;
reed@google.comac10a2d2010-12-22 21:39:39 +0000643 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000644 *vertexCount = currVertices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000645 }
646 return flush;
647}
648
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000649bool GrInOrderDrawBuffer::onReserveVertexSpace(GrVertexLayout vertexLayout,
650 int vertexCount,
651 void** vertices) {
652 GeometryPoolState& poolState = fGeoPoolStateStack.back();
653 GrAssert(vertexCount > 0);
654 GrAssert(NULL != vertices);
655 GrAssert(0 == poolState.fUsedPoolVertexBytes);
656
657 *vertices = fVertexPool.makeSpace(vertexLayout,
658 vertexCount,
659 &poolState.fPoolVertexBuffer,
660 &poolState.fPoolStartVertex);
661 return NULL != *vertices;
662}
663
664bool GrInOrderDrawBuffer::onReserveIndexSpace(int indexCount, void** indices) {
665 GeometryPoolState& poolState = fGeoPoolStateStack.back();
666 GrAssert(indexCount > 0);
667 GrAssert(NULL != indices);
668 GrAssert(0 == poolState.fUsedPoolIndexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000669
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000670 *indices = fIndexPool.makeSpace(indexCount,
671 &poolState.fPoolIndexBuffer,
672 &poolState.fPoolStartIndex);
673 return NULL != *indices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000674}
675
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000676void GrInOrderDrawBuffer::releaseReservedVertexSpace() {
677 GeometryPoolState& poolState = fGeoPoolStateStack.back();
678 const GeometrySrcState& geoSrc = this->getGeomSrc();
679
680 GrAssert(kReserved_GeometrySrcType == geoSrc.fVertexSrc);
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000681
682 // When the caller reserved vertex buffer space we gave it back a pointer
683 // provided by the vertex buffer pool. At each draw we tracked the largest
684 // offset into the pool's pointer that was referenced. Now we return to the
685 // pool any portion at the tail of the allocation that no draw referenced.
686 size_t reservedVertexBytes = VertexSize(geoSrc.fVertexLayout) *
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000687 geoSrc.fVertexCount;
688 fVertexPool.putBack(reservedVertexBytes -
689 poolState.fUsedPoolVertexBytes);
690 poolState.fUsedPoolVertexBytes = 0;
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000691 poolState.fPoolVertexBuffer = NULL;
692 poolState.fPoolStartVertex = 0;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000693}
694
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000695void GrInOrderDrawBuffer::releaseReservedIndexSpace() {
696 GeometryPoolState& poolState = fGeoPoolStateStack.back();
697 const GeometrySrcState& geoSrc = this->getGeomSrc();
698
699 GrAssert(kReserved_GeometrySrcType == geoSrc.fIndexSrc);
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000700
701 // Similar to releaseReservedVertexSpace we return any unused portion at
702 // the tail
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000703 size_t reservedIndexBytes = sizeof(uint16_t) * geoSrc.fIndexCount;
704 fIndexPool.putBack(reservedIndexBytes - poolState.fUsedPoolIndexBytes);
705 poolState.fUsedPoolIndexBytes = 0;
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000706 poolState.fPoolIndexBuffer = NULL;
707 poolState.fPoolStartIndex = 0;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000708}
709
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000710void GrInOrderDrawBuffer::onSetVertexSourceToArray(const void* vertexArray,
711 int vertexCount) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000712
713 GeometryPoolState& poolState = fGeoPoolStateStack.back();
714 GrAssert(0 == poolState.fUsedPoolVertexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000715#if GR_DEBUG
716 bool success =
717#endif
bsalomon@google.come79c8152012-03-29 19:07:12 +0000718 fVertexPool.appendVertices(this->getVertexLayout(),
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000719 vertexCount,
720 vertexArray,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000721 &poolState.fPoolVertexBuffer,
722 &poolState.fPoolStartVertex);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000723 GR_DEBUGASSERT(success);
724}
725
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000726void GrInOrderDrawBuffer::onSetIndexSourceToArray(const void* indexArray,
727 int indexCount) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000728 GeometryPoolState& poolState = fGeoPoolStateStack.back();
729 GrAssert(0 == poolState.fUsedPoolIndexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000730#if GR_DEBUG
731 bool success =
732#endif
733 fIndexPool.appendIndices(indexCount,
734 indexArray,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000735 &poolState.fPoolIndexBuffer,
736 &poolState.fPoolStartIndex);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000737 GR_DEBUGASSERT(success);
reed@google.comac10a2d2010-12-22 21:39:39 +0000738}
739
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000740void GrInOrderDrawBuffer::releaseVertexArray() {
741 // When the client provides an array as the vertex source we handled it
742 // by copying their array into reserved space.
743 this->GrInOrderDrawBuffer::releaseReservedVertexSpace();
744}
745
746void GrInOrderDrawBuffer::releaseIndexArray() {
747 // When the client provides an array as the index source we handled it
748 // by copying their array into reserved space.
749 this->GrInOrderDrawBuffer::releaseReservedIndexSpace();
750}
751
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000752void GrInOrderDrawBuffer::geometrySourceWillPush() {
753 GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
754 poolState.fUsedPoolVertexBytes = 0;
755 poolState.fUsedPoolIndexBytes = 0;
bsalomon@google.com934c5702012-03-20 21:17:58 +0000756 this->resetDrawTracking();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000757#if GR_DEBUG
758 poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0;
759 poolState.fPoolStartVertex = ~0;
760 poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0;
761 poolState.fPoolStartIndex = ~0;
762#endif
763}
764
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000765void GrInOrderDrawBuffer::geometrySourceWillPop(
766 const GeometrySrcState& restoredState) {
767 GrAssert(fGeoPoolStateStack.count() > 1);
768 fGeoPoolStateStack.pop_back();
769 GeometryPoolState& poolState = fGeoPoolStateStack.back();
770 // we have to assume that any slack we had in our vertex/index data
771 // is now unreleasable because data may have been appended later in the
772 // pool.
773 if (kReserved_GeometrySrcType == restoredState.fVertexSrc ||
774 kArray_GeometrySrcType == restoredState.fVertexSrc) {
775 poolState.fUsedPoolVertexBytes =
776 VertexSize(restoredState.fVertexLayout) *
777 restoredState.fVertexCount;
778 }
779 if (kReserved_GeometrySrcType == restoredState.fIndexSrc ||
780 kArray_GeometrySrcType == restoredState.fIndexSrc) {
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000781 poolState.fUsedPoolIndexBytes = sizeof(uint16_t) *
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000782 restoredState.fIndexCount;
783 }
bsalomon@google.com934c5702012-03-20 21:17:58 +0000784 this->resetDrawTracking();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000785}
786
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000787bool GrInOrderDrawBuffer::needsNewState() const {
788 if (fStates.empty()) {
789 return true;
790 } else {
bsalomon@google.com873ea0c2012-03-30 15:55:32 +0000791 return fStates.back() != this->getDrawState();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000792 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000793}
794
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000795void GrInOrderDrawBuffer::pushState() {
robertphillips@google.comc077d1e2012-05-28 14:10:15 +0000796 const GrDrawState& drawState = this->getDrawState();
797 for (int s = 0; s < GrDrawState::kNumStages; ++s) {
798 GrSafeRef(drawState.getTexture(s));
799 }
800 GrSafeRef(drawState.getRenderTarget());
bsalomon@google.com873ea0c2012-03-30 15:55:32 +0000801 fStates.push_back(this->getDrawState());
robertphillips@google.comc077d1e2012-05-28 14:10:15 +0000802
803 // Any textures that are added to the stored state need to be
804 // reffed so the unref in reset doesn't inappropriately free them
805 fStates.back().enableBehavior(GrDrawState::kTexturesNeedRef_BehaviorBit);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000806 }
bsalomon@google.comd302f142011-03-03 13:54:13 +0000807
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000808bool GrInOrderDrawBuffer::needsNewClip() const {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000809 if (this->getDrawState().isClipState()) {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000810 if (fClips.empty() || (fClipSet && fClips.back() != fClip)) {
811 return true;
812 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000813 }
814 return false;
815}
bsalomon@google.comd302f142011-03-03 13:54:13 +0000816
robertphillips@google.com49d9fd52012-05-23 11:44:08 +0000817void GrInOrderDrawBuffer::storeClip() {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000818 fClips.push_back() = fClip;
819 fClipSet = false;
reed@google.comac10a2d2010-12-22 21:39:39 +0000820}
bsalomon@google.comd302f142011-03-03 13:54:13 +0000821
bsalomon@google.comdea2f8d2011-08-01 15:51:05 +0000822void GrInOrderDrawBuffer::clipWillBeSet(const GrClip& newClip) {
823 INHERITED::clipWillBeSet(newClip);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000824 fClipSet = true;
825}