blob: 609a95ee8a311b99227590d1e120c2d9f0332236 [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
joshualittee72dde2015-02-23 07:16:10 -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 if (GrColorIsOpaque(fGeoData[0].fColor)) {
113 out->setUnknownOpaqueFourComponents();
114 } else {
115 out->setUnknownFourComponents();
116 }
117 }
118
119 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const SK_OVERRIDE {
120 out->setUnknownSingleComponent();
121 }
122
123 void initBatchTracker(const GrPipelineInfo& init) SK_OVERRIDE {
124 // Handle any color overrides
125 if (init.fColorIgnored) {
126 fGeoData[0].fColor = GrColor_ILLEGAL;
127 } else if (GrColor_ILLEGAL != init.fOverrideColor) {
128 fGeoData[0].fColor = init.fOverrideColor;
129 }
130
131 // setup batch properties
132 fBatch.fColorIgnored = init.fColorIgnored;
133 fBatch.fColor = fGeoData[0].fColor;
134 fBatch.fUsesLocalCoords = init.fUsesLocalCoords;
135 fBatch.fCoverageIgnored = init.fCoverageIgnored;
136 }
137
138 void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) SK_OVERRIDE {
139 // Go to device coords to allow batching across matrix changes
140 SkMatrix invert = SkMatrix::I();
141
142 // if we have a local rect, then we apply the localMatrix directly to the localRect to
143 // generate vertex local coords
144 bool hasExplicitLocalCoords = this->hasLocalRect();
145 if (!hasExplicitLocalCoords) {
146 if (!this->viewMatrix().isIdentity() && !this->viewMatrix().invert(&invert)) {
147 SkDebugf("Could not invert\n");
148 return;
149 }
150
151 if (this->hasLocalMatrix()) {
152 invert.preConcat(this->localMatrix());
153 }
154 }
155
156 SkAutoTUnref<const GrGeometryProcessor> gp(create_rect_gp(hasExplicitLocalCoords,
157 this->color(),
158 &invert));
159
160 batchTarget->initDraw(gp, pipeline);
161
162 // TODO this is hacky, but the only way we have to initialize the GP is to use the
163 // GrPipelineInfo struct so we can generate the correct shader. Once we have GrBatch
164 // everywhere we can remove this nastiness
165 GrPipelineInfo init;
166 init.fColorIgnored = fBatch.fColorIgnored;
167 init.fOverrideColor = GrColor_ILLEGAL;
168 init.fCoverageIgnored = fBatch.fCoverageIgnored;
169 init.fUsesLocalCoords = this->usesLocalCoords();
170 gp->initBatchTracker(batchTarget->currentBatchTracker(), init);
171
172 size_t vertexStride = gp->getVertexStride();
173
174 SkASSERT(hasExplicitLocalCoords ?
175 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordAttr) :
176 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAttr));
177
178 int instanceCount = fGeoData.count();
179 int vertexCount = kVertsPerRect * instanceCount;
180
181 const GrVertexBuffer* vertexBuffer;
182 int firstVertex;
183
184 void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
185 vertexCount,
186 &vertexBuffer,
187 &firstVertex);
188
189 for (int i = 0; i < instanceCount; i++) {
190 const Geometry& args = fGeoData[i];
191
192 intptr_t offset = GrTCast<intptr_t>(vertices) + kVertsPerRect * i * vertexStride;
193 SkPoint* positions = GrTCast<SkPoint*>(offset);
194
195 positions->setRectFan(args.fRect.fLeft, args.fRect.fTop,
196 args.fRect.fRight, args.fRect.fBottom, vertexStride);
197 args.fViewMatrix.mapPointsWithStride(positions, vertexStride, kVertsPerRect);
198
199 if (args.fHasLocalRect) {
200 static const int kLocalOffset = sizeof(SkPoint) + sizeof(GrColor);
201 SkPoint* coords = GrTCast<SkPoint*>(offset + kLocalOffset);
202 coords->setRectFan(args.fLocalRect.fLeft, args.fLocalRect.fTop,
203 args.fLocalRect.fRight, args.fLocalRect.fBottom,
204 vertexStride);
205 if (args.fHasLocalMatrix) {
206 args.fLocalMatrix.mapPointsWithStride(coords, vertexStride, kVertsPerRect);
207 }
208 }
209
210 static const int kColorOffset = sizeof(SkPoint);
211 GrColor* vertColor = GrTCast<GrColor*>(offset + kColorOffset);
212 for (int j = 0; j < 4; ++j) {
213 *vertColor = args.fColor;
214 vertColor = (GrColor*) ((intptr_t) vertColor + vertexStride);
215 }
216 }
217
218 const GrIndexBuffer* quadIndexBuffer = batchTarget->quadIndexBuffer();
219
220 GrDrawTarget::DrawInfo drawInfo;
221 drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType);
222 drawInfo.setStartVertex(0);
223 drawInfo.setStartIndex(0);
224 drawInfo.setVerticesPerInstance(kVertsPerRect);
225 drawInfo.setIndicesPerInstance(kIndicesPerRect);
226 drawInfo.adjustStartVertex(firstVertex);
227 drawInfo.setVertexBuffer(vertexBuffer);
228 drawInfo.setIndexBuffer(quadIndexBuffer);
229
230 int maxInstancesPerDraw = quadIndexBuffer->maxQuads();
231 while (instanceCount) {
232 drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw));
233 drawInfo.setVertexCount(drawInfo.instanceCount() * drawInfo.verticesPerInstance());
234 drawInfo.setIndexCount(drawInfo.instanceCount() * drawInfo.indicesPerInstance());
235
236 batchTarget->draw(drawInfo);
237
238 drawInfo.setStartVertex(drawInfo.startVertex() + drawInfo.vertexCount());
239 instanceCount -= drawInfo.instanceCount();
240 }
241 }
242
243 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
244
245private:
246 RectBatch(const Geometry& geometry) {
247 this->initClassID<RectBatch>();
248 fGeoData.push_back(geometry);
249 }
250
251 GrColor color() const { return fBatch.fColor; }
252 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; }
253 bool colorIgnored() const { return fBatch.fColorIgnored; }
254 const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; }
255 const SkMatrix& localMatrix() const { return fGeoData[0].fLocalMatrix; }
256 bool hasLocalRect() const { return fGeoData[0].fHasLocalRect; }
257 bool hasLocalMatrix() const { return fGeoData[0].fHasLocalMatrix; }
258
259 bool onCombineIfPossible(GrBatch* t) SK_OVERRIDE {
260 RectBatch* that = t->cast<RectBatch>();
261
262 if (this->hasLocalRect() != that->hasLocalRect()) {
263 return false;
264 }
265
266 SkASSERT(this->usesLocalCoords() == that->usesLocalCoords());
267 if (!this->hasLocalRect() && this->usesLocalCoords()) {
268 if (!this->viewMatrix().cheapEqualTo(that->viewMatrix())) {
269 return false;
270 }
271
272 if (this->hasLocalMatrix() != that->hasLocalMatrix()) {
273 return false;
274 }
275
276 if (this->hasLocalMatrix() && !this->localMatrix().cheapEqualTo(that->localMatrix())) {
277 return false;
278 }
279 }
280
281 if (this->color() != that->color()) {
282 fBatch.fColor = GrColor_ILLEGAL;
283 }
284 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin());
285 return true;
286 }
287
288 struct BatchTracker {
289 GrColor fColor;
290 bool fUsesLocalCoords;
291 bool fColorIgnored;
292 bool fCoverageIgnored;
293 };
294
295 const static int kVertsPerRect = 4;
296 const static int kIndicesPerRect = 6;
297
298 BatchTracker fBatch;
299 SkSTArray<1, Geometry, true> fGeoData;
300};
301
egdaniel8dd688b2015-01-22 10:16:09 -0800302void GrInOrderDrawBuffer::onDrawRect(GrPipelineBuilder* pipelineBuilder,
joshualitt2e3b3e32014-12-09 13:31:14 -0800303 GrColor color,
joshualitt8059eb92014-12-29 15:10:07 -0800304 const SkMatrix& viewMatrix,
joshualitt9853cce2014-11-17 14:22:48 -0800305 const SkRect& rect,
commit-bot@chromium.orgfd03d4a2013-07-17 21:39:42 +0000306 const SkRect* localRect,
bsalomon@google.com0406b9e2013-04-02 21:00:15 +0000307 const SkMatrix* localMatrix) {
egdaniel8dd688b2015-01-22 10:16:09 -0800308 GrPipelineBuilder::AutoRestoreEffects are(pipelineBuilder);
joshualittee72dde2015-02-23 07:16:10 -0800309 RectBatch::Geometry geometry;
310 geometry.fColor = color;
311 geometry.fViewMatrix = viewMatrix;
312 geometry.fRect = rect;
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000313
bsalomon49f085d2014-09-05 13:34:00 -0700314 if (localRect) {
joshualittee72dde2015-02-23 07:16:10 -0800315 geometry.fHasLocalRect = true;
316 geometry.fLocalRect = *localRect;
317 } else {
318 geometry.fHasLocalRect = false;
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000319 }
320
joshualittee72dde2015-02-23 07:16:10 -0800321 if (localMatrix) {
322 geometry.fHasLocalMatrix = true;
323 geometry.fLocalMatrix = *localMatrix;
324 } else {
325 geometry.fHasLocalMatrix = false;
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000326 }
327
joshualittee72dde2015-02-23 07:16:10 -0800328 SkAutoTUnref<GrBatch> batch(RectBatch::Create(geometry));
329
330 SkRect bounds = rect;
331 viewMatrix.mapRect(&bounds);
332 this->drawBatch(pipelineBuilder, batch, &bounds);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000333}
334
egdaniele36914c2015-02-13 09:00:33 -0800335int GrInOrderDrawBuffer::concatInstancedDraw(const DrawInfo& info) {
cdalton6819df32014-10-15 13:43:48 -0700336 SkASSERT(!fCmdBuffer.empty());
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000337 SkASSERT(info.isInstanced());
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000338
bsalomon@google.com934c5702012-03-20 21:17:58 +0000339 const GeometrySrcState& geomSrc = this->getGeomSrc();
340
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000341 // we only attempt to concat the case when reserved verts are used with a client-specified index
342 // buffer. To make this work with client-specified VBs we'd need to know if the VB was updated
343 // between draws.
344 if (kReserved_GeometrySrcType != geomSrc.fVertexSrc ||
345 kBuffer_GeometrySrcType != geomSrc.fIndexSrc) {
346 return 0;
bsalomon@google.com934c5702012-03-20 21:17:58 +0000347 }
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000348 // Check if there is a draw info that is compatible that uses the same VB from the pool and
349 // the same IB
robertphillipse5e72f12015-02-17 09:14:33 -0800350 if (Cmd::kDraw_Cmd != fCmdBuffer.back().type()) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000351 return 0;
352 }
353
cdalton6819df32014-10-15 13:43:48 -0700354 Draw* draw = static_cast<Draw*>(&fCmdBuffer.back());
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000355
cdalton6819df32014-10-15 13:43:48 -0700356 if (!draw->fInfo.isInstanced() ||
joshualitt4d8da812015-01-28 12:53:54 -0800357 draw->fInfo.primitiveType() != info.primitiveType() ||
cdalton6819df32014-10-15 13:43:48 -0700358 draw->fInfo.verticesPerInstance() != info.verticesPerInstance() ||
359 draw->fInfo.indicesPerInstance() != info.indicesPerInstance() ||
bsalomon371bcbc2014-12-01 08:19:34 -0800360 draw->fInfo.vertexBuffer() != info.vertexBuffer() ||
joshualitt54e0c122014-11-19 09:38:51 -0800361 draw->fInfo.indexBuffer() != geomSrc.fIndexBuffer) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000362 return 0;
363 }
bsalomon371bcbc2014-12-01 08:19:34 -0800364 if (draw->fInfo.startVertex() + draw->fInfo.vertexCount() != info.startVertex()) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000365 return 0;
366 }
367
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000368 // how many instances can be concat'ed onto draw given the size of the index buffer
369 int instancesToConcat = this->indexCountInCurrentSource() / info.indicesPerInstance();
cdalton6819df32014-10-15 13:43:48 -0700370 instancesToConcat -= draw->fInfo.instanceCount();
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000371 instancesToConcat = SkTMin(instancesToConcat, info.instanceCount());
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000372
cdalton6819df32014-10-15 13:43:48 -0700373 draw->fInfo.adjustInstanceCount(instancesToConcat);
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000374
375 // update last fGpuCmdMarkers to include any additional trace markers that have been added
376 if (this->getActiveTraceMarkers().count() > 0) {
robertphillipse5e72f12015-02-17 09:14:33 -0800377 if (draw->isTraced()) {
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000378 fGpuCmdMarkers.back().addSet(this->getActiveTraceMarkers());
379 } else {
380 fGpuCmdMarkers.push_back(this->getActiveTraceMarkers());
robertphillipse5e72f12015-02-17 09:14:33 -0800381 draw->makeTraced();
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000382 }
383 }
384
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000385 return instancesToConcat;
bsalomon@google.com934c5702012-03-20 21:17:58 +0000386}
387
egdaniele36914c2015-02-13 09:00:33 -0800388void GrInOrderDrawBuffer::onDraw(const GrGeometryProcessor* gp,
joshualitt9853cce2014-11-17 14:22:48 -0800389 const DrawInfo& info,
egdaniele36914c2015-02-13 09:00:33 -0800390 const PipelineInfo& pipelineInfo) {
joshualitt7eb8c7b2014-11-18 14:24:27 -0800391 SkASSERT(info.vertexBuffer() && (!info.isIndexed() || info.indexBuffer()));
joshualitt4d8da812015-01-28 12:53:54 -0800392 this->closeBatch();
393
egdaniele36914c2015-02-13 09:00:33 -0800394 if (!this->setupPipelineAndShouldDraw(gp, pipelineInfo)) {
bsalomonae59b772014-11-19 08:23:49 -0800395 return;
396 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000397
bsalomonb3e3a952014-09-19 11:10:40 -0700398 Draw* draw;
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000399 if (info.isInstanced()) {
egdaniele36914c2015-02-13 09:00:33 -0800400 int instancesConcated = this->concatInstancedDraw(info);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000401 if (info.instanceCount() > instancesConcated) {
joshualitt54e0c122014-11-19 09:38:51 -0800402 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info));
cdalton6819df32014-10-15 13:43:48 -0700403 draw->fInfo.adjustInstanceCount(-instancesConcated);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000404 } else {
405 return;
406 }
407 } else {
joshualitt54e0c122014-11-19 09:38:51 -0800408 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info));
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000409 }
cdalton6819df32014-10-15 13:43:48 -0700410 this->recordTraceMarkersIfNecessary();
commit-bot@chromium.org9b62aa12014-03-25 11:59:40 +0000411}
sugoi@google.com5f74cf82012-12-17 21:16:45 +0000412
joshualitt4d8da812015-01-28 12:53:54 -0800413void GrInOrderDrawBuffer::onDrawBatch(GrBatch* batch,
egdaniele36914c2015-02-13 09:00:33 -0800414 const PipelineInfo& pipelineInfo) {
415 if (!this->setupPipelineAndShouldDraw(batch, pipelineInfo)) {
joshualitt4d8da812015-01-28 12:53:54 -0800416 return;
417 }
418
419 // Check if there is a Batch Draw we can batch with
robertphillipse5e72f12015-02-17 09:14:33 -0800420 if (Cmd::kDrawBatch_Cmd != fCmdBuffer.back().type()) {
joshualitt4d8da812015-01-28 12:53:54 -0800421 fDrawBatch = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawBatch, (batch));
422 return;
423 }
424
425 DrawBatch* draw = static_cast<DrawBatch*>(&fCmdBuffer.back());
426 if (draw->fBatch->combineIfPossible(batch)) {
427 return;
428 } else {
429 this->closeBatch();
430 fDrawBatch = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawBatch, (batch));
431 }
432 this->recordTraceMarkersIfNecessary();
433}
434
egdaniel8dd688b2015-01-22 10:16:09 -0800435void GrInOrderDrawBuffer::onStencilPath(const GrPipelineBuilder& pipelineBuilder,
joshualitt56995b52014-12-11 15:44:02 -0800436 const GrPathProcessor* pathProc,
joshualitt9853cce2014-11-17 14:22:48 -0800437 const GrPath* path,
bsalomon3e791242014-12-17 13:43:13 -0800438 const GrScissorState& scissorState,
joshualitt2c93efe2014-11-06 12:57:13 -0800439 const GrStencilSettings& stencilSettings) {
joshualitt70f00042015-02-06 15:53:59 -0800440 this->closeBatch();
441
bsalomon3e791242014-12-17 13:43:13 -0800442 StencilPath* sp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, StencilPath,
egdaniel8dd688b2015-01-22 10:16:09 -0800443 (path, pipelineBuilder.getRenderTarget()));
joshualittee72dde2015-02-23 07:16:10 -0800444
bsalomon3e791242014-12-17 13:43:13 -0800445 sp->fScissor = scissorState;
egdaniel8dd688b2015-01-22 10:16:09 -0800446 sp->fUseHWAA = pipelineBuilder.isHWAntialias();
joshualitt8059eb92014-12-29 15:10:07 -0800447 sp->fViewMatrix = pathProc->viewMatrix();
bsalomon3e791242014-12-17 13:43:13 -0800448 sp->fStencil = stencilSettings;
cdalton6819df32014-10-15 13:43:48 -0700449 this->recordTraceMarkersIfNecessary();
bsalomon@google.com64aef2b2012-06-11 15:36:13 +0000450}
451
egdaniele36914c2015-02-13 09:00:33 -0800452void GrInOrderDrawBuffer::onDrawPath(const GrPathProcessor* pathProc,
joshualitt9853cce2014-11-17 14:22:48 -0800453 const GrPath* path,
joshualitt2c93efe2014-11-06 12:57:13 -0800454 const GrStencilSettings& stencilSettings,
egdaniele36914c2015-02-13 09:00:33 -0800455 const PipelineInfo& pipelineInfo) {
joshualitt4d8da812015-01-28 12:53:54 -0800456 this->closeBatch();
457
egdaniel8dd688b2015-01-22 10:16:09 -0800458 // TODO: Only compare the subset of GrPipelineBuilder relevant to path covering?
egdaniele36914c2015-02-13 09:00:33 -0800459 if (!this->setupPipelineAndShouldDraw(pathProc, pipelineInfo)) {
bsalomonae59b772014-11-19 08:23:49 -0800460 return;
461 }
cdalton6819df32014-10-15 13:43:48 -0700462 DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (path));
joshualitt2c93efe2014-11-06 12:57:13 -0800463 dp->fStencilSettings = stencilSettings;
cdalton6819df32014-10-15 13:43:48 -0700464 this->recordTraceMarkersIfNecessary();
commit-bot@chromium.orgc4dc0ad2013-10-09 14:11:33 +0000465}
466
egdaniele36914c2015-02-13 09:00:33 -0800467void GrInOrderDrawBuffer::onDrawPaths(const GrPathProcessor* pathProc,
joshualitt9853cce2014-11-17 14:22:48 -0800468 const GrPathRange* pathRange,
cdalton55b24af2014-11-25 11:00:56 -0800469 const void* indices,
470 PathIndexType indexType,
471 const float transformValues[],
472 PathTransformType transformType,
joshualitt2c93efe2014-11-06 12:57:13 -0800473 int count,
joshualitt2c93efe2014-11-06 12:57:13 -0800474 const GrStencilSettings& stencilSettings,
egdaniele36914c2015-02-13 09:00:33 -0800475 const PipelineInfo& pipelineInfo) {
bsalomon49f085d2014-09-05 13:34:00 -0700476 SkASSERT(pathRange);
477 SkASSERT(indices);
cdalton55b24af2014-11-25 11:00:56 -0800478 SkASSERT(transformValues);
joshualitt4d8da812015-01-28 12:53:54 -0800479 this->closeBatch();
480
egdaniele36914c2015-02-13 09:00:33 -0800481 if (!this->setupPipelineAndShouldDraw(pathProc, pipelineInfo)) {
bsalomonae59b772014-11-19 08:23:49 -0800482 return;
483 }
cdalton6819df32014-10-15 13:43:48 -0700484
cdalton55b24af2014-11-25 11:00:56 -0800485 int indexBytes = GrPathRange::PathIndexSizeInBytes(indexType);
486 if (int misalign = fPathIndexBuffer.count() % indexBytes) {
487 // Add padding to the index buffer so the indices are aligned properly.
488 fPathIndexBuffer.append(indexBytes - misalign);
489 }
490
491 char* savedIndices = fPathIndexBuffer.append(count * indexBytes,
492 reinterpret_cast<const char*>(indices));
493 float* savedTransforms = fPathTransformBuffer.append(
494 count * GrPathRendering::PathTransformSize(transformType),
495 transformValues);
cdalton6819df32014-10-15 13:43:48 -0700496
robertphillipse5e72f12015-02-17 09:14:33 -0800497 if (Cmd::kDrawPaths_Cmd == fCmdBuffer.back().type()) {
cdalton3fc6a2f2014-11-13 11:54:20 -0800498 // The previous command was also DrawPaths. Try to collapse this call into the one
bsalomon371bcbc2014-12-01 08:19:34 -0800499 // before. Note that stenciling all the paths at once, then covering, may not be
cdalton3fc6a2f2014-11-13 11:54:20 -0800500 // equivalent to two separate draw calls if there is overlap. Blending won't work,
501 // and the combined calls may also cancel each other's winding numbers in some
502 // places. For now the winding numbers are only an issue if the fill is even/odd,
503 // because DrawPaths is currently only used for glyphs, and glyphs in the same
504 // font tend to all wind in the same direction.
505 DrawPaths* previous = static_cast<DrawPaths*>(&fCmdBuffer.back());
506 if (pathRange == previous->pathRange() &&
cdalton55b24af2014-11-25 11:00:56 -0800507 indexType == previous->fIndexType &&
508 transformType == previous->fTransformType &&
cdalton3fc6a2f2014-11-13 11:54:20 -0800509 stencilSettings == previous->fStencilSettings &&
510 path_fill_type_is_winding(stencilSettings) &&
egdaniele36914c2015-02-13 09:00:33 -0800511 !pipelineInfo.willBlendWithDst(pathProc)) {
cdalton3fc6a2f2014-11-13 11:54:20 -0800512 // Fold this DrawPaths call into the one previous.
513 previous->fCount += count;
514 return;
515 }
516 }
517
518 DrawPaths* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPaths, (pathRange));
bsalomonef3fcd82014-12-12 08:51:38 -0800519 dp->fIndicesLocation = SkToU32(savedIndices - fPathIndexBuffer.begin());
cdalton55b24af2014-11-25 11:00:56 -0800520 dp->fIndexType = indexType;
bsalomonef3fcd82014-12-12 08:51:38 -0800521 dp->fTransformsLocation = SkToU32(savedTransforms - fPathTransformBuffer.begin());
cdalton55b24af2014-11-25 11:00:56 -0800522 dp->fTransformType = transformType;
523 dp->fCount = count;
joshualitt2c93efe2014-11-06 12:57:13 -0800524 dp->fStencilSettings = stencilSettings;
cdalton6819df32014-10-15 13:43:48 -0700525
526 this->recordTraceMarkersIfNecessary();
commit-bot@chromium.org9b62aa12014-03-25 11:59:40 +0000527}
528
bsalomon63b21962014-11-05 07:05:34 -0800529void GrInOrderDrawBuffer::onClear(const SkIRect* rect, GrColor color,
530 bool canIgnoreRect, GrRenderTarget* renderTarget) {
joshualitt9853cce2014-11-17 14:22:48 -0800531 SkASSERT(renderTarget);
joshualitt70f00042015-02-06 15:53:59 -0800532 this->closeBatch();
533
commit-bot@chromium.orgfd03d4a2013-07-17 21:39:42 +0000534 SkIRect r;
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000535 if (NULL == rect) {
536 // We could do something smart and remove previous draws and clears to
537 // the current render target. If we get that smart we have to make sure
538 // those draws aren't read before this clear (render-to-texture).
bsalomon@google.com1b3ce472012-08-17 13:43:08 +0000539 r.setLTRB(0, 0, renderTarget->width(), renderTarget->height());
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000540 rect = &r;
541 }
cdalton6819df32014-10-15 13:43:48 -0700542 Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget));
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000543 GrColorIsPMAssert(color);
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000544 clr->fColor = color;
545 clr->fRect = *rect;
robertphillips@google.com56ce48a2013-10-31 21:44:25 +0000546 clr->fCanIgnoreRect = canIgnoreRect;
cdalton6819df32014-10-15 13:43:48 -0700547 this->recordTraceMarkersIfNecessary();
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000548}
549
joshualitt6db519c2014-10-29 08:48:18 -0700550void GrInOrderDrawBuffer::clearStencilClip(const SkIRect& rect,
551 bool insideClip,
552 GrRenderTarget* renderTarget) {
joshualitt9853cce2014-11-17 14:22:48 -0800553 SkASSERT(renderTarget);
joshualitt70f00042015-02-06 15:53:59 -0800554 this->closeBatch();
555
joshualitt6db519c2014-10-29 08:48:18 -0700556 ClearStencilClip* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, ClearStencilClip, (renderTarget));
557 clr->fRect = rect;
558 clr->fInsideClip = insideClip;
559 this->recordTraceMarkersIfNecessary();
560}
561
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000562void GrInOrderDrawBuffer::discard(GrRenderTarget* renderTarget) {
bsalomon89c62982014-11-03 12:08:42 -0800563 SkASSERT(renderTarget);
joshualitt70f00042015-02-06 15:53:59 -0800564 this->closeBatch();
565
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000566 if (!this->caps()->discardRenderTargetSupport()) {
567 return;
568 }
cdalton6819df32014-10-15 13:43:48 -0700569 Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget));
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000570 clr->fColor = GrColor_ILLEGAL;
cdalton6819df32014-10-15 13:43:48 -0700571 this->recordTraceMarkersIfNecessary();
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000572}
573
bsalomon371bcbc2014-12-01 08:19:34 -0800574void GrInOrderDrawBuffer::onReset() {
cdalton6819df32014-10-15 13:43:48 -0700575 fCmdBuffer.reset();
bsalomon932f8662014-11-24 06:47:48 -0800576 fPrevState = NULL;
cdalton3fc6a2f2014-11-13 11:54:20 -0800577 reset_data_buffer(&fPathIndexBuffer, kPathIdxBufferMinReserve);
578 reset_data_buffer(&fPathTransformBuffer, kPathXformBufferMinReserve);
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000579 fGpuCmdMarkers.reset();
joshualitt4d8da812015-01-28 12:53:54 -0800580 fDrawBatch = NULL;
reed@google.comac10a2d2010-12-22 21:39:39 +0000581}
582
bsalomon371bcbc2014-12-01 08:19:34 -0800583void GrInOrderDrawBuffer::onFlush() {
cdalton6819df32014-10-15 13:43:48 -0700584 if (fCmdBuffer.empty()) {
robertphillips@google.com1267fbd2013-07-03 18:37:27 +0000585 return;
reed@google.comac10a2d2010-12-22 21:39:39 +0000586 }
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000587
joshualittc2893c52015-01-28 06:54:30 -0800588 // Updated every time we find a set state cmd to reflect the current state in the playback
589 // stream.
590 SetState* currentState = NULL;
591
joshualitt4d8da812015-01-28 12:53:54 -0800592 // TODO this is temporary while batch is being rolled out
593 this->closeBatch();
594 this->getVertexAllocPool()->unmap();
595 this->getIndexAllocPool()->unmap();
596 fBatchTarget.preFlush();
597
598 currentState = NULL;
599 CmdBuffer::Iter iter(fCmdBuffer);
600
601 int currCmdMarker = 0;
602
joshualitt7bc18b72015-02-03 16:41:41 -0800603 int i = 0;
cdalton6819df32014-10-15 13:43:48 -0700604 while (iter.next()) {
joshualitt7bc18b72015-02-03 16:41:41 -0800605 i++;
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000606 GrGpuTraceMarker newMarker("", -1);
egdanield78a1682014-07-09 10:41:26 -0700607 SkString traceString;
robertphillipse5e72f12015-02-17 09:14:33 -0800608 if (iter->isTraced()) {
egdanield78a1682014-07-09 10:41:26 -0700609 traceString = fGpuCmdMarkers[currCmdMarker].toString();
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000610 newMarker.fMarker = traceString.c_str();
bsalomon371bcbc2014-12-01 08:19:34 -0800611 this->getGpu()->addGpuTraceMarker(&newMarker);
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000612 ++currCmdMarker;
613 }
cdalton6819df32014-10-15 13:43:48 -0700614
joshualitt4d8da812015-01-28 12:53:54 -0800615 // TODO temporary hack
robertphillipse5e72f12015-02-17 09:14:33 -0800616 if (Cmd::kDrawBatch_Cmd == iter->type()) {
joshualitt7bc18b72015-02-03 16:41:41 -0800617 DrawBatch* db = reinterpret_cast<DrawBatch*>(iter.get());
618 fBatchTarget.flushNext(db->fBatch->numberOfDraws());
joshualitt4d8da812015-01-28 12:53:54 -0800619 continue;
620 }
621
robertphillipse5e72f12015-02-17 09:14:33 -0800622 if (Cmd::kSetState_Cmd == iter->type()) {
joshualitt9853cce2014-11-17 14:22:48 -0800623 SetState* ss = reinterpret_cast<SetState*>(iter.get());
joshualitt873ad0e2015-01-20 09:08:51 -0800624
joshualitt4d8da812015-01-28 12:53:54 -0800625 // TODO sometimes we have a prim proc, othertimes we have a GrBatch. Eventually we will
626 // only have GrBatch and we can delete this
627 if (ss->fPrimitiveProcessor) {
628 this->getGpu()->buildProgramDesc(&ss->fDesc, *ss->fPrimitiveProcessor,
egdaniele36914c2015-02-13 09:00:33 -0800629 *ss->getPipeline(),
joshualitt4d8da812015-01-28 12:53:54 -0800630 ss->fBatchTracker);
631 }
joshualitt873ad0e2015-01-20 09:08:51 -0800632 currentState = ss;
joshualittd53a8272014-11-10 16:03:14 -0800633 } else {
joshualitt873ad0e2015-01-20 09:08:51 -0800634 iter->execute(this, currentState);
joshualittd53a8272014-11-10 16:03:14 -0800635 }
cdalton6819df32014-10-15 13:43:48 -0700636
robertphillipse5e72f12015-02-17 09:14:33 -0800637 if (iter->isTraced()) {
bsalomon371bcbc2014-12-01 08:19:34 -0800638 this->getGpu()->removeGpuTraceMarker(&newMarker);
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000639 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000640 }
mtkleinf439c772014-10-14 14:29:30 -0700641
joshualitt4d8da812015-01-28 12:53:54 -0800642 // TODO see copious notes about hack
643 fBatchTarget.postFlush();
644
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000645 SkASSERT(fGpuCmdMarkers.count() == currCmdMarker);
commit-bot@chromium.orga8916ff2013-08-16 15:53:46 +0000646 ++fDrawID;
reed@google.comac10a2d2010-12-22 21:39:39 +0000647}
648
joshualitt873ad0e2015-01-20 09:08:51 -0800649void GrInOrderDrawBuffer::Draw::execute(GrInOrderDrawBuffer* buf, const SetState* state) {
650 SkASSERT(state);
egdaniele36914c2015-02-13 09:00:33 -0800651 DrawArgs args(state->fPrimitiveProcessor.get(), state->getPipeline(), &state->fDesc,
joshualitt17e73142015-01-21 11:52:36 -0800652 &state->fBatchTracker);
joshualitt873ad0e2015-01-20 09:08:51 -0800653 buf->getGpu()->draw(args, fInfo);
cdalton6819df32014-10-15 13:43:48 -0700654}
655
joshualitt873ad0e2015-01-20 09:08:51 -0800656void GrInOrderDrawBuffer::StencilPath::execute(GrInOrderDrawBuffer* buf, const SetState*) {
bsalomon3e791242014-12-17 13:43:13 -0800657 GrGpu::StencilPathState state;
658 state.fRenderTarget = fRenderTarget.get();
659 state.fScissor = &fScissor;
660 state.fStencil = &fStencil;
661 state.fUseHWAA = fUseHWAA;
662 state.fViewMatrix = &fViewMatrix;
663
664 buf->getGpu()->stencilPath(this->path(), state);
cdalton6819df32014-10-15 13:43:48 -0700665}
666
joshualitt873ad0e2015-01-20 09:08:51 -0800667void GrInOrderDrawBuffer::DrawPath::execute(GrInOrderDrawBuffer* buf, const SetState* state) {
668 SkASSERT(state);
egdaniele36914c2015-02-13 09:00:33 -0800669 DrawArgs args(state->fPrimitiveProcessor.get(), state->getPipeline(), &state->fDesc,
joshualitt17e73142015-01-21 11:52:36 -0800670 &state->fBatchTracker);
joshualitt873ad0e2015-01-20 09:08:51 -0800671 buf->getGpu()->drawPath(args, this->path(), fStencilSettings);
cdalton6819df32014-10-15 13:43:48 -0700672}
673
joshualitt873ad0e2015-01-20 09:08:51 -0800674void GrInOrderDrawBuffer::DrawPaths::execute(GrInOrderDrawBuffer* buf, const SetState* state) {
675 SkASSERT(state);
egdaniele36914c2015-02-13 09:00:33 -0800676 DrawArgs args(state->fPrimitiveProcessor.get(), state->getPipeline(), &state->fDesc,
joshualitt17e73142015-01-21 11:52:36 -0800677 &state->fBatchTracker);
joshualitt873ad0e2015-01-20 09:08:51 -0800678 buf->getGpu()->drawPaths(args, this->pathRange(),
cdalton55b24af2014-11-25 11:00:56 -0800679 &buf->fPathIndexBuffer[fIndicesLocation], fIndexType,
680 &buf->fPathTransformBuffer[fTransformsLocation], fTransformType,
681 fCount, fStencilSettings);
cdalton6819df32014-10-15 13:43:48 -0700682}
683
joshualitt4d8da812015-01-28 12:53:54 -0800684void GrInOrderDrawBuffer::DrawBatch::execute(GrInOrderDrawBuffer* buf, const SetState* state) {
685 SkASSERT(state);
egdaniele36914c2015-02-13 09:00:33 -0800686 fBatch->generateGeometry(buf->getBatchTarget(), state->getPipeline());
joshualitt4d8da812015-01-28 12:53:54 -0800687}
688
joshualitt873ad0e2015-01-20 09:08:51 -0800689void GrInOrderDrawBuffer::SetState::execute(GrInOrderDrawBuffer*, const SetState*) {}
cdalton6819df32014-10-15 13:43:48 -0700690
joshualitt873ad0e2015-01-20 09:08:51 -0800691void GrInOrderDrawBuffer::Clear::execute(GrInOrderDrawBuffer* buf, const SetState*) {
cdalton6819df32014-10-15 13:43:48 -0700692 if (GrColor_ILLEGAL == fColor) {
bsalomon371bcbc2014-12-01 08:19:34 -0800693 buf->getGpu()->discard(this->renderTarget());
cdalton6819df32014-10-15 13:43:48 -0700694 } else {
bsalomon371bcbc2014-12-01 08:19:34 -0800695 buf->getGpu()->clear(&fRect, fColor, fCanIgnoreRect, this->renderTarget());
cdalton6819df32014-10-15 13:43:48 -0700696 }
697}
698
joshualitt873ad0e2015-01-20 09:08:51 -0800699void GrInOrderDrawBuffer::ClearStencilClip::execute(GrInOrderDrawBuffer* buf, const SetState*) {
bsalomon371bcbc2014-12-01 08:19:34 -0800700 buf->getGpu()->clearStencilClip(fRect, fInsideClip, this->renderTarget());
joshualitt6db519c2014-10-29 08:48:18 -0700701}
702
joshualitt873ad0e2015-01-20 09:08:51 -0800703void GrInOrderDrawBuffer::CopySurface::execute(GrInOrderDrawBuffer* buf, const SetState*) {
bsalomon371bcbc2014-12-01 08:19:34 -0800704 buf->getGpu()->copySurface(this->dst(), this->src(), fSrcRect, fDstPoint);
cdalton6819df32014-10-15 13:43:48 -0700705}
706
bsalomonf90a02b2014-11-26 12:28:00 -0800707bool GrInOrderDrawBuffer::onCopySurface(GrSurface* dst,
708 GrSurface* src,
709 const SkIRect& srcRect,
710 const SkIPoint& dstPoint) {
bsalomon371bcbc2014-12-01 08:19:34 -0800711 if (getGpu()->canCopySurface(dst, src, srcRect, dstPoint)) {
joshualitt95964c62015-02-11 13:45:50 -0800712 this->closeBatch();
cdalton6819df32014-10-15 13:43:48 -0700713 CopySurface* cs = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, CopySurface, (dst, src));
bsalomon@google.com116ad842013-04-09 15:38:19 +0000714 cs->fSrcRect = srcRect;
715 cs->fDstPoint = dstPoint;
cdalton6819df32014-10-15 13:43:48 -0700716 this->recordTraceMarkersIfNecessary();
bsalomon@google.com116ad842013-04-09 15:38:19 +0000717 return true;
bsalomon@google.com116ad842013-04-09 15:38:19 +0000718 }
bsalomonf90a02b2014-11-26 12:28:00 -0800719 return false;
bsalomon@google.com116ad842013-04-09 15:38:19 +0000720}
721
egdaniele36914c2015-02-13 09:00:33 -0800722bool GrInOrderDrawBuffer::setupPipelineAndShouldDraw(const GrPrimitiveProcessor* primProc,
723 const PipelineInfo& pipelineInfo) {
724 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (primProc));
725 this->setupPipeline(pipelineInfo, ss->pipelineLocation());
726
727 if (ss->getPipeline()->mustSkip()) {
bsalomon932f8662014-11-24 06:47:48 -0800728 fCmdBuffer.pop_back();
bsalomonae59b772014-11-19 08:23:49 -0800729 return false;
730 }
joshualitt873ad0e2015-01-20 09:08:51 -0800731
732 ss->fPrimitiveProcessor->initBatchTracker(&ss->fBatchTracker,
egdaniele36914c2015-02-13 09:00:33 -0800733 ss->getPipeline()->getInitBatchTracker());
joshualitt873ad0e2015-01-20 09:08:51 -0800734
joshualitt4d8da812015-01-28 12:53:54 -0800735 if (fPrevState && fPrevState->fPrimitiveProcessor.get() &&
joshualitt873ad0e2015-01-20 09:08:51 -0800736 fPrevState->fPrimitiveProcessor->canMakeEqual(fPrevState->fBatchTracker,
737 *ss->fPrimitiveProcessor,
738 ss->fBatchTracker) &&
egdaniele36914c2015-02-13 09:00:33 -0800739 fPrevState->getPipeline()->isEqual(*ss->getPipeline())) {
bsalomon932f8662014-11-24 06:47:48 -0800740 fCmdBuffer.pop_back();
741 } else {
joshualitt873ad0e2015-01-20 09:08:51 -0800742 fPrevState = ss;
cdalton6819df32014-10-15 13:43:48 -0700743 this->recordTraceMarkersIfNecessary();
bsalomon838f62d2014-08-05 07:15:57 -0700744 }
bsalomonae59b772014-11-19 08:23:49 -0800745 return true;
reed@google.comac10a2d2010-12-22 21:39:39 +0000746}
747
egdaniele36914c2015-02-13 09:00:33 -0800748bool GrInOrderDrawBuffer::setupPipelineAndShouldDraw(GrBatch* batch,
749 const PipelineInfo& pipelineInfo) {
750 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, ());
751 this->setupPipeline(pipelineInfo, ss->pipelineLocation());
752
753 if (ss->getPipeline()->mustSkip()) {
joshualitt4d8da812015-01-28 12:53:54 -0800754 fCmdBuffer.pop_back();
755 return false;
756 }
757
egdaniele36914c2015-02-13 09:00:33 -0800758 batch->initBatchTracker(ss->getPipeline()->getInitBatchTracker());
joshualitt4d8da812015-01-28 12:53:54 -0800759
760 if (fPrevState && !fPrevState->fPrimitiveProcessor.get() &&
egdaniele36914c2015-02-13 09:00:33 -0800761 fPrevState->getPipeline()->isEqual(*ss->getPipeline())) {
joshualitt4d8da812015-01-28 12:53:54 -0800762 fCmdBuffer.pop_back();
763 } else {
764 this->closeBatch();
765 fPrevState = ss;
766 this->recordTraceMarkersIfNecessary();
767 }
768 return true;
769}
770
cdalton6819df32014-10-15 13:43:48 -0700771void GrInOrderDrawBuffer::recordTraceMarkersIfNecessary() {
772 SkASSERT(!fCmdBuffer.empty());
robertphillipse5e72f12015-02-17 09:14:33 -0800773 SkASSERT(!fCmdBuffer.back().isTraced());
mtkleinf439c772014-10-14 14:29:30 -0700774 const GrTraceMarkerSet& activeTraceMarkers = this->getActiveTraceMarkers();
775 if (activeTraceMarkers.count() > 0) {
robertphillipse5e72f12015-02-17 09:14:33 -0800776 fCmdBuffer.back().makeTraced();
mtkleinf439c772014-10-14 14:29:30 -0700777 fGpuCmdMarkers.push_back(activeTraceMarkers);
mtklein07894c42014-10-13 14:00:42 -0700778 }
mtklein07894c42014-10-13 14:00:42 -0700779}
joshualitt4d8da812015-01-28 12:53:54 -0800780
joshualitt4d8da812015-01-28 12:53:54 -0800781void GrInOrderDrawBuffer::willReserveVertexAndIndexSpace(int vertexCount,
782 size_t vertexStride,
783 int indexCount) {
784 this->closeBatch();
785
robertphillips54fac8b2015-02-16 09:35:50 -0800786 this->INHERITED::willReserveVertexAndIndexSpace(vertexCount, vertexStride, indexCount);
joshualitt4d8da812015-01-28 12:53:54 -0800787}