blob: 0807bf3d47aba50098fb84b16a79d8dd3ea63d35 [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
bsalomon@google.com934c5702012-03-20 21:17:58 +000038////////////////////////////////////////////////////////////////////////////////
39
bsalomon62c447d2014-08-08 08:08:50 -070040/** We always use per-vertex colors so that rects can be batched across color changes. Sometimes we
41 have explicit local coords and sometimes not. We *could* always provide explicit local coords
42 and just duplicate the positions when the caller hasn't provided a local coord rect, but we
43 haven't seen a use case which frequently switches between local rect and no local rect draws.
44
45 The color param is used to determine whether the opaque hint can be set on the draw state.
46 The caller must populate the vertex colors itself.
47
48 The vertex attrib order is always pos, color, [local coords].
49 */
joshualitt8fc6c2d2014-12-22 15:27:05 -080050static const GrGeometryProcessor* create_rect_gp(bool hasExplicitLocalCoords,
51 GrColor color,
52 const SkMatrix* localMatrix) {
joshualitt5478d422014-11-14 16:00:38 -080053 uint32_t flags = GrDefaultGeoProcFactory::kPosition_GPType |
54 GrDefaultGeoProcFactory::kColor_GPType;
joshualitt8fc6c2d2014-12-22 15:27:05 -080055 flags |= hasExplicitLocalCoords ? GrDefaultGeoProcFactory::kLocalCoord_GPType : 0;
56 if (localMatrix) {
joshualitt8059eb92014-12-29 15:10:07 -080057 return GrDefaultGeoProcFactory::Create(flags, color, SkMatrix::I(), *localMatrix,
58 GrColorIsOpaque(color));
joshualitt8fc6c2d2014-12-22 15:27:05 -080059 } else {
joshualitt8059eb92014-12-29 15:10:07 -080060 return GrDefaultGeoProcFactory::Create(flags, color, SkMatrix::I(), SkMatrix::I(),
61 GrColorIsOpaque(color));
joshualitt8fc6c2d2014-12-22 15:27:05 -080062 }
bsalomon62c447d2014-08-08 08:08:50 -070063}
robertphillips@google.com42903302013-04-20 12:26:07 +000064
cdalton3fc6a2f2014-11-13 11:54:20 -080065static bool path_fill_type_is_winding(const GrStencilSettings& pathStencilSettings) {
66 static const GrStencilSettings::Face pathFace = GrStencilSettings::kFront_Face;
67 bool isWinding = kInvert_StencilOp != pathStencilSettings.passOp(pathFace);
68 if (isWinding) {
69 // Double check that it is in fact winding.
70 SkASSERT(kIncClamp_StencilOp == pathStencilSettings.passOp(pathFace));
71 SkASSERT(kIncClamp_StencilOp == pathStencilSettings.failOp(pathFace));
72 SkASSERT(0x1 != pathStencilSettings.writeMask(pathFace));
73 SkASSERT(!pathStencilSettings.isTwoSided());
74 }
75 return isWinding;
76}
77
joshualitt58773332015-02-23 16:41:42 -080078class RectBatch : public GrBatch {
79public:
80 struct Geometry {
81 GrColor fColor;
82 SkMatrix fViewMatrix;
83 SkRect fRect;
84 bool fHasLocalRect;
85 bool fHasLocalMatrix;
86 SkRect fLocalRect;
87 SkMatrix fLocalMatrix;
88 };
89
90 static GrBatch* Create(const Geometry& geometry) {
91 return SkNEW_ARGS(RectBatch, (geometry));
92 }
93
94 const char* name() const SK_OVERRIDE { return "RectBatch"; }
95
96 void getInvariantOutputColor(GrInitInvariantOutput* out) const SK_OVERRIDE {
97 // When this is called on a batch, there is only one geometry bundle
98 out->setKnownFourComponents(fGeoData[0].fColor);
99 }
100
101 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const SK_OVERRIDE {
102 out->setKnownSingleComponent(0xff);
103 }
104
105 void initBatchTracker(const GrPipelineInfo& init) SK_OVERRIDE {
106 // Handle any color overrides
107 if (init.fColorIgnored) {
108 fGeoData[0].fColor = GrColor_ILLEGAL;
109 } else if (GrColor_ILLEGAL != init.fOverrideColor) {
110 fGeoData[0].fColor = init.fOverrideColor;
111 }
112
113 // setup batch properties
114 fBatch.fColorIgnored = init.fColorIgnored;
115 fBatch.fColor = fGeoData[0].fColor;
116 fBatch.fUsesLocalCoords = init.fUsesLocalCoords;
117 fBatch.fCoverageIgnored = init.fCoverageIgnored;
118 }
119
120 void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) SK_OVERRIDE {
121 // Go to device coords to allow batching across matrix changes
122 SkMatrix invert = SkMatrix::I();
123
124 // if we have a local rect, then we apply the localMatrix directly to the localRect to
125 // generate vertex local coords
126 bool hasExplicitLocalCoords = this->hasLocalRect();
127 if (!hasExplicitLocalCoords) {
128 if (!this->viewMatrix().isIdentity() && !this->viewMatrix().invert(&invert)) {
129 SkDebugf("Could not invert\n");
130 return;
131 }
132
133 if (this->hasLocalMatrix()) {
134 invert.preConcat(this->localMatrix());
135 }
136 }
137
138 SkAutoTUnref<const GrGeometryProcessor> gp(create_rect_gp(hasExplicitLocalCoords,
139 this->color(),
140 &invert));
141
142 batchTarget->initDraw(gp, pipeline);
143
144 // TODO this is hacky, but the only way we have to initialize the GP is to use the
145 // GrPipelineInfo struct so we can generate the correct shader. Once we have GrBatch
146 // everywhere we can remove this nastiness
147 GrPipelineInfo init;
148 init.fColorIgnored = fBatch.fColorIgnored;
149 init.fOverrideColor = GrColor_ILLEGAL;
150 init.fCoverageIgnored = fBatch.fCoverageIgnored;
151 init.fUsesLocalCoords = this->usesLocalCoords();
152 gp->initBatchTracker(batchTarget->currentBatchTracker(), init);
153
154 size_t vertexStride = gp->getVertexStride();
155
156 SkASSERT(hasExplicitLocalCoords ?
157 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordAttr) :
158 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAttr));
159
160 int instanceCount = fGeoData.count();
161 int vertexCount = kVertsPerRect * instanceCount;
162
163 const GrVertexBuffer* vertexBuffer;
164 int firstVertex;
165
166 void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
167 vertexCount,
168 &vertexBuffer,
169 &firstVertex);
170
171 for (int i = 0; i < instanceCount; i++) {
172 const Geometry& args = fGeoData[i];
173
174 intptr_t offset = GrTCast<intptr_t>(vertices) + kVertsPerRect * i * vertexStride;
175 SkPoint* positions = GrTCast<SkPoint*>(offset);
176
177 positions->setRectFan(args.fRect.fLeft, args.fRect.fTop,
178 args.fRect.fRight, args.fRect.fBottom, vertexStride);
179 args.fViewMatrix.mapPointsWithStride(positions, vertexStride, kVertsPerRect);
180
181 if (args.fHasLocalRect) {
182 static const int kLocalOffset = sizeof(SkPoint) + sizeof(GrColor);
183 SkPoint* coords = GrTCast<SkPoint*>(offset + kLocalOffset);
184 coords->setRectFan(args.fLocalRect.fLeft, args.fLocalRect.fTop,
185 args.fLocalRect.fRight, args.fLocalRect.fBottom,
186 vertexStride);
187 if (args.fHasLocalMatrix) {
188 args.fLocalMatrix.mapPointsWithStride(coords, vertexStride, kVertsPerRect);
189 }
190 }
191
192 static const int kColorOffset = sizeof(SkPoint);
193 GrColor* vertColor = GrTCast<GrColor*>(offset + kColorOffset);
194 for (int j = 0; j < 4; ++j) {
195 *vertColor = args.fColor;
196 vertColor = (GrColor*) ((intptr_t) vertColor + vertexStride);
197 }
198 }
199
200 const GrIndexBuffer* quadIndexBuffer = batchTarget->quadIndexBuffer();
201
202 GrDrawTarget::DrawInfo drawInfo;
203 drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType);
204 drawInfo.setStartVertex(0);
205 drawInfo.setStartIndex(0);
206 drawInfo.setVerticesPerInstance(kVertsPerRect);
207 drawInfo.setIndicesPerInstance(kIndicesPerRect);
208 drawInfo.adjustStartVertex(firstVertex);
209 drawInfo.setVertexBuffer(vertexBuffer);
210 drawInfo.setIndexBuffer(quadIndexBuffer);
211
212 int maxInstancesPerDraw = quadIndexBuffer->maxQuads();
213 while (instanceCount) {
214 drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw));
215 drawInfo.setVertexCount(drawInfo.instanceCount() * drawInfo.verticesPerInstance());
216 drawInfo.setIndexCount(drawInfo.instanceCount() * drawInfo.indicesPerInstance());
217
218 batchTarget->draw(drawInfo);
219
220 drawInfo.setStartVertex(drawInfo.startVertex() + drawInfo.vertexCount());
221 instanceCount -= drawInfo.instanceCount();
222 }
223 }
224
225 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
226
227private:
228 RectBatch(const Geometry& geometry) {
229 this->initClassID<RectBatch>();
230 fGeoData.push_back(geometry);
231 }
232
233 GrColor color() const { return fBatch.fColor; }
234 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; }
235 bool colorIgnored() const { return fBatch.fColorIgnored; }
236 const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; }
237 const SkMatrix& localMatrix() const { return fGeoData[0].fLocalMatrix; }
238 bool hasLocalRect() const { return fGeoData[0].fHasLocalRect; }
239 bool hasLocalMatrix() const { return fGeoData[0].fHasLocalMatrix; }
240
241 bool onCombineIfPossible(GrBatch* t) SK_OVERRIDE {
242 RectBatch* that = t->cast<RectBatch>();
243
244 if (this->hasLocalRect() != that->hasLocalRect()) {
245 return false;
246 }
247
248 SkASSERT(this->usesLocalCoords() == that->usesLocalCoords());
249 if (!this->hasLocalRect() && this->usesLocalCoords()) {
250 if (!this->viewMatrix().cheapEqualTo(that->viewMatrix())) {
251 return false;
252 }
253
254 if (this->hasLocalMatrix() != that->hasLocalMatrix()) {
255 return false;
256 }
257
258 if (this->hasLocalMatrix() && !this->localMatrix().cheapEqualTo(that->localMatrix())) {
259 return false;
260 }
261 }
262
263 if (this->color() != that->color()) {
264 fBatch.fColor = GrColor_ILLEGAL;
265 }
266 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin());
267 return true;
268 }
269
270 struct BatchTracker {
271 GrColor fColor;
272 bool fUsesLocalCoords;
273 bool fColorIgnored;
274 bool fCoverageIgnored;
275 };
276
277 const static int kVertsPerRect = 4;
278 const static int kIndicesPerRect = 6;
279
280 BatchTracker fBatch;
281 SkSTArray<1, Geometry, true> fGeoData;
282};
283
egdaniel8dd688b2015-01-22 10:16:09 -0800284void GrInOrderDrawBuffer::onDrawRect(GrPipelineBuilder* pipelineBuilder,
joshualitt2e3b3e32014-12-09 13:31:14 -0800285 GrColor color,
joshualitt8059eb92014-12-29 15:10:07 -0800286 const SkMatrix& viewMatrix,
joshualitt9853cce2014-11-17 14:22:48 -0800287 const SkRect& rect,
commit-bot@chromium.orgfd03d4a2013-07-17 21:39:42 +0000288 const SkRect* localRect,
bsalomon@google.com0406b9e2013-04-02 21:00:15 +0000289 const SkMatrix* localMatrix) {
joshualitt58773332015-02-23 16:41:42 -0800290 RectBatch::Geometry geometry;
291 geometry.fColor = color;
292 geometry.fViewMatrix = viewMatrix;
293 geometry.fRect = rect;
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000294
bsalomon49f085d2014-09-05 13:34:00 -0700295 if (localRect) {
joshualitt58773332015-02-23 16:41:42 -0800296 geometry.fHasLocalRect = true;
297 geometry.fLocalRect = *localRect;
298 } else {
299 geometry.fHasLocalRect = false;
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000300 }
301
joshualitt58773332015-02-23 16:41:42 -0800302 if (localMatrix) {
303 geometry.fHasLocalMatrix = true;
304 geometry.fLocalMatrix = *localMatrix;
305 } else {
306 geometry.fHasLocalMatrix = false;
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000307 }
308
joshualitt58773332015-02-23 16:41:42 -0800309 SkAutoTUnref<GrBatch> batch(RectBatch::Create(geometry));
310
311 SkRect bounds = rect;
312 viewMatrix.mapRect(&bounds);
313 this->drawBatch(pipelineBuilder, batch, &bounds);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000314}
315
egdaniele36914c2015-02-13 09:00:33 -0800316int GrInOrderDrawBuffer::concatInstancedDraw(const DrawInfo& info) {
cdalton6819df32014-10-15 13:43:48 -0700317 SkASSERT(!fCmdBuffer.empty());
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000318 SkASSERT(info.isInstanced());
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000319
bsalomon@google.com934c5702012-03-20 21:17:58 +0000320 const GeometrySrcState& geomSrc = this->getGeomSrc();
321
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000322 // we only attempt to concat the case when reserved verts are used with a client-specified index
323 // buffer. To make this work with client-specified VBs we'd need to know if the VB was updated
324 // between draws.
325 if (kReserved_GeometrySrcType != geomSrc.fVertexSrc ||
326 kBuffer_GeometrySrcType != geomSrc.fIndexSrc) {
327 return 0;
bsalomon@google.com934c5702012-03-20 21:17:58 +0000328 }
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000329 // Check if there is a draw info that is compatible that uses the same VB from the pool and
330 // the same IB
robertphillipse5e72f12015-02-17 09:14:33 -0800331 if (Cmd::kDraw_Cmd != fCmdBuffer.back().type()) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000332 return 0;
333 }
334
cdalton6819df32014-10-15 13:43:48 -0700335 Draw* draw = static_cast<Draw*>(&fCmdBuffer.back());
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000336
cdalton6819df32014-10-15 13:43:48 -0700337 if (!draw->fInfo.isInstanced() ||
joshualitt4d8da812015-01-28 12:53:54 -0800338 draw->fInfo.primitiveType() != info.primitiveType() ||
cdalton6819df32014-10-15 13:43:48 -0700339 draw->fInfo.verticesPerInstance() != info.verticesPerInstance() ||
340 draw->fInfo.indicesPerInstance() != info.indicesPerInstance() ||
bsalomon371bcbc2014-12-01 08:19:34 -0800341 draw->fInfo.vertexBuffer() != info.vertexBuffer() ||
joshualitt54e0c122014-11-19 09:38:51 -0800342 draw->fInfo.indexBuffer() != geomSrc.fIndexBuffer) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000343 return 0;
344 }
bsalomon371bcbc2014-12-01 08:19:34 -0800345 if (draw->fInfo.startVertex() + draw->fInfo.vertexCount() != info.startVertex()) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000346 return 0;
347 }
348
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000349 // how many instances can be concat'ed onto draw given the size of the index buffer
350 int instancesToConcat = this->indexCountInCurrentSource() / info.indicesPerInstance();
cdalton6819df32014-10-15 13:43:48 -0700351 instancesToConcat -= draw->fInfo.instanceCount();
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000352 instancesToConcat = SkTMin(instancesToConcat, info.instanceCount());
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000353
cdalton6819df32014-10-15 13:43:48 -0700354 draw->fInfo.adjustInstanceCount(instancesToConcat);
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000355
356 // update last fGpuCmdMarkers to include any additional trace markers that have been added
357 if (this->getActiveTraceMarkers().count() > 0) {
robertphillipse5e72f12015-02-17 09:14:33 -0800358 if (draw->isTraced()) {
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000359 fGpuCmdMarkers.back().addSet(this->getActiveTraceMarkers());
360 } else {
361 fGpuCmdMarkers.push_back(this->getActiveTraceMarkers());
robertphillipse5e72f12015-02-17 09:14:33 -0800362 draw->makeTraced();
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000363 }
364 }
365
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000366 return instancesToConcat;
bsalomon@google.com934c5702012-03-20 21:17:58 +0000367}
368
egdaniele36914c2015-02-13 09:00:33 -0800369void GrInOrderDrawBuffer::onDraw(const GrGeometryProcessor* gp,
joshualitt9853cce2014-11-17 14:22:48 -0800370 const DrawInfo& info,
egdaniele36914c2015-02-13 09:00:33 -0800371 const PipelineInfo& pipelineInfo) {
joshualitt7eb8c7b2014-11-18 14:24:27 -0800372 SkASSERT(info.vertexBuffer() && (!info.isIndexed() || info.indexBuffer()));
joshualitt4d8da812015-01-28 12:53:54 -0800373 this->closeBatch();
374
egdaniele36914c2015-02-13 09:00:33 -0800375 if (!this->setupPipelineAndShouldDraw(gp, pipelineInfo)) {
bsalomonae59b772014-11-19 08:23:49 -0800376 return;
377 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000378
bsalomonb3e3a952014-09-19 11:10:40 -0700379 Draw* draw;
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000380 if (info.isInstanced()) {
egdaniele36914c2015-02-13 09:00:33 -0800381 int instancesConcated = this->concatInstancedDraw(info);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000382 if (info.instanceCount() > instancesConcated) {
joshualitt54e0c122014-11-19 09:38:51 -0800383 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info));
cdalton6819df32014-10-15 13:43:48 -0700384 draw->fInfo.adjustInstanceCount(-instancesConcated);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000385 } else {
386 return;
387 }
388 } else {
joshualitt54e0c122014-11-19 09:38:51 -0800389 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info));
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000390 }
cdalton6819df32014-10-15 13:43:48 -0700391 this->recordTraceMarkersIfNecessary();
commit-bot@chromium.org9b62aa12014-03-25 11:59:40 +0000392}
sugoi@google.com5f74cf82012-12-17 21:16:45 +0000393
joshualitt4d8da812015-01-28 12:53:54 -0800394void GrInOrderDrawBuffer::onDrawBatch(GrBatch* batch,
egdaniele36914c2015-02-13 09:00:33 -0800395 const PipelineInfo& pipelineInfo) {
396 if (!this->setupPipelineAndShouldDraw(batch, pipelineInfo)) {
joshualitt4d8da812015-01-28 12:53:54 -0800397 return;
398 }
399
400 // Check if there is a Batch Draw we can batch with
robertphillipse5e72f12015-02-17 09:14:33 -0800401 if (Cmd::kDrawBatch_Cmd != fCmdBuffer.back().type()) {
robertphillips9888b222015-02-27 08:50:34 -0800402 fDrawBatch = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawBatch, (batch, &fBatchTarget));
joshualitt4d8da812015-01-28 12:53:54 -0800403 return;
404 }
405
406 DrawBatch* draw = static_cast<DrawBatch*>(&fCmdBuffer.back());
407 if (draw->fBatch->combineIfPossible(batch)) {
408 return;
409 } else {
410 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 }
413 this->recordTraceMarkersIfNecessary();
414}
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;
cdalton6819df32014-10-15 13:43:48 -0700430 this->recordTraceMarkersIfNecessary();
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;
cdalton6819df32014-10-15 13:43:48 -0700445 this->recordTraceMarkersIfNecessary();
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
515 this->recordTraceMarkersIfNecessary();
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;
cdalton6819df32014-10-15 13:43:48 -0700536 this->recordTraceMarkersIfNecessary();
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;
548 this->recordTraceMarkersIfNecessary();
549}
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;
cdalton6819df32014-10-15 13:43:48 -0700560 this->recordTraceMarkersIfNecessary();
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()) {
egdanield78a1682014-07-09 10:41:26 -0700598 traceString = fGpuCmdMarkers[currCmdMarker].toString();
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;
cdalton6819df32014-10-15 13:43:48 -0700705 this->recordTraceMarkersIfNecessary();
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;
cdalton6819df32014-10-15 13:43:48 -0700732 this->recordTraceMarkersIfNecessary();
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;
755 this->recordTraceMarkersIfNecessary();
756 }
757 return true;
758}
759
cdalton6819df32014-10-15 13:43:48 -0700760void GrInOrderDrawBuffer::recordTraceMarkersIfNecessary() {
761 SkASSERT(!fCmdBuffer.empty());
robertphillipse5e72f12015-02-17 09:14:33 -0800762 SkASSERT(!fCmdBuffer.back().isTraced());
mtkleinf439c772014-10-14 14:29:30 -0700763 const GrTraceMarkerSet& activeTraceMarkers = this->getActiveTraceMarkers();
764 if (activeTraceMarkers.count() > 0) {
robertphillipse5e72f12015-02-17 09:14:33 -0800765 fCmdBuffer.back().makeTraced();
mtkleinf439c772014-10-14 14:29:30 -0700766 fGpuCmdMarkers.push_back(activeTraceMarkers);
mtklein07894c42014-10-13 14:00:42 -0700767 }
mtklein07894c42014-10-13 14:00:42 -0700768}
joshualitt4d8da812015-01-28 12:53:54 -0800769
joshualitt4d8da812015-01-28 12:53:54 -0800770void GrInOrderDrawBuffer::willReserveVertexAndIndexSpace(int vertexCount,
771 size_t vertexStride,
772 int indexCount) {
773 this->closeBatch();
774
robertphillips54fac8b2015-02-16 09:35:50 -0800775 this->INHERITED::willReserveVertexAndIndexSpace(vertexCount, vertexStride, indexCount);
joshualitt4d8da812015-01-28 12:53:54 -0800776}