blob: 0f10623970394d276017bd1c3323234eaa7a7730 [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) {
joshualitt58773332015-02-23 16:41:42 -0800304 RectBatch::Geometry geometry;
305 geometry.fColor = color;
306 geometry.fViewMatrix = viewMatrix;
307 geometry.fRect = rect;
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000308
bsalomon49f085d2014-09-05 13:34:00 -0700309 if (localRect) {
joshualitt58773332015-02-23 16:41:42 -0800310 geometry.fHasLocalRect = true;
311 geometry.fLocalRect = *localRect;
312 } else {
313 geometry.fHasLocalRect = false;
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000314 }
315
joshualitt58773332015-02-23 16:41:42 -0800316 if (localMatrix) {
317 geometry.fHasLocalMatrix = true;
318 geometry.fLocalMatrix = *localMatrix;
319 } else {
320 geometry.fHasLocalMatrix = false;
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000321 }
322
joshualitt58773332015-02-23 16:41:42 -0800323 SkAutoTUnref<GrBatch> batch(RectBatch::Create(geometry));
324
325 SkRect bounds = rect;
326 viewMatrix.mapRect(&bounds);
327 this->drawBatch(pipelineBuilder, batch, &bounds);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000328}
329
egdaniele36914c2015-02-13 09:00:33 -0800330int GrInOrderDrawBuffer::concatInstancedDraw(const DrawInfo& info) {
cdalton6819df32014-10-15 13:43:48 -0700331 SkASSERT(!fCmdBuffer.empty());
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000332 SkASSERT(info.isInstanced());
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000333
bsalomon@google.com934c5702012-03-20 21:17:58 +0000334 const GeometrySrcState& geomSrc = this->getGeomSrc();
335
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000336 // we only attempt to concat the case when reserved verts are used with a client-specified index
337 // buffer. To make this work with client-specified VBs we'd need to know if the VB was updated
338 // between draws.
339 if (kReserved_GeometrySrcType != geomSrc.fVertexSrc ||
340 kBuffer_GeometrySrcType != geomSrc.fIndexSrc) {
341 return 0;
bsalomon@google.com934c5702012-03-20 21:17:58 +0000342 }
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000343 // Check if there is a draw info that is compatible that uses the same VB from the pool and
344 // the same IB
robertphillipse5e72f12015-02-17 09:14:33 -0800345 if (Cmd::kDraw_Cmd != fCmdBuffer.back().type()) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000346 return 0;
347 }
348
cdalton6819df32014-10-15 13:43:48 -0700349 Draw* draw = static_cast<Draw*>(&fCmdBuffer.back());
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000350
cdalton6819df32014-10-15 13:43:48 -0700351 if (!draw->fInfo.isInstanced() ||
joshualitt4d8da812015-01-28 12:53:54 -0800352 draw->fInfo.primitiveType() != info.primitiveType() ||
cdalton6819df32014-10-15 13:43:48 -0700353 draw->fInfo.verticesPerInstance() != info.verticesPerInstance() ||
354 draw->fInfo.indicesPerInstance() != info.indicesPerInstance() ||
bsalomon371bcbc2014-12-01 08:19:34 -0800355 draw->fInfo.vertexBuffer() != info.vertexBuffer() ||
joshualitt54e0c122014-11-19 09:38:51 -0800356 draw->fInfo.indexBuffer() != geomSrc.fIndexBuffer) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000357 return 0;
358 }
bsalomon371bcbc2014-12-01 08:19:34 -0800359 if (draw->fInfo.startVertex() + draw->fInfo.vertexCount() != info.startVertex()) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000360 return 0;
361 }
362
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000363 // how many instances can be concat'ed onto draw given the size of the index buffer
364 int instancesToConcat = this->indexCountInCurrentSource() / info.indicesPerInstance();
cdalton6819df32014-10-15 13:43:48 -0700365 instancesToConcat -= draw->fInfo.instanceCount();
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000366 instancesToConcat = SkTMin(instancesToConcat, info.instanceCount());
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000367
cdalton6819df32014-10-15 13:43:48 -0700368 draw->fInfo.adjustInstanceCount(instancesToConcat);
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000369
370 // update last fGpuCmdMarkers to include any additional trace markers that have been added
371 if (this->getActiveTraceMarkers().count() > 0) {
robertphillipse5e72f12015-02-17 09:14:33 -0800372 if (draw->isTraced()) {
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000373 fGpuCmdMarkers.back().addSet(this->getActiveTraceMarkers());
374 } else {
375 fGpuCmdMarkers.push_back(this->getActiveTraceMarkers());
robertphillipse5e72f12015-02-17 09:14:33 -0800376 draw->makeTraced();
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000377 }
378 }
379
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000380 return instancesToConcat;
bsalomon@google.com934c5702012-03-20 21:17:58 +0000381}
382
egdaniele36914c2015-02-13 09:00:33 -0800383void GrInOrderDrawBuffer::onDraw(const GrGeometryProcessor* gp,
joshualitt9853cce2014-11-17 14:22:48 -0800384 const DrawInfo& info,
egdaniele36914c2015-02-13 09:00:33 -0800385 const PipelineInfo& pipelineInfo) {
joshualitt7eb8c7b2014-11-18 14:24:27 -0800386 SkASSERT(info.vertexBuffer() && (!info.isIndexed() || info.indexBuffer()));
joshualitt4d8da812015-01-28 12:53:54 -0800387 this->closeBatch();
388
egdaniele36914c2015-02-13 09:00:33 -0800389 if (!this->setupPipelineAndShouldDraw(gp, pipelineInfo)) {
bsalomonae59b772014-11-19 08:23:49 -0800390 return;
391 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000392
bsalomonb3e3a952014-09-19 11:10:40 -0700393 Draw* draw;
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000394 if (info.isInstanced()) {
egdaniele36914c2015-02-13 09:00:33 -0800395 int instancesConcated = this->concatInstancedDraw(info);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000396 if (info.instanceCount() > instancesConcated) {
joshualitt54e0c122014-11-19 09:38:51 -0800397 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info));
cdalton6819df32014-10-15 13:43:48 -0700398 draw->fInfo.adjustInstanceCount(-instancesConcated);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000399 } else {
400 return;
401 }
402 } else {
joshualitt54e0c122014-11-19 09:38:51 -0800403 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info));
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000404 }
cdalton6819df32014-10-15 13:43:48 -0700405 this->recordTraceMarkersIfNecessary();
commit-bot@chromium.org9b62aa12014-03-25 11:59:40 +0000406}
sugoi@google.com5f74cf82012-12-17 21:16:45 +0000407
joshualitt4d8da812015-01-28 12:53:54 -0800408void GrInOrderDrawBuffer::onDrawBatch(GrBatch* batch,
egdaniele36914c2015-02-13 09:00:33 -0800409 const PipelineInfo& pipelineInfo) {
410 if (!this->setupPipelineAndShouldDraw(batch, pipelineInfo)) {
joshualitt4d8da812015-01-28 12:53:54 -0800411 return;
412 }
413
414 // Check if there is a Batch Draw we can batch with
robertphillipse5e72f12015-02-17 09:14:33 -0800415 if (Cmd::kDrawBatch_Cmd != fCmdBuffer.back().type()) {
joshualitt4d8da812015-01-28 12:53:54 -0800416 fDrawBatch = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawBatch, (batch));
417 return;
418 }
419
420 DrawBatch* draw = static_cast<DrawBatch*>(&fCmdBuffer.back());
421 if (draw->fBatch->combineIfPossible(batch)) {
422 return;
423 } else {
424 this->closeBatch();
425 fDrawBatch = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawBatch, (batch));
426 }
427 this->recordTraceMarkersIfNecessary();
428}
429
egdaniel8dd688b2015-01-22 10:16:09 -0800430void GrInOrderDrawBuffer::onStencilPath(const GrPipelineBuilder& pipelineBuilder,
joshualitt56995b52014-12-11 15:44:02 -0800431 const GrPathProcessor* pathProc,
joshualitt9853cce2014-11-17 14:22:48 -0800432 const GrPath* path,
bsalomon3e791242014-12-17 13:43:13 -0800433 const GrScissorState& scissorState,
joshualitt2c93efe2014-11-06 12:57:13 -0800434 const GrStencilSettings& stencilSettings) {
joshualitt70f00042015-02-06 15:53:59 -0800435 this->closeBatch();
436
bsalomon3e791242014-12-17 13:43:13 -0800437 StencilPath* sp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, StencilPath,
egdaniel8dd688b2015-01-22 10:16:09 -0800438 (path, pipelineBuilder.getRenderTarget()));
joshualitt58773332015-02-23 16:41:42 -0800439
bsalomon3e791242014-12-17 13:43:13 -0800440 sp->fScissor = scissorState;
egdaniel8dd688b2015-01-22 10:16:09 -0800441 sp->fUseHWAA = pipelineBuilder.isHWAntialias();
joshualitt8059eb92014-12-29 15:10:07 -0800442 sp->fViewMatrix = pathProc->viewMatrix();
bsalomon3e791242014-12-17 13:43:13 -0800443 sp->fStencil = stencilSettings;
cdalton6819df32014-10-15 13:43:48 -0700444 this->recordTraceMarkersIfNecessary();
bsalomon@google.com64aef2b2012-06-11 15:36:13 +0000445}
446
egdaniele36914c2015-02-13 09:00:33 -0800447void GrInOrderDrawBuffer::onDrawPath(const GrPathProcessor* pathProc,
joshualitt9853cce2014-11-17 14:22:48 -0800448 const GrPath* path,
joshualitt2c93efe2014-11-06 12:57:13 -0800449 const GrStencilSettings& stencilSettings,
egdaniele36914c2015-02-13 09:00:33 -0800450 const PipelineInfo& pipelineInfo) {
joshualitt4d8da812015-01-28 12:53:54 -0800451 this->closeBatch();
452
egdaniel8dd688b2015-01-22 10:16:09 -0800453 // TODO: Only compare the subset of GrPipelineBuilder relevant to path covering?
egdaniele36914c2015-02-13 09:00:33 -0800454 if (!this->setupPipelineAndShouldDraw(pathProc, pipelineInfo)) {
bsalomonae59b772014-11-19 08:23:49 -0800455 return;
456 }
cdalton6819df32014-10-15 13:43:48 -0700457 DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (path));
joshualitt2c93efe2014-11-06 12:57:13 -0800458 dp->fStencilSettings = stencilSettings;
cdalton6819df32014-10-15 13:43:48 -0700459 this->recordTraceMarkersIfNecessary();
commit-bot@chromium.orgc4dc0ad2013-10-09 14:11:33 +0000460}
461
egdaniele36914c2015-02-13 09:00:33 -0800462void GrInOrderDrawBuffer::onDrawPaths(const GrPathProcessor* pathProc,
joshualitt9853cce2014-11-17 14:22:48 -0800463 const GrPathRange* pathRange,
cdalton55b24af2014-11-25 11:00:56 -0800464 const void* indices,
465 PathIndexType indexType,
466 const float transformValues[],
467 PathTransformType transformType,
joshualitt2c93efe2014-11-06 12:57:13 -0800468 int count,
joshualitt2c93efe2014-11-06 12:57:13 -0800469 const GrStencilSettings& stencilSettings,
egdaniele36914c2015-02-13 09:00:33 -0800470 const PipelineInfo& pipelineInfo) {
bsalomon49f085d2014-09-05 13:34:00 -0700471 SkASSERT(pathRange);
472 SkASSERT(indices);
cdalton55b24af2014-11-25 11:00:56 -0800473 SkASSERT(transformValues);
joshualitt4d8da812015-01-28 12:53:54 -0800474 this->closeBatch();
475
egdaniele36914c2015-02-13 09:00:33 -0800476 if (!this->setupPipelineAndShouldDraw(pathProc, pipelineInfo)) {
bsalomonae59b772014-11-19 08:23:49 -0800477 return;
478 }
cdalton6819df32014-10-15 13:43:48 -0700479
cdalton55b24af2014-11-25 11:00:56 -0800480 int indexBytes = GrPathRange::PathIndexSizeInBytes(indexType);
481 if (int misalign = fPathIndexBuffer.count() % indexBytes) {
482 // Add padding to the index buffer so the indices are aligned properly.
483 fPathIndexBuffer.append(indexBytes - misalign);
484 }
485
486 char* savedIndices = fPathIndexBuffer.append(count * indexBytes,
487 reinterpret_cast<const char*>(indices));
488 float* savedTransforms = fPathTransformBuffer.append(
489 count * GrPathRendering::PathTransformSize(transformType),
490 transformValues);
cdalton6819df32014-10-15 13:43:48 -0700491
robertphillipse5e72f12015-02-17 09:14:33 -0800492 if (Cmd::kDrawPaths_Cmd == fCmdBuffer.back().type()) {
cdalton3fc6a2f2014-11-13 11:54:20 -0800493 // The previous command was also DrawPaths. Try to collapse this call into the one
bsalomon371bcbc2014-12-01 08:19:34 -0800494 // before. Note that stenciling all the paths at once, then covering, may not be
cdalton3fc6a2f2014-11-13 11:54:20 -0800495 // equivalent to two separate draw calls if there is overlap. Blending won't work,
496 // and the combined calls may also cancel each other's winding numbers in some
497 // places. For now the winding numbers are only an issue if the fill is even/odd,
498 // because DrawPaths is currently only used for glyphs, and glyphs in the same
499 // font tend to all wind in the same direction.
500 DrawPaths* previous = static_cast<DrawPaths*>(&fCmdBuffer.back());
501 if (pathRange == previous->pathRange() &&
cdalton55b24af2014-11-25 11:00:56 -0800502 indexType == previous->fIndexType &&
503 transformType == previous->fTransformType &&
cdalton3fc6a2f2014-11-13 11:54:20 -0800504 stencilSettings == previous->fStencilSettings &&
505 path_fill_type_is_winding(stencilSettings) &&
egdaniele36914c2015-02-13 09:00:33 -0800506 !pipelineInfo.willBlendWithDst(pathProc)) {
cdalton3fc6a2f2014-11-13 11:54:20 -0800507 // Fold this DrawPaths call into the one previous.
508 previous->fCount += count;
509 return;
510 }
511 }
512
513 DrawPaths* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPaths, (pathRange));
bsalomonef3fcd82014-12-12 08:51:38 -0800514 dp->fIndicesLocation = SkToU32(savedIndices - fPathIndexBuffer.begin());
cdalton55b24af2014-11-25 11:00:56 -0800515 dp->fIndexType = indexType;
bsalomonef3fcd82014-12-12 08:51:38 -0800516 dp->fTransformsLocation = SkToU32(savedTransforms - fPathTransformBuffer.begin());
cdalton55b24af2014-11-25 11:00:56 -0800517 dp->fTransformType = transformType;
518 dp->fCount = count;
joshualitt2c93efe2014-11-06 12:57:13 -0800519 dp->fStencilSettings = stencilSettings;
cdalton6819df32014-10-15 13:43:48 -0700520
521 this->recordTraceMarkersIfNecessary();
commit-bot@chromium.org9b62aa12014-03-25 11:59:40 +0000522}
523
bsalomon63b21962014-11-05 07:05:34 -0800524void GrInOrderDrawBuffer::onClear(const SkIRect* rect, GrColor color,
525 bool canIgnoreRect, GrRenderTarget* renderTarget) {
joshualitt9853cce2014-11-17 14:22:48 -0800526 SkASSERT(renderTarget);
joshualitt70f00042015-02-06 15:53:59 -0800527 this->closeBatch();
528
commit-bot@chromium.orgfd03d4a2013-07-17 21:39:42 +0000529 SkIRect r;
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000530 if (NULL == rect) {
531 // We could do something smart and remove previous draws and clears to
532 // the current render target. If we get that smart we have to make sure
533 // those draws aren't read before this clear (render-to-texture).
bsalomon@google.com1b3ce472012-08-17 13:43:08 +0000534 r.setLTRB(0, 0, renderTarget->width(), renderTarget->height());
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000535 rect = &r;
536 }
cdalton6819df32014-10-15 13:43:48 -0700537 Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget));
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000538 GrColorIsPMAssert(color);
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000539 clr->fColor = color;
540 clr->fRect = *rect;
robertphillips@google.com56ce48a2013-10-31 21:44:25 +0000541 clr->fCanIgnoreRect = canIgnoreRect;
cdalton6819df32014-10-15 13:43:48 -0700542 this->recordTraceMarkersIfNecessary();
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000543}
544
joshualitt6db519c2014-10-29 08:48:18 -0700545void GrInOrderDrawBuffer::clearStencilClip(const SkIRect& rect,
546 bool insideClip,
547 GrRenderTarget* renderTarget) {
joshualitt9853cce2014-11-17 14:22:48 -0800548 SkASSERT(renderTarget);
joshualitt70f00042015-02-06 15:53:59 -0800549 this->closeBatch();
550
joshualitt6db519c2014-10-29 08:48:18 -0700551 ClearStencilClip* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, ClearStencilClip, (renderTarget));
552 clr->fRect = rect;
553 clr->fInsideClip = insideClip;
554 this->recordTraceMarkersIfNecessary();
555}
556
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000557void GrInOrderDrawBuffer::discard(GrRenderTarget* renderTarget) {
bsalomon89c62982014-11-03 12:08:42 -0800558 SkASSERT(renderTarget);
joshualitt70f00042015-02-06 15:53:59 -0800559 this->closeBatch();
560
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000561 if (!this->caps()->discardRenderTargetSupport()) {
562 return;
563 }
cdalton6819df32014-10-15 13:43:48 -0700564 Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget));
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000565 clr->fColor = GrColor_ILLEGAL;
cdalton6819df32014-10-15 13:43:48 -0700566 this->recordTraceMarkersIfNecessary();
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000567}
568
bsalomon371bcbc2014-12-01 08:19:34 -0800569void GrInOrderDrawBuffer::onReset() {
cdalton6819df32014-10-15 13:43:48 -0700570 fCmdBuffer.reset();
bsalomon932f8662014-11-24 06:47:48 -0800571 fPrevState = NULL;
cdalton3fc6a2f2014-11-13 11:54:20 -0800572 reset_data_buffer(&fPathIndexBuffer, kPathIdxBufferMinReserve);
573 reset_data_buffer(&fPathTransformBuffer, kPathXformBufferMinReserve);
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000574 fGpuCmdMarkers.reset();
joshualitt4d8da812015-01-28 12:53:54 -0800575 fDrawBatch = NULL;
reed@google.comac10a2d2010-12-22 21:39:39 +0000576}
577
bsalomon371bcbc2014-12-01 08:19:34 -0800578void GrInOrderDrawBuffer::onFlush() {
cdalton6819df32014-10-15 13:43:48 -0700579 if (fCmdBuffer.empty()) {
robertphillips@google.com1267fbd2013-07-03 18:37:27 +0000580 return;
reed@google.comac10a2d2010-12-22 21:39:39 +0000581 }
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000582
joshualittc2893c52015-01-28 06:54:30 -0800583 // Updated every time we find a set state cmd to reflect the current state in the playback
584 // stream.
585 SetState* currentState = NULL;
586
joshualitt4d8da812015-01-28 12:53:54 -0800587 // TODO this is temporary while batch is being rolled out
588 this->closeBatch();
589 this->getVertexAllocPool()->unmap();
590 this->getIndexAllocPool()->unmap();
591 fBatchTarget.preFlush();
592
593 currentState = NULL;
594 CmdBuffer::Iter iter(fCmdBuffer);
595
596 int currCmdMarker = 0;
597
joshualitt7bc18b72015-02-03 16:41:41 -0800598 int i = 0;
cdalton6819df32014-10-15 13:43:48 -0700599 while (iter.next()) {
joshualitt7bc18b72015-02-03 16:41:41 -0800600 i++;
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000601 GrGpuTraceMarker newMarker("", -1);
egdanield78a1682014-07-09 10:41:26 -0700602 SkString traceString;
robertphillipse5e72f12015-02-17 09:14:33 -0800603 if (iter->isTraced()) {
egdanield78a1682014-07-09 10:41:26 -0700604 traceString = fGpuCmdMarkers[currCmdMarker].toString();
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000605 newMarker.fMarker = traceString.c_str();
bsalomon371bcbc2014-12-01 08:19:34 -0800606 this->getGpu()->addGpuTraceMarker(&newMarker);
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000607 ++currCmdMarker;
608 }
cdalton6819df32014-10-15 13:43:48 -0700609
joshualitt4d8da812015-01-28 12:53:54 -0800610 // TODO temporary hack
robertphillipse5e72f12015-02-17 09:14:33 -0800611 if (Cmd::kDrawBatch_Cmd == iter->type()) {
joshualitt7bc18b72015-02-03 16:41:41 -0800612 DrawBatch* db = reinterpret_cast<DrawBatch*>(iter.get());
613 fBatchTarget.flushNext(db->fBatch->numberOfDraws());
joshualitt4d8da812015-01-28 12:53:54 -0800614 continue;
615 }
616
robertphillipse5e72f12015-02-17 09:14:33 -0800617 if (Cmd::kSetState_Cmd == iter->type()) {
joshualitt9853cce2014-11-17 14:22:48 -0800618 SetState* ss = reinterpret_cast<SetState*>(iter.get());
joshualitt873ad0e2015-01-20 09:08:51 -0800619
joshualitt4d8da812015-01-28 12:53:54 -0800620 // TODO sometimes we have a prim proc, othertimes we have a GrBatch. Eventually we will
621 // only have GrBatch and we can delete this
622 if (ss->fPrimitiveProcessor) {
623 this->getGpu()->buildProgramDesc(&ss->fDesc, *ss->fPrimitiveProcessor,
egdaniele36914c2015-02-13 09:00:33 -0800624 *ss->getPipeline(),
joshualitt4d8da812015-01-28 12:53:54 -0800625 ss->fBatchTracker);
626 }
joshualitt873ad0e2015-01-20 09:08:51 -0800627 currentState = ss;
joshualittd53a8272014-11-10 16:03:14 -0800628 } else {
joshualitt873ad0e2015-01-20 09:08:51 -0800629 iter->execute(this, currentState);
joshualittd53a8272014-11-10 16:03:14 -0800630 }
cdalton6819df32014-10-15 13:43:48 -0700631
robertphillipse5e72f12015-02-17 09:14:33 -0800632 if (iter->isTraced()) {
bsalomon371bcbc2014-12-01 08:19:34 -0800633 this->getGpu()->removeGpuTraceMarker(&newMarker);
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000634 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000635 }
mtkleinf439c772014-10-14 14:29:30 -0700636
joshualitt4d8da812015-01-28 12:53:54 -0800637 // TODO see copious notes about hack
638 fBatchTarget.postFlush();
639
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000640 SkASSERT(fGpuCmdMarkers.count() == currCmdMarker);
commit-bot@chromium.orga8916ff2013-08-16 15:53:46 +0000641 ++fDrawID;
reed@google.comac10a2d2010-12-22 21:39:39 +0000642}
643
joshualitt873ad0e2015-01-20 09:08:51 -0800644void GrInOrderDrawBuffer::Draw::execute(GrInOrderDrawBuffer* buf, const SetState* state) {
645 SkASSERT(state);
egdaniele36914c2015-02-13 09:00:33 -0800646 DrawArgs args(state->fPrimitiveProcessor.get(), state->getPipeline(), &state->fDesc,
joshualitt17e73142015-01-21 11:52:36 -0800647 &state->fBatchTracker);
joshualitt873ad0e2015-01-20 09:08:51 -0800648 buf->getGpu()->draw(args, fInfo);
cdalton6819df32014-10-15 13:43:48 -0700649}
650
joshualitt873ad0e2015-01-20 09:08:51 -0800651void GrInOrderDrawBuffer::StencilPath::execute(GrInOrderDrawBuffer* buf, const SetState*) {
bsalomon3e791242014-12-17 13:43:13 -0800652 GrGpu::StencilPathState state;
653 state.fRenderTarget = fRenderTarget.get();
654 state.fScissor = &fScissor;
655 state.fStencil = &fStencil;
656 state.fUseHWAA = fUseHWAA;
657 state.fViewMatrix = &fViewMatrix;
658
659 buf->getGpu()->stencilPath(this->path(), state);
cdalton6819df32014-10-15 13:43:48 -0700660}
661
joshualitt873ad0e2015-01-20 09:08:51 -0800662void GrInOrderDrawBuffer::DrawPath::execute(GrInOrderDrawBuffer* buf, const SetState* state) {
663 SkASSERT(state);
egdaniele36914c2015-02-13 09:00:33 -0800664 DrawArgs args(state->fPrimitiveProcessor.get(), state->getPipeline(), &state->fDesc,
joshualitt17e73142015-01-21 11:52:36 -0800665 &state->fBatchTracker);
joshualitt873ad0e2015-01-20 09:08:51 -0800666 buf->getGpu()->drawPath(args, this->path(), fStencilSettings);
cdalton6819df32014-10-15 13:43:48 -0700667}
668
joshualitt873ad0e2015-01-20 09:08:51 -0800669void GrInOrderDrawBuffer::DrawPaths::execute(GrInOrderDrawBuffer* buf, const SetState* state) {
670 SkASSERT(state);
egdaniele36914c2015-02-13 09:00:33 -0800671 DrawArgs args(state->fPrimitiveProcessor.get(), state->getPipeline(), &state->fDesc,
joshualitt17e73142015-01-21 11:52:36 -0800672 &state->fBatchTracker);
joshualitt873ad0e2015-01-20 09:08:51 -0800673 buf->getGpu()->drawPaths(args, this->pathRange(),
cdalton55b24af2014-11-25 11:00:56 -0800674 &buf->fPathIndexBuffer[fIndicesLocation], fIndexType,
675 &buf->fPathTransformBuffer[fTransformsLocation], fTransformType,
676 fCount, fStencilSettings);
cdalton6819df32014-10-15 13:43:48 -0700677}
678
joshualitt4d8da812015-01-28 12:53:54 -0800679void GrInOrderDrawBuffer::DrawBatch::execute(GrInOrderDrawBuffer* buf, const SetState* state) {
680 SkASSERT(state);
egdaniele36914c2015-02-13 09:00:33 -0800681 fBatch->generateGeometry(buf->getBatchTarget(), state->getPipeline());
joshualitt4d8da812015-01-28 12:53:54 -0800682}
683
joshualitt873ad0e2015-01-20 09:08:51 -0800684void GrInOrderDrawBuffer::SetState::execute(GrInOrderDrawBuffer*, const SetState*) {}
cdalton6819df32014-10-15 13:43:48 -0700685
joshualitt873ad0e2015-01-20 09:08:51 -0800686void GrInOrderDrawBuffer::Clear::execute(GrInOrderDrawBuffer* buf, const SetState*) {
cdalton6819df32014-10-15 13:43:48 -0700687 if (GrColor_ILLEGAL == fColor) {
bsalomon371bcbc2014-12-01 08:19:34 -0800688 buf->getGpu()->discard(this->renderTarget());
cdalton6819df32014-10-15 13:43:48 -0700689 } else {
bsalomon371bcbc2014-12-01 08:19:34 -0800690 buf->getGpu()->clear(&fRect, fColor, fCanIgnoreRect, this->renderTarget());
cdalton6819df32014-10-15 13:43:48 -0700691 }
692}
693
joshualitt873ad0e2015-01-20 09:08:51 -0800694void GrInOrderDrawBuffer::ClearStencilClip::execute(GrInOrderDrawBuffer* buf, const SetState*) {
bsalomon371bcbc2014-12-01 08:19:34 -0800695 buf->getGpu()->clearStencilClip(fRect, fInsideClip, this->renderTarget());
joshualitt6db519c2014-10-29 08:48:18 -0700696}
697
joshualitt873ad0e2015-01-20 09:08:51 -0800698void GrInOrderDrawBuffer::CopySurface::execute(GrInOrderDrawBuffer* buf, const SetState*) {
bsalomon371bcbc2014-12-01 08:19:34 -0800699 buf->getGpu()->copySurface(this->dst(), this->src(), fSrcRect, fDstPoint);
cdalton6819df32014-10-15 13:43:48 -0700700}
701
bsalomonf90a02b2014-11-26 12:28:00 -0800702bool GrInOrderDrawBuffer::onCopySurface(GrSurface* dst,
703 GrSurface* src,
704 const SkIRect& srcRect,
705 const SkIPoint& dstPoint) {
bsalomon371bcbc2014-12-01 08:19:34 -0800706 if (getGpu()->canCopySurface(dst, src, srcRect, dstPoint)) {
joshualitt95964c62015-02-11 13:45:50 -0800707 this->closeBatch();
cdalton6819df32014-10-15 13:43:48 -0700708 CopySurface* cs = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, CopySurface, (dst, src));
bsalomon@google.com116ad842013-04-09 15:38:19 +0000709 cs->fSrcRect = srcRect;
710 cs->fDstPoint = dstPoint;
cdalton6819df32014-10-15 13:43:48 -0700711 this->recordTraceMarkersIfNecessary();
bsalomon@google.com116ad842013-04-09 15:38:19 +0000712 return true;
bsalomon@google.com116ad842013-04-09 15:38:19 +0000713 }
bsalomonf90a02b2014-11-26 12:28:00 -0800714 return false;
bsalomon@google.com116ad842013-04-09 15:38:19 +0000715}
716
egdaniele36914c2015-02-13 09:00:33 -0800717bool GrInOrderDrawBuffer::setupPipelineAndShouldDraw(const GrPrimitiveProcessor* primProc,
718 const PipelineInfo& pipelineInfo) {
719 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (primProc));
720 this->setupPipeline(pipelineInfo, ss->pipelineLocation());
721
722 if (ss->getPipeline()->mustSkip()) {
bsalomon932f8662014-11-24 06:47:48 -0800723 fCmdBuffer.pop_back();
bsalomonae59b772014-11-19 08:23:49 -0800724 return false;
725 }
joshualitt873ad0e2015-01-20 09:08:51 -0800726
727 ss->fPrimitiveProcessor->initBatchTracker(&ss->fBatchTracker,
egdaniele36914c2015-02-13 09:00:33 -0800728 ss->getPipeline()->getInitBatchTracker());
joshualitt873ad0e2015-01-20 09:08:51 -0800729
joshualitt4d8da812015-01-28 12:53:54 -0800730 if (fPrevState && fPrevState->fPrimitiveProcessor.get() &&
joshualitt873ad0e2015-01-20 09:08:51 -0800731 fPrevState->fPrimitiveProcessor->canMakeEqual(fPrevState->fBatchTracker,
732 *ss->fPrimitiveProcessor,
733 ss->fBatchTracker) &&
egdaniele36914c2015-02-13 09:00:33 -0800734 fPrevState->getPipeline()->isEqual(*ss->getPipeline())) {
bsalomon932f8662014-11-24 06:47:48 -0800735 fCmdBuffer.pop_back();
736 } else {
joshualitt873ad0e2015-01-20 09:08:51 -0800737 fPrevState = ss;
cdalton6819df32014-10-15 13:43:48 -0700738 this->recordTraceMarkersIfNecessary();
bsalomon838f62d2014-08-05 07:15:57 -0700739 }
bsalomonae59b772014-11-19 08:23:49 -0800740 return true;
reed@google.comac10a2d2010-12-22 21:39:39 +0000741}
742
egdaniele36914c2015-02-13 09:00:33 -0800743bool GrInOrderDrawBuffer::setupPipelineAndShouldDraw(GrBatch* batch,
744 const PipelineInfo& pipelineInfo) {
745 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, ());
746 this->setupPipeline(pipelineInfo, ss->pipelineLocation());
747
748 if (ss->getPipeline()->mustSkip()) {
joshualitt4d8da812015-01-28 12:53:54 -0800749 fCmdBuffer.pop_back();
750 return false;
751 }
752
egdaniele36914c2015-02-13 09:00:33 -0800753 batch->initBatchTracker(ss->getPipeline()->getInitBatchTracker());
joshualitt4d8da812015-01-28 12:53:54 -0800754
755 if (fPrevState && !fPrevState->fPrimitiveProcessor.get() &&
egdaniele36914c2015-02-13 09:00:33 -0800756 fPrevState->getPipeline()->isEqual(*ss->getPipeline())) {
joshualitt4d8da812015-01-28 12:53:54 -0800757 fCmdBuffer.pop_back();
758 } else {
759 this->closeBatch();
760 fPrevState = ss;
761 this->recordTraceMarkersIfNecessary();
762 }
763 return true;
764}
765
cdalton6819df32014-10-15 13:43:48 -0700766void GrInOrderDrawBuffer::recordTraceMarkersIfNecessary() {
767 SkASSERT(!fCmdBuffer.empty());
robertphillipse5e72f12015-02-17 09:14:33 -0800768 SkASSERT(!fCmdBuffer.back().isTraced());
mtkleinf439c772014-10-14 14:29:30 -0700769 const GrTraceMarkerSet& activeTraceMarkers = this->getActiveTraceMarkers();
770 if (activeTraceMarkers.count() > 0) {
robertphillipse5e72f12015-02-17 09:14:33 -0800771 fCmdBuffer.back().makeTraced();
mtkleinf439c772014-10-14 14:29:30 -0700772 fGpuCmdMarkers.push_back(activeTraceMarkers);
mtklein07894c42014-10-13 14:00:42 -0700773 }
mtklein07894c42014-10-13 14:00:42 -0700774}
joshualitt4d8da812015-01-28 12:53:54 -0800775
joshualitt4d8da812015-01-28 12:53:54 -0800776void GrInOrderDrawBuffer::willReserveVertexAndIndexSpace(int vertexCount,
777 size_t vertexStride,
778 int indexCount) {
779 this->closeBatch();
780
robertphillips54fac8b2015-02-16 09:35:50 -0800781 this->INHERITED::willReserveVertexAndIndexSpace(vertexCount, vertexStride, indexCount);
joshualitt4d8da812015-01-28 12:53:54 -0800782}