blob: 5dc851c768c8702035c1f366887fe81d390273d4 [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
bsalomon62c447d2014-08-08 08:08:50 -070041/** We always use per-vertex colors so that rects can be batched across color changes. Sometimes we
42 have explicit local coords and sometimes not. We *could* always provide explicit local coords
43 and just duplicate the positions when the caller hasn't provided a local coord rect, but we
44 haven't seen a use case which frequently switches between local rect and no local rect draws.
45
46 The color param is used to determine whether the opaque hint can be set on the draw state.
47 The caller must populate the vertex colors itself.
48
49 The vertex attrib order is always pos, color, [local coords].
50 */
joshualitt8fc6c2d2014-12-22 15:27:05 -080051static const GrGeometryProcessor* create_rect_gp(bool hasExplicitLocalCoords,
52 GrColor color,
53 const SkMatrix* localMatrix) {
joshualitt5478d422014-11-14 16:00:38 -080054 uint32_t flags = GrDefaultGeoProcFactory::kPosition_GPType |
55 GrDefaultGeoProcFactory::kColor_GPType;
joshualitt8fc6c2d2014-12-22 15:27:05 -080056 flags |= hasExplicitLocalCoords ? GrDefaultGeoProcFactory::kLocalCoord_GPType : 0;
57 if (localMatrix) {
joshualitt8059eb92014-12-29 15:10:07 -080058 return GrDefaultGeoProcFactory::Create(flags, color, SkMatrix::I(), *localMatrix,
59 GrColorIsOpaque(color));
joshualitt8fc6c2d2014-12-22 15:27:05 -080060 } else {
joshualitt8059eb92014-12-29 15:10:07 -080061 return GrDefaultGeoProcFactory::Create(flags, color, SkMatrix::I(), SkMatrix::I(),
62 GrColorIsOpaque(color));
joshualitt8fc6c2d2014-12-22 15:27:05 -080063 }
bsalomon62c447d2014-08-08 08:08:50 -070064}
robertphillips@google.com42903302013-04-20 12:26:07 +000065
cdalton3fc6a2f2014-11-13 11:54:20 -080066static bool path_fill_type_is_winding(const GrStencilSettings& pathStencilSettings) {
67 static const GrStencilSettings::Face pathFace = GrStencilSettings::kFront_Face;
68 bool isWinding = kInvert_StencilOp != pathStencilSettings.passOp(pathFace);
69 if (isWinding) {
70 // Double check that it is in fact winding.
71 SkASSERT(kIncClamp_StencilOp == pathStencilSettings.passOp(pathFace));
72 SkASSERT(kIncClamp_StencilOp == pathStencilSettings.failOp(pathFace));
73 SkASSERT(0x1 != pathStencilSettings.writeMask(pathFace));
74 SkASSERT(!pathStencilSettings.isTwoSided());
75 }
76 return isWinding;
77}
78
79template<typename T> static void reset_data_buffer(SkTDArray<T>* buffer, int minReserve) {
80 // Assume the next time this buffer fills up it will use approximately the same amount
81 // of space as last time. Only resize if we're using less than a third of the
82 // allocated space, and leave enough for 50% growth over last time.
83 if (3 * buffer->count() < buffer->reserved() && buffer->reserved() > minReserve) {
84 int reserve = SkTMax(minReserve, buffer->count() * 3 / 2);
85 buffer->reset();
86 buffer->setReserve(reserve);
87 } else {
88 buffer->rewind();
89 }
90}
91
joshualitt58773332015-02-23 16:41:42 -080092class RectBatch : public GrBatch {
93public:
94 struct Geometry {
95 GrColor fColor;
96 SkMatrix fViewMatrix;
97 SkRect fRect;
98 bool fHasLocalRect;
99 bool fHasLocalMatrix;
100 SkRect fLocalRect;
101 SkMatrix fLocalMatrix;
102 };
103
104 static GrBatch* Create(const Geometry& geometry) {
105 return SkNEW_ARGS(RectBatch, (geometry));
106 }
107
108 const char* name() const SK_OVERRIDE { return "RectBatch"; }
109
110 void getInvariantOutputColor(GrInitInvariantOutput* out) const SK_OVERRIDE {
111 // When this is called on a batch, there is only one geometry bundle
112 out->setKnownFourComponents(fGeoData[0].fColor);
113 }
114
115 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const SK_OVERRIDE {
116 out->setKnownSingleComponent(0xff);
117 }
118
119 void initBatchTracker(const GrPipelineInfo& init) SK_OVERRIDE {
120 // Handle any color overrides
121 if (init.fColorIgnored) {
122 fGeoData[0].fColor = GrColor_ILLEGAL;
123 } else if (GrColor_ILLEGAL != init.fOverrideColor) {
124 fGeoData[0].fColor = init.fOverrideColor;
125 }
126
127 // setup batch properties
128 fBatch.fColorIgnored = init.fColorIgnored;
129 fBatch.fColor = fGeoData[0].fColor;
130 fBatch.fUsesLocalCoords = init.fUsesLocalCoords;
131 fBatch.fCoverageIgnored = init.fCoverageIgnored;
132 }
133
134 void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) SK_OVERRIDE {
135 // Go to device coords to allow batching across matrix changes
136 SkMatrix invert = SkMatrix::I();
137
138 // if we have a local rect, then we apply the localMatrix directly to the localRect to
139 // generate vertex local coords
140 bool hasExplicitLocalCoords = this->hasLocalRect();
141 if (!hasExplicitLocalCoords) {
142 if (!this->viewMatrix().isIdentity() && !this->viewMatrix().invert(&invert)) {
143 SkDebugf("Could not invert\n");
144 return;
145 }
146
147 if (this->hasLocalMatrix()) {
148 invert.preConcat(this->localMatrix());
149 }
150 }
151
152 SkAutoTUnref<const GrGeometryProcessor> gp(create_rect_gp(hasExplicitLocalCoords,
153 this->color(),
154 &invert));
155
156 batchTarget->initDraw(gp, pipeline);
157
158 // TODO this is hacky, but the only way we have to initialize the GP is to use the
159 // GrPipelineInfo struct so we can generate the correct shader. Once we have GrBatch
160 // everywhere we can remove this nastiness
161 GrPipelineInfo init;
162 init.fColorIgnored = fBatch.fColorIgnored;
163 init.fOverrideColor = GrColor_ILLEGAL;
164 init.fCoverageIgnored = fBatch.fCoverageIgnored;
165 init.fUsesLocalCoords = this->usesLocalCoords();
166 gp->initBatchTracker(batchTarget->currentBatchTracker(), init);
167
168 size_t vertexStride = gp->getVertexStride();
169
170 SkASSERT(hasExplicitLocalCoords ?
171 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordAttr) :
172 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAttr));
173
174 int instanceCount = fGeoData.count();
175 int vertexCount = kVertsPerRect * instanceCount;
176
177 const GrVertexBuffer* vertexBuffer;
178 int firstVertex;
179
180 void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
181 vertexCount,
182 &vertexBuffer,
183 &firstVertex);
184
185 for (int i = 0; i < instanceCount; i++) {
186 const Geometry& args = fGeoData[i];
187
188 intptr_t offset = GrTCast<intptr_t>(vertices) + kVertsPerRect * i * vertexStride;
189 SkPoint* positions = GrTCast<SkPoint*>(offset);
190
191 positions->setRectFan(args.fRect.fLeft, args.fRect.fTop,
192 args.fRect.fRight, args.fRect.fBottom, vertexStride);
193 args.fViewMatrix.mapPointsWithStride(positions, vertexStride, kVertsPerRect);
194
195 if (args.fHasLocalRect) {
196 static const int kLocalOffset = sizeof(SkPoint) + sizeof(GrColor);
197 SkPoint* coords = GrTCast<SkPoint*>(offset + kLocalOffset);
198 coords->setRectFan(args.fLocalRect.fLeft, args.fLocalRect.fTop,
199 args.fLocalRect.fRight, args.fLocalRect.fBottom,
200 vertexStride);
201 if (args.fHasLocalMatrix) {
202 args.fLocalMatrix.mapPointsWithStride(coords, vertexStride, kVertsPerRect);
203 }
204 }
205
206 static const int kColorOffset = sizeof(SkPoint);
207 GrColor* vertColor = GrTCast<GrColor*>(offset + kColorOffset);
208 for (int j = 0; j < 4; ++j) {
209 *vertColor = args.fColor;
210 vertColor = (GrColor*) ((intptr_t) vertColor + vertexStride);
211 }
212 }
213
214 const GrIndexBuffer* quadIndexBuffer = batchTarget->quadIndexBuffer();
215
216 GrDrawTarget::DrawInfo drawInfo;
217 drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType);
218 drawInfo.setStartVertex(0);
219 drawInfo.setStartIndex(0);
220 drawInfo.setVerticesPerInstance(kVertsPerRect);
221 drawInfo.setIndicesPerInstance(kIndicesPerRect);
222 drawInfo.adjustStartVertex(firstVertex);
223 drawInfo.setVertexBuffer(vertexBuffer);
224 drawInfo.setIndexBuffer(quadIndexBuffer);
225
226 int maxInstancesPerDraw = quadIndexBuffer->maxQuads();
227 while (instanceCount) {
228 drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw));
229 drawInfo.setVertexCount(drawInfo.instanceCount() * drawInfo.verticesPerInstance());
230 drawInfo.setIndexCount(drawInfo.instanceCount() * drawInfo.indicesPerInstance());
231
232 batchTarget->draw(drawInfo);
233
234 drawInfo.setStartVertex(drawInfo.startVertex() + drawInfo.vertexCount());
235 instanceCount -= drawInfo.instanceCount();
236 }
237 }
238
239 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
240
241private:
242 RectBatch(const Geometry& geometry) {
243 this->initClassID<RectBatch>();
244 fGeoData.push_back(geometry);
245 }
246
247 GrColor color() const { return fBatch.fColor; }
248 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; }
249 bool colorIgnored() const { return fBatch.fColorIgnored; }
250 const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; }
251 const SkMatrix& localMatrix() const { return fGeoData[0].fLocalMatrix; }
252 bool hasLocalRect() const { return fGeoData[0].fHasLocalRect; }
253 bool hasLocalMatrix() const { return fGeoData[0].fHasLocalMatrix; }
254
255 bool onCombineIfPossible(GrBatch* t) SK_OVERRIDE {
256 RectBatch* that = t->cast<RectBatch>();
257
258 if (this->hasLocalRect() != that->hasLocalRect()) {
259 return false;
260 }
261
262 SkASSERT(this->usesLocalCoords() == that->usesLocalCoords());
263 if (!this->hasLocalRect() && this->usesLocalCoords()) {
264 if (!this->viewMatrix().cheapEqualTo(that->viewMatrix())) {
265 return false;
266 }
267
268 if (this->hasLocalMatrix() != that->hasLocalMatrix()) {
269 return false;
270 }
271
272 if (this->hasLocalMatrix() && !this->localMatrix().cheapEqualTo(that->localMatrix())) {
273 return false;
274 }
275 }
276
277 if (this->color() != that->color()) {
278 fBatch.fColor = GrColor_ILLEGAL;
279 }
280 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin());
281 return true;
282 }
283
284 struct BatchTracker {
285 GrColor fColor;
286 bool fUsesLocalCoords;
287 bool fColorIgnored;
288 bool fCoverageIgnored;
289 };
290
291 const static int kVertsPerRect = 4;
292 const static int kIndicesPerRect = 6;
293
294 BatchTracker fBatch;
295 SkSTArray<1, Geometry, true> fGeoData;
296};
297
egdaniel8dd688b2015-01-22 10:16:09 -0800298void GrInOrderDrawBuffer::onDrawRect(GrPipelineBuilder* pipelineBuilder,
joshualitt2e3b3e32014-12-09 13:31:14 -0800299 GrColor color,
joshualitt8059eb92014-12-29 15:10:07 -0800300 const SkMatrix& viewMatrix,
joshualitt9853cce2014-11-17 14:22:48 -0800301 const SkRect& rect,
commit-bot@chromium.orgfd03d4a2013-07-17 21:39:42 +0000302 const SkRect* localRect,
bsalomon@google.com0406b9e2013-04-02 21:00:15 +0000303 const SkMatrix* localMatrix) {
egdaniel8dd688b2015-01-22 10:16:09 -0800304 GrPipelineBuilder::AutoRestoreEffects are(pipelineBuilder);
joshualitt58773332015-02-23 16:41:42 -0800305 RectBatch::Geometry geometry;
306 geometry.fColor = color;
307 geometry.fViewMatrix = viewMatrix;
308 geometry.fRect = rect;
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000309
bsalomon49f085d2014-09-05 13:34:00 -0700310 if (localRect) {
joshualitt58773332015-02-23 16:41:42 -0800311 geometry.fHasLocalRect = true;
312 geometry.fLocalRect = *localRect;
313 } else {
314 geometry.fHasLocalRect = false;
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000315 }
316
joshualitt58773332015-02-23 16:41:42 -0800317 if (localMatrix) {
318 geometry.fHasLocalMatrix = true;
319 geometry.fLocalMatrix = *localMatrix;
320 } else {
321 geometry.fHasLocalMatrix = false;
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000322 }
323
joshualitt58773332015-02-23 16:41:42 -0800324 SkAutoTUnref<GrBatch> batch(RectBatch::Create(geometry));
325
326 SkRect bounds = rect;
327 viewMatrix.mapRect(&bounds);
328 this->drawBatch(pipelineBuilder, batch, &bounds);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000329}
330
egdaniele36914c2015-02-13 09:00:33 -0800331int GrInOrderDrawBuffer::concatInstancedDraw(const DrawInfo& info) {
cdalton6819df32014-10-15 13:43:48 -0700332 SkASSERT(!fCmdBuffer.empty());
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000333 SkASSERT(info.isInstanced());
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000334
bsalomon@google.com934c5702012-03-20 21:17:58 +0000335 const GeometrySrcState& geomSrc = this->getGeomSrc();
336
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000337 // we only attempt to concat the case when reserved verts are used with a client-specified index
338 // buffer. To make this work with client-specified VBs we'd need to know if the VB was updated
339 // between draws.
340 if (kReserved_GeometrySrcType != geomSrc.fVertexSrc ||
341 kBuffer_GeometrySrcType != geomSrc.fIndexSrc) {
342 return 0;
bsalomon@google.com934c5702012-03-20 21:17:58 +0000343 }
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000344 // Check if there is a draw info that is compatible that uses the same VB from the pool and
345 // the same IB
robertphillipse5e72f12015-02-17 09:14:33 -0800346 if (Cmd::kDraw_Cmd != fCmdBuffer.back().type()) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000347 return 0;
348 }
349
cdalton6819df32014-10-15 13:43:48 -0700350 Draw* draw = static_cast<Draw*>(&fCmdBuffer.back());
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000351
cdalton6819df32014-10-15 13:43:48 -0700352 if (!draw->fInfo.isInstanced() ||
joshualitt4d8da812015-01-28 12:53:54 -0800353 draw->fInfo.primitiveType() != info.primitiveType() ||
cdalton6819df32014-10-15 13:43:48 -0700354 draw->fInfo.verticesPerInstance() != info.verticesPerInstance() ||
355 draw->fInfo.indicesPerInstance() != info.indicesPerInstance() ||
bsalomon371bcbc2014-12-01 08:19:34 -0800356 draw->fInfo.vertexBuffer() != info.vertexBuffer() ||
joshualitt54e0c122014-11-19 09:38:51 -0800357 draw->fInfo.indexBuffer() != geomSrc.fIndexBuffer) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000358 return 0;
359 }
bsalomon371bcbc2014-12-01 08:19:34 -0800360 if (draw->fInfo.startVertex() + draw->fInfo.vertexCount() != info.startVertex()) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000361 return 0;
362 }
363
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000364 // how many instances can be concat'ed onto draw given the size of the index buffer
365 int instancesToConcat = this->indexCountInCurrentSource() / info.indicesPerInstance();
cdalton6819df32014-10-15 13:43:48 -0700366 instancesToConcat -= draw->fInfo.instanceCount();
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000367 instancesToConcat = SkTMin(instancesToConcat, info.instanceCount());
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000368
cdalton6819df32014-10-15 13:43:48 -0700369 draw->fInfo.adjustInstanceCount(instancesToConcat);
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000370
371 // update last fGpuCmdMarkers to include any additional trace markers that have been added
372 if (this->getActiveTraceMarkers().count() > 0) {
robertphillipse5e72f12015-02-17 09:14:33 -0800373 if (draw->isTraced()) {
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000374 fGpuCmdMarkers.back().addSet(this->getActiveTraceMarkers());
375 } else {
376 fGpuCmdMarkers.push_back(this->getActiveTraceMarkers());
robertphillipse5e72f12015-02-17 09:14:33 -0800377 draw->makeTraced();
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000378 }
379 }
380
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000381 return instancesToConcat;
bsalomon@google.com934c5702012-03-20 21:17:58 +0000382}
383
egdaniele36914c2015-02-13 09:00:33 -0800384void GrInOrderDrawBuffer::onDraw(const GrGeometryProcessor* gp,
joshualitt9853cce2014-11-17 14:22:48 -0800385 const DrawInfo& info,
egdaniele36914c2015-02-13 09:00:33 -0800386 const PipelineInfo& pipelineInfo) {
joshualitt7eb8c7b2014-11-18 14:24:27 -0800387 SkASSERT(info.vertexBuffer() && (!info.isIndexed() || info.indexBuffer()));
joshualitt4d8da812015-01-28 12:53:54 -0800388 this->closeBatch();
389
egdaniele36914c2015-02-13 09:00:33 -0800390 if (!this->setupPipelineAndShouldDraw(gp, pipelineInfo)) {
bsalomonae59b772014-11-19 08:23:49 -0800391 return;
392 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000393
bsalomonb3e3a952014-09-19 11:10:40 -0700394 Draw* draw;
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000395 if (info.isInstanced()) {
egdaniele36914c2015-02-13 09:00:33 -0800396 int instancesConcated = this->concatInstancedDraw(info);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000397 if (info.instanceCount() > instancesConcated) {
joshualitt54e0c122014-11-19 09:38:51 -0800398 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info));
cdalton6819df32014-10-15 13:43:48 -0700399 draw->fInfo.adjustInstanceCount(-instancesConcated);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000400 } else {
401 return;
402 }
403 } else {
joshualitt54e0c122014-11-19 09:38:51 -0800404 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info));
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000405 }
cdalton6819df32014-10-15 13:43:48 -0700406 this->recordTraceMarkersIfNecessary();
commit-bot@chromium.org9b62aa12014-03-25 11:59:40 +0000407}
sugoi@google.com5f74cf82012-12-17 21:16:45 +0000408
joshualitt4d8da812015-01-28 12:53:54 -0800409void GrInOrderDrawBuffer::onDrawBatch(GrBatch* batch,
egdaniele36914c2015-02-13 09:00:33 -0800410 const PipelineInfo& pipelineInfo) {
411 if (!this->setupPipelineAndShouldDraw(batch, pipelineInfo)) {
joshualitt4d8da812015-01-28 12:53:54 -0800412 return;
413 }
414
415 // Check if there is a Batch Draw we can batch with
robertphillipse5e72f12015-02-17 09:14:33 -0800416 if (Cmd::kDrawBatch_Cmd != fCmdBuffer.back().type()) {
joshualitt4d8da812015-01-28 12:53:54 -0800417 fDrawBatch = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawBatch, (batch));
418 return;
419 }
420
421 DrawBatch* draw = static_cast<DrawBatch*>(&fCmdBuffer.back());
422 if (draw->fBatch->combineIfPossible(batch)) {
423 return;
424 } else {
425 this->closeBatch();
426 fDrawBatch = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawBatch, (batch));
427 }
428 this->recordTraceMarkersIfNecessary();
429}
430
egdaniel8dd688b2015-01-22 10:16:09 -0800431void GrInOrderDrawBuffer::onStencilPath(const GrPipelineBuilder& pipelineBuilder,
joshualitt56995b52014-12-11 15:44:02 -0800432 const GrPathProcessor* pathProc,
joshualitt9853cce2014-11-17 14:22:48 -0800433 const GrPath* path,
bsalomon3e791242014-12-17 13:43:13 -0800434 const GrScissorState& scissorState,
joshualitt2c93efe2014-11-06 12:57:13 -0800435 const GrStencilSettings& stencilSettings) {
joshualitt70f00042015-02-06 15:53:59 -0800436 this->closeBatch();
437
bsalomon3e791242014-12-17 13:43:13 -0800438 StencilPath* sp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, StencilPath,
egdaniel8dd688b2015-01-22 10:16:09 -0800439 (path, pipelineBuilder.getRenderTarget()));
joshualitt58773332015-02-23 16:41:42 -0800440
bsalomon3e791242014-12-17 13:43:13 -0800441 sp->fScissor = scissorState;
egdaniel8dd688b2015-01-22 10:16:09 -0800442 sp->fUseHWAA = pipelineBuilder.isHWAntialias();
joshualitt8059eb92014-12-29 15:10:07 -0800443 sp->fViewMatrix = pathProc->viewMatrix();
bsalomon3e791242014-12-17 13:43:13 -0800444 sp->fStencil = stencilSettings;
cdalton6819df32014-10-15 13:43:48 -0700445 this->recordTraceMarkersIfNecessary();
bsalomon@google.com64aef2b2012-06-11 15:36:13 +0000446}
447
egdaniele36914c2015-02-13 09:00:33 -0800448void GrInOrderDrawBuffer::onDrawPath(const GrPathProcessor* pathProc,
joshualitt9853cce2014-11-17 14:22:48 -0800449 const GrPath* path,
joshualitt2c93efe2014-11-06 12:57:13 -0800450 const GrStencilSettings& stencilSettings,
egdaniele36914c2015-02-13 09:00:33 -0800451 const PipelineInfo& pipelineInfo) {
joshualitt4d8da812015-01-28 12:53:54 -0800452 this->closeBatch();
453
egdaniel8dd688b2015-01-22 10:16:09 -0800454 // TODO: Only compare the subset of GrPipelineBuilder relevant to path covering?
egdaniele36914c2015-02-13 09:00:33 -0800455 if (!this->setupPipelineAndShouldDraw(pathProc, pipelineInfo)) {
bsalomonae59b772014-11-19 08:23:49 -0800456 return;
457 }
cdalton6819df32014-10-15 13:43:48 -0700458 DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (path));
joshualitt2c93efe2014-11-06 12:57:13 -0800459 dp->fStencilSettings = stencilSettings;
cdalton6819df32014-10-15 13:43:48 -0700460 this->recordTraceMarkersIfNecessary();
commit-bot@chromium.orgc4dc0ad2013-10-09 14:11:33 +0000461}
462
egdaniele36914c2015-02-13 09:00:33 -0800463void GrInOrderDrawBuffer::onDrawPaths(const GrPathProcessor* pathProc,
joshualitt9853cce2014-11-17 14:22:48 -0800464 const GrPathRange* pathRange,
cdalton55b24af2014-11-25 11:00:56 -0800465 const void* indices,
466 PathIndexType indexType,
467 const float transformValues[],
468 PathTransformType transformType,
joshualitt2c93efe2014-11-06 12:57:13 -0800469 int count,
joshualitt2c93efe2014-11-06 12:57:13 -0800470 const GrStencilSettings& stencilSettings,
egdaniele36914c2015-02-13 09:00:33 -0800471 const PipelineInfo& pipelineInfo) {
bsalomon49f085d2014-09-05 13:34:00 -0700472 SkASSERT(pathRange);
473 SkASSERT(indices);
cdalton55b24af2014-11-25 11:00:56 -0800474 SkASSERT(transformValues);
joshualitt4d8da812015-01-28 12:53:54 -0800475 this->closeBatch();
476
egdaniele36914c2015-02-13 09:00:33 -0800477 if (!this->setupPipelineAndShouldDraw(pathProc, pipelineInfo)) {
bsalomonae59b772014-11-19 08:23:49 -0800478 return;
479 }
cdalton6819df32014-10-15 13:43:48 -0700480
cdalton55b24af2014-11-25 11:00:56 -0800481 int indexBytes = GrPathRange::PathIndexSizeInBytes(indexType);
482 if (int misalign = fPathIndexBuffer.count() % indexBytes) {
483 // Add padding to the index buffer so the indices are aligned properly.
484 fPathIndexBuffer.append(indexBytes - misalign);
485 }
486
487 char* savedIndices = fPathIndexBuffer.append(count * indexBytes,
488 reinterpret_cast<const char*>(indices));
489 float* savedTransforms = fPathTransformBuffer.append(
490 count * GrPathRendering::PathTransformSize(transformType),
491 transformValues);
cdalton6819df32014-10-15 13:43:48 -0700492
robertphillipse5e72f12015-02-17 09:14:33 -0800493 if (Cmd::kDrawPaths_Cmd == fCmdBuffer.back().type()) {
cdalton3fc6a2f2014-11-13 11:54:20 -0800494 // The previous command was also DrawPaths. Try to collapse this call into the one
bsalomon371bcbc2014-12-01 08:19:34 -0800495 // before. Note that stenciling all the paths at once, then covering, may not be
cdalton3fc6a2f2014-11-13 11:54:20 -0800496 // equivalent to two separate draw calls if there is overlap. Blending won't work,
497 // and the combined calls may also cancel each other's winding numbers in some
498 // places. For now the winding numbers are only an issue if the fill is even/odd,
499 // because DrawPaths is currently only used for glyphs, and glyphs in the same
500 // font tend to all wind in the same direction.
501 DrawPaths* previous = static_cast<DrawPaths*>(&fCmdBuffer.back());
502 if (pathRange == previous->pathRange() &&
cdalton55b24af2014-11-25 11:00:56 -0800503 indexType == previous->fIndexType &&
504 transformType == previous->fTransformType &&
cdalton3fc6a2f2014-11-13 11:54:20 -0800505 stencilSettings == previous->fStencilSettings &&
506 path_fill_type_is_winding(stencilSettings) &&
egdaniele36914c2015-02-13 09:00:33 -0800507 !pipelineInfo.willBlendWithDst(pathProc)) {
cdalton3fc6a2f2014-11-13 11:54:20 -0800508 // Fold this DrawPaths call into the one previous.
509 previous->fCount += count;
510 return;
511 }
512 }
513
514 DrawPaths* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPaths, (pathRange));
bsalomonef3fcd82014-12-12 08:51:38 -0800515 dp->fIndicesLocation = SkToU32(savedIndices - fPathIndexBuffer.begin());
cdalton55b24af2014-11-25 11:00:56 -0800516 dp->fIndexType = indexType;
bsalomonef3fcd82014-12-12 08:51:38 -0800517 dp->fTransformsLocation = SkToU32(savedTransforms - fPathTransformBuffer.begin());
cdalton55b24af2014-11-25 11:00:56 -0800518 dp->fTransformType = transformType;
519 dp->fCount = count;
joshualitt2c93efe2014-11-06 12:57:13 -0800520 dp->fStencilSettings = stencilSettings;
cdalton6819df32014-10-15 13:43:48 -0700521
522 this->recordTraceMarkersIfNecessary();
commit-bot@chromium.org9b62aa12014-03-25 11:59:40 +0000523}
524
bsalomon63b21962014-11-05 07:05:34 -0800525void GrInOrderDrawBuffer::onClear(const SkIRect* rect, GrColor color,
526 bool canIgnoreRect, GrRenderTarget* renderTarget) {
joshualitt9853cce2014-11-17 14:22:48 -0800527 SkASSERT(renderTarget);
joshualitt70f00042015-02-06 15:53:59 -0800528 this->closeBatch();
529
commit-bot@chromium.orgfd03d4a2013-07-17 21:39:42 +0000530 SkIRect r;
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000531 if (NULL == rect) {
532 // We could do something smart and remove previous draws and clears to
533 // the current render target. If we get that smart we have to make sure
534 // those draws aren't read before this clear (render-to-texture).
bsalomon@google.com1b3ce472012-08-17 13:43:08 +0000535 r.setLTRB(0, 0, renderTarget->width(), renderTarget->height());
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000536 rect = &r;
537 }
cdalton6819df32014-10-15 13:43:48 -0700538 Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget));
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000539 GrColorIsPMAssert(color);
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000540 clr->fColor = color;
541 clr->fRect = *rect;
robertphillips@google.com56ce48a2013-10-31 21:44:25 +0000542 clr->fCanIgnoreRect = canIgnoreRect;
cdalton6819df32014-10-15 13:43:48 -0700543 this->recordTraceMarkersIfNecessary();
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000544}
545
joshualitt6db519c2014-10-29 08:48:18 -0700546void GrInOrderDrawBuffer::clearStencilClip(const SkIRect& rect,
547 bool insideClip,
548 GrRenderTarget* renderTarget) {
joshualitt9853cce2014-11-17 14:22:48 -0800549 SkASSERT(renderTarget);
joshualitt70f00042015-02-06 15:53:59 -0800550 this->closeBatch();
551
joshualitt6db519c2014-10-29 08:48:18 -0700552 ClearStencilClip* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, ClearStencilClip, (renderTarget));
553 clr->fRect = rect;
554 clr->fInsideClip = insideClip;
555 this->recordTraceMarkersIfNecessary();
556}
557
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000558void GrInOrderDrawBuffer::discard(GrRenderTarget* renderTarget) {
bsalomon89c62982014-11-03 12:08:42 -0800559 SkASSERT(renderTarget);
joshualitt70f00042015-02-06 15:53:59 -0800560 this->closeBatch();
561
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000562 if (!this->caps()->discardRenderTargetSupport()) {
563 return;
564 }
cdalton6819df32014-10-15 13:43:48 -0700565 Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget));
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000566 clr->fColor = GrColor_ILLEGAL;
cdalton6819df32014-10-15 13:43:48 -0700567 this->recordTraceMarkersIfNecessary();
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000568}
569
bsalomon371bcbc2014-12-01 08:19:34 -0800570void GrInOrderDrawBuffer::onReset() {
cdalton6819df32014-10-15 13:43:48 -0700571 fCmdBuffer.reset();
bsalomon932f8662014-11-24 06:47:48 -0800572 fPrevState = NULL;
cdalton3fc6a2f2014-11-13 11:54:20 -0800573 reset_data_buffer(&fPathIndexBuffer, kPathIdxBufferMinReserve);
574 reset_data_buffer(&fPathTransformBuffer, kPathXformBufferMinReserve);
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000575 fGpuCmdMarkers.reset();
joshualitt4d8da812015-01-28 12:53:54 -0800576 fDrawBatch = NULL;
reed@google.comac10a2d2010-12-22 21:39:39 +0000577}
578
bsalomon371bcbc2014-12-01 08:19:34 -0800579void GrInOrderDrawBuffer::onFlush() {
cdalton6819df32014-10-15 13:43:48 -0700580 if (fCmdBuffer.empty()) {
robertphillips@google.com1267fbd2013-07-03 18:37:27 +0000581 return;
reed@google.comac10a2d2010-12-22 21:39:39 +0000582 }
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000583
joshualittc2893c52015-01-28 06:54:30 -0800584 // Updated every time we find a set state cmd to reflect the current state in the playback
585 // stream.
586 SetState* currentState = NULL;
587
joshualitt4d8da812015-01-28 12:53:54 -0800588 // TODO this is temporary while batch is being rolled out
589 this->closeBatch();
590 this->getVertexAllocPool()->unmap();
591 this->getIndexAllocPool()->unmap();
592 fBatchTarget.preFlush();
593
594 currentState = NULL;
595 CmdBuffer::Iter iter(fCmdBuffer);
596
597 int currCmdMarker = 0;
598
joshualitt7bc18b72015-02-03 16:41:41 -0800599 int i = 0;
cdalton6819df32014-10-15 13:43:48 -0700600 while (iter.next()) {
joshualitt7bc18b72015-02-03 16:41:41 -0800601 i++;
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000602 GrGpuTraceMarker newMarker("", -1);
egdanield78a1682014-07-09 10:41:26 -0700603 SkString traceString;
robertphillipse5e72f12015-02-17 09:14:33 -0800604 if (iter->isTraced()) {
egdanield78a1682014-07-09 10:41:26 -0700605 traceString = fGpuCmdMarkers[currCmdMarker].toString();
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000606 newMarker.fMarker = traceString.c_str();
bsalomon371bcbc2014-12-01 08:19:34 -0800607 this->getGpu()->addGpuTraceMarker(&newMarker);
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000608 ++currCmdMarker;
609 }
cdalton6819df32014-10-15 13:43:48 -0700610
joshualitt4d8da812015-01-28 12:53:54 -0800611 // TODO temporary hack
robertphillipse5e72f12015-02-17 09:14:33 -0800612 if (Cmd::kDrawBatch_Cmd == iter->type()) {
joshualitt7bc18b72015-02-03 16:41:41 -0800613 DrawBatch* db = reinterpret_cast<DrawBatch*>(iter.get());
614 fBatchTarget.flushNext(db->fBatch->numberOfDraws());
joshualitt4d8da812015-01-28 12:53:54 -0800615 continue;
616 }
617
robertphillipse5e72f12015-02-17 09:14:33 -0800618 if (Cmd::kSetState_Cmd == iter->type()) {
joshualitt9853cce2014-11-17 14:22:48 -0800619 SetState* ss = reinterpret_cast<SetState*>(iter.get());
joshualitt873ad0e2015-01-20 09:08:51 -0800620
joshualitt4d8da812015-01-28 12:53:54 -0800621 // TODO sometimes we have a prim proc, othertimes we have a GrBatch. Eventually we will
622 // only have GrBatch and we can delete this
623 if (ss->fPrimitiveProcessor) {
624 this->getGpu()->buildProgramDesc(&ss->fDesc, *ss->fPrimitiveProcessor,
egdaniele36914c2015-02-13 09:00:33 -0800625 *ss->getPipeline(),
joshualitt4d8da812015-01-28 12:53:54 -0800626 ss->fBatchTracker);
627 }
joshualitt873ad0e2015-01-20 09:08:51 -0800628 currentState = ss;
joshualittd53a8272014-11-10 16:03:14 -0800629 } else {
joshualitt873ad0e2015-01-20 09:08:51 -0800630 iter->execute(this, currentState);
joshualittd53a8272014-11-10 16:03:14 -0800631 }
cdalton6819df32014-10-15 13:43:48 -0700632
robertphillipse5e72f12015-02-17 09:14:33 -0800633 if (iter->isTraced()) {
bsalomon371bcbc2014-12-01 08:19:34 -0800634 this->getGpu()->removeGpuTraceMarker(&newMarker);
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000635 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000636 }
mtkleinf439c772014-10-14 14:29:30 -0700637
joshualitt4d8da812015-01-28 12:53:54 -0800638 // TODO see copious notes about hack
639 fBatchTarget.postFlush();
640
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000641 SkASSERT(fGpuCmdMarkers.count() == currCmdMarker);
commit-bot@chromium.orga8916ff2013-08-16 15:53:46 +0000642 ++fDrawID;
reed@google.comac10a2d2010-12-22 21:39:39 +0000643}
644
joshualitt873ad0e2015-01-20 09:08:51 -0800645void GrInOrderDrawBuffer::Draw::execute(GrInOrderDrawBuffer* buf, const SetState* state) {
646 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);
joshualitt873ad0e2015-01-20 09:08:51 -0800649 buf->getGpu()->draw(args, fInfo);
cdalton6819df32014-10-15 13:43:48 -0700650}
651
joshualitt873ad0e2015-01-20 09:08:51 -0800652void GrInOrderDrawBuffer::StencilPath::execute(GrInOrderDrawBuffer* buf, const SetState*) {
bsalomon3e791242014-12-17 13:43:13 -0800653 GrGpu::StencilPathState state;
654 state.fRenderTarget = fRenderTarget.get();
655 state.fScissor = &fScissor;
656 state.fStencil = &fStencil;
657 state.fUseHWAA = fUseHWAA;
658 state.fViewMatrix = &fViewMatrix;
659
660 buf->getGpu()->stencilPath(this->path(), state);
cdalton6819df32014-10-15 13:43:48 -0700661}
662
joshualitt873ad0e2015-01-20 09:08:51 -0800663void GrInOrderDrawBuffer::DrawPath::execute(GrInOrderDrawBuffer* buf, const SetState* state) {
664 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);
joshualitt873ad0e2015-01-20 09:08:51 -0800667 buf->getGpu()->drawPath(args, this->path(), fStencilSettings);
cdalton6819df32014-10-15 13:43:48 -0700668}
669
joshualitt873ad0e2015-01-20 09:08:51 -0800670void GrInOrderDrawBuffer::DrawPaths::execute(GrInOrderDrawBuffer* buf, const SetState* state) {
671 SkASSERT(state);
egdaniele36914c2015-02-13 09:00:33 -0800672 DrawArgs args(state->fPrimitiveProcessor.get(), state->getPipeline(), &state->fDesc,
joshualitt17e73142015-01-21 11:52:36 -0800673 &state->fBatchTracker);
joshualitt873ad0e2015-01-20 09:08:51 -0800674 buf->getGpu()->drawPaths(args, this->pathRange(),
cdalton55b24af2014-11-25 11:00:56 -0800675 &buf->fPathIndexBuffer[fIndicesLocation], fIndexType,
676 &buf->fPathTransformBuffer[fTransformsLocation], fTransformType,
677 fCount, fStencilSettings);
cdalton6819df32014-10-15 13:43:48 -0700678}
679
joshualitt4d8da812015-01-28 12:53:54 -0800680void GrInOrderDrawBuffer::DrawBatch::execute(GrInOrderDrawBuffer* buf, const SetState* state) {
681 SkASSERT(state);
egdaniele36914c2015-02-13 09:00:33 -0800682 fBatch->generateGeometry(buf->getBatchTarget(), state->getPipeline());
joshualitt4d8da812015-01-28 12:53:54 -0800683}
684
joshualitt873ad0e2015-01-20 09:08:51 -0800685void GrInOrderDrawBuffer::SetState::execute(GrInOrderDrawBuffer*, const SetState*) {}
cdalton6819df32014-10-15 13:43:48 -0700686
joshualitt873ad0e2015-01-20 09:08:51 -0800687void GrInOrderDrawBuffer::Clear::execute(GrInOrderDrawBuffer* buf, const SetState*) {
cdalton6819df32014-10-15 13:43:48 -0700688 if (GrColor_ILLEGAL == fColor) {
bsalomon371bcbc2014-12-01 08:19:34 -0800689 buf->getGpu()->discard(this->renderTarget());
cdalton6819df32014-10-15 13:43:48 -0700690 } else {
bsalomon371bcbc2014-12-01 08:19:34 -0800691 buf->getGpu()->clear(&fRect, fColor, fCanIgnoreRect, this->renderTarget());
cdalton6819df32014-10-15 13:43:48 -0700692 }
693}
694
joshualitt873ad0e2015-01-20 09:08:51 -0800695void GrInOrderDrawBuffer::ClearStencilClip::execute(GrInOrderDrawBuffer* buf, const SetState*) {
bsalomon371bcbc2014-12-01 08:19:34 -0800696 buf->getGpu()->clearStencilClip(fRect, fInsideClip, this->renderTarget());
joshualitt6db519c2014-10-29 08:48:18 -0700697}
698
joshualitt873ad0e2015-01-20 09:08:51 -0800699void GrInOrderDrawBuffer::CopySurface::execute(GrInOrderDrawBuffer* buf, const SetState*) {
bsalomon371bcbc2014-12-01 08:19:34 -0800700 buf->getGpu()->copySurface(this->dst(), this->src(), fSrcRect, fDstPoint);
cdalton6819df32014-10-15 13:43:48 -0700701}
702
bsalomonf90a02b2014-11-26 12:28:00 -0800703bool GrInOrderDrawBuffer::onCopySurface(GrSurface* dst,
704 GrSurface* src,
705 const SkIRect& srcRect,
706 const SkIPoint& dstPoint) {
bsalomon371bcbc2014-12-01 08:19:34 -0800707 if (getGpu()->canCopySurface(dst, src, srcRect, dstPoint)) {
joshualitt95964c62015-02-11 13:45:50 -0800708 this->closeBatch();
cdalton6819df32014-10-15 13:43:48 -0700709 CopySurface* cs = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, CopySurface, (dst, src));
bsalomon@google.com116ad842013-04-09 15:38:19 +0000710 cs->fSrcRect = srcRect;
711 cs->fDstPoint = dstPoint;
cdalton6819df32014-10-15 13:43:48 -0700712 this->recordTraceMarkersIfNecessary();
bsalomon@google.com116ad842013-04-09 15:38:19 +0000713 return true;
bsalomon@google.com116ad842013-04-09 15:38:19 +0000714 }
bsalomonf90a02b2014-11-26 12:28:00 -0800715 return false;
bsalomon@google.com116ad842013-04-09 15:38:19 +0000716}
717
egdaniele36914c2015-02-13 09:00:33 -0800718bool GrInOrderDrawBuffer::setupPipelineAndShouldDraw(const GrPrimitiveProcessor* primProc,
719 const PipelineInfo& pipelineInfo) {
720 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (primProc));
721 this->setupPipeline(pipelineInfo, ss->pipelineLocation());
722
723 if (ss->getPipeline()->mustSkip()) {
bsalomon932f8662014-11-24 06:47:48 -0800724 fCmdBuffer.pop_back();
bsalomonae59b772014-11-19 08:23:49 -0800725 return false;
726 }
joshualitt873ad0e2015-01-20 09:08:51 -0800727
728 ss->fPrimitiveProcessor->initBatchTracker(&ss->fBatchTracker,
egdaniele36914c2015-02-13 09:00:33 -0800729 ss->getPipeline()->getInitBatchTracker());
joshualitt873ad0e2015-01-20 09:08:51 -0800730
joshualitt4d8da812015-01-28 12:53:54 -0800731 if (fPrevState && fPrevState->fPrimitiveProcessor.get() &&
joshualitt873ad0e2015-01-20 09:08:51 -0800732 fPrevState->fPrimitiveProcessor->canMakeEqual(fPrevState->fBatchTracker,
733 *ss->fPrimitiveProcessor,
734 ss->fBatchTracker) &&
egdaniele36914c2015-02-13 09:00:33 -0800735 fPrevState->getPipeline()->isEqual(*ss->getPipeline())) {
bsalomon932f8662014-11-24 06:47:48 -0800736 fCmdBuffer.pop_back();
737 } else {
joshualitt873ad0e2015-01-20 09:08:51 -0800738 fPrevState = ss;
cdalton6819df32014-10-15 13:43:48 -0700739 this->recordTraceMarkersIfNecessary();
bsalomon838f62d2014-08-05 07:15:57 -0700740 }
bsalomonae59b772014-11-19 08:23:49 -0800741 return true;
reed@google.comac10a2d2010-12-22 21:39:39 +0000742}
743
egdaniele36914c2015-02-13 09:00:33 -0800744bool GrInOrderDrawBuffer::setupPipelineAndShouldDraw(GrBatch* batch,
745 const PipelineInfo& pipelineInfo) {
746 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, ());
747 this->setupPipeline(pipelineInfo, ss->pipelineLocation());
748
749 if (ss->getPipeline()->mustSkip()) {
joshualitt4d8da812015-01-28 12:53:54 -0800750 fCmdBuffer.pop_back();
751 return false;
752 }
753
egdaniele36914c2015-02-13 09:00:33 -0800754 batch->initBatchTracker(ss->getPipeline()->getInitBatchTracker());
joshualitt4d8da812015-01-28 12:53:54 -0800755
756 if (fPrevState && !fPrevState->fPrimitiveProcessor.get() &&
egdaniele36914c2015-02-13 09:00:33 -0800757 fPrevState->getPipeline()->isEqual(*ss->getPipeline())) {
joshualitt4d8da812015-01-28 12:53:54 -0800758 fCmdBuffer.pop_back();
759 } else {
760 this->closeBatch();
761 fPrevState = ss;
762 this->recordTraceMarkersIfNecessary();
763 }
764 return true;
765}
766
cdalton6819df32014-10-15 13:43:48 -0700767void GrInOrderDrawBuffer::recordTraceMarkersIfNecessary() {
768 SkASSERT(!fCmdBuffer.empty());
robertphillipse5e72f12015-02-17 09:14:33 -0800769 SkASSERT(!fCmdBuffer.back().isTraced());
mtkleinf439c772014-10-14 14:29:30 -0700770 const GrTraceMarkerSet& activeTraceMarkers = this->getActiveTraceMarkers();
771 if (activeTraceMarkers.count() > 0) {
robertphillipse5e72f12015-02-17 09:14:33 -0800772 fCmdBuffer.back().makeTraced();
mtkleinf439c772014-10-14 14:29:30 -0700773 fGpuCmdMarkers.push_back(activeTraceMarkers);
mtklein07894c42014-10-13 14:00:42 -0700774 }
mtklein07894c42014-10-13 14:00:42 -0700775}
joshualitt4d8da812015-01-28 12:53:54 -0800776
joshualitt4d8da812015-01-28 12:53:54 -0800777void GrInOrderDrawBuffer::willReserveVertexAndIndexSpace(int vertexCount,
778 size_t vertexStride,
779 int indexCount) {
780 this->closeBatch();
781
robertphillips54fac8b2015-02-16 09:35:50 -0800782 this->INHERITED::willReserveVertexAndIndexSpace(vertexCount, vertexStride, indexCount);
joshualitt4d8da812015-01-28 12:53:54 -0800783}