blob: 8c2bea95a020f31f21832a70142738a07f53254a [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
bsalomon@google.com934c5702012-03-20 21:17:58 +0000329 const GeometrySrcState& geomSrc = this->getGeomSrc();
330
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000331 // we only attempt to concat the case when reserved verts are used with a client-specified index
332 // buffer. To make this work with client-specified VBs we'd need to know if the VB was updated
333 // between draws.
334 if (kReserved_GeometrySrcType != geomSrc.fVertexSrc ||
335 kBuffer_GeometrySrcType != geomSrc.fIndexSrc) {
336 return 0;
bsalomon@google.com934c5702012-03-20 21:17:58 +0000337 }
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000338 // Check if there is a draw info that is compatible that uses the same VB from the pool and
339 // the same IB
robertphillipse5e72f12015-02-17 09:14:33 -0800340 if (Cmd::kDraw_Cmd != fCmdBuffer.back().type()) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000341 return 0;
342 }
343
cdalton6819df32014-10-15 13:43:48 -0700344 Draw* draw = static_cast<Draw*>(&fCmdBuffer.back());
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000345
cdalton6819df32014-10-15 13:43:48 -0700346 if (!draw->fInfo.isInstanced() ||
joshualitt4d8da812015-01-28 12:53:54 -0800347 draw->fInfo.primitiveType() != info.primitiveType() ||
cdalton6819df32014-10-15 13:43:48 -0700348 draw->fInfo.verticesPerInstance() != info.verticesPerInstance() ||
349 draw->fInfo.indicesPerInstance() != info.indicesPerInstance() ||
bsalomon371bcbc2014-12-01 08:19:34 -0800350 draw->fInfo.vertexBuffer() != info.vertexBuffer() ||
joshualitt54e0c122014-11-19 09:38:51 -0800351 draw->fInfo.indexBuffer() != geomSrc.fIndexBuffer) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000352 return 0;
353 }
bsalomon371bcbc2014-12-01 08:19:34 -0800354 if (draw->fInfo.startVertex() + draw->fInfo.vertexCount() != info.startVertex()) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000355 return 0;
356 }
357
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000358 // how many instances can be concat'ed onto draw given the size of the index buffer
359 int instancesToConcat = this->indexCountInCurrentSource() / info.indicesPerInstance();
cdalton6819df32014-10-15 13:43:48 -0700360 instancesToConcat -= draw->fInfo.instanceCount();
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000361 instancesToConcat = SkTMin(instancesToConcat, info.instanceCount());
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000362
cdalton6819df32014-10-15 13:43:48 -0700363 draw->fInfo.adjustInstanceCount(instancesToConcat);
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000364
365 // update last fGpuCmdMarkers to include any additional trace markers that have been added
robertphillips7f966f42015-03-02 06:40:12 -0800366 this->recordTraceMarkersIfNecessary(draw);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000367 return instancesToConcat;
bsalomon@google.com934c5702012-03-20 21:17:58 +0000368}
369
egdaniele36914c2015-02-13 09:00:33 -0800370void GrInOrderDrawBuffer::onDraw(const GrGeometryProcessor* gp,
joshualitt9853cce2014-11-17 14:22:48 -0800371 const DrawInfo& info,
egdaniele36914c2015-02-13 09:00:33 -0800372 const PipelineInfo& pipelineInfo) {
joshualitt7eb8c7b2014-11-18 14:24:27 -0800373 SkASSERT(info.vertexBuffer() && (!info.isIndexed() || info.indexBuffer()));
joshualitt4d8da812015-01-28 12:53:54 -0800374 this->closeBatch();
375
egdaniele36914c2015-02-13 09:00:33 -0800376 if (!this->setupPipelineAndShouldDraw(gp, pipelineInfo)) {
bsalomonae59b772014-11-19 08:23:49 -0800377 return;
378 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000379
bsalomonb3e3a952014-09-19 11:10:40 -0700380 Draw* draw;
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000381 if (info.isInstanced()) {
egdaniele36914c2015-02-13 09:00:33 -0800382 int instancesConcated = this->concatInstancedDraw(info);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000383 if (info.instanceCount() > instancesConcated) {
joshualitt54e0c122014-11-19 09:38:51 -0800384 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info));
cdalton6819df32014-10-15 13:43:48 -0700385 draw->fInfo.adjustInstanceCount(-instancesConcated);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000386 } else {
387 return;
388 }
389 } else {
joshualitt54e0c122014-11-19 09:38:51 -0800390 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info));
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000391 }
robertphillips7f966f42015-03-02 06:40:12 -0800392 this->recordTraceMarkersIfNecessary(draw);
commit-bot@chromium.org9b62aa12014-03-25 11:59:40 +0000393}
sugoi@google.com5f74cf82012-12-17 21:16:45 +0000394
joshualitt4d8da812015-01-28 12:53:54 -0800395void GrInOrderDrawBuffer::onDrawBatch(GrBatch* batch,
egdaniele36914c2015-02-13 09:00:33 -0800396 const PipelineInfo& pipelineInfo) {
397 if (!this->setupPipelineAndShouldDraw(batch, pipelineInfo)) {
joshualitt4d8da812015-01-28 12:53:54 -0800398 return;
399 }
400
401 // Check if there is a Batch Draw we can batch with
robertphillipse5e72f12015-02-17 09:14:33 -0800402 if (Cmd::kDrawBatch_Cmd != fCmdBuffer.back().type()) {
robertphillips9888b222015-02-27 08:50:34 -0800403 fDrawBatch = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawBatch, (batch, &fBatchTarget));
robertphillips7f966f42015-03-02 06:40:12 -0800404 this->recordTraceMarkersIfNecessary(fDrawBatch);
joshualitt4d8da812015-01-28 12:53:54 -0800405 return;
406 }
407
robertphillips7f966f42015-03-02 06:40:12 -0800408 SkASSERT(&fCmdBuffer.back() == fDrawBatch);
409 if (!fDrawBatch->fBatch->combineIfPossible(batch)) {
joshualitt4d8da812015-01-28 12:53:54 -0800410 this->closeBatch();
robertphillips9888b222015-02-27 08:50:34 -0800411 fDrawBatch = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawBatch, (batch, &fBatchTarget));
joshualitt4d8da812015-01-28 12:53:54 -0800412 }
robertphillips7f966f42015-03-02 06:40:12 -0800413 this->recordTraceMarkersIfNecessary(fDrawBatch);
joshualitt4d8da812015-01-28 12:53:54 -0800414}
415
egdaniel8dd688b2015-01-22 10:16:09 -0800416void GrInOrderDrawBuffer::onStencilPath(const GrPipelineBuilder& pipelineBuilder,
joshualitt56995b52014-12-11 15:44:02 -0800417 const GrPathProcessor* pathProc,
joshualitt9853cce2014-11-17 14:22:48 -0800418 const GrPath* path,
bsalomon3e791242014-12-17 13:43:13 -0800419 const GrScissorState& scissorState,
joshualitt2c93efe2014-11-06 12:57:13 -0800420 const GrStencilSettings& stencilSettings) {
joshualitt70f00042015-02-06 15:53:59 -0800421 this->closeBatch();
422
bsalomon3e791242014-12-17 13:43:13 -0800423 StencilPath* sp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, StencilPath,
egdaniel8dd688b2015-01-22 10:16:09 -0800424 (path, pipelineBuilder.getRenderTarget()));
joshualitt58773332015-02-23 16:41:42 -0800425
bsalomon3e791242014-12-17 13:43:13 -0800426 sp->fScissor = scissorState;
egdaniel8dd688b2015-01-22 10:16:09 -0800427 sp->fUseHWAA = pipelineBuilder.isHWAntialias();
joshualitt8059eb92014-12-29 15:10:07 -0800428 sp->fViewMatrix = pathProc->viewMatrix();
bsalomon3e791242014-12-17 13:43:13 -0800429 sp->fStencil = stencilSettings;
robertphillips7f966f42015-03-02 06:40:12 -0800430 this->recordTraceMarkersIfNecessary(sp);
bsalomon@google.com64aef2b2012-06-11 15:36:13 +0000431}
432
egdaniele36914c2015-02-13 09:00:33 -0800433void GrInOrderDrawBuffer::onDrawPath(const GrPathProcessor* pathProc,
joshualitt9853cce2014-11-17 14:22:48 -0800434 const GrPath* path,
joshualitt2c93efe2014-11-06 12:57:13 -0800435 const GrStencilSettings& stencilSettings,
egdaniele36914c2015-02-13 09:00:33 -0800436 const PipelineInfo& pipelineInfo) {
joshualitt4d8da812015-01-28 12:53:54 -0800437 this->closeBatch();
438
egdaniel8dd688b2015-01-22 10:16:09 -0800439 // TODO: Only compare the subset of GrPipelineBuilder relevant to path covering?
egdaniele36914c2015-02-13 09:00:33 -0800440 if (!this->setupPipelineAndShouldDraw(pathProc, pipelineInfo)) {
bsalomonae59b772014-11-19 08:23:49 -0800441 return;
442 }
cdalton6819df32014-10-15 13:43:48 -0700443 DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (path));
joshualitt2c93efe2014-11-06 12:57:13 -0800444 dp->fStencilSettings = stencilSettings;
robertphillips7f966f42015-03-02 06:40:12 -0800445 this->recordTraceMarkersIfNecessary(dp);
commit-bot@chromium.orgc4dc0ad2013-10-09 14:11:33 +0000446}
447
egdaniele36914c2015-02-13 09:00:33 -0800448void GrInOrderDrawBuffer::onDrawPaths(const GrPathProcessor* pathProc,
joshualitt9853cce2014-11-17 14:22:48 -0800449 const GrPathRange* pathRange,
cdalton55b24af2014-11-25 11:00:56 -0800450 const void* indices,
451 PathIndexType indexType,
452 const float transformValues[],
453 PathTransformType transformType,
joshualitt2c93efe2014-11-06 12:57:13 -0800454 int count,
joshualitt2c93efe2014-11-06 12:57:13 -0800455 const GrStencilSettings& stencilSettings,
egdaniele36914c2015-02-13 09:00:33 -0800456 const PipelineInfo& pipelineInfo) {
bsalomon49f085d2014-09-05 13:34:00 -0700457 SkASSERT(pathRange);
458 SkASSERT(indices);
cdalton55b24af2014-11-25 11:00:56 -0800459 SkASSERT(transformValues);
joshualitt4d8da812015-01-28 12:53:54 -0800460 this->closeBatch();
461
egdaniele36914c2015-02-13 09:00:33 -0800462 if (!this->setupPipelineAndShouldDraw(pathProc, pipelineInfo)) {
bsalomonae59b772014-11-19 08:23:49 -0800463 return;
464 }
cdalton6819df32014-10-15 13:43:48 -0700465
cdalton55b24af2014-11-25 11:00:56 -0800466 int indexBytes = GrPathRange::PathIndexSizeInBytes(indexType);
robertphillips9888b222015-02-27 08:50:34 -0800467 char* savedIndices = (char*) fPathIndexBuffer.alloc(count * indexBytes,
468 SkChunkAlloc::kThrow_AllocFailType);
469 SkASSERT(SkIsAlign4((uintptr_t)savedIndices));
470 memcpy(savedIndices, reinterpret_cast<const char*>(indices), count * indexBytes);
cdalton55b24af2014-11-25 11:00:56 -0800471
robertphillips9888b222015-02-27 08:50:34 -0800472 const int xformSize = GrPathRendering::PathTransformSize(transformType);
473 const int xformBytes = xformSize * sizeof(float);
474 float* savedTransforms = NULL;
475 if (0 != xformBytes) {
476 savedTransforms = (float*) fPathTransformBuffer.alloc(count * xformBytes,
477 SkChunkAlloc::kThrow_AllocFailType);
478 SkASSERT(SkIsAlign4((uintptr_t)savedTransforms));
479 memcpy(savedTransforms, transformValues, count * xformBytes);
480 }
cdalton6819df32014-10-15 13:43:48 -0700481
robertphillipse5e72f12015-02-17 09:14:33 -0800482 if (Cmd::kDrawPaths_Cmd == fCmdBuffer.back().type()) {
cdalton3fc6a2f2014-11-13 11:54:20 -0800483 // The previous command was also DrawPaths. Try to collapse this call into the one
bsalomon371bcbc2014-12-01 08:19:34 -0800484 // before. Note that stenciling all the paths at once, then covering, may not be
cdalton3fc6a2f2014-11-13 11:54:20 -0800485 // equivalent to two separate draw calls if there is overlap. Blending won't work,
486 // and the combined calls may also cancel each other's winding numbers in some
487 // places. For now the winding numbers are only an issue if the fill is even/odd,
488 // because DrawPaths is currently only used for glyphs, and glyphs in the same
489 // font tend to all wind in the same direction.
490 DrawPaths* previous = static_cast<DrawPaths*>(&fCmdBuffer.back());
491 if (pathRange == previous->pathRange() &&
cdalton55b24af2014-11-25 11:00:56 -0800492 indexType == previous->fIndexType &&
493 transformType == previous->fTransformType &&
cdalton3fc6a2f2014-11-13 11:54:20 -0800494 stencilSettings == previous->fStencilSettings &&
495 path_fill_type_is_winding(stencilSettings) &&
egdaniele36914c2015-02-13 09:00:33 -0800496 !pipelineInfo.willBlendWithDst(pathProc)) {
robertphillips9888b222015-02-27 08:50:34 -0800497 if (&previous->fIndices[previous->fCount*indexBytes] == savedIndices &&
498 (0 == xformBytes ||
499 &previous->fTransforms[previous->fCount*xformSize] == savedTransforms)) {
500 // Fold this DrawPaths call into the one previous.
501 previous->fCount += count;
502 return;
503 }
cdalton3fc6a2f2014-11-13 11:54:20 -0800504 }
505 }
506
507 DrawPaths* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPaths, (pathRange));
robertphillips9888b222015-02-27 08:50:34 -0800508 dp->fIndices = savedIndices;
cdalton55b24af2014-11-25 11:00:56 -0800509 dp->fIndexType = indexType;
robertphillips9888b222015-02-27 08:50:34 -0800510 dp->fTransforms = savedTransforms;
cdalton55b24af2014-11-25 11:00:56 -0800511 dp->fTransformType = transformType;
512 dp->fCount = count;
joshualitt2c93efe2014-11-06 12:57:13 -0800513 dp->fStencilSettings = stencilSettings;
cdalton6819df32014-10-15 13:43:48 -0700514
robertphillips7f966f42015-03-02 06:40:12 -0800515 this->recordTraceMarkersIfNecessary(dp);
commit-bot@chromium.org9b62aa12014-03-25 11:59:40 +0000516}
517
bsalomon63b21962014-11-05 07:05:34 -0800518void GrInOrderDrawBuffer::onClear(const SkIRect* rect, GrColor color,
519 bool canIgnoreRect, GrRenderTarget* renderTarget) {
joshualitt9853cce2014-11-17 14:22:48 -0800520 SkASSERT(renderTarget);
joshualitt70f00042015-02-06 15:53:59 -0800521 this->closeBatch();
522
commit-bot@chromium.orgfd03d4a2013-07-17 21:39:42 +0000523 SkIRect r;
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000524 if (NULL == rect) {
525 // We could do something smart and remove previous draws and clears to
526 // the current render target. If we get that smart we have to make sure
527 // those draws aren't read before this clear (render-to-texture).
bsalomon@google.com1b3ce472012-08-17 13:43:08 +0000528 r.setLTRB(0, 0, renderTarget->width(), renderTarget->height());
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000529 rect = &r;
530 }
cdalton6819df32014-10-15 13:43:48 -0700531 Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget));
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000532 GrColorIsPMAssert(color);
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000533 clr->fColor = color;
534 clr->fRect = *rect;
robertphillips@google.com56ce48a2013-10-31 21:44:25 +0000535 clr->fCanIgnoreRect = canIgnoreRect;
robertphillips7f966f42015-03-02 06:40:12 -0800536 this->recordTraceMarkersIfNecessary(clr);
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000537}
538
joshualitt6db519c2014-10-29 08:48:18 -0700539void GrInOrderDrawBuffer::clearStencilClip(const SkIRect& rect,
540 bool insideClip,
541 GrRenderTarget* renderTarget) {
joshualitt9853cce2014-11-17 14:22:48 -0800542 SkASSERT(renderTarget);
joshualitt70f00042015-02-06 15:53:59 -0800543 this->closeBatch();
544
joshualitt6db519c2014-10-29 08:48:18 -0700545 ClearStencilClip* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, ClearStencilClip, (renderTarget));
546 clr->fRect = rect;
547 clr->fInsideClip = insideClip;
robertphillips7f966f42015-03-02 06:40:12 -0800548 this->recordTraceMarkersIfNecessary(clr);
joshualitt6db519c2014-10-29 08:48:18 -0700549}
550
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000551void GrInOrderDrawBuffer::discard(GrRenderTarget* renderTarget) {
bsalomon89c62982014-11-03 12:08:42 -0800552 SkASSERT(renderTarget);
joshualitt70f00042015-02-06 15:53:59 -0800553 this->closeBatch();
554
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000555 if (!this->caps()->discardRenderTargetSupport()) {
556 return;
557 }
cdalton6819df32014-10-15 13:43:48 -0700558 Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget));
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000559 clr->fColor = GrColor_ILLEGAL;
robertphillips7f966f42015-03-02 06:40:12 -0800560 this->recordTraceMarkersIfNecessary(clr);
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000561}
562
bsalomon371bcbc2014-12-01 08:19:34 -0800563void GrInOrderDrawBuffer::onReset() {
cdalton6819df32014-10-15 13:43:48 -0700564 fCmdBuffer.reset();
bsalomon932f8662014-11-24 06:47:48 -0800565 fPrevState = NULL;
robertphillips9888b222015-02-27 08:50:34 -0800566 fPathIndexBuffer.rewind();
567 fPathTransformBuffer.rewind();
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000568 fGpuCmdMarkers.reset();
joshualitt4d8da812015-01-28 12:53:54 -0800569 fDrawBatch = NULL;
reed@google.comac10a2d2010-12-22 21:39:39 +0000570}
571
bsalomon371bcbc2014-12-01 08:19:34 -0800572void GrInOrderDrawBuffer::onFlush() {
cdalton6819df32014-10-15 13:43:48 -0700573 if (fCmdBuffer.empty()) {
robertphillips@google.com1267fbd2013-07-03 18:37:27 +0000574 return;
reed@google.comac10a2d2010-12-22 21:39:39 +0000575 }
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000576
joshualittc2893c52015-01-28 06:54:30 -0800577 // Updated every time we find a set state cmd to reflect the current state in the playback
578 // stream.
579 SetState* currentState = NULL;
580
joshualitt4d8da812015-01-28 12:53:54 -0800581 // TODO this is temporary while batch is being rolled out
582 this->closeBatch();
583 this->getVertexAllocPool()->unmap();
584 this->getIndexAllocPool()->unmap();
585 fBatchTarget.preFlush();
586
587 currentState = NULL;
588 CmdBuffer::Iter iter(fCmdBuffer);
589
590 int currCmdMarker = 0;
591
joshualitt7bc18b72015-02-03 16:41:41 -0800592 int i = 0;
cdalton6819df32014-10-15 13:43:48 -0700593 while (iter.next()) {
joshualitt7bc18b72015-02-03 16:41:41 -0800594 i++;
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000595 GrGpuTraceMarker newMarker("", -1);
egdanield78a1682014-07-09 10:41:26 -0700596 SkString traceString;
robertphillipse5e72f12015-02-17 09:14:33 -0800597 if (iter->isTraced()) {
robertphillips7f966f42015-03-02 06:40:12 -0800598 traceString = this->getCmdString(currCmdMarker);
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000599 newMarker.fMarker = traceString.c_str();
bsalomon371bcbc2014-12-01 08:19:34 -0800600 this->getGpu()->addGpuTraceMarker(&newMarker);
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000601 ++currCmdMarker;
602 }
cdalton6819df32014-10-15 13:43:48 -0700603
joshualitt4d8da812015-01-28 12:53:54 -0800604 // TODO temporary hack
robertphillipse5e72f12015-02-17 09:14:33 -0800605 if (Cmd::kDrawBatch_Cmd == iter->type()) {
joshualitt7bc18b72015-02-03 16:41:41 -0800606 DrawBatch* db = reinterpret_cast<DrawBatch*>(iter.get());
607 fBatchTarget.flushNext(db->fBatch->numberOfDraws());
joshualitt4d8da812015-01-28 12:53:54 -0800608 continue;
609 }
610
robertphillipse5e72f12015-02-17 09:14:33 -0800611 if (Cmd::kSetState_Cmd == iter->type()) {
joshualitt9853cce2014-11-17 14:22:48 -0800612 SetState* ss = reinterpret_cast<SetState*>(iter.get());
joshualitt873ad0e2015-01-20 09:08:51 -0800613
joshualitt4d8da812015-01-28 12:53:54 -0800614 // TODO sometimes we have a prim proc, othertimes we have a GrBatch. Eventually we will
615 // only have GrBatch and we can delete this
616 if (ss->fPrimitiveProcessor) {
617 this->getGpu()->buildProgramDesc(&ss->fDesc, *ss->fPrimitiveProcessor,
egdaniele36914c2015-02-13 09:00:33 -0800618 *ss->getPipeline(),
joshualitt4d8da812015-01-28 12:53:54 -0800619 ss->fBatchTracker);
620 }
joshualitt873ad0e2015-01-20 09:08:51 -0800621 currentState = ss;
joshualittd53a8272014-11-10 16:03:14 -0800622 } else {
robertphillips9888b222015-02-27 08:50:34 -0800623 iter->execute(this->getGpu(), currentState);
joshualittd53a8272014-11-10 16:03:14 -0800624 }
cdalton6819df32014-10-15 13:43:48 -0700625
robertphillipse5e72f12015-02-17 09:14:33 -0800626 if (iter->isTraced()) {
bsalomon371bcbc2014-12-01 08:19:34 -0800627 this->getGpu()->removeGpuTraceMarker(&newMarker);
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000628 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000629 }
mtkleinf439c772014-10-14 14:29:30 -0700630
joshualitt4d8da812015-01-28 12:53:54 -0800631 // TODO see copious notes about hack
632 fBatchTarget.postFlush();
633
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000634 SkASSERT(fGpuCmdMarkers.count() == currCmdMarker);
commit-bot@chromium.orga8916ff2013-08-16 15:53:46 +0000635 ++fDrawID;
reed@google.comac10a2d2010-12-22 21:39:39 +0000636}
637
robertphillips9888b222015-02-27 08:50:34 -0800638void GrInOrderDrawBuffer::Draw::execute(GrGpu* gpu, const SetState* state) {
joshualitt873ad0e2015-01-20 09:08:51 -0800639 SkASSERT(state);
egdaniele36914c2015-02-13 09:00:33 -0800640 DrawArgs args(state->fPrimitiveProcessor.get(), state->getPipeline(), &state->fDesc,
joshualitt17e73142015-01-21 11:52:36 -0800641 &state->fBatchTracker);
robertphillips9888b222015-02-27 08:50:34 -0800642 gpu->draw(args, fInfo);
cdalton6819df32014-10-15 13:43:48 -0700643}
644
robertphillips9888b222015-02-27 08:50:34 -0800645void GrInOrderDrawBuffer::StencilPath::execute(GrGpu* gpu, const SetState*) {
bsalomon3e791242014-12-17 13:43:13 -0800646 GrGpu::StencilPathState state;
647 state.fRenderTarget = fRenderTarget.get();
648 state.fScissor = &fScissor;
649 state.fStencil = &fStencil;
650 state.fUseHWAA = fUseHWAA;
651 state.fViewMatrix = &fViewMatrix;
652
robertphillips9888b222015-02-27 08:50:34 -0800653 gpu->stencilPath(this->path(), state);
cdalton6819df32014-10-15 13:43:48 -0700654}
655
robertphillips9888b222015-02-27 08:50:34 -0800656void GrInOrderDrawBuffer::DrawPath::execute(GrGpu* gpu, const SetState* state) {
joshualitt873ad0e2015-01-20 09:08:51 -0800657 SkASSERT(state);
egdaniele36914c2015-02-13 09:00:33 -0800658 DrawArgs args(state->fPrimitiveProcessor.get(), state->getPipeline(), &state->fDesc,
joshualitt17e73142015-01-21 11:52:36 -0800659 &state->fBatchTracker);
robertphillips9888b222015-02-27 08:50:34 -0800660 gpu->drawPath(args, this->path(), fStencilSettings);
cdalton6819df32014-10-15 13:43:48 -0700661}
662
robertphillips9888b222015-02-27 08:50:34 -0800663void GrInOrderDrawBuffer::DrawPaths::execute(GrGpu* gpu, const SetState* state) {
joshualitt873ad0e2015-01-20 09:08:51 -0800664 SkASSERT(state);
egdaniele36914c2015-02-13 09:00:33 -0800665 DrawArgs args(state->fPrimitiveProcessor.get(), state->getPipeline(), &state->fDesc,
joshualitt17e73142015-01-21 11:52:36 -0800666 &state->fBatchTracker);
robertphillips9888b222015-02-27 08:50:34 -0800667 gpu->drawPaths(args, this->pathRange(),
668 fIndices, fIndexType,
669 fTransforms, fTransformType,
670 fCount, fStencilSettings);
cdalton6819df32014-10-15 13:43:48 -0700671}
672
robertphillips9888b222015-02-27 08:50:34 -0800673void GrInOrderDrawBuffer::DrawBatch::execute(GrGpu* gpu, const SetState* state) {
joshualitt4d8da812015-01-28 12:53:54 -0800674 SkASSERT(state);
robertphillips9888b222015-02-27 08:50:34 -0800675 fBatch->generateGeometry(fBatchTarget, state->getPipeline());
joshualitt4d8da812015-01-28 12:53:54 -0800676}
677
robertphillips9888b222015-02-27 08:50:34 -0800678void GrInOrderDrawBuffer::SetState::execute(GrGpu* gpu, const SetState*) {}
cdalton6819df32014-10-15 13:43:48 -0700679
robertphillips9888b222015-02-27 08:50:34 -0800680void GrInOrderDrawBuffer::Clear::execute(GrGpu* gpu, const SetState*) {
cdalton6819df32014-10-15 13:43:48 -0700681 if (GrColor_ILLEGAL == fColor) {
robertphillips9888b222015-02-27 08:50:34 -0800682 gpu->discard(this->renderTarget());
cdalton6819df32014-10-15 13:43:48 -0700683 } else {
robertphillips9888b222015-02-27 08:50:34 -0800684 gpu->clear(&fRect, fColor, fCanIgnoreRect, this->renderTarget());
cdalton6819df32014-10-15 13:43:48 -0700685 }
686}
687
robertphillips9888b222015-02-27 08:50:34 -0800688void GrInOrderDrawBuffer::ClearStencilClip::execute(GrGpu* gpu, const SetState*) {
689 gpu->clearStencilClip(fRect, fInsideClip, this->renderTarget());
joshualitt6db519c2014-10-29 08:48:18 -0700690}
691
robertphillips9888b222015-02-27 08:50:34 -0800692void GrInOrderDrawBuffer::CopySurface::execute(GrGpu* gpu, const SetState*) {
693 gpu->copySurface(this->dst(), this->src(), fSrcRect, fDstPoint);
cdalton6819df32014-10-15 13:43:48 -0700694}
695
bsalomonf90a02b2014-11-26 12:28:00 -0800696bool GrInOrderDrawBuffer::onCopySurface(GrSurface* dst,
697 GrSurface* src,
698 const SkIRect& srcRect,
699 const SkIPoint& dstPoint) {
bsalomon371bcbc2014-12-01 08:19:34 -0800700 if (getGpu()->canCopySurface(dst, src, srcRect, dstPoint)) {
joshualitt95964c62015-02-11 13:45:50 -0800701 this->closeBatch();
cdalton6819df32014-10-15 13:43:48 -0700702 CopySurface* cs = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, CopySurface, (dst, src));
bsalomon@google.com116ad842013-04-09 15:38:19 +0000703 cs->fSrcRect = srcRect;
704 cs->fDstPoint = dstPoint;
robertphillips7f966f42015-03-02 06:40:12 -0800705 this->recordTraceMarkersIfNecessary(cs);
bsalomon@google.com116ad842013-04-09 15:38:19 +0000706 return true;
bsalomon@google.com116ad842013-04-09 15:38:19 +0000707 }
bsalomonf90a02b2014-11-26 12:28:00 -0800708 return false;
bsalomon@google.com116ad842013-04-09 15:38:19 +0000709}
710
egdaniele36914c2015-02-13 09:00:33 -0800711bool GrInOrderDrawBuffer::setupPipelineAndShouldDraw(const GrPrimitiveProcessor* primProc,
712 const PipelineInfo& pipelineInfo) {
713 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (primProc));
714 this->setupPipeline(pipelineInfo, ss->pipelineLocation());
715
716 if (ss->getPipeline()->mustSkip()) {
bsalomon932f8662014-11-24 06:47:48 -0800717 fCmdBuffer.pop_back();
bsalomonae59b772014-11-19 08:23:49 -0800718 return false;
719 }
joshualitt873ad0e2015-01-20 09:08:51 -0800720
721 ss->fPrimitiveProcessor->initBatchTracker(&ss->fBatchTracker,
egdaniele36914c2015-02-13 09:00:33 -0800722 ss->getPipeline()->getInitBatchTracker());
joshualitt873ad0e2015-01-20 09:08:51 -0800723
joshualitt4d8da812015-01-28 12:53:54 -0800724 if (fPrevState && fPrevState->fPrimitiveProcessor.get() &&
joshualitt873ad0e2015-01-20 09:08:51 -0800725 fPrevState->fPrimitiveProcessor->canMakeEqual(fPrevState->fBatchTracker,
726 *ss->fPrimitiveProcessor,
727 ss->fBatchTracker) &&
egdaniele36914c2015-02-13 09:00:33 -0800728 fPrevState->getPipeline()->isEqual(*ss->getPipeline())) {
bsalomon932f8662014-11-24 06:47:48 -0800729 fCmdBuffer.pop_back();
730 } else {
joshualitt873ad0e2015-01-20 09:08:51 -0800731 fPrevState = ss;
robertphillips7f966f42015-03-02 06:40:12 -0800732 this->recordTraceMarkersIfNecessary(ss);
bsalomon838f62d2014-08-05 07:15:57 -0700733 }
bsalomonae59b772014-11-19 08:23:49 -0800734 return true;
reed@google.comac10a2d2010-12-22 21:39:39 +0000735}
736
egdaniele36914c2015-02-13 09:00:33 -0800737bool GrInOrderDrawBuffer::setupPipelineAndShouldDraw(GrBatch* batch,
738 const PipelineInfo& pipelineInfo) {
739 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, ());
740 this->setupPipeline(pipelineInfo, ss->pipelineLocation());
741
742 if (ss->getPipeline()->mustSkip()) {
joshualitt4d8da812015-01-28 12:53:54 -0800743 fCmdBuffer.pop_back();
744 return false;
745 }
746
egdaniele36914c2015-02-13 09:00:33 -0800747 batch->initBatchTracker(ss->getPipeline()->getInitBatchTracker());
joshualitt4d8da812015-01-28 12:53:54 -0800748
749 if (fPrevState && !fPrevState->fPrimitiveProcessor.get() &&
egdaniele36914c2015-02-13 09:00:33 -0800750 fPrevState->getPipeline()->isEqual(*ss->getPipeline())) {
joshualitt4d8da812015-01-28 12:53:54 -0800751 fCmdBuffer.pop_back();
752 } else {
753 this->closeBatch();
754 fPrevState = ss;
robertphillips7f966f42015-03-02 06:40:12 -0800755 this->recordTraceMarkersIfNecessary(ss);
joshualitt4d8da812015-01-28 12:53:54 -0800756 }
757 return true;
758}
759
robertphillips7f966f42015-03-02 06:40:12 -0800760void GrInOrderDrawBuffer::recordTraceMarkersIfNecessary(Cmd* cmd) {
761 if (!cmd) {
762 return;
763 }
mtkleinf439c772014-10-14 14:29:30 -0700764 const GrTraceMarkerSet& activeTraceMarkers = this->getActiveTraceMarkers();
765 if (activeTraceMarkers.count() > 0) {
robertphillips7f966f42015-03-02 06:40:12 -0800766 if (cmd->isTraced()) {
767 fGpuCmdMarkers.back().addSet(activeTraceMarkers);
768 } else {
769 cmd->makeTraced();
770 fGpuCmdMarkers.push_back(activeTraceMarkers);
771 }
mtklein07894c42014-10-13 14:00:42 -0700772 }
mtklein07894c42014-10-13 14:00:42 -0700773}
joshualitt4d8da812015-01-28 12:53:54 -0800774
joshualitt4d8da812015-01-28 12:53:54 -0800775void GrInOrderDrawBuffer::willReserveVertexAndIndexSpace(int vertexCount,
776 size_t vertexStride,
777 int indexCount) {
778 this->closeBatch();
779
robertphillips54fac8b2015-02-16 09:35:50 -0800780 this->INHERITED::willReserveVertexAndIndexSpace(vertexCount, vertexStride, indexCount);
joshualitt4d8da812015-01-28 12:53:54 -0800781}