blob: eb3d19da9cc6b644dbebfce7bbf6aeda0e3875eb [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
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
egdaniele36914c2015-02-13 09:00:33 -0800193int GrInOrderDrawBuffer::concatInstancedDraw(const DrawInfo& info) {
cdalton6819df32014-10-15 13:43:48 -0700194 SkASSERT(!fCmdBuffer.empty());
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000195 SkASSERT(info.isInstanced());
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000196
bsalomon@google.com934c5702012-03-20 21:17:58 +0000197 const GeometrySrcState& geomSrc = this->getGeomSrc();
198
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000199 // we only attempt to concat the case when reserved verts are used with a client-specified index
200 // buffer. To make this work with client-specified VBs we'd need to know if the VB was updated
201 // between draws.
202 if (kReserved_GeometrySrcType != geomSrc.fVertexSrc ||
203 kBuffer_GeometrySrcType != geomSrc.fIndexSrc) {
204 return 0;
bsalomon@google.com934c5702012-03-20 21:17:58 +0000205 }
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000206 // Check if there is a draw info that is compatible that uses the same VB from the pool and
207 // the same IB
cdalton6819df32014-10-15 13:43:48 -0700208 if (kDraw_Cmd != strip_trace_bit(fCmdBuffer.back().fType)) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000209 return 0;
210 }
211
cdalton6819df32014-10-15 13:43:48 -0700212 Draw* draw = static_cast<Draw*>(&fCmdBuffer.back());
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000213
cdalton6819df32014-10-15 13:43:48 -0700214 if (!draw->fInfo.isInstanced() ||
joshualitt4d8da812015-01-28 12:53:54 -0800215 draw->fInfo.primitiveType() != info.primitiveType() ||
cdalton6819df32014-10-15 13:43:48 -0700216 draw->fInfo.verticesPerInstance() != info.verticesPerInstance() ||
217 draw->fInfo.indicesPerInstance() != info.indicesPerInstance() ||
bsalomon371bcbc2014-12-01 08:19:34 -0800218 draw->fInfo.vertexBuffer() != info.vertexBuffer() ||
joshualitt54e0c122014-11-19 09:38:51 -0800219 draw->fInfo.indexBuffer() != geomSrc.fIndexBuffer) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000220 return 0;
221 }
bsalomon371bcbc2014-12-01 08:19:34 -0800222 if (draw->fInfo.startVertex() + draw->fInfo.vertexCount() != info.startVertex()) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000223 return 0;
224 }
225
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000226 // how many instances can be concat'ed onto draw given the size of the index buffer
227 int instancesToConcat = this->indexCountInCurrentSource() / info.indicesPerInstance();
cdalton6819df32014-10-15 13:43:48 -0700228 instancesToConcat -= draw->fInfo.instanceCount();
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000229 instancesToConcat = SkTMin(instancesToConcat, info.instanceCount());
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000230
cdalton6819df32014-10-15 13:43:48 -0700231 draw->fInfo.adjustInstanceCount(instancesToConcat);
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000232
233 // update last fGpuCmdMarkers to include any additional trace markers that have been added
234 if (this->getActiveTraceMarkers().count() > 0) {
cdalton6819df32014-10-15 13:43:48 -0700235 if (cmd_has_trace_marker(draw->fType)) {
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000236 fGpuCmdMarkers.back().addSet(this->getActiveTraceMarkers());
237 } else {
238 fGpuCmdMarkers.push_back(this->getActiveTraceMarkers());
cdalton6819df32014-10-15 13:43:48 -0700239 draw->fType = add_trace_bit(draw->fType);
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000240 }
241 }
242
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000243 return instancesToConcat;
bsalomon@google.com934c5702012-03-20 21:17:58 +0000244}
245
egdaniele36914c2015-02-13 09:00:33 -0800246void GrInOrderDrawBuffer::onDraw(const GrGeometryProcessor* gp,
joshualitt9853cce2014-11-17 14:22:48 -0800247 const DrawInfo& info,
egdaniele36914c2015-02-13 09:00:33 -0800248 const PipelineInfo& pipelineInfo) {
joshualitt7eb8c7b2014-11-18 14:24:27 -0800249 SkASSERT(info.vertexBuffer() && (!info.isIndexed() || info.indexBuffer()));
joshualitt4d8da812015-01-28 12:53:54 -0800250 this->closeBatch();
251
egdaniele36914c2015-02-13 09:00:33 -0800252 if (!this->setupPipelineAndShouldDraw(gp, pipelineInfo)) {
bsalomonae59b772014-11-19 08:23:49 -0800253 return;
254 }
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000255
bsalomonb3e3a952014-09-19 11:10:40 -0700256 Draw* draw;
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000257 if (info.isInstanced()) {
egdaniele36914c2015-02-13 09:00:33 -0800258 int instancesConcated = this->concatInstancedDraw(info);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000259 if (info.instanceCount() > instancesConcated) {
joshualitt54e0c122014-11-19 09:38:51 -0800260 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info));
cdalton6819df32014-10-15 13:43:48 -0700261 draw->fInfo.adjustInstanceCount(-instancesConcated);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000262 } else {
263 return;
264 }
265 } else {
joshualitt54e0c122014-11-19 09:38:51 -0800266 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info));
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000267 }
cdalton6819df32014-10-15 13:43:48 -0700268 this->recordTraceMarkersIfNecessary();
commit-bot@chromium.org9b62aa12014-03-25 11:59:40 +0000269}
sugoi@google.com5f74cf82012-12-17 21:16:45 +0000270
joshualitt4d8da812015-01-28 12:53:54 -0800271void GrInOrderDrawBuffer::onDrawBatch(GrBatch* batch,
egdaniele36914c2015-02-13 09:00:33 -0800272 const PipelineInfo& pipelineInfo) {
273 if (!this->setupPipelineAndShouldDraw(batch, pipelineInfo)) {
joshualitt4d8da812015-01-28 12:53:54 -0800274 return;
275 }
276
277 // Check if there is a Batch Draw we can batch with
278 if (kDrawBatch_Cmd != strip_trace_bit(fCmdBuffer.back().fType)) {
279 fDrawBatch = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawBatch, (batch));
280 return;
281 }
282
283 DrawBatch* draw = static_cast<DrawBatch*>(&fCmdBuffer.back());
284 if (draw->fBatch->combineIfPossible(batch)) {
285 return;
286 } else {
287 this->closeBatch();
288 fDrawBatch = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawBatch, (batch));
289 }
290 this->recordTraceMarkersIfNecessary();
291}
292
egdaniel8dd688b2015-01-22 10:16:09 -0800293void GrInOrderDrawBuffer::onStencilPath(const GrPipelineBuilder& pipelineBuilder,
joshualitt56995b52014-12-11 15:44:02 -0800294 const GrPathProcessor* pathProc,
joshualitt9853cce2014-11-17 14:22:48 -0800295 const GrPath* path,
bsalomon3e791242014-12-17 13:43:13 -0800296 const GrScissorState& scissorState,
joshualitt2c93efe2014-11-06 12:57:13 -0800297 const GrStencilSettings& stencilSettings) {
joshualitt70f00042015-02-06 15:53:59 -0800298 this->closeBatch();
299
bsalomon3e791242014-12-17 13:43:13 -0800300 StencilPath* sp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, StencilPath,
egdaniel8dd688b2015-01-22 10:16:09 -0800301 (path, pipelineBuilder.getRenderTarget()));
bsalomon3e791242014-12-17 13:43:13 -0800302 sp->fScissor = scissorState;
egdaniel8dd688b2015-01-22 10:16:09 -0800303 sp->fUseHWAA = pipelineBuilder.isHWAntialias();
joshualitt8059eb92014-12-29 15:10:07 -0800304 sp->fViewMatrix = pathProc->viewMatrix();
bsalomon3e791242014-12-17 13:43:13 -0800305 sp->fStencil = stencilSettings;
cdalton6819df32014-10-15 13:43:48 -0700306 this->recordTraceMarkersIfNecessary();
bsalomon@google.com64aef2b2012-06-11 15:36:13 +0000307}
308
egdaniele36914c2015-02-13 09:00:33 -0800309void GrInOrderDrawBuffer::onDrawPath(const GrPathProcessor* pathProc,
joshualitt9853cce2014-11-17 14:22:48 -0800310 const GrPath* path,
joshualitt2c93efe2014-11-06 12:57:13 -0800311 const GrStencilSettings& stencilSettings,
egdaniele36914c2015-02-13 09:00:33 -0800312 const PipelineInfo& pipelineInfo) {
joshualitt4d8da812015-01-28 12:53:54 -0800313 this->closeBatch();
314
egdaniel8dd688b2015-01-22 10:16:09 -0800315 // TODO: Only compare the subset of GrPipelineBuilder relevant to path covering?
egdaniele36914c2015-02-13 09:00:33 -0800316 if (!this->setupPipelineAndShouldDraw(pathProc, pipelineInfo)) {
bsalomonae59b772014-11-19 08:23:49 -0800317 return;
318 }
cdalton6819df32014-10-15 13:43:48 -0700319 DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (path));
joshualitt2c93efe2014-11-06 12:57:13 -0800320 dp->fStencilSettings = stencilSettings;
cdalton6819df32014-10-15 13:43:48 -0700321 this->recordTraceMarkersIfNecessary();
commit-bot@chromium.orgc4dc0ad2013-10-09 14:11:33 +0000322}
323
egdaniele36914c2015-02-13 09:00:33 -0800324void GrInOrderDrawBuffer::onDrawPaths(const GrPathProcessor* pathProc,
joshualitt9853cce2014-11-17 14:22:48 -0800325 const GrPathRange* pathRange,
cdalton55b24af2014-11-25 11:00:56 -0800326 const void* indices,
327 PathIndexType indexType,
328 const float transformValues[],
329 PathTransformType transformType,
joshualitt2c93efe2014-11-06 12:57:13 -0800330 int count,
joshualitt2c93efe2014-11-06 12:57:13 -0800331 const GrStencilSettings& stencilSettings,
egdaniele36914c2015-02-13 09:00:33 -0800332 const PipelineInfo& pipelineInfo) {
bsalomon49f085d2014-09-05 13:34:00 -0700333 SkASSERT(pathRange);
334 SkASSERT(indices);
cdalton55b24af2014-11-25 11:00:56 -0800335 SkASSERT(transformValues);
joshualitt4d8da812015-01-28 12:53:54 -0800336 this->closeBatch();
337
egdaniele36914c2015-02-13 09:00:33 -0800338 if (!this->setupPipelineAndShouldDraw(pathProc, pipelineInfo)) {
bsalomonae59b772014-11-19 08:23:49 -0800339 return;
340 }
cdalton6819df32014-10-15 13:43:48 -0700341
cdalton55b24af2014-11-25 11:00:56 -0800342 int indexBytes = GrPathRange::PathIndexSizeInBytes(indexType);
343 if (int misalign = fPathIndexBuffer.count() % indexBytes) {
344 // Add padding to the index buffer so the indices are aligned properly.
345 fPathIndexBuffer.append(indexBytes - misalign);
346 }
347
348 char* savedIndices = fPathIndexBuffer.append(count * indexBytes,
349 reinterpret_cast<const char*>(indices));
350 float* savedTransforms = fPathTransformBuffer.append(
351 count * GrPathRendering::PathTransformSize(transformType),
352 transformValues);
cdalton6819df32014-10-15 13:43:48 -0700353
cdalton3fc6a2f2014-11-13 11:54:20 -0800354 if (kDrawPaths_Cmd == strip_trace_bit(fCmdBuffer.back().fType)) {
355 // The previous command was also DrawPaths. Try to collapse this call into the one
bsalomon371bcbc2014-12-01 08:19:34 -0800356 // before. Note that stenciling all the paths at once, then covering, may not be
cdalton3fc6a2f2014-11-13 11:54:20 -0800357 // equivalent to two separate draw calls if there is overlap. Blending won't work,
358 // and the combined calls may also cancel each other's winding numbers in some
359 // places. For now the winding numbers are only an issue if the fill is even/odd,
360 // because DrawPaths is currently only used for glyphs, and glyphs in the same
361 // font tend to all wind in the same direction.
362 DrawPaths* previous = static_cast<DrawPaths*>(&fCmdBuffer.back());
363 if (pathRange == previous->pathRange() &&
cdalton55b24af2014-11-25 11:00:56 -0800364 indexType == previous->fIndexType &&
365 transformType == previous->fTransformType &&
cdalton3fc6a2f2014-11-13 11:54:20 -0800366 stencilSettings == previous->fStencilSettings &&
367 path_fill_type_is_winding(stencilSettings) &&
egdaniele36914c2015-02-13 09:00:33 -0800368 !pipelineInfo.willBlendWithDst(pathProc)) {
cdalton3fc6a2f2014-11-13 11:54:20 -0800369 // Fold this DrawPaths call into the one previous.
370 previous->fCount += count;
371 return;
372 }
373 }
374
375 DrawPaths* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPaths, (pathRange));
bsalomonef3fcd82014-12-12 08:51:38 -0800376 dp->fIndicesLocation = SkToU32(savedIndices - fPathIndexBuffer.begin());
cdalton55b24af2014-11-25 11:00:56 -0800377 dp->fIndexType = indexType;
bsalomonef3fcd82014-12-12 08:51:38 -0800378 dp->fTransformsLocation = SkToU32(savedTransforms - fPathTransformBuffer.begin());
cdalton55b24af2014-11-25 11:00:56 -0800379 dp->fTransformType = transformType;
380 dp->fCount = count;
joshualitt2c93efe2014-11-06 12:57:13 -0800381 dp->fStencilSettings = stencilSettings;
cdalton6819df32014-10-15 13:43:48 -0700382
383 this->recordTraceMarkersIfNecessary();
commit-bot@chromium.org9b62aa12014-03-25 11:59:40 +0000384}
385
bsalomon63b21962014-11-05 07:05:34 -0800386void GrInOrderDrawBuffer::onClear(const SkIRect* rect, GrColor color,
387 bool canIgnoreRect, GrRenderTarget* renderTarget) {
joshualitt9853cce2014-11-17 14:22:48 -0800388 SkASSERT(renderTarget);
joshualitt70f00042015-02-06 15:53:59 -0800389 this->closeBatch();
390
commit-bot@chromium.orgfd03d4a2013-07-17 21:39:42 +0000391 SkIRect r;
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000392 if (NULL == rect) {
393 // We could do something smart and remove previous draws and clears to
394 // the current render target. If we get that smart we have to make sure
395 // those draws aren't read before this clear (render-to-texture).
bsalomon@google.com1b3ce472012-08-17 13:43:08 +0000396 r.setLTRB(0, 0, renderTarget->width(), renderTarget->height());
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000397 rect = &r;
398 }
cdalton6819df32014-10-15 13:43:48 -0700399 Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget));
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000400 GrColorIsPMAssert(color);
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000401 clr->fColor = color;
402 clr->fRect = *rect;
robertphillips@google.com56ce48a2013-10-31 21:44:25 +0000403 clr->fCanIgnoreRect = canIgnoreRect;
cdalton6819df32014-10-15 13:43:48 -0700404 this->recordTraceMarkersIfNecessary();
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000405}
406
joshualitt6db519c2014-10-29 08:48:18 -0700407void GrInOrderDrawBuffer::clearStencilClip(const SkIRect& rect,
408 bool insideClip,
409 GrRenderTarget* renderTarget) {
joshualitt9853cce2014-11-17 14:22:48 -0800410 SkASSERT(renderTarget);
joshualitt70f00042015-02-06 15:53:59 -0800411 this->closeBatch();
412
joshualitt6db519c2014-10-29 08:48:18 -0700413 ClearStencilClip* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, ClearStencilClip, (renderTarget));
414 clr->fRect = rect;
415 clr->fInsideClip = insideClip;
416 this->recordTraceMarkersIfNecessary();
417}
418
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000419void GrInOrderDrawBuffer::discard(GrRenderTarget* renderTarget) {
bsalomon89c62982014-11-03 12:08:42 -0800420 SkASSERT(renderTarget);
joshualitt70f00042015-02-06 15:53:59 -0800421 this->closeBatch();
422
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000423 if (!this->caps()->discardRenderTargetSupport()) {
424 return;
425 }
cdalton6819df32014-10-15 13:43:48 -0700426 Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget));
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000427 clr->fColor = GrColor_ILLEGAL;
cdalton6819df32014-10-15 13:43:48 -0700428 this->recordTraceMarkersIfNecessary();
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000429}
430
bsalomon371bcbc2014-12-01 08:19:34 -0800431void GrInOrderDrawBuffer::onReset() {
cdalton6819df32014-10-15 13:43:48 -0700432 fCmdBuffer.reset();
bsalomon932f8662014-11-24 06:47:48 -0800433 fPrevState = NULL;
cdalton3fc6a2f2014-11-13 11:54:20 -0800434 reset_data_buffer(&fPathIndexBuffer, kPathIdxBufferMinReserve);
435 reset_data_buffer(&fPathTransformBuffer, kPathXformBufferMinReserve);
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000436 fGpuCmdMarkers.reset();
joshualitt4d8da812015-01-28 12:53:54 -0800437 fDrawBatch = NULL;
reed@google.comac10a2d2010-12-22 21:39:39 +0000438}
439
bsalomon371bcbc2014-12-01 08:19:34 -0800440void GrInOrderDrawBuffer::onFlush() {
cdalton6819df32014-10-15 13:43:48 -0700441 if (fCmdBuffer.empty()) {
robertphillips@google.com1267fbd2013-07-03 18:37:27 +0000442 return;
reed@google.comac10a2d2010-12-22 21:39:39 +0000443 }
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000444
joshualittc2893c52015-01-28 06:54:30 -0800445 // Updated every time we find a set state cmd to reflect the current state in the playback
446 // stream.
447 SetState* currentState = NULL;
448
joshualitt4d8da812015-01-28 12:53:54 -0800449 // TODO this is temporary while batch is being rolled out
450 this->closeBatch();
451 this->getVertexAllocPool()->unmap();
452 this->getIndexAllocPool()->unmap();
453 fBatchTarget.preFlush();
454
455 currentState = NULL;
456 CmdBuffer::Iter iter(fCmdBuffer);
457
458 int currCmdMarker = 0;
459
joshualitt7bc18b72015-02-03 16:41:41 -0800460 int i = 0;
cdalton6819df32014-10-15 13:43:48 -0700461 while (iter.next()) {
joshualitt7bc18b72015-02-03 16:41:41 -0800462 i++;
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000463 GrGpuTraceMarker newMarker("", -1);
egdanield78a1682014-07-09 10:41:26 -0700464 SkString traceString;
cdalton6819df32014-10-15 13:43:48 -0700465 if (cmd_has_trace_marker(iter->fType)) {
egdanield78a1682014-07-09 10:41:26 -0700466 traceString = fGpuCmdMarkers[currCmdMarker].toString();
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000467 newMarker.fMarker = traceString.c_str();
bsalomon371bcbc2014-12-01 08:19:34 -0800468 this->getGpu()->addGpuTraceMarker(&newMarker);
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000469 ++currCmdMarker;
470 }
cdalton6819df32014-10-15 13:43:48 -0700471
joshualitt4d8da812015-01-28 12:53:54 -0800472 // TODO temporary hack
473 if (kDrawBatch_Cmd == strip_trace_bit(iter->fType)) {
joshualitt7bc18b72015-02-03 16:41:41 -0800474 DrawBatch* db = reinterpret_cast<DrawBatch*>(iter.get());
475 fBatchTarget.flushNext(db->fBatch->numberOfDraws());
joshualitt4d8da812015-01-28 12:53:54 -0800476 continue;
477 }
478
479 bool isSetState = kSetState_Cmd == strip_trace_bit(iter->fType);
480 if (isSetState) {
joshualitt9853cce2014-11-17 14:22:48 -0800481 SetState* ss = reinterpret_cast<SetState*>(iter.get());
joshualitt873ad0e2015-01-20 09:08:51 -0800482
joshualitt4d8da812015-01-28 12:53:54 -0800483 // TODO sometimes we have a prim proc, othertimes we have a GrBatch. Eventually we will
484 // only have GrBatch and we can delete this
485 if (ss->fPrimitiveProcessor) {
486 this->getGpu()->buildProgramDesc(&ss->fDesc, *ss->fPrimitiveProcessor,
egdaniele36914c2015-02-13 09:00:33 -0800487 *ss->getPipeline(),
joshualitt4d8da812015-01-28 12:53:54 -0800488 ss->fBatchTracker);
489 }
joshualitt873ad0e2015-01-20 09:08:51 -0800490 currentState = ss;
joshualittd53a8272014-11-10 16:03:14 -0800491 } else {
joshualitt873ad0e2015-01-20 09:08:51 -0800492 iter->execute(this, currentState);
joshualittd53a8272014-11-10 16:03:14 -0800493 }
cdalton6819df32014-10-15 13:43:48 -0700494
495 if (cmd_has_trace_marker(iter->fType)) {
bsalomon371bcbc2014-12-01 08:19:34 -0800496 this->getGpu()->removeGpuTraceMarker(&newMarker);
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000497 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000498 }
mtkleinf439c772014-10-14 14:29:30 -0700499
joshualitt4d8da812015-01-28 12:53:54 -0800500 // TODO see copious notes about hack
501 fBatchTarget.postFlush();
502
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000503 SkASSERT(fGpuCmdMarkers.count() == currCmdMarker);
commit-bot@chromium.orga8916ff2013-08-16 15:53:46 +0000504 ++fDrawID;
reed@google.comac10a2d2010-12-22 21:39:39 +0000505}
506
joshualitt873ad0e2015-01-20 09:08:51 -0800507void GrInOrderDrawBuffer::Draw::execute(GrInOrderDrawBuffer* buf, const SetState* state) {
508 SkASSERT(state);
egdaniele36914c2015-02-13 09:00:33 -0800509 DrawArgs args(state->fPrimitiveProcessor.get(), state->getPipeline(), &state->fDesc,
joshualitt17e73142015-01-21 11:52:36 -0800510 &state->fBatchTracker);
joshualitt873ad0e2015-01-20 09:08:51 -0800511 buf->getGpu()->draw(args, fInfo);
cdalton6819df32014-10-15 13:43:48 -0700512}
513
joshualitt873ad0e2015-01-20 09:08:51 -0800514void GrInOrderDrawBuffer::StencilPath::execute(GrInOrderDrawBuffer* buf, const SetState*) {
bsalomon3e791242014-12-17 13:43:13 -0800515 GrGpu::StencilPathState state;
516 state.fRenderTarget = fRenderTarget.get();
517 state.fScissor = &fScissor;
518 state.fStencil = &fStencil;
519 state.fUseHWAA = fUseHWAA;
520 state.fViewMatrix = &fViewMatrix;
521
522 buf->getGpu()->stencilPath(this->path(), state);
cdalton6819df32014-10-15 13:43:48 -0700523}
524
joshualitt873ad0e2015-01-20 09:08:51 -0800525void GrInOrderDrawBuffer::DrawPath::execute(GrInOrderDrawBuffer* buf, const SetState* state) {
526 SkASSERT(state);
egdaniele36914c2015-02-13 09:00:33 -0800527 DrawArgs args(state->fPrimitiveProcessor.get(), state->getPipeline(), &state->fDesc,
joshualitt17e73142015-01-21 11:52:36 -0800528 &state->fBatchTracker);
joshualitt873ad0e2015-01-20 09:08:51 -0800529 buf->getGpu()->drawPath(args, this->path(), fStencilSettings);
cdalton6819df32014-10-15 13:43:48 -0700530}
531
joshualitt873ad0e2015-01-20 09:08:51 -0800532void GrInOrderDrawBuffer::DrawPaths::execute(GrInOrderDrawBuffer* buf, const SetState* state) {
533 SkASSERT(state);
egdaniele36914c2015-02-13 09:00:33 -0800534 DrawArgs args(state->fPrimitiveProcessor.get(), state->getPipeline(), &state->fDesc,
joshualitt17e73142015-01-21 11:52:36 -0800535 &state->fBatchTracker);
joshualitt873ad0e2015-01-20 09:08:51 -0800536 buf->getGpu()->drawPaths(args, this->pathRange(),
cdalton55b24af2014-11-25 11:00:56 -0800537 &buf->fPathIndexBuffer[fIndicesLocation], fIndexType,
538 &buf->fPathTransformBuffer[fTransformsLocation], fTransformType,
539 fCount, fStencilSettings);
cdalton6819df32014-10-15 13:43:48 -0700540}
541
joshualitt4d8da812015-01-28 12:53:54 -0800542void GrInOrderDrawBuffer::DrawBatch::execute(GrInOrderDrawBuffer* buf, const SetState* state) {
543 SkASSERT(state);
egdaniele36914c2015-02-13 09:00:33 -0800544 fBatch->generateGeometry(buf->getBatchTarget(), state->getPipeline());
joshualitt4d8da812015-01-28 12:53:54 -0800545}
546
joshualitt873ad0e2015-01-20 09:08:51 -0800547void GrInOrderDrawBuffer::SetState::execute(GrInOrderDrawBuffer*, const SetState*) {}
cdalton6819df32014-10-15 13:43:48 -0700548
joshualitt873ad0e2015-01-20 09:08:51 -0800549void GrInOrderDrawBuffer::Clear::execute(GrInOrderDrawBuffer* buf, const SetState*) {
cdalton6819df32014-10-15 13:43:48 -0700550 if (GrColor_ILLEGAL == fColor) {
bsalomon371bcbc2014-12-01 08:19:34 -0800551 buf->getGpu()->discard(this->renderTarget());
cdalton6819df32014-10-15 13:43:48 -0700552 } else {
bsalomon371bcbc2014-12-01 08:19:34 -0800553 buf->getGpu()->clear(&fRect, fColor, fCanIgnoreRect, this->renderTarget());
cdalton6819df32014-10-15 13:43:48 -0700554 }
555}
556
joshualitt873ad0e2015-01-20 09:08:51 -0800557void GrInOrderDrawBuffer::ClearStencilClip::execute(GrInOrderDrawBuffer* buf, const SetState*) {
bsalomon371bcbc2014-12-01 08:19:34 -0800558 buf->getGpu()->clearStencilClip(fRect, fInsideClip, this->renderTarget());
joshualitt6db519c2014-10-29 08:48:18 -0700559}
560
joshualitt873ad0e2015-01-20 09:08:51 -0800561void GrInOrderDrawBuffer::CopySurface::execute(GrInOrderDrawBuffer* buf, const SetState*) {
bsalomon371bcbc2014-12-01 08:19:34 -0800562 buf->getGpu()->copySurface(this->dst(), this->src(), fSrcRect, fDstPoint);
cdalton6819df32014-10-15 13:43:48 -0700563}
564
bsalomonf90a02b2014-11-26 12:28:00 -0800565bool GrInOrderDrawBuffer::onCopySurface(GrSurface* dst,
566 GrSurface* src,
567 const SkIRect& srcRect,
568 const SkIPoint& dstPoint) {
bsalomon371bcbc2014-12-01 08:19:34 -0800569 if (getGpu()->canCopySurface(dst, src, srcRect, dstPoint)) {
joshualitt95964c62015-02-11 13:45:50 -0800570 this->closeBatch();
cdalton6819df32014-10-15 13:43:48 -0700571 CopySurface* cs = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, CopySurface, (dst, src));
bsalomon@google.com116ad842013-04-09 15:38:19 +0000572 cs->fSrcRect = srcRect;
573 cs->fDstPoint = dstPoint;
cdalton6819df32014-10-15 13:43:48 -0700574 this->recordTraceMarkersIfNecessary();
bsalomon@google.com116ad842013-04-09 15:38:19 +0000575 return true;
bsalomon@google.com116ad842013-04-09 15:38:19 +0000576 }
bsalomonf90a02b2014-11-26 12:28:00 -0800577 return false;
bsalomon@google.com116ad842013-04-09 15:38:19 +0000578}
579
egdaniele36914c2015-02-13 09:00:33 -0800580bool GrInOrderDrawBuffer::setupPipelineAndShouldDraw(const GrPrimitiveProcessor* primProc,
581 const PipelineInfo& pipelineInfo) {
582 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (primProc));
583 this->setupPipeline(pipelineInfo, ss->pipelineLocation());
584
585 if (ss->getPipeline()->mustSkip()) {
bsalomon932f8662014-11-24 06:47:48 -0800586 fCmdBuffer.pop_back();
bsalomonae59b772014-11-19 08:23:49 -0800587 return false;
588 }
joshualitt873ad0e2015-01-20 09:08:51 -0800589
590 ss->fPrimitiveProcessor->initBatchTracker(&ss->fBatchTracker,
egdaniele36914c2015-02-13 09:00:33 -0800591 ss->getPipeline()->getInitBatchTracker());
joshualitt873ad0e2015-01-20 09:08:51 -0800592
joshualitt4d8da812015-01-28 12:53:54 -0800593 if (fPrevState && fPrevState->fPrimitiveProcessor.get() &&
joshualitt873ad0e2015-01-20 09:08:51 -0800594 fPrevState->fPrimitiveProcessor->canMakeEqual(fPrevState->fBatchTracker,
595 *ss->fPrimitiveProcessor,
596 ss->fBatchTracker) &&
egdaniele36914c2015-02-13 09:00:33 -0800597 fPrevState->getPipeline()->isEqual(*ss->getPipeline())) {
bsalomon932f8662014-11-24 06:47:48 -0800598 fCmdBuffer.pop_back();
599 } else {
joshualitt873ad0e2015-01-20 09:08:51 -0800600 fPrevState = ss;
cdalton6819df32014-10-15 13:43:48 -0700601 this->recordTraceMarkersIfNecessary();
bsalomon838f62d2014-08-05 07:15:57 -0700602 }
bsalomonae59b772014-11-19 08:23:49 -0800603 return true;
reed@google.comac10a2d2010-12-22 21:39:39 +0000604}
605
egdaniele36914c2015-02-13 09:00:33 -0800606bool GrInOrderDrawBuffer::setupPipelineAndShouldDraw(GrBatch* batch,
607 const PipelineInfo& pipelineInfo) {
608 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, ());
609 this->setupPipeline(pipelineInfo, ss->pipelineLocation());
610
611 if (ss->getPipeline()->mustSkip()) {
joshualitt4d8da812015-01-28 12:53:54 -0800612 fCmdBuffer.pop_back();
613 return false;
614 }
615
egdaniele36914c2015-02-13 09:00:33 -0800616 batch->initBatchTracker(ss->getPipeline()->getInitBatchTracker());
joshualitt4d8da812015-01-28 12:53:54 -0800617
618 if (fPrevState && !fPrevState->fPrimitiveProcessor.get() &&
egdaniele36914c2015-02-13 09:00:33 -0800619 fPrevState->getPipeline()->isEqual(*ss->getPipeline())) {
joshualitt4d8da812015-01-28 12:53:54 -0800620 fCmdBuffer.pop_back();
621 } else {
622 this->closeBatch();
623 fPrevState = ss;
624 this->recordTraceMarkersIfNecessary();
625 }
626 return true;
627}
628
cdalton6819df32014-10-15 13:43:48 -0700629void GrInOrderDrawBuffer::recordTraceMarkersIfNecessary() {
630 SkASSERT(!fCmdBuffer.empty());
631 SkASSERT(!cmd_has_trace_marker(fCmdBuffer.back().fType));
mtkleinf439c772014-10-14 14:29:30 -0700632 const GrTraceMarkerSet& activeTraceMarkers = this->getActiveTraceMarkers();
633 if (activeTraceMarkers.count() > 0) {
cdalton6819df32014-10-15 13:43:48 -0700634 fCmdBuffer.back().fType = add_trace_bit(fCmdBuffer.back().fType);
mtkleinf439c772014-10-14 14:29:30 -0700635 fGpuCmdMarkers.push_back(activeTraceMarkers);
mtklein07894c42014-10-13 14:00:42 -0700636 }
mtklein07894c42014-10-13 14:00:42 -0700637}
joshualitt4d8da812015-01-28 12:53:54 -0800638
joshualitt4d8da812015-01-28 12:53:54 -0800639void GrInOrderDrawBuffer::willReserveVertexAndIndexSpace(int vertexCount,
640 size_t vertexStride,
641 int indexCount) {
642 this->closeBatch();
643
644 // We use geometryHints() to know whether to flush the draw buffer. We
645 // can't flush if we are inside an unbalanced pushGeometrySource.
646 // Moreover, flushing blows away vertex and index data that was
647 // previously reserved. So if the vertex or index data is pulled from
648 // reserved space and won't be released by this request then we can't
649 // flush.
650 bool insideGeoPush = this->getGeoPoolStateStack().count() > 1;
651
652 bool unreleasedVertexSpace =
653 !vertexCount &&
654 kReserved_GeometrySrcType == this->getGeomSrc().fVertexSrc;
655
656 bool unreleasedIndexSpace =
657 !indexCount &&
658 kReserved_GeometrySrcType == this->getGeomSrc().fIndexSrc;
659
660 int vcount = vertexCount;
661 int icount = indexCount;
662
663 if (!insideGeoPush &&
664 !unreleasedVertexSpace &&
665 !unreleasedIndexSpace &&
666 this->geometryHints(vertexStride, &vcount, &icount)) {
667 this->flush();
668 }
669}