blob: d89dd430d788eecab876d2e728761fe26d746052 [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)
robertphillips9888b222015-02-27 08:50:34 -080024 , fPathIndexBuffer(kPathIdxBufferMinReserve * sizeof(char)/4)
25 , fPathTransformBuffer(kPathXformBufferMinReserve * sizeof(float)/4)
joshualitt4d8da812015-01-28 12:53:54 -080026 , fDrawID(0)
27 , fBatchTarget(gpu, vertexPool, indexPool)
28 , fDrawBatch(NULL) {
bsalomon@google.com18c9c192011-09-22 21:01:31 +000029
bsalomon49f085d2014-09-05 13:34:00 -070030 SkASSERT(vertexPool);
31 SkASSERT(indexPool);
reed@google.comac10a2d2010-12-22 21:39:39 +000032}
33
34GrInOrderDrawBuffer::~GrInOrderDrawBuffer() {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000035 this->reset();
reed@google.comac10a2d2010-12-22 21:39:39 +000036}
37
robertphillips7f966f42015-03-02 06:40:12 -080038void GrInOrderDrawBuffer::closeBatch() {
39 if (fDrawBatch) {
40 fBatchTarget.resetNumberOfDraws();
41 fDrawBatch->execute(this->getGpu(), fPrevState);
42 fDrawBatch->fBatch->setNumberOfDraws(fBatchTarget.numberOfDraws());
43 fDrawBatch = NULL;
44 }
45}
46
bsalomon@google.com934c5702012-03-20 21:17:58 +000047////////////////////////////////////////////////////////////////////////////////
48
bsalomon62c447d2014-08-08 08:08:50 -070049/** We always use per-vertex colors so that rects can be batched across color changes. Sometimes we
50 have explicit local coords and sometimes not. We *could* always provide explicit local coords
51 and just duplicate the positions when the caller hasn't provided a local coord rect, but we
52 haven't seen a use case which frequently switches between local rect and no local rect draws.
53
54 The color param is used to determine whether the opaque hint can be set on the draw state.
55 The caller must populate the vertex colors itself.
56
57 The vertex attrib order is always pos, color, [local coords].
58 */
joshualitt8fc6c2d2014-12-22 15:27:05 -080059static const GrGeometryProcessor* create_rect_gp(bool hasExplicitLocalCoords,
60 GrColor color,
61 const SkMatrix* localMatrix) {
joshualitt5478d422014-11-14 16:00:38 -080062 uint32_t flags = GrDefaultGeoProcFactory::kPosition_GPType |
63 GrDefaultGeoProcFactory::kColor_GPType;
joshualitt8fc6c2d2014-12-22 15:27:05 -080064 flags |= hasExplicitLocalCoords ? GrDefaultGeoProcFactory::kLocalCoord_GPType : 0;
65 if (localMatrix) {
joshualitt8059eb92014-12-29 15:10:07 -080066 return GrDefaultGeoProcFactory::Create(flags, color, SkMatrix::I(), *localMatrix,
67 GrColorIsOpaque(color));
joshualitt8fc6c2d2014-12-22 15:27:05 -080068 } else {
joshualitt8059eb92014-12-29 15:10:07 -080069 return GrDefaultGeoProcFactory::Create(flags, color, SkMatrix::I(), SkMatrix::I(),
70 GrColorIsOpaque(color));
joshualitt8fc6c2d2014-12-22 15:27:05 -080071 }
bsalomon62c447d2014-08-08 08:08:50 -070072}
robertphillips@google.com42903302013-04-20 12:26:07 +000073
cdalton3fc6a2f2014-11-13 11:54:20 -080074static bool path_fill_type_is_winding(const GrStencilSettings& pathStencilSettings) {
75 static const GrStencilSettings::Face pathFace = GrStencilSettings::kFront_Face;
76 bool isWinding = kInvert_StencilOp != pathStencilSettings.passOp(pathFace);
77 if (isWinding) {
78 // Double check that it is in fact winding.
79 SkASSERT(kIncClamp_StencilOp == pathStencilSettings.passOp(pathFace));
80 SkASSERT(kIncClamp_StencilOp == pathStencilSettings.failOp(pathFace));
81 SkASSERT(0x1 != pathStencilSettings.writeMask(pathFace));
82 SkASSERT(!pathStencilSettings.isTwoSided());
83 }
84 return isWinding;
85}
86
joshualitt58773332015-02-23 16:41:42 -080087class RectBatch : public GrBatch {
88public:
89 struct Geometry {
90 GrColor fColor;
91 SkMatrix fViewMatrix;
92 SkRect fRect;
93 bool fHasLocalRect;
94 bool fHasLocalMatrix;
95 SkRect fLocalRect;
96 SkMatrix fLocalMatrix;
97 };
98
99 static GrBatch* Create(const Geometry& geometry) {
100 return SkNEW_ARGS(RectBatch, (geometry));
101 }
102
103 const char* name() const SK_OVERRIDE { return "RectBatch"; }
104
105 void getInvariantOutputColor(GrInitInvariantOutput* out) const SK_OVERRIDE {
106 // When this is called on a batch, there is only one geometry bundle
107 out->setKnownFourComponents(fGeoData[0].fColor);
108 }
109
110 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const SK_OVERRIDE {
111 out->setKnownSingleComponent(0xff);
112 }
113
114 void initBatchTracker(const GrPipelineInfo& init) SK_OVERRIDE {
115 // Handle any color overrides
116 if (init.fColorIgnored) {
117 fGeoData[0].fColor = GrColor_ILLEGAL;
118 } else if (GrColor_ILLEGAL != init.fOverrideColor) {
119 fGeoData[0].fColor = init.fOverrideColor;
120 }
121
122 // setup batch properties
123 fBatch.fColorIgnored = init.fColorIgnored;
124 fBatch.fColor = fGeoData[0].fColor;
125 fBatch.fUsesLocalCoords = init.fUsesLocalCoords;
126 fBatch.fCoverageIgnored = init.fCoverageIgnored;
127 }
128
129 void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) SK_OVERRIDE {
130 // Go to device coords to allow batching across matrix changes
131 SkMatrix invert = SkMatrix::I();
132
133 // if we have a local rect, then we apply the localMatrix directly to the localRect to
134 // generate vertex local coords
135 bool hasExplicitLocalCoords = this->hasLocalRect();
136 if (!hasExplicitLocalCoords) {
137 if (!this->viewMatrix().isIdentity() && !this->viewMatrix().invert(&invert)) {
138 SkDebugf("Could not invert\n");
139 return;
140 }
141
142 if (this->hasLocalMatrix()) {
143 invert.preConcat(this->localMatrix());
144 }
145 }
146
147 SkAutoTUnref<const GrGeometryProcessor> gp(create_rect_gp(hasExplicitLocalCoords,
148 this->color(),
149 &invert));
150
151 batchTarget->initDraw(gp, pipeline);
152
153 // TODO this is hacky, but the only way we have to initialize the GP is to use the
154 // GrPipelineInfo struct so we can generate the correct shader. Once we have GrBatch
155 // everywhere we can remove this nastiness
156 GrPipelineInfo init;
157 init.fColorIgnored = fBatch.fColorIgnored;
158 init.fOverrideColor = GrColor_ILLEGAL;
159 init.fCoverageIgnored = fBatch.fCoverageIgnored;
160 init.fUsesLocalCoords = this->usesLocalCoords();
161 gp->initBatchTracker(batchTarget->currentBatchTracker(), init);
162
163 size_t vertexStride = gp->getVertexStride();
164
165 SkASSERT(hasExplicitLocalCoords ?
166 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordAttr) :
167 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAttr));
168
169 int instanceCount = fGeoData.count();
170 int vertexCount = kVertsPerRect * instanceCount;
171
172 const GrVertexBuffer* vertexBuffer;
173 int firstVertex;
174
175 void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
176 vertexCount,
177 &vertexBuffer,
178 &firstVertex);
179
180 for (int i = 0; i < instanceCount; i++) {
181 const Geometry& args = fGeoData[i];
182
183 intptr_t offset = GrTCast<intptr_t>(vertices) + kVertsPerRect * i * vertexStride;
184 SkPoint* positions = GrTCast<SkPoint*>(offset);
185
186 positions->setRectFan(args.fRect.fLeft, args.fRect.fTop,
187 args.fRect.fRight, args.fRect.fBottom, vertexStride);
188 args.fViewMatrix.mapPointsWithStride(positions, vertexStride, kVertsPerRect);
189
190 if (args.fHasLocalRect) {
191 static const int kLocalOffset = sizeof(SkPoint) + sizeof(GrColor);
192 SkPoint* coords = GrTCast<SkPoint*>(offset + kLocalOffset);
193 coords->setRectFan(args.fLocalRect.fLeft, args.fLocalRect.fTop,
194 args.fLocalRect.fRight, args.fLocalRect.fBottom,
195 vertexStride);
196 if (args.fHasLocalMatrix) {
197 args.fLocalMatrix.mapPointsWithStride(coords, vertexStride, kVertsPerRect);
198 }
199 }
200
201 static const int kColorOffset = sizeof(SkPoint);
202 GrColor* vertColor = GrTCast<GrColor*>(offset + kColorOffset);
203 for (int j = 0; j < 4; ++j) {
204 *vertColor = args.fColor;
205 vertColor = (GrColor*) ((intptr_t) vertColor + vertexStride);
206 }
207 }
208
209 const GrIndexBuffer* quadIndexBuffer = batchTarget->quadIndexBuffer();
210
211 GrDrawTarget::DrawInfo drawInfo;
212 drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType);
213 drawInfo.setStartVertex(0);
214 drawInfo.setStartIndex(0);
215 drawInfo.setVerticesPerInstance(kVertsPerRect);
216 drawInfo.setIndicesPerInstance(kIndicesPerRect);
217 drawInfo.adjustStartVertex(firstVertex);
218 drawInfo.setVertexBuffer(vertexBuffer);
219 drawInfo.setIndexBuffer(quadIndexBuffer);
220
221 int maxInstancesPerDraw = quadIndexBuffer->maxQuads();
222 while (instanceCount) {
223 drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw));
224 drawInfo.setVertexCount(drawInfo.instanceCount() * drawInfo.verticesPerInstance());
225 drawInfo.setIndexCount(drawInfo.instanceCount() * drawInfo.indicesPerInstance());
226
227 batchTarget->draw(drawInfo);
228
229 drawInfo.setStartVertex(drawInfo.startVertex() + drawInfo.vertexCount());
230 instanceCount -= drawInfo.instanceCount();
231 }
232 }
233
234 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
235
236private:
237 RectBatch(const Geometry& geometry) {
238 this->initClassID<RectBatch>();
239 fGeoData.push_back(geometry);
240 }
241
242 GrColor color() const { return fBatch.fColor; }
243 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; }
244 bool colorIgnored() const { return fBatch.fColorIgnored; }
245 const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; }
246 const SkMatrix& localMatrix() const { return fGeoData[0].fLocalMatrix; }
247 bool hasLocalRect() const { return fGeoData[0].fHasLocalRect; }
248 bool hasLocalMatrix() const { return fGeoData[0].fHasLocalMatrix; }
249
250 bool onCombineIfPossible(GrBatch* t) SK_OVERRIDE {
251 RectBatch* that = t->cast<RectBatch>();
252
253 if (this->hasLocalRect() != that->hasLocalRect()) {
254 return false;
255 }
256
257 SkASSERT(this->usesLocalCoords() == that->usesLocalCoords());
258 if (!this->hasLocalRect() && this->usesLocalCoords()) {
259 if (!this->viewMatrix().cheapEqualTo(that->viewMatrix())) {
260 return false;
261 }
262
263 if (this->hasLocalMatrix() != that->hasLocalMatrix()) {
264 return false;
265 }
266
267 if (this->hasLocalMatrix() && !this->localMatrix().cheapEqualTo(that->localMatrix())) {
268 return false;
269 }
270 }
271
272 if (this->color() != that->color()) {
273 fBatch.fColor = GrColor_ILLEGAL;
274 }
275 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin());
276 return true;
277 }
278
279 struct BatchTracker {
280 GrColor fColor;
281 bool fUsesLocalCoords;
282 bool fColorIgnored;
283 bool fCoverageIgnored;
284 };
285
286 const static int kVertsPerRect = 4;
287 const static int kIndicesPerRect = 6;
288
289 BatchTracker fBatch;
290 SkSTArray<1, Geometry, true> fGeoData;
291};
292
egdaniel8dd688b2015-01-22 10:16:09 -0800293void GrInOrderDrawBuffer::onDrawRect(GrPipelineBuilder* pipelineBuilder,
joshualitt2e3b3e32014-12-09 13:31:14 -0800294 GrColor color,
joshualitt8059eb92014-12-29 15:10:07 -0800295 const SkMatrix& viewMatrix,
joshualitt9853cce2014-11-17 14:22:48 -0800296 const SkRect& rect,
commit-bot@chromium.orgfd03d4a2013-07-17 21:39:42 +0000297 const SkRect* localRect,
bsalomon@google.com0406b9e2013-04-02 21:00:15 +0000298 const SkMatrix* localMatrix) {
joshualitt58773332015-02-23 16:41:42 -0800299 RectBatch::Geometry geometry;
300 geometry.fColor = color;
301 geometry.fViewMatrix = viewMatrix;
302 geometry.fRect = rect;
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000303
bsalomon49f085d2014-09-05 13:34:00 -0700304 if (localRect) {
joshualitt58773332015-02-23 16:41:42 -0800305 geometry.fHasLocalRect = true;
306 geometry.fLocalRect = *localRect;
307 } else {
308 geometry.fHasLocalRect = false;
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000309 }
310
joshualitt58773332015-02-23 16:41:42 -0800311 if (localMatrix) {
312 geometry.fHasLocalMatrix = true;
313 geometry.fLocalMatrix = *localMatrix;
314 } else {
315 geometry.fHasLocalMatrix = false;
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000316 }
317
joshualitt58773332015-02-23 16:41:42 -0800318 SkAutoTUnref<GrBatch> batch(RectBatch::Create(geometry));
319
320 SkRect bounds = rect;
321 viewMatrix.mapRect(&bounds);
322 this->drawBatch(pipelineBuilder, batch, &bounds);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000323}
324
egdaniele36914c2015-02-13 09:00:33 -0800325int GrInOrderDrawBuffer::concatInstancedDraw(const DrawInfo& info) {
cdalton6819df32014-10-15 13:43:48 -0700326 SkASSERT(!fCmdBuffer.empty());
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000327 SkASSERT(info.isInstanced());
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000328
robertphillips8f9e8162015-03-02 10:12:17 -0800329 const GrIndexBuffer* ib;
330 if (!this->canConcatToIndexBuffer(&ib)) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000331 return 0;
bsalomon@google.com934c5702012-03-20 21:17:58 +0000332 }
robertphillips8f9e8162015-03-02 10:12:17 -0800333
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000334 // Check if there is a draw info that is compatible that uses the same VB from the pool and
335 // the same IB
robertphillipse5e72f12015-02-17 09:14:33 -0800336 if (Cmd::kDraw_Cmd != fCmdBuffer.back().type()) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000337 return 0;
338 }
339
cdalton6819df32014-10-15 13:43:48 -0700340 Draw* draw = static_cast<Draw*>(&fCmdBuffer.back());
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000341
cdalton6819df32014-10-15 13:43:48 -0700342 if (!draw->fInfo.isInstanced() ||
joshualitt4d8da812015-01-28 12:53:54 -0800343 draw->fInfo.primitiveType() != info.primitiveType() ||
cdalton6819df32014-10-15 13:43:48 -0700344 draw->fInfo.verticesPerInstance() != info.verticesPerInstance() ||
345 draw->fInfo.indicesPerInstance() != info.indicesPerInstance() ||
bsalomon371bcbc2014-12-01 08:19:34 -0800346 draw->fInfo.vertexBuffer() != info.vertexBuffer() ||
robertphillips8f9e8162015-03-02 10:12:17 -0800347 draw->fInfo.indexBuffer() != ib) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000348 return 0;
349 }
bsalomon371bcbc2014-12-01 08:19:34 -0800350 if (draw->fInfo.startVertex() + draw->fInfo.vertexCount() != info.startVertex()) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000351 return 0;
352 }
353
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000354 // how many instances can be concat'ed onto draw given the size of the index buffer
355 int instancesToConcat = this->indexCountInCurrentSource() / info.indicesPerInstance();
cdalton6819df32014-10-15 13:43:48 -0700356 instancesToConcat -= draw->fInfo.instanceCount();
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000357 instancesToConcat = SkTMin(instancesToConcat, info.instanceCount());
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000358
cdalton6819df32014-10-15 13:43:48 -0700359 draw->fInfo.adjustInstanceCount(instancesToConcat);
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000360
361 // update last fGpuCmdMarkers to include any additional trace markers that have been added
robertphillips7f966f42015-03-02 06:40:12 -0800362 this->recordTraceMarkersIfNecessary(draw);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000363 return instancesToConcat;
bsalomon@google.com934c5702012-03-20 21:17:58 +0000364}
365
egdaniele36914c2015-02-13 09:00:33 -0800366void GrInOrderDrawBuffer::onDraw(const GrGeometryProcessor* gp,
joshualitt9853cce2014-11-17 14:22:48 -0800367 const DrawInfo& info,
egdaniele36914c2015-02-13 09:00:33 -0800368 const PipelineInfo& pipelineInfo) {
joshualitt7eb8c7b2014-11-18 14:24:27 -0800369 SkASSERT(info.vertexBuffer() && (!info.isIndexed() || info.indexBuffer()));
joshualitt4d8da812015-01-28 12:53:54 -0800370 this->closeBatch();
371
egdaniele36914c2015-02-13 09:00:33 -0800372 if (!this->setupPipelineAndShouldDraw(gp, pipelineInfo)) {
bsalomonae59b772014-11-19 08:23:49 -0800373 return;
374 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000375
bsalomonb3e3a952014-09-19 11:10:40 -0700376 Draw* draw;
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000377 if (info.isInstanced()) {
egdaniele36914c2015-02-13 09:00:33 -0800378 int instancesConcated = this->concatInstancedDraw(info);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000379 if (info.instanceCount() > instancesConcated) {
joshualitt54e0c122014-11-19 09:38:51 -0800380 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info));
cdalton6819df32014-10-15 13:43:48 -0700381 draw->fInfo.adjustInstanceCount(-instancesConcated);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000382 } else {
383 return;
384 }
385 } else {
joshualitt54e0c122014-11-19 09:38:51 -0800386 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info));
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000387 }
robertphillips7f966f42015-03-02 06:40:12 -0800388 this->recordTraceMarkersIfNecessary(draw);
commit-bot@chromium.org9b62aa12014-03-25 11:59:40 +0000389}
sugoi@google.com5f74cf82012-12-17 21:16:45 +0000390
joshualitt4d8da812015-01-28 12:53:54 -0800391void GrInOrderDrawBuffer::onDrawBatch(GrBatch* batch,
egdaniele36914c2015-02-13 09:00:33 -0800392 const PipelineInfo& pipelineInfo) {
393 if (!this->setupPipelineAndShouldDraw(batch, pipelineInfo)) {
joshualitt4d8da812015-01-28 12:53:54 -0800394 return;
395 }
396
397 // Check if there is a Batch Draw we can batch with
joshualittcc1ac862015-03-02 11:23:07 -0800398 if (Cmd::kDrawBatch_Cmd != fCmdBuffer.back().type() || !fDrawBatch) {
robertphillips9888b222015-02-27 08:50:34 -0800399 fDrawBatch = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawBatch, (batch, &fBatchTarget));
robertphillips7f966f42015-03-02 06:40:12 -0800400 this->recordTraceMarkersIfNecessary(fDrawBatch);
joshualitt4d8da812015-01-28 12:53:54 -0800401 return;
402 }
403
robertphillips7f966f42015-03-02 06:40:12 -0800404 SkASSERT(&fCmdBuffer.back() == fDrawBatch);
405 if (!fDrawBatch->fBatch->combineIfPossible(batch)) {
joshualitt4d8da812015-01-28 12:53:54 -0800406 this->closeBatch();
robertphillips9888b222015-02-27 08:50:34 -0800407 fDrawBatch = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawBatch, (batch, &fBatchTarget));
joshualitt4d8da812015-01-28 12:53:54 -0800408 }
robertphillips7f966f42015-03-02 06:40:12 -0800409 this->recordTraceMarkersIfNecessary(fDrawBatch);
joshualitt4d8da812015-01-28 12:53:54 -0800410}
411
egdaniel8dd688b2015-01-22 10:16:09 -0800412void GrInOrderDrawBuffer::onStencilPath(const GrPipelineBuilder& pipelineBuilder,
joshualitt56995b52014-12-11 15:44:02 -0800413 const GrPathProcessor* pathProc,
joshualitt9853cce2014-11-17 14:22:48 -0800414 const GrPath* path,
bsalomon3e791242014-12-17 13:43:13 -0800415 const GrScissorState& scissorState,
joshualitt2c93efe2014-11-06 12:57:13 -0800416 const GrStencilSettings& stencilSettings) {
joshualitt70f00042015-02-06 15:53:59 -0800417 this->closeBatch();
418
bsalomon3e791242014-12-17 13:43:13 -0800419 StencilPath* sp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, StencilPath,
egdaniel8dd688b2015-01-22 10:16:09 -0800420 (path, pipelineBuilder.getRenderTarget()));
joshualitt58773332015-02-23 16:41:42 -0800421
bsalomon3e791242014-12-17 13:43:13 -0800422 sp->fScissor = scissorState;
egdaniel8dd688b2015-01-22 10:16:09 -0800423 sp->fUseHWAA = pipelineBuilder.isHWAntialias();
joshualitt8059eb92014-12-29 15:10:07 -0800424 sp->fViewMatrix = pathProc->viewMatrix();
bsalomon3e791242014-12-17 13:43:13 -0800425 sp->fStencil = stencilSettings;
robertphillips7f966f42015-03-02 06:40:12 -0800426 this->recordTraceMarkersIfNecessary(sp);
bsalomon@google.com64aef2b2012-06-11 15:36:13 +0000427}
428
egdaniele36914c2015-02-13 09:00:33 -0800429void GrInOrderDrawBuffer::onDrawPath(const GrPathProcessor* pathProc,
joshualitt9853cce2014-11-17 14:22:48 -0800430 const GrPath* path,
joshualitt2c93efe2014-11-06 12:57:13 -0800431 const GrStencilSettings& stencilSettings,
egdaniele36914c2015-02-13 09:00:33 -0800432 const PipelineInfo& pipelineInfo) {
joshualitt4d8da812015-01-28 12:53:54 -0800433 this->closeBatch();
434
egdaniel8dd688b2015-01-22 10:16:09 -0800435 // TODO: Only compare the subset of GrPipelineBuilder relevant to path covering?
egdaniele36914c2015-02-13 09:00:33 -0800436 if (!this->setupPipelineAndShouldDraw(pathProc, pipelineInfo)) {
bsalomonae59b772014-11-19 08:23:49 -0800437 return;
438 }
cdalton6819df32014-10-15 13:43:48 -0700439 DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (path));
joshualitt2c93efe2014-11-06 12:57:13 -0800440 dp->fStencilSettings = stencilSettings;
robertphillips7f966f42015-03-02 06:40:12 -0800441 this->recordTraceMarkersIfNecessary(dp);
commit-bot@chromium.orgc4dc0ad2013-10-09 14:11:33 +0000442}
443
egdaniele36914c2015-02-13 09:00:33 -0800444void GrInOrderDrawBuffer::onDrawPaths(const GrPathProcessor* pathProc,
joshualitt9853cce2014-11-17 14:22:48 -0800445 const GrPathRange* pathRange,
cdalton55b24af2014-11-25 11:00:56 -0800446 const void* indices,
447 PathIndexType indexType,
448 const float transformValues[],
449 PathTransformType transformType,
joshualitt2c93efe2014-11-06 12:57:13 -0800450 int count,
joshualitt2c93efe2014-11-06 12:57:13 -0800451 const GrStencilSettings& stencilSettings,
egdaniele36914c2015-02-13 09:00:33 -0800452 const PipelineInfo& pipelineInfo) {
bsalomon49f085d2014-09-05 13:34:00 -0700453 SkASSERT(pathRange);
454 SkASSERT(indices);
cdalton55b24af2014-11-25 11:00:56 -0800455 SkASSERT(transformValues);
joshualitt4d8da812015-01-28 12:53:54 -0800456 this->closeBatch();
457
egdaniele36914c2015-02-13 09:00:33 -0800458 if (!this->setupPipelineAndShouldDraw(pathProc, pipelineInfo)) {
bsalomonae59b772014-11-19 08:23:49 -0800459 return;
460 }
cdalton6819df32014-10-15 13:43:48 -0700461
robertphillips8f9e8162015-03-02 10:12:17 -0800462 char* savedIndices;
463 float* savedTransforms;
cdalton55b24af2014-11-25 11:00:56 -0800464
robertphillips8f9e8162015-03-02 10:12:17 -0800465 this->appendIndicesAndTransforms(indices, indexType,
466 transformValues, transformType,
467 count, &savedIndices, &savedTransforms);
cdalton6819df32014-10-15 13:43:48 -0700468
robertphillipse5e72f12015-02-17 09:14:33 -0800469 if (Cmd::kDrawPaths_Cmd == fCmdBuffer.back().type()) {
cdalton3fc6a2f2014-11-13 11:54:20 -0800470 // The previous command was also DrawPaths. Try to collapse this call into the one
bsalomon371bcbc2014-12-01 08:19:34 -0800471 // before. Note that stenciling all the paths at once, then covering, may not be
cdalton3fc6a2f2014-11-13 11:54:20 -0800472 // equivalent to two separate draw calls if there is overlap. Blending won't work,
473 // and the combined calls may also cancel each other's winding numbers in some
474 // places. For now the winding numbers are only an issue if the fill is even/odd,
475 // because DrawPaths is currently only used for glyphs, and glyphs in the same
476 // font tend to all wind in the same direction.
477 DrawPaths* previous = static_cast<DrawPaths*>(&fCmdBuffer.back());
478 if (pathRange == previous->pathRange() &&
cdalton55b24af2014-11-25 11:00:56 -0800479 indexType == previous->fIndexType &&
480 transformType == previous->fTransformType &&
cdalton3fc6a2f2014-11-13 11:54:20 -0800481 stencilSettings == previous->fStencilSettings &&
482 path_fill_type_is_winding(stencilSettings) &&
egdaniele36914c2015-02-13 09:00:33 -0800483 !pipelineInfo.willBlendWithDst(pathProc)) {
robertphillips8f9e8162015-03-02 10:12:17 -0800484 const int indexBytes = GrPathRange::PathIndexSizeInBytes(indexType);
485 const int xformSize = GrPathRendering::PathTransformSize(transformType);
robertphillips9888b222015-02-27 08:50:34 -0800486 if (&previous->fIndices[previous->fCount*indexBytes] == savedIndices &&
robertphillips8f9e8162015-03-02 10:12:17 -0800487 (0 == xformSize ||
robertphillips9888b222015-02-27 08:50:34 -0800488 &previous->fTransforms[previous->fCount*xformSize] == savedTransforms)) {
489 // Fold this DrawPaths call into the one previous.
490 previous->fCount += count;
491 return;
492 }
cdalton3fc6a2f2014-11-13 11:54:20 -0800493 }
494 }
495
496 DrawPaths* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPaths, (pathRange));
robertphillips9888b222015-02-27 08:50:34 -0800497 dp->fIndices = savedIndices;
cdalton55b24af2014-11-25 11:00:56 -0800498 dp->fIndexType = indexType;
robertphillips9888b222015-02-27 08:50:34 -0800499 dp->fTransforms = savedTransforms;
cdalton55b24af2014-11-25 11:00:56 -0800500 dp->fTransformType = transformType;
501 dp->fCount = count;
joshualitt2c93efe2014-11-06 12:57:13 -0800502 dp->fStencilSettings = stencilSettings;
cdalton6819df32014-10-15 13:43:48 -0700503
robertphillips7f966f42015-03-02 06:40:12 -0800504 this->recordTraceMarkersIfNecessary(dp);
commit-bot@chromium.org9b62aa12014-03-25 11:59:40 +0000505}
506
bsalomon63b21962014-11-05 07:05:34 -0800507void GrInOrderDrawBuffer::onClear(const SkIRect* rect, GrColor color,
508 bool canIgnoreRect, GrRenderTarget* renderTarget) {
joshualitt9853cce2014-11-17 14:22:48 -0800509 SkASSERT(renderTarget);
joshualitt70f00042015-02-06 15:53:59 -0800510 this->closeBatch();
511
commit-bot@chromium.orgfd03d4a2013-07-17 21:39:42 +0000512 SkIRect r;
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000513 if (NULL == rect) {
514 // We could do something smart and remove previous draws and clears to
515 // the current render target. If we get that smart we have to make sure
516 // those draws aren't read before this clear (render-to-texture).
bsalomon@google.com1b3ce472012-08-17 13:43:08 +0000517 r.setLTRB(0, 0, renderTarget->width(), renderTarget->height());
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000518 rect = &r;
519 }
cdalton6819df32014-10-15 13:43:48 -0700520 Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget));
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000521 GrColorIsPMAssert(color);
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000522 clr->fColor = color;
523 clr->fRect = *rect;
robertphillips@google.com56ce48a2013-10-31 21:44:25 +0000524 clr->fCanIgnoreRect = canIgnoreRect;
robertphillips7f966f42015-03-02 06:40:12 -0800525 this->recordTraceMarkersIfNecessary(clr);
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000526}
527
joshualitt6db519c2014-10-29 08:48:18 -0700528void GrInOrderDrawBuffer::clearStencilClip(const SkIRect& rect,
529 bool insideClip,
530 GrRenderTarget* renderTarget) {
joshualitt9853cce2014-11-17 14:22:48 -0800531 SkASSERT(renderTarget);
joshualitt70f00042015-02-06 15:53:59 -0800532 this->closeBatch();
533
joshualitt6db519c2014-10-29 08:48:18 -0700534 ClearStencilClip* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, ClearStencilClip, (renderTarget));
535 clr->fRect = rect;
536 clr->fInsideClip = insideClip;
robertphillips7f966f42015-03-02 06:40:12 -0800537 this->recordTraceMarkersIfNecessary(clr);
joshualitt6db519c2014-10-29 08:48:18 -0700538}
539
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000540void GrInOrderDrawBuffer::discard(GrRenderTarget* renderTarget) {
bsalomon89c62982014-11-03 12:08:42 -0800541 SkASSERT(renderTarget);
joshualitt70f00042015-02-06 15:53:59 -0800542 this->closeBatch();
543
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000544 if (!this->caps()->discardRenderTargetSupport()) {
545 return;
546 }
cdalton6819df32014-10-15 13:43:48 -0700547 Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget));
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000548 clr->fColor = GrColor_ILLEGAL;
robertphillips7f966f42015-03-02 06:40:12 -0800549 this->recordTraceMarkersIfNecessary(clr);
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000550}
551
bsalomon371bcbc2014-12-01 08:19:34 -0800552void GrInOrderDrawBuffer::onReset() {
cdalton6819df32014-10-15 13:43:48 -0700553 fCmdBuffer.reset();
bsalomon932f8662014-11-24 06:47:48 -0800554 fPrevState = NULL;
robertphillips9888b222015-02-27 08:50:34 -0800555 fPathIndexBuffer.rewind();
556 fPathTransformBuffer.rewind();
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000557 fGpuCmdMarkers.reset();
joshualitt4d8da812015-01-28 12:53:54 -0800558 fDrawBatch = NULL;
reed@google.comac10a2d2010-12-22 21:39:39 +0000559}
560
bsalomon371bcbc2014-12-01 08:19:34 -0800561void GrInOrderDrawBuffer::onFlush() {
cdalton6819df32014-10-15 13:43:48 -0700562 if (fCmdBuffer.empty()) {
robertphillips@google.com1267fbd2013-07-03 18:37:27 +0000563 return;
reed@google.comac10a2d2010-12-22 21:39:39 +0000564 }
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000565
joshualittc2893c52015-01-28 06:54:30 -0800566 // Updated every time we find a set state cmd to reflect the current state in the playback
567 // stream.
568 SetState* currentState = NULL;
569
joshualitt4d8da812015-01-28 12:53:54 -0800570 // TODO this is temporary while batch is being rolled out
571 this->closeBatch();
572 this->getVertexAllocPool()->unmap();
573 this->getIndexAllocPool()->unmap();
574 fBatchTarget.preFlush();
575
576 currentState = NULL;
577 CmdBuffer::Iter iter(fCmdBuffer);
578
579 int currCmdMarker = 0;
580
joshualitt7bc18b72015-02-03 16:41:41 -0800581 int i = 0;
cdalton6819df32014-10-15 13:43:48 -0700582 while (iter.next()) {
joshualitt7bc18b72015-02-03 16:41:41 -0800583 i++;
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000584 GrGpuTraceMarker newMarker("", -1);
egdanield78a1682014-07-09 10:41:26 -0700585 SkString traceString;
robertphillipse5e72f12015-02-17 09:14:33 -0800586 if (iter->isTraced()) {
robertphillips7f966f42015-03-02 06:40:12 -0800587 traceString = this->getCmdString(currCmdMarker);
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000588 newMarker.fMarker = traceString.c_str();
bsalomon371bcbc2014-12-01 08:19:34 -0800589 this->getGpu()->addGpuTraceMarker(&newMarker);
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000590 ++currCmdMarker;
591 }
cdalton6819df32014-10-15 13:43:48 -0700592
joshualitt4d8da812015-01-28 12:53:54 -0800593 // TODO temporary hack
robertphillipse5e72f12015-02-17 09:14:33 -0800594 if (Cmd::kDrawBatch_Cmd == iter->type()) {
joshualitt7bc18b72015-02-03 16:41:41 -0800595 DrawBatch* db = reinterpret_cast<DrawBatch*>(iter.get());
596 fBatchTarget.flushNext(db->fBatch->numberOfDraws());
joshualitt4d8da812015-01-28 12:53:54 -0800597 continue;
598 }
599
robertphillipse5e72f12015-02-17 09:14:33 -0800600 if (Cmd::kSetState_Cmd == iter->type()) {
joshualitt9853cce2014-11-17 14:22:48 -0800601 SetState* ss = reinterpret_cast<SetState*>(iter.get());
joshualitt873ad0e2015-01-20 09:08:51 -0800602
joshualitt4d8da812015-01-28 12:53:54 -0800603 // TODO sometimes we have a prim proc, othertimes we have a GrBatch. Eventually we will
604 // only have GrBatch and we can delete this
605 if (ss->fPrimitiveProcessor) {
606 this->getGpu()->buildProgramDesc(&ss->fDesc, *ss->fPrimitiveProcessor,
egdaniele36914c2015-02-13 09:00:33 -0800607 *ss->getPipeline(),
joshualitt4d8da812015-01-28 12:53:54 -0800608 ss->fBatchTracker);
609 }
joshualitt873ad0e2015-01-20 09:08:51 -0800610 currentState = ss;
joshualittd53a8272014-11-10 16:03:14 -0800611 } else {
robertphillips9888b222015-02-27 08:50:34 -0800612 iter->execute(this->getGpu(), currentState);
joshualittd53a8272014-11-10 16:03:14 -0800613 }
cdalton6819df32014-10-15 13:43:48 -0700614
robertphillipse5e72f12015-02-17 09:14:33 -0800615 if (iter->isTraced()) {
bsalomon371bcbc2014-12-01 08:19:34 -0800616 this->getGpu()->removeGpuTraceMarker(&newMarker);
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000617 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000618 }
mtkleinf439c772014-10-14 14:29:30 -0700619
joshualitt4d8da812015-01-28 12:53:54 -0800620 // TODO see copious notes about hack
621 fBatchTarget.postFlush();
622
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000623 SkASSERT(fGpuCmdMarkers.count() == currCmdMarker);
commit-bot@chromium.orga8916ff2013-08-16 15:53:46 +0000624 ++fDrawID;
reed@google.comac10a2d2010-12-22 21:39:39 +0000625}
626
robertphillips9888b222015-02-27 08:50:34 -0800627void GrInOrderDrawBuffer::Draw::execute(GrGpu* gpu, const SetState* state) {
joshualitt873ad0e2015-01-20 09:08:51 -0800628 SkASSERT(state);
egdaniele36914c2015-02-13 09:00:33 -0800629 DrawArgs args(state->fPrimitiveProcessor.get(), state->getPipeline(), &state->fDesc,
joshualitt17e73142015-01-21 11:52:36 -0800630 &state->fBatchTracker);
robertphillips9888b222015-02-27 08:50:34 -0800631 gpu->draw(args, fInfo);
cdalton6819df32014-10-15 13:43:48 -0700632}
633
robertphillips9888b222015-02-27 08:50:34 -0800634void GrInOrderDrawBuffer::StencilPath::execute(GrGpu* gpu, const SetState*) {
bsalomon3e791242014-12-17 13:43:13 -0800635 GrGpu::StencilPathState state;
636 state.fRenderTarget = fRenderTarget.get();
637 state.fScissor = &fScissor;
638 state.fStencil = &fStencil;
639 state.fUseHWAA = fUseHWAA;
640 state.fViewMatrix = &fViewMatrix;
641
robertphillips9888b222015-02-27 08:50:34 -0800642 gpu->stencilPath(this->path(), state);
cdalton6819df32014-10-15 13:43:48 -0700643}
644
robertphillips9888b222015-02-27 08:50:34 -0800645void GrInOrderDrawBuffer::DrawPath::execute(GrGpu* gpu, const SetState* state) {
joshualitt873ad0e2015-01-20 09:08:51 -0800646 SkASSERT(state);
egdaniele36914c2015-02-13 09:00:33 -0800647 DrawArgs args(state->fPrimitiveProcessor.get(), state->getPipeline(), &state->fDesc,
joshualitt17e73142015-01-21 11:52:36 -0800648 &state->fBatchTracker);
robertphillips9888b222015-02-27 08:50:34 -0800649 gpu->drawPath(args, this->path(), fStencilSettings);
cdalton6819df32014-10-15 13:43:48 -0700650}
651
robertphillips9888b222015-02-27 08:50:34 -0800652void GrInOrderDrawBuffer::DrawPaths::execute(GrGpu* gpu, const SetState* state) {
joshualitt873ad0e2015-01-20 09:08:51 -0800653 SkASSERT(state);
egdaniele36914c2015-02-13 09:00:33 -0800654 DrawArgs args(state->fPrimitiveProcessor.get(), state->getPipeline(), &state->fDesc,
joshualitt17e73142015-01-21 11:52:36 -0800655 &state->fBatchTracker);
robertphillips9888b222015-02-27 08:50:34 -0800656 gpu->drawPaths(args, this->pathRange(),
657 fIndices, fIndexType,
658 fTransforms, fTransformType,
659 fCount, fStencilSettings);
cdalton6819df32014-10-15 13:43:48 -0700660}
661
robertphillips9888b222015-02-27 08:50:34 -0800662void GrInOrderDrawBuffer::DrawBatch::execute(GrGpu* gpu, const SetState* state) {
joshualitt4d8da812015-01-28 12:53:54 -0800663 SkASSERT(state);
robertphillips9888b222015-02-27 08:50:34 -0800664 fBatch->generateGeometry(fBatchTarget, state->getPipeline());
joshualitt4d8da812015-01-28 12:53:54 -0800665}
666
robertphillips9888b222015-02-27 08:50:34 -0800667void GrInOrderDrawBuffer::SetState::execute(GrGpu* gpu, const SetState*) {}
cdalton6819df32014-10-15 13:43:48 -0700668
robertphillips9888b222015-02-27 08:50:34 -0800669void GrInOrderDrawBuffer::Clear::execute(GrGpu* gpu, const SetState*) {
cdalton6819df32014-10-15 13:43:48 -0700670 if (GrColor_ILLEGAL == fColor) {
robertphillips9888b222015-02-27 08:50:34 -0800671 gpu->discard(this->renderTarget());
cdalton6819df32014-10-15 13:43:48 -0700672 } else {
robertphillips9888b222015-02-27 08:50:34 -0800673 gpu->clear(&fRect, fColor, fCanIgnoreRect, this->renderTarget());
cdalton6819df32014-10-15 13:43:48 -0700674 }
675}
676
robertphillips9888b222015-02-27 08:50:34 -0800677void GrInOrderDrawBuffer::ClearStencilClip::execute(GrGpu* gpu, const SetState*) {
678 gpu->clearStencilClip(fRect, fInsideClip, this->renderTarget());
joshualitt6db519c2014-10-29 08:48:18 -0700679}
680
robertphillips9888b222015-02-27 08:50:34 -0800681void GrInOrderDrawBuffer::CopySurface::execute(GrGpu* gpu, const SetState*) {
682 gpu->copySurface(this->dst(), this->src(), fSrcRect, fDstPoint);
cdalton6819df32014-10-15 13:43:48 -0700683}
684
bsalomonf90a02b2014-11-26 12:28:00 -0800685bool GrInOrderDrawBuffer::onCopySurface(GrSurface* dst,
686 GrSurface* src,
687 const SkIRect& srcRect,
688 const SkIPoint& dstPoint) {
bsalomon371bcbc2014-12-01 08:19:34 -0800689 if (getGpu()->canCopySurface(dst, src, srcRect, dstPoint)) {
joshualitt95964c62015-02-11 13:45:50 -0800690 this->closeBatch();
cdalton6819df32014-10-15 13:43:48 -0700691 CopySurface* cs = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, CopySurface, (dst, src));
bsalomon@google.com116ad842013-04-09 15:38:19 +0000692 cs->fSrcRect = srcRect;
693 cs->fDstPoint = dstPoint;
robertphillips7f966f42015-03-02 06:40:12 -0800694 this->recordTraceMarkersIfNecessary(cs);
bsalomon@google.com116ad842013-04-09 15:38:19 +0000695 return true;
bsalomon@google.com116ad842013-04-09 15:38:19 +0000696 }
bsalomonf90a02b2014-11-26 12:28:00 -0800697 return false;
bsalomon@google.com116ad842013-04-09 15:38:19 +0000698}
699
egdaniele36914c2015-02-13 09:00:33 -0800700bool GrInOrderDrawBuffer::setupPipelineAndShouldDraw(const GrPrimitiveProcessor* primProc,
701 const PipelineInfo& pipelineInfo) {
702 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (primProc));
703 this->setupPipeline(pipelineInfo, ss->pipelineLocation());
704
705 if (ss->getPipeline()->mustSkip()) {
bsalomon932f8662014-11-24 06:47:48 -0800706 fCmdBuffer.pop_back();
bsalomonae59b772014-11-19 08:23:49 -0800707 return false;
708 }
joshualitt873ad0e2015-01-20 09:08:51 -0800709
710 ss->fPrimitiveProcessor->initBatchTracker(&ss->fBatchTracker,
egdaniele36914c2015-02-13 09:00:33 -0800711 ss->getPipeline()->getInitBatchTracker());
joshualitt873ad0e2015-01-20 09:08:51 -0800712
joshualitt4d8da812015-01-28 12:53:54 -0800713 if (fPrevState && fPrevState->fPrimitiveProcessor.get() &&
joshualitt873ad0e2015-01-20 09:08:51 -0800714 fPrevState->fPrimitiveProcessor->canMakeEqual(fPrevState->fBatchTracker,
715 *ss->fPrimitiveProcessor,
716 ss->fBatchTracker) &&
egdaniele36914c2015-02-13 09:00:33 -0800717 fPrevState->getPipeline()->isEqual(*ss->getPipeline())) {
bsalomon932f8662014-11-24 06:47:48 -0800718 fCmdBuffer.pop_back();
719 } else {
joshualitt873ad0e2015-01-20 09:08:51 -0800720 fPrevState = ss;
robertphillips7f966f42015-03-02 06:40:12 -0800721 this->recordTraceMarkersIfNecessary(ss);
bsalomon838f62d2014-08-05 07:15:57 -0700722 }
bsalomonae59b772014-11-19 08:23:49 -0800723 return true;
reed@google.comac10a2d2010-12-22 21:39:39 +0000724}
725
egdaniele36914c2015-02-13 09:00:33 -0800726bool GrInOrderDrawBuffer::setupPipelineAndShouldDraw(GrBatch* batch,
727 const PipelineInfo& pipelineInfo) {
728 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, ());
729 this->setupPipeline(pipelineInfo, ss->pipelineLocation());
730
731 if (ss->getPipeline()->mustSkip()) {
joshualitt4d8da812015-01-28 12:53:54 -0800732 fCmdBuffer.pop_back();
733 return false;
734 }
735
egdaniele36914c2015-02-13 09:00:33 -0800736 batch->initBatchTracker(ss->getPipeline()->getInitBatchTracker());
joshualitt4d8da812015-01-28 12:53:54 -0800737
738 if (fPrevState && !fPrevState->fPrimitiveProcessor.get() &&
egdaniele36914c2015-02-13 09:00:33 -0800739 fPrevState->getPipeline()->isEqual(*ss->getPipeline())) {
joshualitt4d8da812015-01-28 12:53:54 -0800740 fCmdBuffer.pop_back();
741 } else {
742 this->closeBatch();
743 fPrevState = ss;
robertphillips7f966f42015-03-02 06:40:12 -0800744 this->recordTraceMarkersIfNecessary(ss);
joshualitt4d8da812015-01-28 12:53:54 -0800745 }
746 return true;
747}
748
robertphillips7f966f42015-03-02 06:40:12 -0800749void GrInOrderDrawBuffer::recordTraceMarkersIfNecessary(Cmd* cmd) {
750 if (!cmd) {
751 return;
752 }
mtkleinf439c772014-10-14 14:29:30 -0700753 const GrTraceMarkerSet& activeTraceMarkers = this->getActiveTraceMarkers();
754 if (activeTraceMarkers.count() > 0) {
robertphillips7f966f42015-03-02 06:40:12 -0800755 if (cmd->isTraced()) {
756 fGpuCmdMarkers.back().addSet(activeTraceMarkers);
757 } else {
758 cmd->makeTraced();
759 fGpuCmdMarkers.push_back(activeTraceMarkers);
760 }
mtklein07894c42014-10-13 14:00:42 -0700761 }
mtklein07894c42014-10-13 14:00:42 -0700762}
joshualitt4d8da812015-01-28 12:53:54 -0800763
joshualitt4d8da812015-01-28 12:53:54 -0800764void GrInOrderDrawBuffer::willReserveVertexAndIndexSpace(int vertexCount,
765 size_t vertexStride,
766 int indexCount) {
767 this->closeBatch();
768
robertphillips54fac8b2015-02-16 09:35:50 -0800769 this->INHERITED::willReserveVertexAndIndexSpace(vertexCount, vertexStride, indexCount);
joshualitt4d8da812015-01-28 12:53:54 -0800770}