blob: 1cc6ec39d3297dcd8325ee8c8c36fb0cc91c56d1 [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
joshualittd5a7db42015-01-27 15:39:06 -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)
joshualittd5a7db42015-01-27 15:39:06 -080024 , fDrawID(0)
25 , fBatchTarget(gpu, vertexPool, indexPool)
26 , fFlushBatches(false) {
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
bsalomon@google.comd62e88e2013-02-01 14:19:27 +000041namespace {
42void get_vertex_bounds(const void* vertices,
43 size_t vertexSize,
44 int vertexCount,
45 SkRect* bounds) {
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +000046 SkASSERT(vertexSize >= sizeof(SkPoint));
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +000047 SkASSERT(vertexCount > 0);
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +000048 const SkPoint* point = static_cast<const SkPoint*>(vertices);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +000049 bounds->fLeft = bounds->fRight = point->fX;
50 bounds->fTop = bounds->fBottom = point->fY;
51 for (int i = 1; i < vertexCount; ++i) {
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +000052 point = reinterpret_cast<SkPoint*>(reinterpret_cast<intptr_t>(point) + vertexSize);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +000053 bounds->growToInclude(point->fX, point->fY);
54 }
55}
bsalomon@google.com934c5702012-03-20 21:17:58 +000056}
57
bsalomon62c447d2014-08-08 08:08:50 -070058/** We always use per-vertex colors so that rects can be batched across color changes. Sometimes we
59 have explicit local coords and sometimes not. We *could* always provide explicit local coords
60 and just duplicate the positions when the caller hasn't provided a local coord rect, but we
61 haven't seen a use case which frequently switches between local rect and no local rect draws.
62
63 The color param is used to determine whether the opaque hint can be set on the draw state.
64 The caller must populate the vertex colors itself.
65
66 The vertex attrib order is always pos, color, [local coords].
67 */
joshualitt8fc6c2d2014-12-22 15:27:05 -080068static const GrGeometryProcessor* create_rect_gp(bool hasExplicitLocalCoords,
69 GrColor color,
70 const SkMatrix* localMatrix) {
joshualitt5478d422014-11-14 16:00:38 -080071 uint32_t flags = GrDefaultGeoProcFactory::kPosition_GPType |
72 GrDefaultGeoProcFactory::kColor_GPType;
joshualitt8fc6c2d2014-12-22 15:27:05 -080073 flags |= hasExplicitLocalCoords ? GrDefaultGeoProcFactory::kLocalCoord_GPType : 0;
74 if (localMatrix) {
joshualitt8059eb92014-12-29 15:10:07 -080075 return GrDefaultGeoProcFactory::Create(flags, color, SkMatrix::I(), *localMatrix,
76 GrColorIsOpaque(color));
joshualitt8fc6c2d2014-12-22 15:27:05 -080077 } else {
joshualitt8059eb92014-12-29 15:10:07 -080078 return GrDefaultGeoProcFactory::Create(flags, color, SkMatrix::I(), SkMatrix::I(),
79 GrColorIsOpaque(color));
joshualitt8fc6c2d2014-12-22 15:27:05 -080080 }
bsalomon62c447d2014-08-08 08:08:50 -070081}
robertphillips@google.com42903302013-04-20 12:26:07 +000082
cdalton3fc6a2f2014-11-13 11:54:20 -080083static bool path_fill_type_is_winding(const GrStencilSettings& pathStencilSettings) {
84 static const GrStencilSettings::Face pathFace = GrStencilSettings::kFront_Face;
85 bool isWinding = kInvert_StencilOp != pathStencilSettings.passOp(pathFace);
86 if (isWinding) {
87 // Double check that it is in fact winding.
88 SkASSERT(kIncClamp_StencilOp == pathStencilSettings.passOp(pathFace));
89 SkASSERT(kIncClamp_StencilOp == pathStencilSettings.failOp(pathFace));
90 SkASSERT(0x1 != pathStencilSettings.writeMask(pathFace));
91 SkASSERT(!pathStencilSettings.isTwoSided());
92 }
93 return isWinding;
94}
95
96template<typename T> static void reset_data_buffer(SkTDArray<T>* buffer, int minReserve) {
97 // Assume the next time this buffer fills up it will use approximately the same amount
98 // of space as last time. Only resize if we're using less than a third of the
99 // allocated space, and leave enough for 50% growth over last time.
100 if (3 * buffer->count() < buffer->reserved() && buffer->reserved() > minReserve) {
101 int reserve = SkTMax(minReserve, buffer->count() * 3 / 2);
102 buffer->reset();
103 buffer->setReserve(reserve);
104 } else {
105 buffer->rewind();
106 }
107}
108
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000109enum {
110 kTraceCmdBit = 0x80,
111 kCmdMask = 0x7f,
112};
113
bsalomon62c447d2014-08-08 08:08:50 -0700114static inline uint8_t add_trace_bit(uint8_t cmd) { return cmd | kTraceCmdBit; }
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000115
bsalomon62c447d2014-08-08 08:08:50 -0700116static inline uint8_t strip_trace_bit(uint8_t cmd) { return cmd & kCmdMask; }
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000117
bsalomon62c447d2014-08-08 08:08:50 -0700118static inline bool cmd_has_trace_marker(uint8_t cmd) { return SkToBool(cmd & kTraceCmdBit); }
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000119
egdaniel8dd688b2015-01-22 10:16:09 -0800120void GrInOrderDrawBuffer::onDrawRect(GrPipelineBuilder* pipelineBuilder,
joshualitt2e3b3e32014-12-09 13:31:14 -0800121 GrColor color,
joshualitt8059eb92014-12-29 15:10:07 -0800122 const SkMatrix& viewMatrix,
joshualitt9853cce2014-11-17 14:22:48 -0800123 const SkRect& rect,
commit-bot@chromium.orgfd03d4a2013-07-17 21:39:42 +0000124 const SkRect* localRect,
bsalomon@google.com0406b9e2013-04-02 21:00:15 +0000125 const SkMatrix* localMatrix) {
egdaniel8dd688b2015-01-22 10:16:09 -0800126 GrPipelineBuilder::AutoRestoreEffects are(pipelineBuilder);
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000127
joshualittd27f73e2014-12-29 07:43:36 -0800128 // Go to device coords to allow batching across matrix changes
joshualittd27f73e2014-12-29 07:43:36 -0800129 SkMatrix invert = SkMatrix::I();
130
131 // if we have a local rect, then we apply the localMatrix directly to the localRect to generate
132 // vertex local coords
joshualitt8fc6c2d2014-12-22 15:27:05 -0800133 bool hasExplicitLocalCoords = SkToBool(localRect);
joshualittd27f73e2014-12-29 07:43:36 -0800134 if (!hasExplicitLocalCoords) {
joshualitt8059eb92014-12-29 15:10:07 -0800135 if (!viewMatrix.isIdentity() && !viewMatrix.invert(&invert)) {
joshualittd27f73e2014-12-29 07:43:36 -0800136 SkDebugf("Could not invert\n");
137 return;
138 }
139
140 if (localMatrix) {
141 invert.preConcat(*localMatrix);
142 }
143 }
144
145 SkAutoTUnref<const GrGeometryProcessor> gp(create_rect_gp(hasExplicitLocalCoords,
146 color,
147 &invert));
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000148
joshualitt56995b52014-12-11 15:44:02 -0800149 size_t vstride = gp->getVertexStride();
joshualitt2dd1ae02014-12-03 06:24:10 -0800150 SkASSERT(vstride == sizeof(SkPoint) + sizeof(GrColor) + (SkToBool(localRect) ? sizeof(SkPoint) :
151 0));
152 AutoReleaseGeometry geo(this, 4, vstride, 0);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000153 if (!geo.succeeded()) {
tfarina38406c82014-10-31 07:11:12 -0700154 SkDebugf("Failed to get space for vertices!\n");
bsalomon@google.com934c5702012-03-20 21:17:58 +0000155 return;
156 }
157
joshualitt8059eb92014-12-29 15:10:07 -0800158 geo.positions()->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, vstride);
159 viewMatrix.mapPointsWithStride(geo.positions(), vstride, 4);
160
jvanverth@google.com39768252013-02-14 15:25:44 +0000161 // When the caller has provided an explicit source rect for a stage then we don't want to
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000162 // modify that stage's matrix. Otherwise if the effect is generating its source rect from
joshualitt8059eb92014-12-29 15:10:07 -0800163 // the vertex positions then we have to account for the view matrix
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000164 SkRect devBounds;
joshualitt8059eb92014-12-29 15:10:07 -0800165
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000166 // since we already computed the dev verts, set the bounds hint. This will help us avoid
167 // unnecessary clipping in our onDraw().
egdaniel7b3d5ee2014-08-28 05:41:14 -0700168 get_vertex_bounds(geo.vertices(), vstride, 4, &devBounds);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000169
bsalomon49f085d2014-09-05 13:34:00 -0700170 if (localRect) {
bsalomon62c447d2014-08-08 08:08:50 -0700171 static const int kLocalOffset = sizeof(SkPoint) + sizeof(GrColor);
172 SkPoint* coords = GrTCast<SkPoint*>(GrTCast<intptr_t>(geo.vertices()) + kLocalOffset);
bsalomon@google.comc7818882013-03-20 19:19:53 +0000173 coords->setRectFan(localRect->fLeft, localRect->fTop,
174 localRect->fRight, localRect->fBottom,
egdaniel7b3d5ee2014-08-28 05:41:14 -0700175 vstride);
bsalomon49f085d2014-09-05 13:34:00 -0700176 if (localMatrix) {
egdaniel7b3d5ee2014-08-28 05:41:14 -0700177 localMatrix->mapPointsWithStride(coords, vstride, 4);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000178 }
179 }
180
bsalomon62c447d2014-08-08 08:08:50 -0700181 static const int kColorOffset = sizeof(SkPoint);
182 GrColor* vertColor = GrTCast<GrColor*>(GrTCast<intptr_t>(geo.vertices()) + kColorOffset);
183 for (int i = 0; i < 4; ++i) {
184 *vertColor = color;
egdaniel7b3d5ee2014-08-28 05:41:14 -0700185 vertColor = (GrColor*) ((intptr_t) vertColor + vstride);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000186 }
187
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000188 this->setIndexSourceToBuffer(this->getContext()->getQuadIndexBuffer());
egdaniel8dd688b2015-01-22 10:16:09 -0800189 this->drawIndexedInstances(pipelineBuilder, gp, kTriangles_GrPrimitiveType, 1, 4, 6,
190 &devBounds);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000191}
192
egdaniel8dd688b2015-01-22 10:16:09 -0800193int GrInOrderDrawBuffer::concatInstancedDraw(const GrPipelineBuilder& pipelineBuilder,
194 const DrawInfo& info) {
cdalton6819df32014-10-15 13:43:48 -0700195 SkASSERT(!fCmdBuffer.empty());
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000196 SkASSERT(info.isInstanced());
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000197
bsalomon@google.com934c5702012-03-20 21:17:58 +0000198 const GeometrySrcState& geomSrc = this->getGeomSrc();
199
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000200 // we only attempt to concat the case when reserved verts are used with a client-specified index
201 // buffer. To make this work with client-specified VBs we'd need to know if the VB was updated
202 // between draws.
203 if (kReserved_GeometrySrcType != geomSrc.fVertexSrc ||
204 kBuffer_GeometrySrcType != geomSrc.fIndexSrc) {
205 return 0;
bsalomon@google.com934c5702012-03-20 21:17:58 +0000206 }
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000207 // Check if there is a draw info that is compatible that uses the same VB from the pool and
208 // the same IB
cdalton6819df32014-10-15 13:43:48 -0700209 if (kDraw_Cmd != strip_trace_bit(fCmdBuffer.back().fType)) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000210 return 0;
211 }
212
cdalton6819df32014-10-15 13:43:48 -0700213 Draw* draw = static_cast<Draw*>(&fCmdBuffer.back());
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000214
cdalton6819df32014-10-15 13:43:48 -0700215 if (!draw->fInfo.isInstanced() ||
joshualittd5a7db42015-01-27 15:39:06 -0800216 draw->fInfo.primitiveType() != info.primitiveType() ||
cdalton6819df32014-10-15 13:43:48 -0700217 draw->fInfo.verticesPerInstance() != info.verticesPerInstance() ||
218 draw->fInfo.indicesPerInstance() != info.indicesPerInstance() ||
bsalomon371bcbc2014-12-01 08:19:34 -0800219 draw->fInfo.vertexBuffer() != info.vertexBuffer() ||
joshualitt54e0c122014-11-19 09:38:51 -0800220 draw->fInfo.indexBuffer() != geomSrc.fIndexBuffer) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000221 return 0;
222 }
bsalomon371bcbc2014-12-01 08:19:34 -0800223 if (draw->fInfo.startVertex() + draw->fInfo.vertexCount() != info.startVertex()) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000224 return 0;
225 }
226
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000227 // how many instances can be concat'ed onto draw given the size of the index buffer
228 int instancesToConcat = this->indexCountInCurrentSource() / info.indicesPerInstance();
cdalton6819df32014-10-15 13:43:48 -0700229 instancesToConcat -= draw->fInfo.instanceCount();
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000230 instancesToConcat = SkTMin(instancesToConcat, info.instanceCount());
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000231
cdalton6819df32014-10-15 13:43:48 -0700232 draw->fInfo.adjustInstanceCount(instancesToConcat);
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000233
234 // update last fGpuCmdMarkers to include any additional trace markers that have been added
235 if (this->getActiveTraceMarkers().count() > 0) {
cdalton6819df32014-10-15 13:43:48 -0700236 if (cmd_has_trace_marker(draw->fType)) {
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000237 fGpuCmdMarkers.back().addSet(this->getActiveTraceMarkers());
238 } else {
239 fGpuCmdMarkers.push_back(this->getActiveTraceMarkers());
cdalton6819df32014-10-15 13:43:48 -0700240 draw->fType = add_trace_bit(draw->fType);
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000241 }
242 }
243
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000244 return instancesToConcat;
bsalomon@google.com934c5702012-03-20 21:17:58 +0000245}
246
egdaniel8dd688b2015-01-22 10:16:09 -0800247void GrInOrderDrawBuffer::onDraw(const GrPipelineBuilder& pipelineBuilder,
joshualitt56995b52014-12-11 15:44:02 -0800248 const GrGeometryProcessor* gp,
joshualitt9853cce2014-11-17 14:22:48 -0800249 const DrawInfo& info,
bsalomon3e791242014-12-17 13:43:13 -0800250 const GrScissorState& scissorState,
joshualitt9176e2c2014-11-20 07:28:52 -0800251 const GrDeviceCoordTexture* dstCopy) {
joshualitt7eb8c7b2014-11-18 14:24:27 -0800252 SkASSERT(info.vertexBuffer() && (!info.isIndexed() || info.indexBuffer()));
253
egdaniel8dd688b2015-01-22 10:16:09 -0800254 if (!this->recordStateAndShouldDraw(pipelineBuilder, gp, scissorState, dstCopy)) {
bsalomonae59b772014-11-19 08:23:49 -0800255 return;
256 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000257
bsalomonb3e3a952014-09-19 11:10:40 -0700258 Draw* draw;
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000259 if (info.isInstanced()) {
egdaniel8dd688b2015-01-22 10:16:09 -0800260 int instancesConcated = this->concatInstancedDraw(pipelineBuilder, info);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000261 if (info.instanceCount() > instancesConcated) {
joshualitt54e0c122014-11-19 09:38:51 -0800262 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info));
cdalton6819df32014-10-15 13:43:48 -0700263 draw->fInfo.adjustInstanceCount(-instancesConcated);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000264 } else {
265 return;
266 }
267 } else {
joshualitt54e0c122014-11-19 09:38:51 -0800268 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info));
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000269 }
cdalton6819df32014-10-15 13:43:48 -0700270 this->recordTraceMarkersIfNecessary();
commit-bot@chromium.org9b62aa12014-03-25 11:59:40 +0000271}
sugoi@google.com5f74cf82012-12-17 21:16:45 +0000272
joshualittd5a7db42015-01-27 15:39:06 -0800273void GrInOrderDrawBuffer::onDrawBatch(GrBatch* batch,
274 const GrPipelineBuilder& pipelineBuilder,
275 const GrScissorState& scissorState,
276 const GrDeviceCoordTexture* dstCopy) {
277 if (!this->recordStateAndShouldDraw(batch, pipelineBuilder, scissorState, dstCopy)) {
278 return;
279 }
280
281 // TODO hack until batch is everywhere
282 fFlushBatches = true;
283
284 // Check if there is a Batch Draw we can batch with
285 if (kDrawBatch_Cmd != strip_trace_bit(fCmdBuffer.back().fType)) {
286 GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawBatch, (batch));
287 return;
288 }
289
290 DrawBatch* draw = static_cast<DrawBatch*>(&fCmdBuffer.back());
291 if (draw->fBatch->combineIfPossible(batch)) {
292 return;
293 } else {
294 GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawBatch, (batch));
295 }
296 this->recordTraceMarkersIfNecessary();
297}
298
egdaniel8dd688b2015-01-22 10:16:09 -0800299void GrInOrderDrawBuffer::onStencilPath(const GrPipelineBuilder& pipelineBuilder,
joshualitt56995b52014-12-11 15:44:02 -0800300 const GrPathProcessor* pathProc,
joshualitt9853cce2014-11-17 14:22:48 -0800301 const GrPath* path,
bsalomon3e791242014-12-17 13:43:13 -0800302 const GrScissorState& scissorState,
joshualitt2c93efe2014-11-06 12:57:13 -0800303 const GrStencilSettings& stencilSettings) {
bsalomon3e791242014-12-17 13:43:13 -0800304 StencilPath* sp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, StencilPath,
egdaniel8dd688b2015-01-22 10:16:09 -0800305 (path, pipelineBuilder.getRenderTarget()));
bsalomon3e791242014-12-17 13:43:13 -0800306 sp->fScissor = scissorState;
egdaniel8dd688b2015-01-22 10:16:09 -0800307 sp->fUseHWAA = pipelineBuilder.isHWAntialias();
joshualitt8059eb92014-12-29 15:10:07 -0800308 sp->fViewMatrix = pathProc->viewMatrix();
bsalomon3e791242014-12-17 13:43:13 -0800309 sp->fStencil = stencilSettings;
cdalton6819df32014-10-15 13:43:48 -0700310 this->recordTraceMarkersIfNecessary();
bsalomon@google.com64aef2b2012-06-11 15:36:13 +0000311}
312
egdaniel8dd688b2015-01-22 10:16:09 -0800313void GrInOrderDrawBuffer::onDrawPath(const GrPipelineBuilder& pipelineBuilder,
joshualitt56995b52014-12-11 15:44:02 -0800314 const GrPathProcessor* pathProc,
joshualitt9853cce2014-11-17 14:22:48 -0800315 const GrPath* path,
bsalomon3e791242014-12-17 13:43:13 -0800316 const GrScissorState& scissorState,
joshualitt2c93efe2014-11-06 12:57:13 -0800317 const GrStencilSettings& stencilSettings,
joshualitt92e496f2014-10-31 13:56:50 -0700318 const GrDeviceCoordTexture* dstCopy) {
egdaniel8dd688b2015-01-22 10:16:09 -0800319 // TODO: Only compare the subset of GrPipelineBuilder relevant to path covering?
320 if (!this->recordStateAndShouldDraw(pipelineBuilder, pathProc, scissorState, dstCopy)) {
bsalomonae59b772014-11-19 08:23:49 -0800321 return;
322 }
cdalton6819df32014-10-15 13:43:48 -0700323 DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (path));
joshualitt2c93efe2014-11-06 12:57:13 -0800324 dp->fStencilSettings = stencilSettings;
cdalton6819df32014-10-15 13:43:48 -0700325 this->recordTraceMarkersIfNecessary();
commit-bot@chromium.orgc4dc0ad2013-10-09 14:11:33 +0000326}
327
egdaniel8dd688b2015-01-22 10:16:09 -0800328void GrInOrderDrawBuffer::onDrawPaths(const GrPipelineBuilder& pipelineBuilder,
joshualitt56995b52014-12-11 15:44:02 -0800329 const GrPathProcessor* pathProc,
joshualitt9853cce2014-11-17 14:22:48 -0800330 const GrPathRange* pathRange,
cdalton55b24af2014-11-25 11:00:56 -0800331 const void* indices,
332 PathIndexType indexType,
333 const float transformValues[],
334 PathTransformType transformType,
joshualitt2c93efe2014-11-06 12:57:13 -0800335 int count,
bsalomon3e791242014-12-17 13:43:13 -0800336 const GrScissorState& scissorState,
joshualitt2c93efe2014-11-06 12:57:13 -0800337 const GrStencilSettings& stencilSettings,
joshualitt92e496f2014-10-31 13:56:50 -0700338 const GrDeviceCoordTexture* dstCopy) {
bsalomon49f085d2014-09-05 13:34:00 -0700339 SkASSERT(pathRange);
340 SkASSERT(indices);
cdalton55b24af2014-11-25 11:00:56 -0800341 SkASSERT(transformValues);
commit-bot@chromium.org9b62aa12014-03-25 11:59:40 +0000342
egdaniel8dd688b2015-01-22 10:16:09 -0800343 if (!this->recordStateAndShouldDraw(pipelineBuilder, pathProc, scissorState, dstCopy)) {
bsalomonae59b772014-11-19 08:23:49 -0800344 return;
345 }
cdalton6819df32014-10-15 13:43:48 -0700346
cdalton55b24af2014-11-25 11:00:56 -0800347 int indexBytes = GrPathRange::PathIndexSizeInBytes(indexType);
348 if (int misalign = fPathIndexBuffer.count() % indexBytes) {
349 // Add padding to the index buffer so the indices are aligned properly.
350 fPathIndexBuffer.append(indexBytes - misalign);
351 }
352
353 char* savedIndices = fPathIndexBuffer.append(count * indexBytes,
354 reinterpret_cast<const char*>(indices));
355 float* savedTransforms = fPathTransformBuffer.append(
356 count * GrPathRendering::PathTransformSize(transformType),
357 transformValues);
cdalton6819df32014-10-15 13:43:48 -0700358
cdalton3fc6a2f2014-11-13 11:54:20 -0800359 if (kDrawPaths_Cmd == strip_trace_bit(fCmdBuffer.back().fType)) {
360 // The previous command was also DrawPaths. Try to collapse this call into the one
bsalomon371bcbc2014-12-01 08:19:34 -0800361 // before. Note that stenciling all the paths at once, then covering, may not be
cdalton3fc6a2f2014-11-13 11:54:20 -0800362 // equivalent to two separate draw calls if there is overlap. Blending won't work,
363 // and the combined calls may also cancel each other's winding numbers in some
364 // places. For now the winding numbers are only an issue if the fill is even/odd,
365 // because DrawPaths is currently only used for glyphs, and glyphs in the same
366 // font tend to all wind in the same direction.
367 DrawPaths* previous = static_cast<DrawPaths*>(&fCmdBuffer.back());
368 if (pathRange == previous->pathRange() &&
cdalton55b24af2014-11-25 11:00:56 -0800369 indexType == previous->fIndexType &&
370 transformType == previous->fTransformType &&
cdalton3fc6a2f2014-11-13 11:54:20 -0800371 stencilSettings == previous->fStencilSettings &&
372 path_fill_type_is_winding(stencilSettings) &&
egdaniel8dd688b2015-01-22 10:16:09 -0800373 !pipelineBuilder.willBlendWithDst(pathProc)) {
cdalton3fc6a2f2014-11-13 11:54:20 -0800374 // Fold this DrawPaths call into the one previous.
375 previous->fCount += count;
376 return;
377 }
378 }
379
380 DrawPaths* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPaths, (pathRange));
bsalomonef3fcd82014-12-12 08:51:38 -0800381 dp->fIndicesLocation = SkToU32(savedIndices - fPathIndexBuffer.begin());
cdalton55b24af2014-11-25 11:00:56 -0800382 dp->fIndexType = indexType;
bsalomonef3fcd82014-12-12 08:51:38 -0800383 dp->fTransformsLocation = SkToU32(savedTransforms - fPathTransformBuffer.begin());
cdalton55b24af2014-11-25 11:00:56 -0800384 dp->fTransformType = transformType;
385 dp->fCount = count;
joshualitt2c93efe2014-11-06 12:57:13 -0800386 dp->fStencilSettings = stencilSettings;
cdalton6819df32014-10-15 13:43:48 -0700387
388 this->recordTraceMarkersIfNecessary();
commit-bot@chromium.org9b62aa12014-03-25 11:59:40 +0000389}
390
bsalomon63b21962014-11-05 07:05:34 -0800391void GrInOrderDrawBuffer::onClear(const SkIRect* rect, GrColor color,
392 bool canIgnoreRect, GrRenderTarget* renderTarget) {
joshualitt9853cce2014-11-17 14:22:48 -0800393 SkASSERT(renderTarget);
commit-bot@chromium.orgfd03d4a2013-07-17 21:39:42 +0000394 SkIRect r;
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000395 if (NULL == rect) {
396 // We could do something smart and remove previous draws and clears to
397 // the current render target. If we get that smart we have to make sure
398 // those draws aren't read before this clear (render-to-texture).
bsalomon@google.com1b3ce472012-08-17 13:43:08 +0000399 r.setLTRB(0, 0, renderTarget->width(), renderTarget->height());
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000400 rect = &r;
401 }
cdalton6819df32014-10-15 13:43:48 -0700402 Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget));
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000403 GrColorIsPMAssert(color);
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000404 clr->fColor = color;
405 clr->fRect = *rect;
robertphillips@google.com56ce48a2013-10-31 21:44:25 +0000406 clr->fCanIgnoreRect = canIgnoreRect;
cdalton6819df32014-10-15 13:43:48 -0700407 this->recordTraceMarkersIfNecessary();
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000408}
409
joshualitt6db519c2014-10-29 08:48:18 -0700410void GrInOrderDrawBuffer::clearStencilClip(const SkIRect& rect,
411 bool insideClip,
412 GrRenderTarget* renderTarget) {
joshualitt9853cce2014-11-17 14:22:48 -0800413 SkASSERT(renderTarget);
joshualitt6db519c2014-10-29 08:48:18 -0700414 ClearStencilClip* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, ClearStencilClip, (renderTarget));
415 clr->fRect = rect;
416 clr->fInsideClip = insideClip;
417 this->recordTraceMarkersIfNecessary();
418}
419
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000420void GrInOrderDrawBuffer::discard(GrRenderTarget* renderTarget) {
bsalomon89c62982014-11-03 12:08:42 -0800421 SkASSERT(renderTarget);
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000422 if (!this->caps()->discardRenderTargetSupport()) {
423 return;
424 }
cdalton6819df32014-10-15 13:43:48 -0700425 Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget));
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000426 clr->fColor = GrColor_ILLEGAL;
cdalton6819df32014-10-15 13:43:48 -0700427 this->recordTraceMarkersIfNecessary();
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000428}
429
bsalomon371bcbc2014-12-01 08:19:34 -0800430void GrInOrderDrawBuffer::onReset() {
cdalton6819df32014-10-15 13:43:48 -0700431 fCmdBuffer.reset();
bsalomon932f8662014-11-24 06:47:48 -0800432 fPrevState = NULL;
cdalton3fc6a2f2014-11-13 11:54:20 -0800433 reset_data_buffer(&fPathIndexBuffer, kPathIdxBufferMinReserve);
434 reset_data_buffer(&fPathTransformBuffer, kPathXformBufferMinReserve);
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000435 fGpuCmdMarkers.reset();
reed@google.comac10a2d2010-12-22 21:39:39 +0000436}
437
bsalomon371bcbc2014-12-01 08:19:34 -0800438void GrInOrderDrawBuffer::onFlush() {
cdalton6819df32014-10-15 13:43:48 -0700439 if (fCmdBuffer.empty()) {
robertphillips@google.com1267fbd2013-07-03 18:37:27 +0000440 return;
reed@google.comac10a2d2010-12-22 21:39:39 +0000441 }
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000442
joshualittca0a1792015-01-27 06:41:33 -0800443
bsalomonae59b772014-11-19 08:23:49 -0800444 // Updated every time we find a set state cmd to reflect the current state in the playback
445 // stream.
joshualitt873ad0e2015-01-20 09:08:51 -0800446 SetState* currentState = NULL;
joshualittd53a8272014-11-10 16:03:14 -0800447
joshualittd5a7db42015-01-27 15:39:06 -0800448 // TODO we noticed a huge regression on MacMinis with the initial implementation of GrBatch
449 // Because of vertex buffer mismanagement between batch and non batch. To compensate we
450 // flush all the batches into one contigous buffer
451 if (fFlushBatches) {
452 fFlushBatches = false;
453 CmdBuffer::Iter preflush(fCmdBuffer);
454 while(preflush.next()) {
455 bool isSetState = kSetState_Cmd == strip_trace_bit(preflush->fType);
456 if (isSetState) {
457 SetState* ss = reinterpret_cast<SetState*>(preflush.get());
458 if (!ss->fPrimitiveProcessor) {
459 currentState = ss;
460 }
461 } else if (kDrawBatch_Cmd == strip_trace_bit(preflush->fType)) {
462 preflush->execute(this, currentState);
463 }
464 }
465 }
466
467 // TODO this is temporary while batch is being rolled out
468 this->getVertexAllocPool()->unmap();
469 this->getIndexAllocPool()->unmap();
470 fBatchTarget.preFlush();
471
472 currentState = NULL;
473 CmdBuffer::Iter iter(fCmdBuffer);
474
475 int currCmdMarker = 0;
476
cdalton6819df32014-10-15 13:43:48 -0700477 while (iter.next()) {
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000478 GrGpuTraceMarker newMarker("", -1);
egdanield78a1682014-07-09 10:41:26 -0700479 SkString traceString;
cdalton6819df32014-10-15 13:43:48 -0700480 if (cmd_has_trace_marker(iter->fType)) {
egdanield78a1682014-07-09 10:41:26 -0700481 traceString = fGpuCmdMarkers[currCmdMarker].toString();
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000482 newMarker.fMarker = traceString.c_str();
bsalomon371bcbc2014-12-01 08:19:34 -0800483 this->getGpu()->addGpuTraceMarker(&newMarker);
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000484 ++currCmdMarker;
485 }
cdalton6819df32014-10-15 13:43:48 -0700486
joshualittd5a7db42015-01-27 15:39:06 -0800487 // TODO temporary hack
488 if (kDrawBatch_Cmd == strip_trace_bit(iter->fType)) {
489 fBatchTarget.flushNext();
490 continue;
491 }
492
493 bool isSetState = kSetState_Cmd == strip_trace_bit(iter->fType);
494 if (isSetState) {
joshualitt9853cce2014-11-17 14:22:48 -0800495 SetState* ss = reinterpret_cast<SetState*>(iter.get());
joshualitt873ad0e2015-01-20 09:08:51 -0800496
joshualittd5a7db42015-01-27 15:39:06 -0800497 // TODO sometimes we have a prim proc, othertimes we have a GrBatch. Eventually we will
498 // only have GrBatch and we can delete this
499 if (ss->fPrimitiveProcessor) {
500 this->getGpu()->buildProgramDesc(&ss->fDesc, *ss->fPrimitiveProcessor,
501 ss->fPipeline,
502 ss->fPipeline.descInfo(),
503 ss->fBatchTracker);
504 }
joshualitt873ad0e2015-01-20 09:08:51 -0800505 currentState = ss;
joshualittd53a8272014-11-10 16:03:14 -0800506 } else {
joshualitt873ad0e2015-01-20 09:08:51 -0800507 iter->execute(this, currentState);
joshualittd53a8272014-11-10 16:03:14 -0800508 }
cdalton6819df32014-10-15 13:43:48 -0700509
510 if (cmd_has_trace_marker(iter->fType)) {
bsalomon371bcbc2014-12-01 08:19:34 -0800511 this->getGpu()->removeGpuTraceMarker(&newMarker);
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000512 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000513 }
mtkleinf439c772014-10-14 14:29:30 -0700514
joshualittd5a7db42015-01-27 15:39:06 -0800515 // TODO see copious notes about hack
516 fBatchTarget.postFlush();
517
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000518 SkASSERT(fGpuCmdMarkers.count() == currCmdMarker);
commit-bot@chromium.orga8916ff2013-08-16 15:53:46 +0000519 ++fDrawID;
reed@google.comac10a2d2010-12-22 21:39:39 +0000520}
521
joshualitt873ad0e2015-01-20 09:08:51 -0800522void GrInOrderDrawBuffer::Draw::execute(GrInOrderDrawBuffer* buf, const SetState* state) {
523 SkASSERT(state);
egdaniel8dd688b2015-01-22 10:16:09 -0800524 DrawArgs args(state->fPrimitiveProcessor.get(), &state->fPipeline, &state->fDesc,
joshualitt17e73142015-01-21 11:52:36 -0800525 &state->fBatchTracker);
joshualitt873ad0e2015-01-20 09:08:51 -0800526 buf->getGpu()->draw(args, fInfo);
cdalton6819df32014-10-15 13:43:48 -0700527}
528
joshualitt873ad0e2015-01-20 09:08:51 -0800529void GrInOrderDrawBuffer::StencilPath::execute(GrInOrderDrawBuffer* buf, const SetState*) {
bsalomon3e791242014-12-17 13:43:13 -0800530 GrGpu::StencilPathState state;
531 state.fRenderTarget = fRenderTarget.get();
532 state.fScissor = &fScissor;
533 state.fStencil = &fStencil;
534 state.fUseHWAA = fUseHWAA;
535 state.fViewMatrix = &fViewMatrix;
536
537 buf->getGpu()->stencilPath(this->path(), state);
cdalton6819df32014-10-15 13:43:48 -0700538}
539
joshualitt873ad0e2015-01-20 09:08:51 -0800540void GrInOrderDrawBuffer::DrawPath::execute(GrInOrderDrawBuffer* buf, const SetState* state) {
541 SkASSERT(state);
egdaniel8dd688b2015-01-22 10:16:09 -0800542 DrawArgs args(state->fPrimitiveProcessor.get(), &state->fPipeline, &state->fDesc,
joshualitt17e73142015-01-21 11:52:36 -0800543 &state->fBatchTracker);
joshualitt873ad0e2015-01-20 09:08:51 -0800544 buf->getGpu()->drawPath(args, this->path(), fStencilSettings);
cdalton6819df32014-10-15 13:43:48 -0700545}
546
joshualitt873ad0e2015-01-20 09:08:51 -0800547void GrInOrderDrawBuffer::DrawPaths::execute(GrInOrderDrawBuffer* buf, const SetState* state) {
548 SkASSERT(state);
egdaniel8dd688b2015-01-22 10:16:09 -0800549 DrawArgs args(state->fPrimitiveProcessor.get(), &state->fPipeline, &state->fDesc,
joshualitt17e73142015-01-21 11:52:36 -0800550 &state->fBatchTracker);
joshualitt873ad0e2015-01-20 09:08:51 -0800551 buf->getGpu()->drawPaths(args, this->pathRange(),
cdalton55b24af2014-11-25 11:00:56 -0800552 &buf->fPathIndexBuffer[fIndicesLocation], fIndexType,
553 &buf->fPathTransformBuffer[fTransformsLocation], fTransformType,
554 fCount, fStencilSettings);
cdalton6819df32014-10-15 13:43:48 -0700555}
556
joshualittd5a7db42015-01-27 15:39:06 -0800557void GrInOrderDrawBuffer::DrawBatch::execute(GrInOrderDrawBuffer* buf, const SetState* state) {
558 SkASSERT(state);
559 fBatch->generateGeometry(buf->getBatchTarget(), &state->fPipeline);
560}
561
joshualitt873ad0e2015-01-20 09:08:51 -0800562void GrInOrderDrawBuffer::SetState::execute(GrInOrderDrawBuffer*, const SetState*) {}
cdalton6819df32014-10-15 13:43:48 -0700563
joshualitt873ad0e2015-01-20 09:08:51 -0800564void GrInOrderDrawBuffer::Clear::execute(GrInOrderDrawBuffer* buf, const SetState*) {
cdalton6819df32014-10-15 13:43:48 -0700565 if (GrColor_ILLEGAL == fColor) {
bsalomon371bcbc2014-12-01 08:19:34 -0800566 buf->getGpu()->discard(this->renderTarget());
cdalton6819df32014-10-15 13:43:48 -0700567 } else {
bsalomon371bcbc2014-12-01 08:19:34 -0800568 buf->getGpu()->clear(&fRect, fColor, fCanIgnoreRect, this->renderTarget());
cdalton6819df32014-10-15 13:43:48 -0700569 }
570}
571
joshualitt873ad0e2015-01-20 09:08:51 -0800572void GrInOrderDrawBuffer::ClearStencilClip::execute(GrInOrderDrawBuffer* buf, const SetState*) {
bsalomon371bcbc2014-12-01 08:19:34 -0800573 buf->getGpu()->clearStencilClip(fRect, fInsideClip, this->renderTarget());
joshualitt6db519c2014-10-29 08:48:18 -0700574}
575
joshualitt873ad0e2015-01-20 09:08:51 -0800576void GrInOrderDrawBuffer::CopySurface::execute(GrInOrderDrawBuffer* buf, const SetState*) {
bsalomon371bcbc2014-12-01 08:19:34 -0800577 buf->getGpu()->copySurface(this->dst(), this->src(), fSrcRect, fDstPoint);
cdalton6819df32014-10-15 13:43:48 -0700578}
579
bsalomonf90a02b2014-11-26 12:28:00 -0800580bool GrInOrderDrawBuffer::onCopySurface(GrSurface* dst,
581 GrSurface* src,
582 const SkIRect& srcRect,
583 const SkIPoint& dstPoint) {
bsalomon371bcbc2014-12-01 08:19:34 -0800584 if (getGpu()->canCopySurface(dst, src, srcRect, dstPoint)) {
cdalton6819df32014-10-15 13:43:48 -0700585 CopySurface* cs = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, CopySurface, (dst, src));
bsalomon@google.com116ad842013-04-09 15:38:19 +0000586 cs->fSrcRect = srcRect;
587 cs->fDstPoint = dstPoint;
cdalton6819df32014-10-15 13:43:48 -0700588 this->recordTraceMarkersIfNecessary();
bsalomon@google.com116ad842013-04-09 15:38:19 +0000589 return true;
bsalomon@google.com116ad842013-04-09 15:38:19 +0000590 }
bsalomonf90a02b2014-11-26 12:28:00 -0800591 return false;
bsalomon@google.com116ad842013-04-09 15:38:19 +0000592}
593
egdaniel8dd688b2015-01-22 10:16:09 -0800594bool GrInOrderDrawBuffer::recordStateAndShouldDraw(const GrPipelineBuilder& pipelineBuilder,
joshualitt71c92602015-01-14 08:12:47 -0800595 const GrPrimitiveProcessor* primProc,
bsalomon3e791242014-12-17 13:43:13 -0800596 const GrScissorState& scissor,
bsalomonae59b772014-11-19 08:23:49 -0800597 const GrDeviceCoordTexture* dstCopy) {
bsalomon932f8662014-11-24 06:47:48 -0800598 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState,
egdaniel8dd688b2015-01-22 10:16:09 -0800599 (pipelineBuilder, primProc, *this->getGpu()->caps(),
600 scissor, dstCopy));
601 if (ss->fPipeline.mustSkip()) {
bsalomon932f8662014-11-24 06:47:48 -0800602 fCmdBuffer.pop_back();
bsalomonae59b772014-11-19 08:23:49 -0800603 return false;
604 }
joshualitt873ad0e2015-01-20 09:08:51 -0800605
606 ss->fPrimitiveProcessor->initBatchTracker(&ss->fBatchTracker,
egdaniel8dd688b2015-01-22 10:16:09 -0800607 ss->fPipeline.getInitBatchTracker());
joshualitt873ad0e2015-01-20 09:08:51 -0800608
joshualittd5a7db42015-01-27 15:39:06 -0800609 if (fPrevState && fPrevState->fPrimitiveProcessor.get() &&
joshualitt873ad0e2015-01-20 09:08:51 -0800610 fPrevState->fPrimitiveProcessor->canMakeEqual(fPrevState->fBatchTracker,
611 *ss->fPrimitiveProcessor,
612 ss->fBatchTracker) &&
egdaniel8dd688b2015-01-22 10:16:09 -0800613 fPrevState->fPipeline.isEqual(ss->fPipeline)) {
bsalomon932f8662014-11-24 06:47:48 -0800614 fCmdBuffer.pop_back();
615 } else {
joshualitt873ad0e2015-01-20 09:08:51 -0800616 fPrevState = ss;
cdalton6819df32014-10-15 13:43:48 -0700617 this->recordTraceMarkersIfNecessary();
bsalomon838f62d2014-08-05 07:15:57 -0700618 }
bsalomonae59b772014-11-19 08:23:49 -0800619 return true;
reed@google.comac10a2d2010-12-22 21:39:39 +0000620}
621
joshualittd5a7db42015-01-27 15:39:06 -0800622bool GrInOrderDrawBuffer::recordStateAndShouldDraw(GrBatch* batch,
623 const GrPipelineBuilder& pipelineBuilder,
624 const GrScissorState& scissor,
625 const GrDeviceCoordTexture* dstCopy) {
626 // TODO this gets much simpler when we have batches everywhere.
627 // If the previous command is also a set state, then we check to see if it has a Batch. If so,
628 // and we can make the two batches equal, and we can combine the states, then we make them equal
629 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState,
630 (batch, pipelineBuilder, *this->getGpu()->caps(), scissor,
631 dstCopy));
632 if (ss->fPipeline.mustSkip()) {
633 fCmdBuffer.pop_back();
634 return false;
635 }
636
637 batch->initBatchTracker(ss->fPipeline.getInitBatchTracker());
638
639 if (fPrevState && !fPrevState->fPrimitiveProcessor.get() &&
640 fPrevState->fPipeline.isEqual(ss->fPipeline)) {
641 fCmdBuffer.pop_back();
642 } else {
643 fPrevState = ss;
644 this->recordTraceMarkersIfNecessary();
645 }
646 return true;
647}
648
cdalton6819df32014-10-15 13:43:48 -0700649void GrInOrderDrawBuffer::recordTraceMarkersIfNecessary() {
650 SkASSERT(!fCmdBuffer.empty());
651 SkASSERT(!cmd_has_trace_marker(fCmdBuffer.back().fType));
mtkleinf439c772014-10-14 14:29:30 -0700652 const GrTraceMarkerSet& activeTraceMarkers = this->getActiveTraceMarkers();
653 if (activeTraceMarkers.count() > 0) {
cdalton6819df32014-10-15 13:43:48 -0700654 fCmdBuffer.back().fType = add_trace_bit(fCmdBuffer.back().fType);
mtkleinf439c772014-10-14 14:29:30 -0700655 fGpuCmdMarkers.push_back(activeTraceMarkers);
mtklein07894c42014-10-13 14:00:42 -0700656 }
mtklein07894c42014-10-13 14:00:42 -0700657}