blob: 3a17fa9fcb5952d2f986b51cced0ef62b2c67c4a [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)
robertphillipsdad77942015-03-03 09:28:16 -080022 , fCommands(gpu, vertexPool, indexPool)
robertphillips9888b222015-02-27 08:50:34 -080023 , fPathIndexBuffer(kPathIdxBufferMinReserve * sizeof(char)/4)
24 , fPathTransformBuffer(kPathXformBufferMinReserve * sizeof(float)/4)
robertphillipsdad77942015-03-03 09:28:16 -080025 , fDrawID(0) {
bsalomon@google.com18c9c192011-09-22 21:01:31 +000026
bsalomon49f085d2014-09-05 13:34:00 -070027 SkASSERT(vertexPool);
28 SkASSERT(indexPool);
reed@google.comac10a2d2010-12-22 21:39:39 +000029}
30
31GrInOrderDrawBuffer::~GrInOrderDrawBuffer() {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000032 this->reset();
reed@google.comac10a2d2010-12-22 21:39:39 +000033}
34
robertphillipsdad77942015-03-03 09:28:16 -080035void GrTargetCommands::closeBatch() {
robertphillips7f966f42015-03-02 06:40:12 -080036 if (fDrawBatch) {
37 fBatchTarget.resetNumberOfDraws();
robertphillipsdad77942015-03-03 09:28:16 -080038 fDrawBatch->execute(NULL, fPrevState);
robertphillips7f966f42015-03-02 06:40:12 -080039 fDrawBatch->fBatch->setNumberOfDraws(fBatchTarget.numberOfDraws());
40 fDrawBatch = NULL;
41 }
42}
43
bsalomon@google.com934c5702012-03-20 21:17:58 +000044////////////////////////////////////////////////////////////////////////////////
45
bsalomon62c447d2014-08-08 08:08:50 -070046/** We always use per-vertex colors so that rects can be batched across color changes. Sometimes we
47 have explicit local coords and sometimes not. We *could* always provide explicit local coords
48 and just duplicate the positions when the caller hasn't provided a local coord rect, but we
49 haven't seen a use case which frequently switches between local rect and no local rect draws.
50
51 The color param is used to determine whether the opaque hint can be set on the draw state.
52 The caller must populate the vertex colors itself.
53
54 The vertex attrib order is always pos, color, [local coords].
55 */
joshualitt8fc6c2d2014-12-22 15:27:05 -080056static const GrGeometryProcessor* create_rect_gp(bool hasExplicitLocalCoords,
57 GrColor color,
58 const SkMatrix* localMatrix) {
joshualitt5478d422014-11-14 16:00:38 -080059 uint32_t flags = GrDefaultGeoProcFactory::kPosition_GPType |
60 GrDefaultGeoProcFactory::kColor_GPType;
joshualitt8fc6c2d2014-12-22 15:27:05 -080061 flags |= hasExplicitLocalCoords ? GrDefaultGeoProcFactory::kLocalCoord_GPType : 0;
62 if (localMatrix) {
joshualitt8059eb92014-12-29 15:10:07 -080063 return GrDefaultGeoProcFactory::Create(flags, color, SkMatrix::I(), *localMatrix,
64 GrColorIsOpaque(color));
joshualitt8fc6c2d2014-12-22 15:27:05 -080065 } else {
joshualitt8059eb92014-12-29 15:10:07 -080066 return GrDefaultGeoProcFactory::Create(flags, color, SkMatrix::I(), SkMatrix::I(),
67 GrColorIsOpaque(color));
joshualitt8fc6c2d2014-12-22 15:27:05 -080068 }
bsalomon62c447d2014-08-08 08:08:50 -070069}
robertphillips@google.com42903302013-04-20 12:26:07 +000070
cdalton3fc6a2f2014-11-13 11:54:20 -080071static bool path_fill_type_is_winding(const GrStencilSettings& pathStencilSettings) {
72 static const GrStencilSettings::Face pathFace = GrStencilSettings::kFront_Face;
73 bool isWinding = kInvert_StencilOp != pathStencilSettings.passOp(pathFace);
74 if (isWinding) {
75 // Double check that it is in fact winding.
76 SkASSERT(kIncClamp_StencilOp == pathStencilSettings.passOp(pathFace));
77 SkASSERT(kIncClamp_StencilOp == pathStencilSettings.failOp(pathFace));
78 SkASSERT(0x1 != pathStencilSettings.writeMask(pathFace));
79 SkASSERT(!pathStencilSettings.isTwoSided());
80 }
81 return isWinding;
82}
83
joshualitt58773332015-02-23 16:41:42 -080084class RectBatch : public GrBatch {
85public:
86 struct Geometry {
87 GrColor fColor;
88 SkMatrix fViewMatrix;
89 SkRect fRect;
90 bool fHasLocalRect;
91 bool fHasLocalMatrix;
92 SkRect fLocalRect;
93 SkMatrix fLocalMatrix;
94 };
95
96 static GrBatch* Create(const Geometry& geometry) {
97 return SkNEW_ARGS(RectBatch, (geometry));
98 }
99
100 const char* name() const SK_OVERRIDE { return "RectBatch"; }
101
102 void getInvariantOutputColor(GrInitInvariantOutput* out) const SK_OVERRIDE {
103 // When this is called on a batch, there is only one geometry bundle
104 out->setKnownFourComponents(fGeoData[0].fColor);
105 }
106
107 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const SK_OVERRIDE {
108 out->setKnownSingleComponent(0xff);
109 }
110
111 void initBatchTracker(const GrPipelineInfo& init) SK_OVERRIDE {
112 // Handle any color overrides
113 if (init.fColorIgnored) {
114 fGeoData[0].fColor = GrColor_ILLEGAL;
115 } else if (GrColor_ILLEGAL != init.fOverrideColor) {
116 fGeoData[0].fColor = init.fOverrideColor;
117 }
118
119 // setup batch properties
120 fBatch.fColorIgnored = init.fColorIgnored;
121 fBatch.fColor = fGeoData[0].fColor;
122 fBatch.fUsesLocalCoords = init.fUsesLocalCoords;
123 fBatch.fCoverageIgnored = init.fCoverageIgnored;
124 }
125
126 void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) SK_OVERRIDE {
127 // Go to device coords to allow batching across matrix changes
128 SkMatrix invert = SkMatrix::I();
129
130 // if we have a local rect, then we apply the localMatrix directly to the localRect to
131 // generate vertex local coords
132 bool hasExplicitLocalCoords = this->hasLocalRect();
133 if (!hasExplicitLocalCoords) {
134 if (!this->viewMatrix().isIdentity() && !this->viewMatrix().invert(&invert)) {
135 SkDebugf("Could not invert\n");
136 return;
137 }
138
139 if (this->hasLocalMatrix()) {
140 invert.preConcat(this->localMatrix());
141 }
142 }
143
144 SkAutoTUnref<const GrGeometryProcessor> gp(create_rect_gp(hasExplicitLocalCoords,
145 this->color(),
146 &invert));
147
148 batchTarget->initDraw(gp, pipeline);
149
150 // TODO this is hacky, but the only way we have to initialize the GP is to use the
151 // GrPipelineInfo struct so we can generate the correct shader. Once we have GrBatch
152 // everywhere we can remove this nastiness
153 GrPipelineInfo init;
154 init.fColorIgnored = fBatch.fColorIgnored;
155 init.fOverrideColor = GrColor_ILLEGAL;
156 init.fCoverageIgnored = fBatch.fCoverageIgnored;
157 init.fUsesLocalCoords = this->usesLocalCoords();
158 gp->initBatchTracker(batchTarget->currentBatchTracker(), init);
159
160 size_t vertexStride = gp->getVertexStride();
161
162 SkASSERT(hasExplicitLocalCoords ?
163 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordAttr) :
164 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAttr));
165
166 int instanceCount = fGeoData.count();
167 int vertexCount = kVertsPerRect * instanceCount;
168
169 const GrVertexBuffer* vertexBuffer;
170 int firstVertex;
171
172 void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
173 vertexCount,
174 &vertexBuffer,
175 &firstVertex);
176
177 for (int i = 0; i < instanceCount; i++) {
178 const Geometry& args = fGeoData[i];
179
180 intptr_t offset = GrTCast<intptr_t>(vertices) + kVertsPerRect * i * vertexStride;
181 SkPoint* positions = GrTCast<SkPoint*>(offset);
182
183 positions->setRectFan(args.fRect.fLeft, args.fRect.fTop,
184 args.fRect.fRight, args.fRect.fBottom, vertexStride);
185 args.fViewMatrix.mapPointsWithStride(positions, vertexStride, kVertsPerRect);
186
187 if (args.fHasLocalRect) {
188 static const int kLocalOffset = sizeof(SkPoint) + sizeof(GrColor);
189 SkPoint* coords = GrTCast<SkPoint*>(offset + kLocalOffset);
190 coords->setRectFan(args.fLocalRect.fLeft, args.fLocalRect.fTop,
191 args.fLocalRect.fRight, args.fLocalRect.fBottom,
192 vertexStride);
193 if (args.fHasLocalMatrix) {
194 args.fLocalMatrix.mapPointsWithStride(coords, vertexStride, kVertsPerRect);
195 }
196 }
197
198 static const int kColorOffset = sizeof(SkPoint);
199 GrColor* vertColor = GrTCast<GrColor*>(offset + kColorOffset);
200 for (int j = 0; j < 4; ++j) {
201 *vertColor = args.fColor;
202 vertColor = (GrColor*) ((intptr_t) vertColor + vertexStride);
203 }
204 }
205
206 const GrIndexBuffer* quadIndexBuffer = batchTarget->quadIndexBuffer();
207
208 GrDrawTarget::DrawInfo drawInfo;
209 drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType);
210 drawInfo.setStartVertex(0);
211 drawInfo.setStartIndex(0);
212 drawInfo.setVerticesPerInstance(kVertsPerRect);
213 drawInfo.setIndicesPerInstance(kIndicesPerRect);
214 drawInfo.adjustStartVertex(firstVertex);
215 drawInfo.setVertexBuffer(vertexBuffer);
216 drawInfo.setIndexBuffer(quadIndexBuffer);
217
218 int maxInstancesPerDraw = quadIndexBuffer->maxQuads();
219 while (instanceCount) {
220 drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw));
221 drawInfo.setVertexCount(drawInfo.instanceCount() * drawInfo.verticesPerInstance());
222 drawInfo.setIndexCount(drawInfo.instanceCount() * drawInfo.indicesPerInstance());
223
224 batchTarget->draw(drawInfo);
225
226 drawInfo.setStartVertex(drawInfo.startVertex() + drawInfo.vertexCount());
227 instanceCount -= drawInfo.instanceCount();
228 }
229 }
230
231 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
232
233private:
234 RectBatch(const Geometry& geometry) {
235 this->initClassID<RectBatch>();
236 fGeoData.push_back(geometry);
237 }
238
239 GrColor color() const { return fBatch.fColor; }
240 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; }
241 bool colorIgnored() const { return fBatch.fColorIgnored; }
242 const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; }
243 const SkMatrix& localMatrix() const { return fGeoData[0].fLocalMatrix; }
244 bool hasLocalRect() const { return fGeoData[0].fHasLocalRect; }
245 bool hasLocalMatrix() const { return fGeoData[0].fHasLocalMatrix; }
246
247 bool onCombineIfPossible(GrBatch* t) SK_OVERRIDE {
248 RectBatch* that = t->cast<RectBatch>();
249
250 if (this->hasLocalRect() != that->hasLocalRect()) {
251 return false;
252 }
253
254 SkASSERT(this->usesLocalCoords() == that->usesLocalCoords());
255 if (!this->hasLocalRect() && this->usesLocalCoords()) {
256 if (!this->viewMatrix().cheapEqualTo(that->viewMatrix())) {
257 return false;
258 }
259
260 if (this->hasLocalMatrix() != that->hasLocalMatrix()) {
261 return false;
262 }
263
264 if (this->hasLocalMatrix() && !this->localMatrix().cheapEqualTo(that->localMatrix())) {
265 return false;
266 }
267 }
268
269 if (this->color() != that->color()) {
270 fBatch.fColor = GrColor_ILLEGAL;
271 }
272 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin());
273 return true;
274 }
275
276 struct BatchTracker {
277 GrColor fColor;
278 bool fUsesLocalCoords;
279 bool fColorIgnored;
280 bool fCoverageIgnored;
281 };
282
283 const static int kVertsPerRect = 4;
284 const static int kIndicesPerRect = 6;
285
286 BatchTracker fBatch;
287 SkSTArray<1, Geometry, true> fGeoData;
288};
289
egdaniel8dd688b2015-01-22 10:16:09 -0800290void GrInOrderDrawBuffer::onDrawRect(GrPipelineBuilder* pipelineBuilder,
joshualitt2e3b3e32014-12-09 13:31:14 -0800291 GrColor color,
joshualitt8059eb92014-12-29 15:10:07 -0800292 const SkMatrix& viewMatrix,
joshualitt9853cce2014-11-17 14:22:48 -0800293 const SkRect& rect,
commit-bot@chromium.orgfd03d4a2013-07-17 21:39:42 +0000294 const SkRect* localRect,
bsalomon@google.com0406b9e2013-04-02 21:00:15 +0000295 const SkMatrix* localMatrix) {
joshualitt58773332015-02-23 16:41:42 -0800296 RectBatch::Geometry geometry;
297 geometry.fColor = color;
298 geometry.fViewMatrix = viewMatrix;
299 geometry.fRect = rect;
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000300
bsalomon49f085d2014-09-05 13:34:00 -0700301 if (localRect) {
joshualitt58773332015-02-23 16:41:42 -0800302 geometry.fHasLocalRect = true;
303 geometry.fLocalRect = *localRect;
304 } else {
305 geometry.fHasLocalRect = false;
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000306 }
307
joshualitt58773332015-02-23 16:41:42 -0800308 if (localMatrix) {
309 geometry.fHasLocalMatrix = true;
310 geometry.fLocalMatrix = *localMatrix;
311 } else {
312 geometry.fHasLocalMatrix = false;
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000313 }
314
joshualitt58773332015-02-23 16:41:42 -0800315 SkAutoTUnref<GrBatch> batch(RectBatch::Create(geometry));
316
317 SkRect bounds = rect;
318 viewMatrix.mapRect(&bounds);
319 this->drawBatch(pipelineBuilder, batch, &bounds);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000320}
321
robertphillipsdad77942015-03-03 09:28:16 -0800322int GrTargetCommands::concatInstancedDraw(GrInOrderDrawBuffer* iodb,
323 const GrDrawTarget::DrawInfo& info) {
cdalton6819df32014-10-15 13:43:48 -0700324 SkASSERT(!fCmdBuffer.empty());
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000325 SkASSERT(info.isInstanced());
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000326
robertphillips8f9e8162015-03-02 10:12:17 -0800327 const GrIndexBuffer* ib;
robertphillipsdad77942015-03-03 09:28:16 -0800328 if (!iodb->canConcatToIndexBuffer(&ib)) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000329 return 0;
bsalomon@google.com934c5702012-03-20 21:17:58 +0000330 }
robertphillips8f9e8162015-03-02 10:12:17 -0800331
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000332 // Check if there is a draw info that is compatible that uses the same VB from the pool and
333 // the same IB
robertphillipse5e72f12015-02-17 09:14:33 -0800334 if (Cmd::kDraw_Cmd != fCmdBuffer.back().type()) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000335 return 0;
336 }
337
cdalton6819df32014-10-15 13:43:48 -0700338 Draw* draw = static_cast<Draw*>(&fCmdBuffer.back());
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000339
cdalton6819df32014-10-15 13:43:48 -0700340 if (!draw->fInfo.isInstanced() ||
joshualitt4d8da812015-01-28 12:53:54 -0800341 draw->fInfo.primitiveType() != info.primitiveType() ||
cdalton6819df32014-10-15 13:43:48 -0700342 draw->fInfo.verticesPerInstance() != info.verticesPerInstance() ||
343 draw->fInfo.indicesPerInstance() != info.indicesPerInstance() ||
bsalomon371bcbc2014-12-01 08:19:34 -0800344 draw->fInfo.vertexBuffer() != info.vertexBuffer() ||
robertphillips8f9e8162015-03-02 10:12:17 -0800345 draw->fInfo.indexBuffer() != ib) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000346 return 0;
347 }
bsalomon371bcbc2014-12-01 08:19:34 -0800348 if (draw->fInfo.startVertex() + draw->fInfo.vertexCount() != info.startVertex()) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000349 return 0;
350 }
351
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000352 // how many instances can be concat'ed onto draw given the size of the index buffer
robertphillipsdad77942015-03-03 09:28:16 -0800353 int instancesToConcat = iodb->indexCountInCurrentSource() / info.indicesPerInstance();
cdalton6819df32014-10-15 13:43:48 -0700354 instancesToConcat -= draw->fInfo.instanceCount();
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000355 instancesToConcat = SkTMin(instancesToConcat, info.instanceCount());
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000356
cdalton6819df32014-10-15 13:43:48 -0700357 draw->fInfo.adjustInstanceCount(instancesToConcat);
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000358
359 // update last fGpuCmdMarkers to include any additional trace markers that have been added
robertphillipsdad77942015-03-03 09:28:16 -0800360 iodb->recordTraceMarkersIfNecessary(draw);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000361 return instancesToConcat;
bsalomon@google.com934c5702012-03-20 21:17:58 +0000362}
363
egdaniele36914c2015-02-13 09:00:33 -0800364void GrInOrderDrawBuffer::onDraw(const GrGeometryProcessor* gp,
joshualitt9853cce2014-11-17 14:22:48 -0800365 const DrawInfo& info,
egdaniele36914c2015-02-13 09:00:33 -0800366 const PipelineInfo& pipelineInfo) {
robertphillipsdad77942015-03-03 09:28:16 -0800367 GrTargetCommands::Cmd* cmd = fCommands.recordDraw(this, gp, info, pipelineInfo);
368 this->recordTraceMarkersIfNecessary(cmd);
369}
370
371GrTargetCommands::Cmd* GrTargetCommands::recordDraw(
372 GrInOrderDrawBuffer* iodb,
373 const GrGeometryProcessor* gp,
374 const GrDrawTarget::DrawInfo& info,
375 const GrDrawTarget::PipelineInfo& pipelineInfo) {
joshualitt7eb8c7b2014-11-18 14:24:27 -0800376 SkASSERT(info.vertexBuffer() && (!info.isIndexed() || info.indexBuffer()));
joshualitt4d8da812015-01-28 12:53:54 -0800377 this->closeBatch();
378
robertphillipsdad77942015-03-03 09:28:16 -0800379 if (!this->setupPipelineAndShouldDraw(iodb, gp, pipelineInfo)) {
380 return NULL;
bsalomonae59b772014-11-19 08:23:49 -0800381 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000382
bsalomonb3e3a952014-09-19 11:10:40 -0700383 Draw* draw;
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000384 if (info.isInstanced()) {
robertphillipsdad77942015-03-03 09:28:16 -0800385 int instancesConcated = this->concatInstancedDraw(iodb, info);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000386 if (info.instanceCount() > instancesConcated) {
joshualitt54e0c122014-11-19 09:38:51 -0800387 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info));
cdalton6819df32014-10-15 13:43:48 -0700388 draw->fInfo.adjustInstanceCount(-instancesConcated);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000389 } else {
robertphillipsdad77942015-03-03 09:28:16 -0800390 return NULL;
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000391 }
392 } else {
joshualitt54e0c122014-11-19 09:38:51 -0800393 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info));
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000394 }
robertphillipsdad77942015-03-03 09:28:16 -0800395
396 return draw;
commit-bot@chromium.org9b62aa12014-03-25 11:59:40 +0000397}
sugoi@google.com5f74cf82012-12-17 21:16:45 +0000398
joshualitt4d8da812015-01-28 12:53:54 -0800399void GrInOrderDrawBuffer::onDrawBatch(GrBatch* batch,
egdaniele36914c2015-02-13 09:00:33 -0800400 const PipelineInfo& pipelineInfo) {
robertphillipsdad77942015-03-03 09:28:16 -0800401 GrTargetCommands::Cmd* cmd = fCommands.recordDrawBatch(this, batch, pipelineInfo);
402 this->recordTraceMarkersIfNecessary(cmd);
403}
404
405GrTargetCommands::Cmd* GrTargetCommands::recordDrawBatch(
406 GrInOrderDrawBuffer* iodb,
407 GrBatch* batch,
408 const GrDrawTarget::PipelineInfo& pipelineInfo) {
409 if (!this->setupPipelineAndShouldDraw(iodb, batch, pipelineInfo)) {
410 return NULL;
joshualitt4d8da812015-01-28 12:53:54 -0800411 }
412
413 // Check if there is a Batch Draw we can batch with
joshualittcc1ac862015-03-02 11:23:07 -0800414 if (Cmd::kDrawBatch_Cmd != fCmdBuffer.back().type() || !fDrawBatch) {
robertphillips9888b222015-02-27 08:50:34 -0800415 fDrawBatch = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawBatch, (batch, &fBatchTarget));
robertphillipsdad77942015-03-03 09:28:16 -0800416 return fDrawBatch;
joshualitt4d8da812015-01-28 12:53:54 -0800417 }
418
robertphillips7f966f42015-03-02 06:40:12 -0800419 SkASSERT(&fCmdBuffer.back() == fDrawBatch);
420 if (!fDrawBatch->fBatch->combineIfPossible(batch)) {
joshualitt4d8da812015-01-28 12:53:54 -0800421 this->closeBatch();
robertphillips9888b222015-02-27 08:50:34 -0800422 fDrawBatch = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawBatch, (batch, &fBatchTarget));
joshualitt4d8da812015-01-28 12:53:54 -0800423 }
robertphillipsdad77942015-03-03 09:28:16 -0800424
425 return fDrawBatch;
joshualitt4d8da812015-01-28 12:53:54 -0800426}
427
egdaniel8dd688b2015-01-22 10:16:09 -0800428void GrInOrderDrawBuffer::onStencilPath(const GrPipelineBuilder& pipelineBuilder,
joshualitt56995b52014-12-11 15:44:02 -0800429 const GrPathProcessor* pathProc,
joshualitt9853cce2014-11-17 14:22:48 -0800430 const GrPath* path,
bsalomon3e791242014-12-17 13:43:13 -0800431 const GrScissorState& scissorState,
joshualitt2c93efe2014-11-06 12:57:13 -0800432 const GrStencilSettings& stencilSettings) {
robertphillipsdad77942015-03-03 09:28:16 -0800433 GrTargetCommands::Cmd* cmd = fCommands.recordStencilPath(this, pipelineBuilder,
434 pathProc, path, scissorState,
435 stencilSettings);
436 this->recordTraceMarkersIfNecessary(cmd);
437}
438
439GrTargetCommands::Cmd* GrTargetCommands::recordStencilPath(
440 GrInOrderDrawBuffer* iodb,
441 const GrPipelineBuilder& pipelineBuilder,
442 const GrPathProcessor* pathProc,
443 const GrPath* path,
444 const GrScissorState& scissorState,
445 const GrStencilSettings& stencilSettings) {
joshualitt70f00042015-02-06 15:53:59 -0800446 this->closeBatch();
447
bsalomon3e791242014-12-17 13:43:13 -0800448 StencilPath* sp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, StencilPath,
egdaniel8dd688b2015-01-22 10:16:09 -0800449 (path, pipelineBuilder.getRenderTarget()));
joshualitt58773332015-02-23 16:41:42 -0800450
bsalomon3e791242014-12-17 13:43:13 -0800451 sp->fScissor = scissorState;
egdaniel8dd688b2015-01-22 10:16:09 -0800452 sp->fUseHWAA = pipelineBuilder.isHWAntialias();
joshualitt8059eb92014-12-29 15:10:07 -0800453 sp->fViewMatrix = pathProc->viewMatrix();
bsalomon3e791242014-12-17 13:43:13 -0800454 sp->fStencil = stencilSettings;
robertphillipsdad77942015-03-03 09:28:16 -0800455 return sp;
bsalomon@google.com64aef2b2012-06-11 15:36:13 +0000456}
457
egdaniele36914c2015-02-13 09:00:33 -0800458void GrInOrderDrawBuffer::onDrawPath(const GrPathProcessor* pathProc,
joshualitt9853cce2014-11-17 14:22:48 -0800459 const GrPath* path,
joshualitt2c93efe2014-11-06 12:57:13 -0800460 const GrStencilSettings& stencilSettings,
egdaniele36914c2015-02-13 09:00:33 -0800461 const PipelineInfo& pipelineInfo) {
robertphillipsdad77942015-03-03 09:28:16 -0800462 GrTargetCommands::Cmd* cmd = fCommands.recordDrawPath(this, pathProc,
463 path, stencilSettings,
464 pipelineInfo);
465 this->recordTraceMarkersIfNecessary(cmd);
466}
467
468GrTargetCommands::Cmd* GrTargetCommands::recordDrawPath(
469 GrInOrderDrawBuffer* iodb,
470 const GrPathProcessor* pathProc,
471 const GrPath* path,
472 const GrStencilSettings& stencilSettings,
473 const GrDrawTarget::PipelineInfo& pipelineInfo) {
joshualitt4d8da812015-01-28 12:53:54 -0800474 this->closeBatch();
475
egdaniel8dd688b2015-01-22 10:16:09 -0800476 // TODO: Only compare the subset of GrPipelineBuilder relevant to path covering?
robertphillipsdad77942015-03-03 09:28:16 -0800477 if (!this->setupPipelineAndShouldDraw(iodb, pathProc, pipelineInfo)) {
478 return NULL;
bsalomonae59b772014-11-19 08:23:49 -0800479 }
cdalton6819df32014-10-15 13:43:48 -0700480 DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (path));
joshualitt2c93efe2014-11-06 12:57:13 -0800481 dp->fStencilSettings = stencilSettings;
robertphillipsdad77942015-03-03 09:28:16 -0800482 return dp;
commit-bot@chromium.orgc4dc0ad2013-10-09 14:11:33 +0000483}
484
egdaniele36914c2015-02-13 09:00:33 -0800485void GrInOrderDrawBuffer::onDrawPaths(const GrPathProcessor* pathProc,
joshualitt9853cce2014-11-17 14:22:48 -0800486 const GrPathRange* pathRange,
cdalton55b24af2014-11-25 11:00:56 -0800487 const void* indices,
488 PathIndexType indexType,
489 const float transformValues[],
490 PathTransformType transformType,
joshualitt2c93efe2014-11-06 12:57:13 -0800491 int count,
joshualitt2c93efe2014-11-06 12:57:13 -0800492 const GrStencilSettings& stencilSettings,
egdaniele36914c2015-02-13 09:00:33 -0800493 const PipelineInfo& pipelineInfo) {
robertphillipsdad77942015-03-03 09:28:16 -0800494 GrTargetCommands::Cmd* cmd = fCommands.recordDrawPaths(this, pathProc, pathRange,
495 indices, indexType, transformValues,
496 transformType, count,
497 stencilSettings, pipelineInfo);
498 this->recordTraceMarkersIfNecessary(cmd);
499}
500
501GrTargetCommands::Cmd* GrTargetCommands::recordDrawPaths(
502 GrInOrderDrawBuffer* iodb,
503 const GrPathProcessor* pathProc,
504 const GrPathRange* pathRange,
505 const void* indexValues,
506 GrDrawTarget::PathIndexType indexType,
507 const float transformValues[],
508 GrDrawTarget::PathTransformType transformType,
509 int count,
510 const GrStencilSettings& stencilSettings,
511 const GrDrawTarget::PipelineInfo& pipelineInfo) {
bsalomon49f085d2014-09-05 13:34:00 -0700512 SkASSERT(pathRange);
robertphillipsdad77942015-03-03 09:28:16 -0800513 SkASSERT(indexValues);
cdalton55b24af2014-11-25 11:00:56 -0800514 SkASSERT(transformValues);
joshualitt4d8da812015-01-28 12:53:54 -0800515 this->closeBatch();
516
robertphillipsdad77942015-03-03 09:28:16 -0800517 if (!this->setupPipelineAndShouldDraw(iodb, pathProc, pipelineInfo)) {
518 return NULL;
bsalomonae59b772014-11-19 08:23:49 -0800519 }
cdalton6819df32014-10-15 13:43:48 -0700520
robertphillips8f9e8162015-03-02 10:12:17 -0800521 char* savedIndices;
522 float* savedTransforms;
robertphillipsdad77942015-03-03 09:28:16 -0800523
524 iodb->appendIndicesAndTransforms(indexValues, indexType,
robertphillips8f9e8162015-03-02 10:12:17 -0800525 transformValues, transformType,
526 count, &savedIndices, &savedTransforms);
cdalton6819df32014-10-15 13:43:48 -0700527
robertphillipse5e72f12015-02-17 09:14:33 -0800528 if (Cmd::kDrawPaths_Cmd == fCmdBuffer.back().type()) {
cdalton3fc6a2f2014-11-13 11:54:20 -0800529 // The previous command was also DrawPaths. Try to collapse this call into the one
bsalomon371bcbc2014-12-01 08:19:34 -0800530 // before. Note that stenciling all the paths at once, then covering, may not be
cdalton3fc6a2f2014-11-13 11:54:20 -0800531 // equivalent to two separate draw calls if there is overlap. Blending won't work,
532 // and the combined calls may also cancel each other's winding numbers in some
533 // places. For now the winding numbers are only an issue if the fill is even/odd,
534 // because DrawPaths is currently only used for glyphs, and glyphs in the same
535 // font tend to all wind in the same direction.
536 DrawPaths* previous = static_cast<DrawPaths*>(&fCmdBuffer.back());
537 if (pathRange == previous->pathRange() &&
cdalton55b24af2014-11-25 11:00:56 -0800538 indexType == previous->fIndexType &&
539 transformType == previous->fTransformType &&
cdalton3fc6a2f2014-11-13 11:54:20 -0800540 stencilSettings == previous->fStencilSettings &&
541 path_fill_type_is_winding(stencilSettings) &&
egdaniele36914c2015-02-13 09:00:33 -0800542 !pipelineInfo.willBlendWithDst(pathProc)) {
robertphillipsdad77942015-03-03 09:28:16 -0800543 const int indexBytes = GrPathRange::PathIndexSizeInBytes(indexType);
544 const int xformSize = GrPathRendering::PathTransformSize(transformType);
545 if (&previous->fIndices[previous->fCount*indexBytes] == savedIndices &&
546 (0 == xformSize ||
547 &previous->fTransforms[previous->fCount*xformSize] == savedTransforms)) {
548 // Fold this DrawPaths call into the one previous.
549 previous->fCount += count;
550 return NULL;
551 }
cdalton3fc6a2f2014-11-13 11:54:20 -0800552 }
553 }
554
555 DrawPaths* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPaths, (pathRange));
robertphillips9888b222015-02-27 08:50:34 -0800556 dp->fIndices = savedIndices;
cdalton55b24af2014-11-25 11:00:56 -0800557 dp->fIndexType = indexType;
robertphillips9888b222015-02-27 08:50:34 -0800558 dp->fTransforms = savedTransforms;
cdalton55b24af2014-11-25 11:00:56 -0800559 dp->fTransformType = transformType;
560 dp->fCount = count;
joshualitt2c93efe2014-11-06 12:57:13 -0800561 dp->fStencilSettings = stencilSettings;
robertphillipsdad77942015-03-03 09:28:16 -0800562 return dp;
commit-bot@chromium.org9b62aa12014-03-25 11:59:40 +0000563}
564
bsalomon63b21962014-11-05 07:05:34 -0800565void GrInOrderDrawBuffer::onClear(const SkIRect* rect, GrColor color,
566 bool canIgnoreRect, GrRenderTarget* renderTarget) {
robertphillipsdad77942015-03-03 09:28:16 -0800567 GrTargetCommands::Cmd* cmd = fCommands.recordClear(this, rect, color,
568 canIgnoreRect, renderTarget);
569 this->recordTraceMarkersIfNecessary(cmd);
570}
571
572GrTargetCommands::Cmd* GrTargetCommands::recordClear(GrInOrderDrawBuffer* iodb,
573 const SkIRect* rect,
574 GrColor color,
575 bool canIgnoreRect,
576 GrRenderTarget* renderTarget) {
joshualitt9853cce2014-11-17 14:22:48 -0800577 SkASSERT(renderTarget);
joshualitt70f00042015-02-06 15:53:59 -0800578 this->closeBatch();
579
commit-bot@chromium.orgfd03d4a2013-07-17 21:39:42 +0000580 SkIRect r;
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000581 if (NULL == rect) {
582 // We could do something smart and remove previous draws and clears to
583 // the current render target. If we get that smart we have to make sure
584 // those draws aren't read before this clear (render-to-texture).
bsalomon@google.com1b3ce472012-08-17 13:43:08 +0000585 r.setLTRB(0, 0, renderTarget->width(), renderTarget->height());
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000586 rect = &r;
587 }
cdalton6819df32014-10-15 13:43:48 -0700588 Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget));
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000589 GrColorIsPMAssert(color);
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000590 clr->fColor = color;
591 clr->fRect = *rect;
robertphillips@google.com56ce48a2013-10-31 21:44:25 +0000592 clr->fCanIgnoreRect = canIgnoreRect;
robertphillipsdad77942015-03-03 09:28:16 -0800593 return clr;
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000594}
595
joshualitt6db519c2014-10-29 08:48:18 -0700596void GrInOrderDrawBuffer::clearStencilClip(const SkIRect& rect,
597 bool insideClip,
598 GrRenderTarget* renderTarget) {
robertphillipsdad77942015-03-03 09:28:16 -0800599 GrTargetCommands::Cmd* cmd = fCommands.recordClearStencilClip(this, rect,
600 insideClip, renderTarget);
601 this->recordTraceMarkersIfNecessary(cmd);
602}
603
604GrTargetCommands::Cmd* GrTargetCommands::recordClearStencilClip(GrInOrderDrawBuffer* iodb,
605 const SkIRect& rect,
606 bool insideClip,
607 GrRenderTarget* renderTarget) {
joshualitt9853cce2014-11-17 14:22:48 -0800608 SkASSERT(renderTarget);
joshualitt70f00042015-02-06 15:53:59 -0800609 this->closeBatch();
610
joshualitt6db519c2014-10-29 08:48:18 -0700611 ClearStencilClip* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, ClearStencilClip, (renderTarget));
612 clr->fRect = rect;
613 clr->fInsideClip = insideClip;
robertphillipsdad77942015-03-03 09:28:16 -0800614 return clr;
joshualitt6db519c2014-10-29 08:48:18 -0700615}
616
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000617void GrInOrderDrawBuffer::discard(GrRenderTarget* renderTarget) {
618 if (!this->caps()->discardRenderTargetSupport()) {
619 return;
620 }
robertphillipsdad77942015-03-03 09:28:16 -0800621
622 GrTargetCommands::Cmd* cmd = fCommands.recordDiscard(this, renderTarget);
623 this->recordTraceMarkersIfNecessary(cmd);
624}
625
626GrTargetCommands::Cmd* GrTargetCommands::recordDiscard(GrInOrderDrawBuffer* iodb,
627 GrRenderTarget* renderTarget) {
628 SkASSERT(renderTarget);
629 this->closeBatch();
630
cdalton6819df32014-10-15 13:43:48 -0700631 Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget));
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000632 clr->fColor = GrColor_ILLEGAL;
robertphillipsdad77942015-03-03 09:28:16 -0800633 return clr;
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000634}
635
bsalomon371bcbc2014-12-01 08:19:34 -0800636void GrInOrderDrawBuffer::onReset() {
robertphillipsdad77942015-03-03 09:28:16 -0800637 fCommands.reset();
robertphillips9888b222015-02-27 08:50:34 -0800638 fPathIndexBuffer.rewind();
639 fPathTransformBuffer.rewind();
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000640 fGpuCmdMarkers.reset();
robertphillipsdad77942015-03-03 09:28:16 -0800641}
642
643void GrTargetCommands::reset() {
644 fCmdBuffer.reset();
645 fPrevState = NULL;
joshualitt4d8da812015-01-28 12:53:54 -0800646 fDrawBatch = NULL;
reed@google.comac10a2d2010-12-22 21:39:39 +0000647}
648
bsalomon371bcbc2014-12-01 08:19:34 -0800649void GrInOrderDrawBuffer::onFlush() {
robertphillipsdad77942015-03-03 09:28:16 -0800650 fCommands.flush(this);
651 ++fDrawID;
652}
653
654void GrTargetCommands::flush(GrInOrderDrawBuffer* iodb) {
cdalton6819df32014-10-15 13:43:48 -0700655 if (fCmdBuffer.empty()) {
robertphillips@google.com1267fbd2013-07-03 18:37:27 +0000656 return;
reed@google.comac10a2d2010-12-22 21:39:39 +0000657 }
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000658
joshualittc2893c52015-01-28 06:54:30 -0800659 // Updated every time we find a set state cmd to reflect the current state in the playback
660 // stream.
661 SetState* currentState = NULL;
662
joshualitt4d8da812015-01-28 12:53:54 -0800663 // TODO this is temporary while batch is being rolled out
664 this->closeBatch();
robertphillipsdad77942015-03-03 09:28:16 -0800665 iodb->getVertexAllocPool()->unmap();
666 iodb->getIndexAllocPool()->unmap();
joshualitt4d8da812015-01-28 12:53:54 -0800667 fBatchTarget.preFlush();
668
669 currentState = NULL;
670 CmdBuffer::Iter iter(fCmdBuffer);
671
672 int currCmdMarker = 0;
673
robertphillipsdad77942015-03-03 09:28:16 -0800674 GrGpu* gpu = iodb->getGpu();
675
joshualitt7bc18b72015-02-03 16:41:41 -0800676 int i = 0;
cdalton6819df32014-10-15 13:43:48 -0700677 while (iter.next()) {
joshualitt7bc18b72015-02-03 16:41:41 -0800678 i++;
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000679 GrGpuTraceMarker newMarker("", -1);
egdanield78a1682014-07-09 10:41:26 -0700680 SkString traceString;
robertphillipse5e72f12015-02-17 09:14:33 -0800681 if (iter->isTraced()) {
robertphillipsdad77942015-03-03 09:28:16 -0800682 traceString = iodb->getCmdString(currCmdMarker);
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000683 newMarker.fMarker = traceString.c_str();
robertphillipsdad77942015-03-03 09:28:16 -0800684 gpu->addGpuTraceMarker(&newMarker);
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000685 ++currCmdMarker;
686 }
cdalton6819df32014-10-15 13:43:48 -0700687
joshualitt4d8da812015-01-28 12:53:54 -0800688 // TODO temporary hack
robertphillipse5e72f12015-02-17 09:14:33 -0800689 if (Cmd::kDrawBatch_Cmd == iter->type()) {
joshualitt7bc18b72015-02-03 16:41:41 -0800690 DrawBatch* db = reinterpret_cast<DrawBatch*>(iter.get());
691 fBatchTarget.flushNext(db->fBatch->numberOfDraws());
joshualitt4d8da812015-01-28 12:53:54 -0800692 continue;
693 }
694
robertphillipse5e72f12015-02-17 09:14:33 -0800695 if (Cmd::kSetState_Cmd == iter->type()) {
joshualitt9853cce2014-11-17 14:22:48 -0800696 SetState* ss = reinterpret_cast<SetState*>(iter.get());
joshualitt873ad0e2015-01-20 09:08:51 -0800697
robertphillipsdad77942015-03-03 09:28:16 -0800698 // TODO sometimes we have a prim proc, othertimes we have a GrBatch. Eventually we
699 // will only have GrBatch and we can delete this
joshualitt4d8da812015-01-28 12:53:54 -0800700 if (ss->fPrimitiveProcessor) {
robertphillipsdad77942015-03-03 09:28:16 -0800701 gpu->buildProgramDesc(&ss->fDesc, *ss->fPrimitiveProcessor,
702 *ss->getPipeline(),
703 ss->fBatchTracker);
joshualitt4d8da812015-01-28 12:53:54 -0800704 }
joshualitt873ad0e2015-01-20 09:08:51 -0800705 currentState = ss;
joshualittd53a8272014-11-10 16:03:14 -0800706 } else {
robertphillipsdad77942015-03-03 09:28:16 -0800707 iter->execute(gpu, currentState);
joshualittd53a8272014-11-10 16:03:14 -0800708 }
cdalton6819df32014-10-15 13:43:48 -0700709
robertphillipse5e72f12015-02-17 09:14:33 -0800710 if (iter->isTraced()) {
robertphillipsdad77942015-03-03 09:28:16 -0800711 gpu->removeGpuTraceMarker(&newMarker);
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000712 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000713 }
mtkleinf439c772014-10-14 14:29:30 -0700714
joshualitt4d8da812015-01-28 12:53:54 -0800715 // TODO see copious notes about hack
716 fBatchTarget.postFlush();
reed@google.comac10a2d2010-12-22 21:39:39 +0000717}
718
robertphillipsdad77942015-03-03 09:28:16 -0800719void GrTargetCommands::Draw::execute(GrGpu* gpu, const SetState* state) {
joshualitt873ad0e2015-01-20 09:08:51 -0800720 SkASSERT(state);
egdaniele36914c2015-02-13 09:00:33 -0800721 DrawArgs args(state->fPrimitiveProcessor.get(), state->getPipeline(), &state->fDesc,
joshualitt17e73142015-01-21 11:52:36 -0800722 &state->fBatchTracker);
robertphillips9888b222015-02-27 08:50:34 -0800723 gpu->draw(args, fInfo);
cdalton6819df32014-10-15 13:43:48 -0700724}
725
robertphillipsdad77942015-03-03 09:28:16 -0800726void GrTargetCommands::StencilPath::execute(GrGpu* gpu, const SetState*) {
bsalomon3e791242014-12-17 13:43:13 -0800727 GrGpu::StencilPathState state;
728 state.fRenderTarget = fRenderTarget.get();
729 state.fScissor = &fScissor;
730 state.fStencil = &fStencil;
731 state.fUseHWAA = fUseHWAA;
732 state.fViewMatrix = &fViewMatrix;
733
robertphillips9888b222015-02-27 08:50:34 -0800734 gpu->stencilPath(this->path(), state);
cdalton6819df32014-10-15 13:43:48 -0700735}
736
robertphillipsdad77942015-03-03 09:28:16 -0800737void GrTargetCommands::DrawPath::execute(GrGpu* gpu, const SetState* state) {
joshualitt873ad0e2015-01-20 09:08:51 -0800738 SkASSERT(state);
egdaniele36914c2015-02-13 09:00:33 -0800739 DrawArgs args(state->fPrimitiveProcessor.get(), state->getPipeline(), &state->fDesc,
joshualitt17e73142015-01-21 11:52:36 -0800740 &state->fBatchTracker);
robertphillips9888b222015-02-27 08:50:34 -0800741 gpu->drawPath(args, this->path(), fStencilSettings);
cdalton6819df32014-10-15 13:43:48 -0700742}
743
robertphillipsdad77942015-03-03 09:28:16 -0800744void GrTargetCommands::DrawPaths::execute(GrGpu* gpu, const SetState* state) {
joshualitt873ad0e2015-01-20 09:08:51 -0800745 SkASSERT(state);
egdaniele36914c2015-02-13 09:00:33 -0800746 DrawArgs args(state->fPrimitiveProcessor.get(), state->getPipeline(), &state->fDesc,
joshualitt17e73142015-01-21 11:52:36 -0800747 &state->fBatchTracker);
robertphillips9888b222015-02-27 08:50:34 -0800748 gpu->drawPaths(args, this->pathRange(),
749 fIndices, fIndexType,
750 fTransforms, fTransformType,
751 fCount, fStencilSettings);
cdalton6819df32014-10-15 13:43:48 -0700752}
753
robertphillipsdad77942015-03-03 09:28:16 -0800754void GrTargetCommands::DrawBatch::execute(GrGpu*, const SetState* state) {
joshualitt4d8da812015-01-28 12:53:54 -0800755 SkASSERT(state);
robertphillips9888b222015-02-27 08:50:34 -0800756 fBatch->generateGeometry(fBatchTarget, state->getPipeline());
joshualitt4d8da812015-01-28 12:53:54 -0800757}
758
robertphillipsdad77942015-03-03 09:28:16 -0800759void GrTargetCommands::SetState::execute(GrGpu*, const SetState*) {}
cdalton6819df32014-10-15 13:43:48 -0700760
robertphillipsdad77942015-03-03 09:28:16 -0800761void GrTargetCommands::Clear::execute(GrGpu* gpu, const SetState*) {
cdalton6819df32014-10-15 13:43:48 -0700762 if (GrColor_ILLEGAL == fColor) {
robertphillips9888b222015-02-27 08:50:34 -0800763 gpu->discard(this->renderTarget());
cdalton6819df32014-10-15 13:43:48 -0700764 } else {
robertphillips9888b222015-02-27 08:50:34 -0800765 gpu->clear(&fRect, fColor, fCanIgnoreRect, this->renderTarget());
cdalton6819df32014-10-15 13:43:48 -0700766 }
767}
768
robertphillipsdad77942015-03-03 09:28:16 -0800769void GrTargetCommands::ClearStencilClip::execute(GrGpu* gpu, const SetState*) {
robertphillips9888b222015-02-27 08:50:34 -0800770 gpu->clearStencilClip(fRect, fInsideClip, this->renderTarget());
joshualitt6db519c2014-10-29 08:48:18 -0700771}
772
robertphillipsdad77942015-03-03 09:28:16 -0800773void GrTargetCommands::CopySurface::execute(GrGpu* gpu, const SetState*) {
robertphillips9888b222015-02-27 08:50:34 -0800774 gpu->copySurface(this->dst(), this->src(), fSrcRect, fDstPoint);
cdalton6819df32014-10-15 13:43:48 -0700775}
776
bsalomonf90a02b2014-11-26 12:28:00 -0800777bool GrInOrderDrawBuffer::onCopySurface(GrSurface* dst,
778 GrSurface* src,
779 const SkIRect& srcRect,
780 const SkIPoint& dstPoint) {
robertphillipsdad77942015-03-03 09:28:16 -0800781 GrTargetCommands::Cmd* cmd = fCommands.recordCopySurface(this, dst, src,
782 srcRect, dstPoint);
783 this->recordTraceMarkersIfNecessary(cmd);
784 return SkToBool(cmd);
785}
786
787GrTargetCommands::Cmd* GrTargetCommands::recordCopySurface(GrInOrderDrawBuffer* iodb,
788 GrSurface* dst,
789 GrSurface* src,
790 const SkIRect& srcRect,
791 const SkIPoint& dstPoint) {
792 if (iodb->getGpu()->canCopySurface(dst, src, srcRect, dstPoint)) {
joshualitt95964c62015-02-11 13:45:50 -0800793 this->closeBatch();
cdalton6819df32014-10-15 13:43:48 -0700794 CopySurface* cs = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, CopySurface, (dst, src));
bsalomon@google.com116ad842013-04-09 15:38:19 +0000795 cs->fSrcRect = srcRect;
796 cs->fDstPoint = dstPoint;
robertphillipsdad77942015-03-03 09:28:16 -0800797 return cs;
bsalomon@google.com116ad842013-04-09 15:38:19 +0000798 }
robertphillipsdad77942015-03-03 09:28:16 -0800799 return NULL;
bsalomon@google.com116ad842013-04-09 15:38:19 +0000800}
801
robertphillipsdad77942015-03-03 09:28:16 -0800802bool GrTargetCommands::setupPipelineAndShouldDraw(GrInOrderDrawBuffer* iodb,
803 const GrPrimitiveProcessor* primProc,
804 const GrDrawTarget::PipelineInfo& pipelineInfo) {
egdaniele36914c2015-02-13 09:00:33 -0800805 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (primProc));
robertphillipsdad77942015-03-03 09:28:16 -0800806 iodb->setupPipeline(pipelineInfo, ss->pipelineLocation());
egdaniele36914c2015-02-13 09:00:33 -0800807
808 if (ss->getPipeline()->mustSkip()) {
bsalomon932f8662014-11-24 06:47:48 -0800809 fCmdBuffer.pop_back();
bsalomonae59b772014-11-19 08:23:49 -0800810 return false;
811 }
joshualitt873ad0e2015-01-20 09:08:51 -0800812
813 ss->fPrimitiveProcessor->initBatchTracker(&ss->fBatchTracker,
egdaniele36914c2015-02-13 09:00:33 -0800814 ss->getPipeline()->getInitBatchTracker());
joshualitt873ad0e2015-01-20 09:08:51 -0800815
joshualitt4d8da812015-01-28 12:53:54 -0800816 if (fPrevState && fPrevState->fPrimitiveProcessor.get() &&
joshualitt873ad0e2015-01-20 09:08:51 -0800817 fPrevState->fPrimitiveProcessor->canMakeEqual(fPrevState->fBatchTracker,
818 *ss->fPrimitiveProcessor,
819 ss->fBatchTracker) &&
egdaniele36914c2015-02-13 09:00:33 -0800820 fPrevState->getPipeline()->isEqual(*ss->getPipeline())) {
bsalomon932f8662014-11-24 06:47:48 -0800821 fCmdBuffer.pop_back();
822 } else {
joshualitt873ad0e2015-01-20 09:08:51 -0800823 fPrevState = ss;
robertphillipsdad77942015-03-03 09:28:16 -0800824 iodb->recordTraceMarkersIfNecessary(ss);
bsalomon838f62d2014-08-05 07:15:57 -0700825 }
bsalomonae59b772014-11-19 08:23:49 -0800826 return true;
reed@google.comac10a2d2010-12-22 21:39:39 +0000827}
828
robertphillipsdad77942015-03-03 09:28:16 -0800829bool GrTargetCommands::setupPipelineAndShouldDraw(GrInOrderDrawBuffer* iodb,
830 GrBatch* batch,
831 const GrDrawTarget::PipelineInfo& pipelineInfo) {
egdaniele36914c2015-02-13 09:00:33 -0800832 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, ());
robertphillipsdad77942015-03-03 09:28:16 -0800833 iodb->setupPipeline(pipelineInfo, ss->pipelineLocation());
egdaniele36914c2015-02-13 09:00:33 -0800834
835 if (ss->getPipeline()->mustSkip()) {
joshualitt4d8da812015-01-28 12:53:54 -0800836 fCmdBuffer.pop_back();
837 return false;
838 }
839
egdaniele36914c2015-02-13 09:00:33 -0800840 batch->initBatchTracker(ss->getPipeline()->getInitBatchTracker());
joshualitt4d8da812015-01-28 12:53:54 -0800841
842 if (fPrevState && !fPrevState->fPrimitiveProcessor.get() &&
egdaniele36914c2015-02-13 09:00:33 -0800843 fPrevState->getPipeline()->isEqual(*ss->getPipeline())) {
joshualitt4d8da812015-01-28 12:53:54 -0800844 fCmdBuffer.pop_back();
845 } else {
846 this->closeBatch();
847 fPrevState = ss;
robertphillipsdad77942015-03-03 09:28:16 -0800848 iodb->recordTraceMarkersIfNecessary(ss);
joshualitt4d8da812015-01-28 12:53:54 -0800849 }
850 return true;
851}
852
robertphillipsdad77942015-03-03 09:28:16 -0800853void GrInOrderDrawBuffer::recordTraceMarkersIfNecessary(GrTargetCommands::Cmd* cmd) {
robertphillips7f966f42015-03-02 06:40:12 -0800854 if (!cmd) {
855 return;
856 }
mtkleinf439c772014-10-14 14:29:30 -0700857 const GrTraceMarkerSet& activeTraceMarkers = this->getActiveTraceMarkers();
858 if (activeTraceMarkers.count() > 0) {
robertphillips7f966f42015-03-02 06:40:12 -0800859 if (cmd->isTraced()) {
860 fGpuCmdMarkers.back().addSet(activeTraceMarkers);
861 } else {
862 cmd->makeTraced();
863 fGpuCmdMarkers.push_back(activeTraceMarkers);
864 }
mtklein07894c42014-10-13 14:00:42 -0700865 }
mtklein07894c42014-10-13 14:00:42 -0700866}
joshualitt4d8da812015-01-28 12:53:54 -0800867
joshualitt4d8da812015-01-28 12:53:54 -0800868void GrInOrderDrawBuffer::willReserveVertexAndIndexSpace(int vertexCount,
869 size_t vertexStride,
870 int indexCount) {
robertphillipsdad77942015-03-03 09:28:16 -0800871 fCommands.closeBatch();
joshualitt4d8da812015-01-28 12:53:54 -0800872
robertphillips54fac8b2015-02-16 09:35:50 -0800873 this->INHERITED::willReserveVertexAndIndexSpace(vertexCount, vertexStride, indexCount);
joshualitt4d8da812015-01-28 12:53:54 -0800874}