blob: e6b53f837442a8ddd8f92d75fe8a6c0284d5c917 [file] [log] [blame]
reed@google.comac10a2d2010-12-22 21:39:39 +00001/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00002 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
reed@google.comac10a2d2010-12-22 21:39:39 +00006 */
7
reed@google.comac10a2d2010-12-22 21:39:39 +00008#include "GrInOrderDrawBuffer.h"
commit-bot@chromium.orgfd03d4a2013-07-17 21:39:42 +00009
joshualitt4d8da812015-01-28 12:53:54 -080010#include "GrBufferAllocPool.h"
joshualitt5478d422014-11-14 16:00:38 -080011#include "GrDefaultGeoProcFactory.h"
bsalomon@google.comc26d94f2013-03-25 18:19:00 +000012#include "GrDrawTargetCaps.h"
bsalomon@google.comded4f4b2012-06-28 18:48:06 +000013#include "GrGpu.h"
bsalomon@google.com6e4e6502013-02-25 20:12:45 +000014#include "GrTemplates.h"
jvanverth787cdf92014-12-04 10:46:50 -080015#include "GrFontCache.h"
reed@google.comac10a2d2010-12-22 21:39:39 +000016#include "GrTexture.h"
reed@google.comac10a2d2010-12-22 21:39:39 +000017
bsalomon@google.com6e4e6502013-02-25 20:12:45 +000018GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrGpu* gpu,
bsalomon@google.com471d4712011-08-23 15:45:25 +000019 GrVertexBufferAllocPool* vertexPool,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000020 GrIndexBufferAllocPool* indexPool)
bsalomon371bcbc2014-12-01 08:19:34 -080021 : INHERITED(gpu, vertexPool, indexPool)
cdalton6819df32014-10-15 13:43:48 -070022 , fCmdBuffer(kCmdBufferInitialSizeInBytes)
bsalomon932f8662014-11-24 06:47:48 -080023 , fPrevState(NULL)
joshualitt4d8da812015-01-28 12:53:54 -080024 , fDrawID(0)
25 , fBatchTarget(gpu, vertexPool, indexPool)
26 , fDrawBatch(NULL) {
bsalomon@google.com18c9c192011-09-22 21:01:31 +000027
bsalomon49f085d2014-09-05 13:34:00 -070028 SkASSERT(vertexPool);
29 SkASSERT(indexPool);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000030
cdalton3fc6a2f2014-11-13 11:54:20 -080031 fPathIndexBuffer.setReserve(kPathIdxBufferMinReserve);
32 fPathTransformBuffer.setReserve(kPathXformBufferMinReserve);
reed@google.comac10a2d2010-12-22 21:39:39 +000033}
34
35GrInOrderDrawBuffer::~GrInOrderDrawBuffer() {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000036 this->reset();
reed@google.comac10a2d2010-12-22 21:39:39 +000037}
38
bsalomon@google.com934c5702012-03-20 21:17:58 +000039////////////////////////////////////////////////////////////////////////////////
40
bsalomon@google.comd62e88e2013-02-01 14:19:27 +000041namespace {
42void get_vertex_bounds(const void* vertices,
43 size_t vertexSize,
44 int vertexCount,
45 SkRect* bounds) {
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +000046 SkASSERT(vertexSize >= sizeof(SkPoint));
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +000047 SkASSERT(vertexCount > 0);
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +000048 const SkPoint* point = static_cast<const SkPoint*>(vertices);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +000049 bounds->fLeft = bounds->fRight = point->fX;
50 bounds->fTop = bounds->fBottom = point->fY;
51 for (int i = 1; i < vertexCount; ++i) {
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +000052 point = reinterpret_cast<SkPoint*>(reinterpret_cast<intptr_t>(point) + vertexSize);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +000053 bounds->growToInclude(point->fX, point->fY);
54 }
55}
bsalomon@google.com934c5702012-03-20 21:17:58 +000056}
57
bsalomon62c447d2014-08-08 08:08:50 -070058/** We always use per-vertex colors so that rects can be batched across color changes. Sometimes we
59 have explicit local coords and sometimes not. We *could* always provide explicit local coords
60 and just duplicate the positions when the caller hasn't provided a local coord rect, but we
61 haven't seen a use case which frequently switches between local rect and no local rect draws.
62
63 The color param is used to determine whether the opaque hint can be set on the draw state.
64 The caller must populate the vertex colors itself.
65
66 The vertex attrib order is always pos, color, [local coords].
67 */
joshualitt8fc6c2d2014-12-22 15:27:05 -080068static const GrGeometryProcessor* create_rect_gp(bool hasExplicitLocalCoords,
69 GrColor color,
70 const SkMatrix* localMatrix) {
joshualitt5478d422014-11-14 16:00:38 -080071 uint32_t flags = GrDefaultGeoProcFactory::kPosition_GPType |
72 GrDefaultGeoProcFactory::kColor_GPType;
joshualitt8fc6c2d2014-12-22 15:27:05 -080073 flags |= hasExplicitLocalCoords ? GrDefaultGeoProcFactory::kLocalCoord_GPType : 0;
74 if (localMatrix) {
joshualitt8059eb92014-12-29 15:10:07 -080075 return GrDefaultGeoProcFactory::Create(flags, color, SkMatrix::I(), *localMatrix,
76 GrColorIsOpaque(color));
joshualitt8fc6c2d2014-12-22 15:27:05 -080077 } else {
joshualitt8059eb92014-12-29 15:10:07 -080078 return GrDefaultGeoProcFactory::Create(flags, color, SkMatrix::I(), SkMatrix::I(),
79 GrColorIsOpaque(color));
joshualitt8fc6c2d2014-12-22 15:27:05 -080080 }
bsalomon62c447d2014-08-08 08:08:50 -070081}
robertphillips@google.com42903302013-04-20 12:26:07 +000082
cdalton3fc6a2f2014-11-13 11:54:20 -080083static bool path_fill_type_is_winding(const GrStencilSettings& pathStencilSettings) {
84 static const GrStencilSettings::Face pathFace = GrStencilSettings::kFront_Face;
85 bool isWinding = kInvert_StencilOp != pathStencilSettings.passOp(pathFace);
86 if (isWinding) {
87 // Double check that it is in fact winding.
88 SkASSERT(kIncClamp_StencilOp == pathStencilSettings.passOp(pathFace));
89 SkASSERT(kIncClamp_StencilOp == pathStencilSettings.failOp(pathFace));
90 SkASSERT(0x1 != pathStencilSettings.writeMask(pathFace));
91 SkASSERT(!pathStencilSettings.isTwoSided());
92 }
93 return isWinding;
94}
95
96template<typename T> static void reset_data_buffer(SkTDArray<T>* buffer, int minReserve) {
97 // Assume the next time this buffer fills up it will use approximately the same amount
98 // of space as last time. Only resize if we're using less than a third of the
99 // allocated space, and leave enough for 50% growth over last time.
100 if (3 * buffer->count() < buffer->reserved() && buffer->reserved() > minReserve) {
101 int reserve = SkTMax(minReserve, buffer->count() * 3 / 2);
102 buffer->reset();
103 buffer->setReserve(reserve);
104 } else {
105 buffer->rewind();
106 }
107}
108
egdaniel8dd688b2015-01-22 10:16:09 -0800109void GrInOrderDrawBuffer::onDrawRect(GrPipelineBuilder* pipelineBuilder,
joshualitt2e3b3e32014-12-09 13:31:14 -0800110 GrColor color,
joshualitt8059eb92014-12-29 15:10:07 -0800111 const SkMatrix& viewMatrix,
joshualitt9853cce2014-11-17 14:22:48 -0800112 const SkRect& rect,
commit-bot@chromium.orgfd03d4a2013-07-17 21:39:42 +0000113 const SkRect* localRect,
bsalomon@google.com0406b9e2013-04-02 21:00:15 +0000114 const SkMatrix* localMatrix) {
egdaniel8dd688b2015-01-22 10:16:09 -0800115 GrPipelineBuilder::AutoRestoreEffects are(pipelineBuilder);
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000116
joshualittd27f73e2014-12-29 07:43:36 -0800117 // Go to device coords to allow batching across matrix changes
joshualittd27f73e2014-12-29 07:43:36 -0800118 SkMatrix invert = SkMatrix::I();
119
120 // if we have a local rect, then we apply the localMatrix directly to the localRect to generate
121 // vertex local coords
joshualitt8fc6c2d2014-12-22 15:27:05 -0800122 bool hasExplicitLocalCoords = SkToBool(localRect);
joshualittd27f73e2014-12-29 07:43:36 -0800123 if (!hasExplicitLocalCoords) {
joshualitt8059eb92014-12-29 15:10:07 -0800124 if (!viewMatrix.isIdentity() && !viewMatrix.invert(&invert)) {
joshualittd27f73e2014-12-29 07:43:36 -0800125 SkDebugf("Could not invert\n");
126 return;
127 }
128
129 if (localMatrix) {
130 invert.preConcat(*localMatrix);
131 }
132 }
133
134 SkAutoTUnref<const GrGeometryProcessor> gp(create_rect_gp(hasExplicitLocalCoords,
135 color,
136 &invert));
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000137
joshualitt56995b52014-12-11 15:44:02 -0800138 size_t vstride = gp->getVertexStride();
joshualitt2dd1ae02014-12-03 06:24:10 -0800139 SkASSERT(vstride == sizeof(SkPoint) + sizeof(GrColor) + (SkToBool(localRect) ? sizeof(SkPoint) :
140 0));
141 AutoReleaseGeometry geo(this, 4, vstride, 0);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000142 if (!geo.succeeded()) {
tfarina38406c82014-10-31 07:11:12 -0700143 SkDebugf("Failed to get space for vertices!\n");
bsalomon@google.com934c5702012-03-20 21:17:58 +0000144 return;
145 }
146
joshualitt8059eb92014-12-29 15:10:07 -0800147 geo.positions()->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, vstride);
148 viewMatrix.mapPointsWithStride(geo.positions(), vstride, 4);
149
jvanverth@google.com39768252013-02-14 15:25:44 +0000150 // When the caller has provided an explicit source rect for a stage then we don't want to
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000151 // modify that stage's matrix. Otherwise if the effect is generating its source rect from
joshualitt8059eb92014-12-29 15:10:07 -0800152 // the vertex positions then we have to account for the view matrix
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000153 SkRect devBounds;
joshualitt8059eb92014-12-29 15:10:07 -0800154
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000155 // since we already computed the dev verts, set the bounds hint. This will help us avoid
156 // unnecessary clipping in our onDraw().
egdaniel7b3d5ee2014-08-28 05:41:14 -0700157 get_vertex_bounds(geo.vertices(), vstride, 4, &devBounds);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000158
bsalomon49f085d2014-09-05 13:34:00 -0700159 if (localRect) {
bsalomon62c447d2014-08-08 08:08:50 -0700160 static const int kLocalOffset = sizeof(SkPoint) + sizeof(GrColor);
161 SkPoint* coords = GrTCast<SkPoint*>(GrTCast<intptr_t>(geo.vertices()) + kLocalOffset);
bsalomon@google.comc7818882013-03-20 19:19:53 +0000162 coords->setRectFan(localRect->fLeft, localRect->fTop,
163 localRect->fRight, localRect->fBottom,
egdaniel7b3d5ee2014-08-28 05:41:14 -0700164 vstride);
bsalomon49f085d2014-09-05 13:34:00 -0700165 if (localMatrix) {
egdaniel7b3d5ee2014-08-28 05:41:14 -0700166 localMatrix->mapPointsWithStride(coords, vstride, 4);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000167 }
168 }
169
bsalomon62c447d2014-08-08 08:08:50 -0700170 static const int kColorOffset = sizeof(SkPoint);
171 GrColor* vertColor = GrTCast<GrColor*>(GrTCast<intptr_t>(geo.vertices()) + kColorOffset);
172 for (int i = 0; i < 4; ++i) {
173 *vertColor = color;
egdaniel7b3d5ee2014-08-28 05:41:14 -0700174 vertColor = (GrColor*) ((intptr_t) vertColor + vstride);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000175 }
176
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000177 this->setIndexSourceToBuffer(this->getContext()->getQuadIndexBuffer());
egdaniel8dd688b2015-01-22 10:16:09 -0800178 this->drawIndexedInstances(pipelineBuilder, gp, kTriangles_GrPrimitiveType, 1, 4, 6,
179 &devBounds);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000180}
181
egdaniele36914c2015-02-13 09:00:33 -0800182int GrInOrderDrawBuffer::concatInstancedDraw(const DrawInfo& info) {
cdalton6819df32014-10-15 13:43:48 -0700183 SkASSERT(!fCmdBuffer.empty());
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000184 SkASSERT(info.isInstanced());
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000185
bsalomon@google.com934c5702012-03-20 21:17:58 +0000186 const GeometrySrcState& geomSrc = this->getGeomSrc();
187
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000188 // we only attempt to concat the case when reserved verts are used with a client-specified index
189 // buffer. To make this work with client-specified VBs we'd need to know if the VB was updated
190 // between draws.
191 if (kReserved_GeometrySrcType != geomSrc.fVertexSrc ||
192 kBuffer_GeometrySrcType != geomSrc.fIndexSrc) {
193 return 0;
bsalomon@google.com934c5702012-03-20 21:17:58 +0000194 }
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000195 // Check if there is a draw info that is compatible that uses the same VB from the pool and
196 // the same IB
robertphillipse5e72f12015-02-17 09:14:33 -0800197 if (Cmd::kDraw_Cmd != fCmdBuffer.back().type()) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000198 return 0;
199 }
200
cdalton6819df32014-10-15 13:43:48 -0700201 Draw* draw = static_cast<Draw*>(&fCmdBuffer.back());
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000202
cdalton6819df32014-10-15 13:43:48 -0700203 if (!draw->fInfo.isInstanced() ||
joshualitt4d8da812015-01-28 12:53:54 -0800204 draw->fInfo.primitiveType() != info.primitiveType() ||
cdalton6819df32014-10-15 13:43:48 -0700205 draw->fInfo.verticesPerInstance() != info.verticesPerInstance() ||
206 draw->fInfo.indicesPerInstance() != info.indicesPerInstance() ||
bsalomon371bcbc2014-12-01 08:19:34 -0800207 draw->fInfo.vertexBuffer() != info.vertexBuffer() ||
joshualitt54e0c122014-11-19 09:38:51 -0800208 draw->fInfo.indexBuffer() != geomSrc.fIndexBuffer) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000209 return 0;
210 }
bsalomon371bcbc2014-12-01 08:19:34 -0800211 if (draw->fInfo.startVertex() + draw->fInfo.vertexCount() != info.startVertex()) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000212 return 0;
213 }
214
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000215 // how many instances can be concat'ed onto draw given the size of the index buffer
216 int instancesToConcat = this->indexCountInCurrentSource() / info.indicesPerInstance();
cdalton6819df32014-10-15 13:43:48 -0700217 instancesToConcat -= draw->fInfo.instanceCount();
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000218 instancesToConcat = SkTMin(instancesToConcat, info.instanceCount());
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000219
cdalton6819df32014-10-15 13:43:48 -0700220 draw->fInfo.adjustInstanceCount(instancesToConcat);
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000221
222 // update last fGpuCmdMarkers to include any additional trace markers that have been added
223 if (this->getActiveTraceMarkers().count() > 0) {
robertphillipse5e72f12015-02-17 09:14:33 -0800224 if (draw->isTraced()) {
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000225 fGpuCmdMarkers.back().addSet(this->getActiveTraceMarkers());
226 } else {
227 fGpuCmdMarkers.push_back(this->getActiveTraceMarkers());
robertphillipse5e72f12015-02-17 09:14:33 -0800228 draw->makeTraced();
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000229 }
230 }
231
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000232 return instancesToConcat;
bsalomon@google.com934c5702012-03-20 21:17:58 +0000233}
234
egdaniele36914c2015-02-13 09:00:33 -0800235void GrInOrderDrawBuffer::onDraw(const GrGeometryProcessor* gp,
joshualitt9853cce2014-11-17 14:22:48 -0800236 const DrawInfo& info,
egdaniele36914c2015-02-13 09:00:33 -0800237 const PipelineInfo& pipelineInfo) {
joshualitt7eb8c7b2014-11-18 14:24:27 -0800238 SkASSERT(info.vertexBuffer() && (!info.isIndexed() || info.indexBuffer()));
joshualitt4d8da812015-01-28 12:53:54 -0800239 this->closeBatch();
240
egdaniele36914c2015-02-13 09:00:33 -0800241 if (!this->setupPipelineAndShouldDraw(gp, pipelineInfo)) {
bsalomonae59b772014-11-19 08:23:49 -0800242 return;
243 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000244
bsalomonb3e3a952014-09-19 11:10:40 -0700245 Draw* draw;
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000246 if (info.isInstanced()) {
egdaniele36914c2015-02-13 09:00:33 -0800247 int instancesConcated = this->concatInstancedDraw(info);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000248 if (info.instanceCount() > instancesConcated) {
joshualitt54e0c122014-11-19 09:38:51 -0800249 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info));
cdalton6819df32014-10-15 13:43:48 -0700250 draw->fInfo.adjustInstanceCount(-instancesConcated);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000251 } else {
252 return;
253 }
254 } else {
joshualitt54e0c122014-11-19 09:38:51 -0800255 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info));
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000256 }
cdalton6819df32014-10-15 13:43:48 -0700257 this->recordTraceMarkersIfNecessary();
commit-bot@chromium.org9b62aa12014-03-25 11:59:40 +0000258}
sugoi@google.com5f74cf82012-12-17 21:16:45 +0000259
joshualitt4d8da812015-01-28 12:53:54 -0800260void GrInOrderDrawBuffer::onDrawBatch(GrBatch* batch,
egdaniele36914c2015-02-13 09:00:33 -0800261 const PipelineInfo& pipelineInfo) {
262 if (!this->setupPipelineAndShouldDraw(batch, pipelineInfo)) {
joshualitt4d8da812015-01-28 12:53:54 -0800263 return;
264 }
265
266 // Check if there is a Batch Draw we can batch with
robertphillipse5e72f12015-02-17 09:14:33 -0800267 if (Cmd::kDrawBatch_Cmd != fCmdBuffer.back().type()) {
joshualitt4d8da812015-01-28 12:53:54 -0800268 fDrawBatch = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawBatch, (batch));
269 return;
270 }
271
272 DrawBatch* draw = static_cast<DrawBatch*>(&fCmdBuffer.back());
273 if (draw->fBatch->combineIfPossible(batch)) {
274 return;
275 } else {
276 this->closeBatch();
277 fDrawBatch = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawBatch, (batch));
278 }
279 this->recordTraceMarkersIfNecessary();
280}
281
egdaniel8dd688b2015-01-22 10:16:09 -0800282void GrInOrderDrawBuffer::onStencilPath(const GrPipelineBuilder& pipelineBuilder,
joshualitt56995b52014-12-11 15:44:02 -0800283 const GrPathProcessor* pathProc,
joshualitt9853cce2014-11-17 14:22:48 -0800284 const GrPath* path,
bsalomon3e791242014-12-17 13:43:13 -0800285 const GrScissorState& scissorState,
joshualitt2c93efe2014-11-06 12:57:13 -0800286 const GrStencilSettings& stencilSettings) {
joshualitt70f00042015-02-06 15:53:59 -0800287 this->closeBatch();
288
bsalomon3e791242014-12-17 13:43:13 -0800289 StencilPath* sp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, StencilPath,
egdaniel8dd688b2015-01-22 10:16:09 -0800290 (path, pipelineBuilder.getRenderTarget()));
bsalomon3e791242014-12-17 13:43:13 -0800291 sp->fScissor = scissorState;
egdaniel8dd688b2015-01-22 10:16:09 -0800292 sp->fUseHWAA = pipelineBuilder.isHWAntialias();
joshualitt8059eb92014-12-29 15:10:07 -0800293 sp->fViewMatrix = pathProc->viewMatrix();
bsalomon3e791242014-12-17 13:43:13 -0800294 sp->fStencil = stencilSettings;
cdalton6819df32014-10-15 13:43:48 -0700295 this->recordTraceMarkersIfNecessary();
bsalomon@google.com64aef2b2012-06-11 15:36:13 +0000296}
297
egdaniele36914c2015-02-13 09:00:33 -0800298void GrInOrderDrawBuffer::onDrawPath(const GrPathProcessor* pathProc,
joshualitt9853cce2014-11-17 14:22:48 -0800299 const GrPath* path,
joshualitt2c93efe2014-11-06 12:57:13 -0800300 const GrStencilSettings& stencilSettings,
egdaniele36914c2015-02-13 09:00:33 -0800301 const PipelineInfo& pipelineInfo) {
joshualitt4d8da812015-01-28 12:53:54 -0800302 this->closeBatch();
303
egdaniel8dd688b2015-01-22 10:16:09 -0800304 // TODO: Only compare the subset of GrPipelineBuilder relevant to path covering?
egdaniele36914c2015-02-13 09:00:33 -0800305 if (!this->setupPipelineAndShouldDraw(pathProc, pipelineInfo)) {
bsalomonae59b772014-11-19 08:23:49 -0800306 return;
307 }
cdalton6819df32014-10-15 13:43:48 -0700308 DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (path));
joshualitt2c93efe2014-11-06 12:57:13 -0800309 dp->fStencilSettings = stencilSettings;
cdalton6819df32014-10-15 13:43:48 -0700310 this->recordTraceMarkersIfNecessary();
commit-bot@chromium.orgc4dc0ad2013-10-09 14:11:33 +0000311}
312
egdaniele36914c2015-02-13 09:00:33 -0800313void GrInOrderDrawBuffer::onDrawPaths(const GrPathProcessor* pathProc,
joshualitt9853cce2014-11-17 14:22:48 -0800314 const GrPathRange* pathRange,
cdalton55b24af2014-11-25 11:00:56 -0800315 const void* indices,
316 PathIndexType indexType,
317 const float transformValues[],
318 PathTransformType transformType,
joshualitt2c93efe2014-11-06 12:57:13 -0800319 int count,
joshualitt2c93efe2014-11-06 12:57:13 -0800320 const GrStencilSettings& stencilSettings,
egdaniele36914c2015-02-13 09:00:33 -0800321 const PipelineInfo& pipelineInfo) {
bsalomon49f085d2014-09-05 13:34:00 -0700322 SkASSERT(pathRange);
323 SkASSERT(indices);
cdalton55b24af2014-11-25 11:00:56 -0800324 SkASSERT(transformValues);
joshualitt4d8da812015-01-28 12:53:54 -0800325 this->closeBatch();
326
egdaniele36914c2015-02-13 09:00:33 -0800327 if (!this->setupPipelineAndShouldDraw(pathProc, pipelineInfo)) {
bsalomonae59b772014-11-19 08:23:49 -0800328 return;
329 }
cdalton6819df32014-10-15 13:43:48 -0700330
cdalton55b24af2014-11-25 11:00:56 -0800331 int indexBytes = GrPathRange::PathIndexSizeInBytes(indexType);
332 if (int misalign = fPathIndexBuffer.count() % indexBytes) {
333 // Add padding to the index buffer so the indices are aligned properly.
334 fPathIndexBuffer.append(indexBytes - misalign);
335 }
336
337 char* savedIndices = fPathIndexBuffer.append(count * indexBytes,
338 reinterpret_cast<const char*>(indices));
339 float* savedTransforms = fPathTransformBuffer.append(
340 count * GrPathRendering::PathTransformSize(transformType),
341 transformValues);
cdalton6819df32014-10-15 13:43:48 -0700342
robertphillipse5e72f12015-02-17 09:14:33 -0800343 if (Cmd::kDrawPaths_Cmd == fCmdBuffer.back().type()) {
cdalton3fc6a2f2014-11-13 11:54:20 -0800344 // The previous command was also DrawPaths. Try to collapse this call into the one
bsalomon371bcbc2014-12-01 08:19:34 -0800345 // before. Note that stenciling all the paths at once, then covering, may not be
cdalton3fc6a2f2014-11-13 11:54:20 -0800346 // equivalent to two separate draw calls if there is overlap. Blending won't work,
347 // and the combined calls may also cancel each other's winding numbers in some
348 // places. For now the winding numbers are only an issue if the fill is even/odd,
349 // because DrawPaths is currently only used for glyphs, and glyphs in the same
350 // font tend to all wind in the same direction.
351 DrawPaths* previous = static_cast<DrawPaths*>(&fCmdBuffer.back());
352 if (pathRange == previous->pathRange() &&
cdalton55b24af2014-11-25 11:00:56 -0800353 indexType == previous->fIndexType &&
354 transformType == previous->fTransformType &&
cdalton3fc6a2f2014-11-13 11:54:20 -0800355 stencilSettings == previous->fStencilSettings &&
356 path_fill_type_is_winding(stencilSettings) &&
egdaniele36914c2015-02-13 09:00:33 -0800357 !pipelineInfo.willBlendWithDst(pathProc)) {
cdalton3fc6a2f2014-11-13 11:54:20 -0800358 // Fold this DrawPaths call into the one previous.
359 previous->fCount += count;
360 return;
361 }
362 }
363
364 DrawPaths* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPaths, (pathRange));
bsalomonef3fcd82014-12-12 08:51:38 -0800365 dp->fIndicesLocation = SkToU32(savedIndices - fPathIndexBuffer.begin());
cdalton55b24af2014-11-25 11:00:56 -0800366 dp->fIndexType = indexType;
bsalomonef3fcd82014-12-12 08:51:38 -0800367 dp->fTransformsLocation = SkToU32(savedTransforms - fPathTransformBuffer.begin());
cdalton55b24af2014-11-25 11:00:56 -0800368 dp->fTransformType = transformType;
369 dp->fCount = count;
joshualitt2c93efe2014-11-06 12:57:13 -0800370 dp->fStencilSettings = stencilSettings;
cdalton6819df32014-10-15 13:43:48 -0700371
372 this->recordTraceMarkersIfNecessary();
commit-bot@chromium.org9b62aa12014-03-25 11:59:40 +0000373}
374
bsalomon63b21962014-11-05 07:05:34 -0800375void GrInOrderDrawBuffer::onClear(const SkIRect* rect, GrColor color,
376 bool canIgnoreRect, GrRenderTarget* renderTarget) {
joshualitt9853cce2014-11-17 14:22:48 -0800377 SkASSERT(renderTarget);
joshualitt70f00042015-02-06 15:53:59 -0800378 this->closeBatch();
379
commit-bot@chromium.orgfd03d4a2013-07-17 21:39:42 +0000380 SkIRect r;
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000381 if (NULL == rect) {
382 // We could do something smart and remove previous draws and clears to
383 // the current render target. If we get that smart we have to make sure
384 // those draws aren't read before this clear (render-to-texture).
bsalomon@google.com1b3ce472012-08-17 13:43:08 +0000385 r.setLTRB(0, 0, renderTarget->width(), renderTarget->height());
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000386 rect = &r;
387 }
cdalton6819df32014-10-15 13:43:48 -0700388 Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget));
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000389 GrColorIsPMAssert(color);
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000390 clr->fColor = color;
391 clr->fRect = *rect;
robertphillips@google.com56ce48a2013-10-31 21:44:25 +0000392 clr->fCanIgnoreRect = canIgnoreRect;
cdalton6819df32014-10-15 13:43:48 -0700393 this->recordTraceMarkersIfNecessary();
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000394}
395
joshualitt6db519c2014-10-29 08:48:18 -0700396void GrInOrderDrawBuffer::clearStencilClip(const SkIRect& rect,
397 bool insideClip,
398 GrRenderTarget* renderTarget) {
joshualitt9853cce2014-11-17 14:22:48 -0800399 SkASSERT(renderTarget);
joshualitt70f00042015-02-06 15:53:59 -0800400 this->closeBatch();
401
joshualitt6db519c2014-10-29 08:48:18 -0700402 ClearStencilClip* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, ClearStencilClip, (renderTarget));
403 clr->fRect = rect;
404 clr->fInsideClip = insideClip;
405 this->recordTraceMarkersIfNecessary();
406}
407
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000408void GrInOrderDrawBuffer::discard(GrRenderTarget* renderTarget) {
bsalomon89c62982014-11-03 12:08:42 -0800409 SkASSERT(renderTarget);
joshualitt70f00042015-02-06 15:53:59 -0800410 this->closeBatch();
411
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000412 if (!this->caps()->discardRenderTargetSupport()) {
413 return;
414 }
cdalton6819df32014-10-15 13:43:48 -0700415 Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget));
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000416 clr->fColor = GrColor_ILLEGAL;
cdalton6819df32014-10-15 13:43:48 -0700417 this->recordTraceMarkersIfNecessary();
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000418}
419
bsalomon371bcbc2014-12-01 08:19:34 -0800420void GrInOrderDrawBuffer::onReset() {
cdalton6819df32014-10-15 13:43:48 -0700421 fCmdBuffer.reset();
bsalomon932f8662014-11-24 06:47:48 -0800422 fPrevState = NULL;
cdalton3fc6a2f2014-11-13 11:54:20 -0800423 reset_data_buffer(&fPathIndexBuffer, kPathIdxBufferMinReserve);
424 reset_data_buffer(&fPathTransformBuffer, kPathXformBufferMinReserve);
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000425 fGpuCmdMarkers.reset();
joshualitt4d8da812015-01-28 12:53:54 -0800426 fDrawBatch = NULL;
reed@google.comac10a2d2010-12-22 21:39:39 +0000427}
428
bsalomon371bcbc2014-12-01 08:19:34 -0800429void GrInOrderDrawBuffer::onFlush() {
cdalton6819df32014-10-15 13:43:48 -0700430 if (fCmdBuffer.empty()) {
robertphillips@google.com1267fbd2013-07-03 18:37:27 +0000431 return;
reed@google.comac10a2d2010-12-22 21:39:39 +0000432 }
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000433
joshualittc2893c52015-01-28 06:54:30 -0800434 // Updated every time we find a set state cmd to reflect the current state in the playback
435 // stream.
436 SetState* currentState = NULL;
437
joshualitt4d8da812015-01-28 12:53:54 -0800438 // TODO this is temporary while batch is being rolled out
439 this->closeBatch();
440 this->getVertexAllocPool()->unmap();
441 this->getIndexAllocPool()->unmap();
442 fBatchTarget.preFlush();
443
444 currentState = NULL;
445 CmdBuffer::Iter iter(fCmdBuffer);
446
447 int currCmdMarker = 0;
448
joshualitt7bc18b72015-02-03 16:41:41 -0800449 int i = 0;
cdalton6819df32014-10-15 13:43:48 -0700450 while (iter.next()) {
joshualitt7bc18b72015-02-03 16:41:41 -0800451 i++;
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000452 GrGpuTraceMarker newMarker("", -1);
egdanield78a1682014-07-09 10:41:26 -0700453 SkString traceString;
robertphillipse5e72f12015-02-17 09:14:33 -0800454 if (iter->isTraced()) {
egdanield78a1682014-07-09 10:41:26 -0700455 traceString = fGpuCmdMarkers[currCmdMarker].toString();
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000456 newMarker.fMarker = traceString.c_str();
bsalomon371bcbc2014-12-01 08:19:34 -0800457 this->getGpu()->addGpuTraceMarker(&newMarker);
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000458 ++currCmdMarker;
459 }
cdalton6819df32014-10-15 13:43:48 -0700460
joshualitt4d8da812015-01-28 12:53:54 -0800461 // TODO temporary hack
robertphillipse5e72f12015-02-17 09:14:33 -0800462 if (Cmd::kDrawBatch_Cmd == iter->type()) {
joshualitt7bc18b72015-02-03 16:41:41 -0800463 DrawBatch* db = reinterpret_cast<DrawBatch*>(iter.get());
464 fBatchTarget.flushNext(db->fBatch->numberOfDraws());
joshualitt4d8da812015-01-28 12:53:54 -0800465 continue;
466 }
467
robertphillipse5e72f12015-02-17 09:14:33 -0800468 if (Cmd::kSetState_Cmd == iter->type()) {
joshualitt9853cce2014-11-17 14:22:48 -0800469 SetState* ss = reinterpret_cast<SetState*>(iter.get());
joshualitt873ad0e2015-01-20 09:08:51 -0800470
joshualitt4d8da812015-01-28 12:53:54 -0800471 // TODO sometimes we have a prim proc, othertimes we have a GrBatch. Eventually we will
472 // only have GrBatch and we can delete this
473 if (ss->fPrimitiveProcessor) {
474 this->getGpu()->buildProgramDesc(&ss->fDesc, *ss->fPrimitiveProcessor,
egdaniele36914c2015-02-13 09:00:33 -0800475 *ss->getPipeline(),
joshualitt4d8da812015-01-28 12:53:54 -0800476 ss->fBatchTracker);
477 }
joshualitt873ad0e2015-01-20 09:08:51 -0800478 currentState = ss;
joshualittd53a8272014-11-10 16:03:14 -0800479 } else {
joshualitt873ad0e2015-01-20 09:08:51 -0800480 iter->execute(this, currentState);
joshualittd53a8272014-11-10 16:03:14 -0800481 }
cdalton6819df32014-10-15 13:43:48 -0700482
robertphillipse5e72f12015-02-17 09:14:33 -0800483 if (iter->isTraced()) {
bsalomon371bcbc2014-12-01 08:19:34 -0800484 this->getGpu()->removeGpuTraceMarker(&newMarker);
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000485 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000486 }
mtkleinf439c772014-10-14 14:29:30 -0700487
joshualitt4d8da812015-01-28 12:53:54 -0800488 // TODO see copious notes about hack
489 fBatchTarget.postFlush();
490
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000491 SkASSERT(fGpuCmdMarkers.count() == currCmdMarker);
commit-bot@chromium.orga8916ff2013-08-16 15:53:46 +0000492 ++fDrawID;
reed@google.comac10a2d2010-12-22 21:39:39 +0000493}
494
joshualitt873ad0e2015-01-20 09:08:51 -0800495void GrInOrderDrawBuffer::Draw::execute(GrInOrderDrawBuffer* buf, const SetState* state) {
496 SkASSERT(state);
egdaniele36914c2015-02-13 09:00:33 -0800497 DrawArgs args(state->fPrimitiveProcessor.get(), state->getPipeline(), &state->fDesc,
joshualitt17e73142015-01-21 11:52:36 -0800498 &state->fBatchTracker);
joshualitt873ad0e2015-01-20 09:08:51 -0800499 buf->getGpu()->draw(args, fInfo);
cdalton6819df32014-10-15 13:43:48 -0700500}
501
joshualitt873ad0e2015-01-20 09:08:51 -0800502void GrInOrderDrawBuffer::StencilPath::execute(GrInOrderDrawBuffer* buf, const SetState*) {
bsalomon3e791242014-12-17 13:43:13 -0800503 GrGpu::StencilPathState state;
504 state.fRenderTarget = fRenderTarget.get();
505 state.fScissor = &fScissor;
506 state.fStencil = &fStencil;
507 state.fUseHWAA = fUseHWAA;
508 state.fViewMatrix = &fViewMatrix;
509
510 buf->getGpu()->stencilPath(this->path(), state);
cdalton6819df32014-10-15 13:43:48 -0700511}
512
joshualitt873ad0e2015-01-20 09:08:51 -0800513void GrInOrderDrawBuffer::DrawPath::execute(GrInOrderDrawBuffer* buf, const SetState* state) {
514 SkASSERT(state);
egdaniele36914c2015-02-13 09:00:33 -0800515 DrawArgs args(state->fPrimitiveProcessor.get(), state->getPipeline(), &state->fDesc,
joshualitt17e73142015-01-21 11:52:36 -0800516 &state->fBatchTracker);
joshualitt873ad0e2015-01-20 09:08:51 -0800517 buf->getGpu()->drawPath(args, this->path(), fStencilSettings);
cdalton6819df32014-10-15 13:43:48 -0700518}
519
joshualitt873ad0e2015-01-20 09:08:51 -0800520void GrInOrderDrawBuffer::DrawPaths::execute(GrInOrderDrawBuffer* buf, const SetState* state) {
521 SkASSERT(state);
egdaniele36914c2015-02-13 09:00:33 -0800522 DrawArgs args(state->fPrimitiveProcessor.get(), state->getPipeline(), &state->fDesc,
joshualitt17e73142015-01-21 11:52:36 -0800523 &state->fBatchTracker);
joshualitt873ad0e2015-01-20 09:08:51 -0800524 buf->getGpu()->drawPaths(args, this->pathRange(),
cdalton55b24af2014-11-25 11:00:56 -0800525 &buf->fPathIndexBuffer[fIndicesLocation], fIndexType,
526 &buf->fPathTransformBuffer[fTransformsLocation], fTransformType,
527 fCount, fStencilSettings);
cdalton6819df32014-10-15 13:43:48 -0700528}
529
joshualitt4d8da812015-01-28 12:53:54 -0800530void GrInOrderDrawBuffer::DrawBatch::execute(GrInOrderDrawBuffer* buf, const SetState* state) {
531 SkASSERT(state);
egdaniele36914c2015-02-13 09:00:33 -0800532 fBatch->generateGeometry(buf->getBatchTarget(), state->getPipeline());
joshualitt4d8da812015-01-28 12:53:54 -0800533}
534
joshualitt873ad0e2015-01-20 09:08:51 -0800535void GrInOrderDrawBuffer::SetState::execute(GrInOrderDrawBuffer*, const SetState*) {}
cdalton6819df32014-10-15 13:43:48 -0700536
joshualitt873ad0e2015-01-20 09:08:51 -0800537void GrInOrderDrawBuffer::Clear::execute(GrInOrderDrawBuffer* buf, const SetState*) {
cdalton6819df32014-10-15 13:43:48 -0700538 if (GrColor_ILLEGAL == fColor) {
bsalomon371bcbc2014-12-01 08:19:34 -0800539 buf->getGpu()->discard(this->renderTarget());
cdalton6819df32014-10-15 13:43:48 -0700540 } else {
bsalomon371bcbc2014-12-01 08:19:34 -0800541 buf->getGpu()->clear(&fRect, fColor, fCanIgnoreRect, this->renderTarget());
cdalton6819df32014-10-15 13:43:48 -0700542 }
543}
544
joshualitt873ad0e2015-01-20 09:08:51 -0800545void GrInOrderDrawBuffer::ClearStencilClip::execute(GrInOrderDrawBuffer* buf, const SetState*) {
bsalomon371bcbc2014-12-01 08:19:34 -0800546 buf->getGpu()->clearStencilClip(fRect, fInsideClip, this->renderTarget());
joshualitt6db519c2014-10-29 08:48:18 -0700547}
548
joshualitt873ad0e2015-01-20 09:08:51 -0800549void GrInOrderDrawBuffer::CopySurface::execute(GrInOrderDrawBuffer* buf, const SetState*) {
bsalomon371bcbc2014-12-01 08:19:34 -0800550 buf->getGpu()->copySurface(this->dst(), this->src(), fSrcRect, fDstPoint);
cdalton6819df32014-10-15 13:43:48 -0700551}
552
bsalomonf90a02b2014-11-26 12:28:00 -0800553bool GrInOrderDrawBuffer::onCopySurface(GrSurface* dst,
554 GrSurface* src,
555 const SkIRect& srcRect,
556 const SkIPoint& dstPoint) {
bsalomon371bcbc2014-12-01 08:19:34 -0800557 if (getGpu()->canCopySurface(dst, src, srcRect, dstPoint)) {
joshualitt95964c62015-02-11 13:45:50 -0800558 this->closeBatch();
cdalton6819df32014-10-15 13:43:48 -0700559 CopySurface* cs = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, CopySurface, (dst, src));
bsalomon@google.com116ad842013-04-09 15:38:19 +0000560 cs->fSrcRect = srcRect;
561 cs->fDstPoint = dstPoint;
cdalton6819df32014-10-15 13:43:48 -0700562 this->recordTraceMarkersIfNecessary();
bsalomon@google.com116ad842013-04-09 15:38:19 +0000563 return true;
bsalomon@google.com116ad842013-04-09 15:38:19 +0000564 }
bsalomonf90a02b2014-11-26 12:28:00 -0800565 return false;
bsalomon@google.com116ad842013-04-09 15:38:19 +0000566}
567
egdaniele36914c2015-02-13 09:00:33 -0800568bool GrInOrderDrawBuffer::setupPipelineAndShouldDraw(const GrPrimitiveProcessor* primProc,
569 const PipelineInfo& pipelineInfo) {
570 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (primProc));
571 this->setupPipeline(pipelineInfo, ss->pipelineLocation());
572
573 if (ss->getPipeline()->mustSkip()) {
bsalomon932f8662014-11-24 06:47:48 -0800574 fCmdBuffer.pop_back();
bsalomonae59b772014-11-19 08:23:49 -0800575 return false;
576 }
joshualitt873ad0e2015-01-20 09:08:51 -0800577
578 ss->fPrimitiveProcessor->initBatchTracker(&ss->fBatchTracker,
egdaniele36914c2015-02-13 09:00:33 -0800579 ss->getPipeline()->getInitBatchTracker());
joshualitt873ad0e2015-01-20 09:08:51 -0800580
joshualitt4d8da812015-01-28 12:53:54 -0800581 if (fPrevState && fPrevState->fPrimitiveProcessor.get() &&
joshualitt873ad0e2015-01-20 09:08:51 -0800582 fPrevState->fPrimitiveProcessor->canMakeEqual(fPrevState->fBatchTracker,
583 *ss->fPrimitiveProcessor,
584 ss->fBatchTracker) &&
egdaniele36914c2015-02-13 09:00:33 -0800585 fPrevState->getPipeline()->isEqual(*ss->getPipeline())) {
bsalomon932f8662014-11-24 06:47:48 -0800586 fCmdBuffer.pop_back();
587 } else {
joshualitt873ad0e2015-01-20 09:08:51 -0800588 fPrevState = ss;
cdalton6819df32014-10-15 13:43:48 -0700589 this->recordTraceMarkersIfNecessary();
bsalomon838f62d2014-08-05 07:15:57 -0700590 }
bsalomonae59b772014-11-19 08:23:49 -0800591 return true;
reed@google.comac10a2d2010-12-22 21:39:39 +0000592}
593
egdaniele36914c2015-02-13 09:00:33 -0800594bool GrInOrderDrawBuffer::setupPipelineAndShouldDraw(GrBatch* batch,
595 const PipelineInfo& pipelineInfo) {
596 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, ());
597 this->setupPipeline(pipelineInfo, ss->pipelineLocation());
598
599 if (ss->getPipeline()->mustSkip()) {
joshualitt4d8da812015-01-28 12:53:54 -0800600 fCmdBuffer.pop_back();
601 return false;
602 }
603
egdaniele36914c2015-02-13 09:00:33 -0800604 batch->initBatchTracker(ss->getPipeline()->getInitBatchTracker());
joshualitt4d8da812015-01-28 12:53:54 -0800605
606 if (fPrevState && !fPrevState->fPrimitiveProcessor.get() &&
egdaniele36914c2015-02-13 09:00:33 -0800607 fPrevState->getPipeline()->isEqual(*ss->getPipeline())) {
joshualitt4d8da812015-01-28 12:53:54 -0800608 fCmdBuffer.pop_back();
609 } else {
610 this->closeBatch();
611 fPrevState = ss;
612 this->recordTraceMarkersIfNecessary();
613 }
614 return true;
615}
616
cdalton6819df32014-10-15 13:43:48 -0700617void GrInOrderDrawBuffer::recordTraceMarkersIfNecessary() {
618 SkASSERT(!fCmdBuffer.empty());
robertphillipse5e72f12015-02-17 09:14:33 -0800619 SkASSERT(!fCmdBuffer.back().isTraced());
mtkleinf439c772014-10-14 14:29:30 -0700620 const GrTraceMarkerSet& activeTraceMarkers = this->getActiveTraceMarkers();
621 if (activeTraceMarkers.count() > 0) {
robertphillipse5e72f12015-02-17 09:14:33 -0800622 fCmdBuffer.back().makeTraced();
mtkleinf439c772014-10-14 14:29:30 -0700623 fGpuCmdMarkers.push_back(activeTraceMarkers);
mtklein07894c42014-10-13 14:00:42 -0700624 }
mtklein07894c42014-10-13 14:00:42 -0700625}
joshualitt4d8da812015-01-28 12:53:54 -0800626
joshualitt4d8da812015-01-28 12:53:54 -0800627void GrInOrderDrawBuffer::willReserveVertexAndIndexSpace(int vertexCount,
628 size_t vertexStride,
629 int indexCount) {
630 this->closeBatch();
631
robertphillips54fac8b2015-02-16 09:35:50 -0800632 this->INHERITED::willReserveVertexAndIndexSpace(vertexCount, vertexStride, indexCount);
joshualitt4d8da812015-01-28 12:53:54 -0800633}