blob: 1789c49aca35dcedebcfe6770296862c48ee1630 [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
bsalomon@google.comded4f4b2012-06-28 18:48:06 +000010#include "GrBufferAllocPool.h"
bsalomon@google.comc26d94f2013-03-25 18:19:00 +000011#include "GrDrawTargetCaps.h"
bsalomon@google.comded4f4b2012-06-28 18:48:06 +000012#include "GrGpu.h"
joshualittd53a8272014-11-10 16:03:14 -080013#include "GrOptDrawState.h"
bsalomon@google.com6e4e6502013-02-25 20:12:45 +000014#include "GrTemplates.h"
joshualittd53a8272014-11-10 16:03:14 -080015#include "GrTextStrike.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)
joshualitt6db519c2014-10-29 08:48:18 -070021 : INHERITED(gpu->getContext())
cdalton6819df32014-10-15 13:43:48 -070022 , fCmdBuffer(kCmdBufferInitialSizeInBytes)
23 , fLastState(NULL)
bsalomon@google.com6e4e6502013-02-25 20:12:45 +000024 , fDstGpu(gpu)
robertphillips@google.com69705572012-03-21 19:46:50 +000025 , fVertexPool(*vertexPool)
26 , fIndexPool(*indexPool)
commit-bot@chromium.orga8916ff2013-08-16 15:53:46 +000027 , fFlushing(false)
28 , fDrawID(0) {
bsalomon@google.com18c9c192011-09-22 21:01:31 +000029
bsalomon@google.com6e4e6502013-02-25 20:12:45 +000030 fDstGpu->ref();
bsalomon@google.combcce8922013-03-25 15:38:39 +000031 fCaps.reset(SkRef(fDstGpu->caps()));
bsalomon@google.com18c9c192011-09-22 21:01:31 +000032
bsalomon49f085d2014-09-05 13:34:00 -070033 SkASSERT(vertexPool);
34 SkASSERT(indexPool);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000035
36 GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
37 poolState.fUsedPoolVertexBytes = 0;
38 poolState.fUsedPoolIndexBytes = 0;
commit-bot@chromium.org515dcd32013-08-28 14:17:03 +000039#ifdef SK_DEBUG
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000040 poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0;
41 poolState.fPoolStartVertex = ~0;
42 poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0;
43 poolState.fPoolStartIndex = ~0;
44#endif
bsalomon@google.coma4f6b102012-06-26 21:04:22 +000045 this->reset();
reed@google.comac10a2d2010-12-22 21:39:39 +000046}
47
48GrInOrderDrawBuffer::~GrInOrderDrawBuffer() {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000049 this->reset();
bsalomon@google.com4a018bb2011-10-28 19:50:21 +000050 // This must be called by before the GrDrawTarget destructor
51 this->releaseGeometry();
bsalomon@google.com6e4e6502013-02-25 20:12:45 +000052 fDstGpu->unref();
reed@google.comac10a2d2010-12-22 21:39:39 +000053}
54
bsalomon@google.com934c5702012-03-20 21:17:58 +000055////////////////////////////////////////////////////////////////////////////////
56
bsalomon@google.comd62e88e2013-02-01 14:19:27 +000057namespace {
58void get_vertex_bounds(const void* vertices,
59 size_t vertexSize,
60 int vertexCount,
61 SkRect* bounds) {
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +000062 SkASSERT(vertexSize >= sizeof(SkPoint));
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +000063 SkASSERT(vertexCount > 0);
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +000064 const SkPoint* point = static_cast<const SkPoint*>(vertices);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +000065 bounds->fLeft = bounds->fRight = point->fX;
66 bounds->fTop = bounds->fBottom = point->fY;
67 for (int i = 1; i < vertexCount; ++i) {
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +000068 point = reinterpret_cast<SkPoint*>(reinterpret_cast<intptr_t>(point) + vertexSize);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +000069 bounds->growToInclude(point->fX, point->fY);
70 }
71}
bsalomon@google.com934c5702012-03-20 21:17:58 +000072}
73
robertphillips@google.com42903302013-04-20 12:26:07 +000074
75namespace {
76
bsalomon62c447d2014-08-08 08:08:50 -070077extern const GrVertexAttrib kRectAttribs[] = {
78 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding},
79 {kVec4ub_GrVertexAttribType, sizeof(SkPoint), kColor_GrVertexAttribBinding},
80 {kVec2f_GrVertexAttribType, sizeof(SkPoint)+sizeof(GrColor), kLocalCoord_GrVertexAttribBinding},
robertphillips@google.com42903302013-04-20 12:26:07 +000081};
robertphillips@google.com42903302013-04-20 12:26:07 +000082}
83
bsalomon62c447d2014-08-08 08:08:50 -070084/** We always use per-vertex colors so that rects can be batched across color changes. Sometimes we
85 have explicit local coords and sometimes not. We *could* always provide explicit local coords
86 and just duplicate the positions when the caller hasn't provided a local coord rect, but we
87 haven't seen a use case which frequently switches between local rect and no local rect draws.
88
89 The color param is used to determine whether the opaque hint can be set on the draw state.
90 The caller must populate the vertex colors itself.
91
92 The vertex attrib order is always pos, color, [local coords].
93 */
94static void set_vertex_attributes(GrDrawState* drawState, bool hasLocalCoords, GrColor color) {
95 if (hasLocalCoords) {
egdaniel7b3d5ee2014-08-28 05:41:14 -070096 drawState->setVertexAttribs<kRectAttribs>(3, 2 * sizeof(SkPoint) + sizeof(SkColor));
bsalomon62c447d2014-08-08 08:08:50 -070097 } else {
egdaniel7b3d5ee2014-08-28 05:41:14 -070098 drawState->setVertexAttribs<kRectAttribs>(2, sizeof(SkPoint) + sizeof(SkColor));
bsalomon62c447d2014-08-08 08:08:50 -070099 }
100 if (0xFF == GrColorUnpackA(color)) {
101 drawState->setHint(GrDrawState::kVertexColorsAreOpaque_Hint, true);
102 }
103}
robertphillips@google.com42903302013-04-20 12:26:07 +0000104
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000105enum {
106 kTraceCmdBit = 0x80,
107 kCmdMask = 0x7f,
108};
109
bsalomon62c447d2014-08-08 08:08:50 -0700110static inline uint8_t add_trace_bit(uint8_t cmd) { return cmd | kTraceCmdBit; }
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000111
bsalomon62c447d2014-08-08 08:08:50 -0700112static inline uint8_t strip_trace_bit(uint8_t cmd) { return cmd & kCmdMask; }
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000113
bsalomon62c447d2014-08-08 08:08:50 -0700114static inline bool cmd_has_trace_marker(uint8_t cmd) { return SkToBool(cmd & kTraceCmdBit); }
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000115
commit-bot@chromium.orgfd03d4a2013-07-17 21:39:42 +0000116void GrInOrderDrawBuffer::onDrawRect(const SkRect& rect,
commit-bot@chromium.orgfd03d4a2013-07-17 21:39:42 +0000117 const SkRect* localRect,
bsalomon@google.com0406b9e2013-04-02 21:00:15 +0000118 const SkMatrix* localMatrix) {
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000119 GrDrawState* drawState = this->drawState();
120
121 GrColor color = drawState->getColor();
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000122
bsalomon49f085d2014-09-05 13:34:00 -0700123 set_vertex_attributes(drawState, SkToBool(localRect), color);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000124
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000125 AutoReleaseGeometry geo(this, 4, 0);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000126 if (!geo.succeeded()) {
tfarina38406c82014-10-31 07:11:12 -0700127 SkDebugf("Failed to get space for vertices!\n");
bsalomon@google.com934c5702012-03-20 21:17:58 +0000128 return;
129 }
130
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000131 // Go to device coords to allow batching across matrix changes
bsalomon01c8da12014-08-04 09:21:30 -0700132 SkMatrix matrix = drawState->getViewMatrix();
133
jvanverth@google.com39768252013-02-14 15:25:44 +0000134 // 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 +0000135 // modify that stage's matrix. Otherwise if the effect is generating its source rect from
136 // the vertex positions then we have to account for the view matrix change.
bsalomon@google.com137f1342013-05-29 21:27:53 +0000137 GrDrawState::AutoViewMatrixRestore avmr;
138 if (!avmr.setIdentity(drawState)) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000139 return;
140 }
141
egdaniel7b3d5ee2014-08-28 05:41:14 -0700142 size_t vstride = drawState->getVertexStride();
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000143
egdaniel7b3d5ee2014-08-28 05:41:14 -0700144 geo.positions()->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, vstride);
145 matrix.mapPointsWithStride(geo.positions(), vstride, 4);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000146
147 SkRect devBounds;
148 // since we already computed the dev verts, set the bounds hint. This will help us avoid
149 // unnecessary clipping in our onDraw().
egdaniel7b3d5ee2014-08-28 05:41:14 -0700150 get_vertex_bounds(geo.vertices(), vstride, 4, &devBounds);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000151
bsalomon49f085d2014-09-05 13:34:00 -0700152 if (localRect) {
bsalomon62c447d2014-08-08 08:08:50 -0700153 static const int kLocalOffset = sizeof(SkPoint) + sizeof(GrColor);
154 SkPoint* coords = GrTCast<SkPoint*>(GrTCast<intptr_t>(geo.vertices()) + kLocalOffset);
bsalomon@google.comc7818882013-03-20 19:19:53 +0000155 coords->setRectFan(localRect->fLeft, localRect->fTop,
156 localRect->fRight, localRect->fBottom,
egdaniel7b3d5ee2014-08-28 05:41:14 -0700157 vstride);
bsalomon49f085d2014-09-05 13:34:00 -0700158 if (localMatrix) {
egdaniel7b3d5ee2014-08-28 05:41:14 -0700159 localMatrix->mapPointsWithStride(coords, vstride, 4);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000160 }
161 }
162
bsalomon62c447d2014-08-08 08:08:50 -0700163 static const int kColorOffset = sizeof(SkPoint);
164 GrColor* vertColor = GrTCast<GrColor*>(GrTCast<intptr_t>(geo.vertices()) + kColorOffset);
165 for (int i = 0; i < 4; ++i) {
166 *vertColor = color;
egdaniel7b3d5ee2014-08-28 05:41:14 -0700167 vertColor = (GrColor*) ((intptr_t) vertColor + vstride);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000168 }
169
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000170 this->setIndexSourceToBuffer(this->getContext()->getQuadIndexBuffer());
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000171 this->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 4, 6, &devBounds);
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000172
173 // to ensure that stashing the drawState ptr is valid
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000174 SkASSERT(this->drawState() == drawState);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000175}
176
joshualitt2c93efe2014-11-06 12:57:13 -0800177int GrInOrderDrawBuffer::concatInstancedDraw(const DrawInfo& info,
178 const GrClipMaskManager::ScissorState& scissorState) {
cdalton6819df32014-10-15 13:43:48 -0700179 SkASSERT(!fCmdBuffer.empty());
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000180 SkASSERT(info.isInstanced());
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000181
bsalomon@google.com934c5702012-03-20 21:17:58 +0000182 const GeometrySrcState& geomSrc = this->getGeomSrc();
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000183 const GrDrawState& drawState = this->getDrawState();
bsalomon@google.com934c5702012-03-20 21:17:58 +0000184
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000185 // we only attempt to concat the case when reserved verts are used with a client-specified index
186 // buffer. To make this work with client-specified VBs we'd need to know if the VB was updated
187 // between draws.
188 if (kReserved_GeometrySrcType != geomSrc.fVertexSrc ||
189 kBuffer_GeometrySrcType != geomSrc.fIndexSrc) {
190 return 0;
bsalomon@google.com934c5702012-03-20 21:17:58 +0000191 }
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000192 // Check if there is a draw info that is compatible that uses the same VB from the pool and
193 // the same IB
cdalton6819df32014-10-15 13:43:48 -0700194 if (kDraw_Cmd != strip_trace_bit(fCmdBuffer.back().fType)) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000195 return 0;
196 }
197
cdalton6819df32014-10-15 13:43:48 -0700198 Draw* draw = static_cast<Draw*>(&fCmdBuffer.back());
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000199 GeometryPoolState& poolState = fGeoPoolStateStack.back();
200 const GrVertexBuffer* vertexBuffer = poolState.fPoolVertexBuffer;
201
cdalton6819df32014-10-15 13:43:48 -0700202 if (!draw->fInfo.isInstanced() ||
203 draw->fInfo.verticesPerInstance() != info.verticesPerInstance() ||
204 draw->fInfo.indicesPerInstance() != info.indicesPerInstance() ||
bsalomonb3e3a952014-09-19 11:10:40 -0700205 draw->vertexBuffer() != vertexBuffer ||
joshualitt2c93efe2014-11-06 12:57:13 -0800206 draw->indexBuffer() != geomSrc.fIndexBuffer ||
207 draw->fScissorState != scissorState) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000208 return 0;
209 }
210 // info does not yet account for the offset from the start of the pool's VB while the previous
211 // draw record does.
212 int adjustedStartVertex = poolState.fPoolStartVertex + info.startVertex();
cdalton6819df32014-10-15 13:43:48 -0700213 if (draw->fInfo.startVertex() + draw->fInfo.vertexCount() != adjustedStartVertex) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000214 return 0;
215 }
216
cdalton6819df32014-10-15 13:43:48 -0700217 SkASSERT(poolState.fPoolStartVertex == draw->fInfo.startVertex() + draw->fInfo.vertexCount());
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000218
219 // how many instances can be concat'ed onto draw given the size of the index buffer
220 int instancesToConcat = this->indexCountInCurrentSource() / info.indicesPerInstance();
cdalton6819df32014-10-15 13:43:48 -0700221 instancesToConcat -= draw->fInfo.instanceCount();
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000222 instancesToConcat = SkTMin(instancesToConcat, info.instanceCount());
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000223
224 // update the amount of reserved vertex data actually referenced in draws
skia.committer@gmail.comae683922013-02-06 07:01:54 +0000225 size_t vertexBytes = instancesToConcat * info.verticesPerInstance() *
egdaniel7b3d5ee2014-08-28 05:41:14 -0700226 drawState.getVertexStride();
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000227 poolState.fUsedPoolVertexBytes = SkTMax(poolState.fUsedPoolVertexBytes, vertexBytes);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000228
cdalton6819df32014-10-15 13:43:48 -0700229 draw->fInfo.adjustInstanceCount(instancesToConcat);
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000230
231 // update last fGpuCmdMarkers to include any additional trace markers that have been added
232 if (this->getActiveTraceMarkers().count() > 0) {
cdalton6819df32014-10-15 13:43:48 -0700233 if (cmd_has_trace_marker(draw->fType)) {
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000234 fGpuCmdMarkers.back().addSet(this->getActiveTraceMarkers());
235 } else {
236 fGpuCmdMarkers.push_back(this->getActiveTraceMarkers());
cdalton6819df32014-10-15 13:43:48 -0700237 draw->fType = add_trace_bit(draw->fType);
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000238 }
239 }
240
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000241 return instancesToConcat;
bsalomon@google.com934c5702012-03-20 21:17:58 +0000242}
243
joshualitt2c93efe2014-11-06 12:57:13 -0800244void GrInOrderDrawBuffer::onDraw(const DrawInfo& info,
245 const GrClipMaskManager::ScissorState& scissorState) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000246
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000247 GeometryPoolState& poolState = fGeoPoolStateStack.back();
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000248 const GrDrawState& drawState = this->getDrawState();
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000249
joshualittd53a8272014-11-10 16:03:14 -0800250 this->recordStateIfNecessary(GrGpu::PrimTypeToDrawType(info.primitiveType()),
251 info.getDstCopy());
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000252
bsalomonb3e3a952014-09-19 11:10:40 -0700253 const GrVertexBuffer* vb;
254 if (kBuffer_GeometrySrcType == this->getGeomSrc().fVertexSrc) {
255 vb = this->getGeomSrc().fVertexBuffer;
256 } else {
257 vb = poolState.fPoolVertexBuffer;
258 }
259
260 const GrIndexBuffer* ib = NULL;
261 if (info.isIndexed()) {
262 if (kBuffer_GeometrySrcType == this->getGeomSrc().fIndexSrc) {
263 ib = this->getGeomSrc().fIndexBuffer;
264 } else {
265 ib = poolState.fPoolIndexBuffer;
266 }
267 }
268
269 Draw* draw;
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000270 if (info.isInstanced()) {
joshualitt2c93efe2014-11-06 12:57:13 -0800271 int instancesConcated = this->concatInstancedDraw(info, scissorState);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000272 if (info.instanceCount() > instancesConcated) {
joshualitt2c93efe2014-11-06 12:57:13 -0800273 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info, scissorState, vb, ib));
cdalton6819df32014-10-15 13:43:48 -0700274 draw->fInfo.adjustInstanceCount(-instancesConcated);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000275 } else {
276 return;
277 }
278 } else {
joshualitt2c93efe2014-11-06 12:57:13 -0800279 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info, scissorState, vb, ib));
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000280 }
cdalton6819df32014-10-15 13:43:48 -0700281 this->recordTraceMarkersIfNecessary();
bsalomon@google.com74749cd2013-01-30 16:12:41 +0000282
bsalomonb3e3a952014-09-19 11:10:40 -0700283 // Adjust the starting vertex and index when we are using reserved or array sources to
284 // compensate for the fact that the data was inserted into a larger vb/ib owned by the pool.
285 if (kBuffer_GeometrySrcType != this->getGeomSrc().fVertexSrc) {
286 size_t bytes = (info.vertexCount() + info.startVertex()) * drawState.getVertexStride();
287 poolState.fUsedPoolVertexBytes = SkTMax(poolState.fUsedPoolVertexBytes, bytes);
cdalton6819df32014-10-15 13:43:48 -0700288 draw->fInfo.adjustStartVertex(poolState.fPoolStartVertex);
reed@google.comac10a2d2010-12-22 21:39:39 +0000289 }
bsalomonb3e3a952014-09-19 11:10:40 -0700290
291 if (info.isIndexed() && kBuffer_GeometrySrcType != this->getGeomSrc().fIndexSrc) {
292 size_t bytes = (info.indexCount() + info.startIndex()) * sizeof(uint16_t);
293 poolState.fUsedPoolIndexBytes = SkTMax(poolState.fUsedPoolIndexBytes, bytes);
cdalton6819df32014-10-15 13:43:48 -0700294 draw->fInfo.adjustStartIndex(poolState.fPoolStartIndex);
commit-bot@chromium.org9b62aa12014-03-25 11:59:40 +0000295 }
commit-bot@chromium.org9b62aa12014-03-25 11:59:40 +0000296}
sugoi@google.com5f74cf82012-12-17 21:16:45 +0000297
joshualitt2c93efe2014-11-06 12:57:13 -0800298void GrInOrderDrawBuffer::onStencilPath(const GrPath* path,
299 const GrClipMaskManager::ScissorState& scissorState,
300 const GrStencilSettings& stencilSettings) {
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000301 // Only compare the subset of GrDrawState relevant to path stenciling?
joshualittd53a8272014-11-10 16:03:14 -0800302 this->recordStateIfNecessary(GrGpu::kStencilPath_DrawType, NULL);
cdalton6819df32014-10-15 13:43:48 -0700303 StencilPath* sp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, StencilPath, (path));
joshualitt2c93efe2014-11-06 12:57:13 -0800304 sp->fScissorState = scissorState;
305 sp->fStencilSettings = stencilSettings;
cdalton6819df32014-10-15 13:43:48 -0700306 this->recordTraceMarkersIfNecessary();
bsalomon@google.com64aef2b2012-06-11 15:36:13 +0000307}
308
commit-bot@chromium.org32184d82013-10-09 15:14:18 +0000309void GrInOrderDrawBuffer::onDrawPath(const GrPath* path,
joshualitt2c93efe2014-11-06 12:57:13 -0800310 const GrClipMaskManager::ScissorState& scissorState,
311 const GrStencilSettings& stencilSettings,
joshualitt92e496f2014-10-31 13:56:50 -0700312 const GrDeviceCoordTexture* dstCopy) {
commit-bot@chromium.orgc4dc0ad2013-10-09 14:11:33 +0000313 // TODO: Only compare the subset of GrDrawState relevant to path covering?
joshualittd53a8272014-11-10 16:03:14 -0800314 this->recordStateIfNecessary(GrGpu::kDrawPath_DrawType, dstCopy);
cdalton6819df32014-10-15 13:43:48 -0700315 DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (path));
bsalomon49f085d2014-09-05 13:34:00 -0700316 if (dstCopy) {
cdalton6819df32014-10-15 13:43:48 -0700317 dp->fDstCopy = *dstCopy;
commit-bot@chromium.orgc4dc0ad2013-10-09 14:11:33 +0000318 }
joshualitt2c93efe2014-11-06 12:57:13 -0800319 dp->fScissorState = scissorState;
320 dp->fStencilSettings = stencilSettings;
cdalton6819df32014-10-15 13:43:48 -0700321 this->recordTraceMarkersIfNecessary();
commit-bot@chromium.orgc4dc0ad2013-10-09 14:11:33 +0000322}
323
cdaltonb85a0aa2014-07-21 15:32:44 -0700324void GrInOrderDrawBuffer::onDrawPaths(const GrPathRange* pathRange,
joshualitt2c93efe2014-11-06 12:57:13 -0800325 const uint32_t indices[],
326 int count,
327 const float transforms[],
328 PathTransformType transformsType,
329 const GrClipMaskManager::ScissorState& scissorState,
330 const GrStencilSettings& stencilSettings,
joshualitt92e496f2014-10-31 13:56:50 -0700331 const GrDeviceCoordTexture* dstCopy) {
bsalomon49f085d2014-09-05 13:34:00 -0700332 SkASSERT(pathRange);
333 SkASSERT(indices);
334 SkASSERT(transforms);
commit-bot@chromium.org9b62aa12014-03-25 11:59:40 +0000335
joshualittd53a8272014-11-10 16:03:14 -0800336 this->recordStateIfNecessary(GrGpu::kDrawPaths_DrawType, dstCopy);
cdalton6819df32014-10-15 13:43:48 -0700337
338 int sizeOfIndices = sizeof(uint32_t) * count;
339 int sizeOfTransforms = sizeof(float) * count *
340 GrPathRendering::PathTransformSize(transformsType);
341
342 DrawPaths* dp = GrNEW_APPEND_WITH_DATA_TO_RECORDER(fCmdBuffer, DrawPaths, (pathRange),
343 sizeOfIndices + sizeOfTransforms);
344 memcpy(dp->indices(), indices, sizeOfIndices);
cdaltonb85a0aa2014-07-21 15:32:44 -0700345 dp->fCount = count;
cdalton6819df32014-10-15 13:43:48 -0700346 memcpy(dp->transforms(), transforms, sizeOfTransforms);
cdaltonb85a0aa2014-07-21 15:32:44 -0700347 dp->fTransformsType = transformsType;
joshualitt2c93efe2014-11-06 12:57:13 -0800348 dp->fScissorState = scissorState;
349 dp->fStencilSettings = stencilSettings;
bsalomon49f085d2014-09-05 13:34:00 -0700350 if (dstCopy) {
commit-bot@chromium.org9b62aa12014-03-25 11:59:40 +0000351 dp->fDstCopy = *dstCopy;
352 }
cdalton6819df32014-10-15 13:43:48 -0700353
354 this->recordTraceMarkersIfNecessary();
commit-bot@chromium.org9b62aa12014-03-25 11:59:40 +0000355}
356
bsalomon63b21962014-11-05 07:05:34 -0800357void GrInOrderDrawBuffer::onClear(const SkIRect* rect, GrColor color,
358 bool canIgnoreRect, GrRenderTarget* renderTarget) {
commit-bot@chromium.orgfd03d4a2013-07-17 21:39:42 +0000359 SkIRect r;
bsalomon@google.com1b3ce472012-08-17 13:43:08 +0000360 if (NULL == renderTarget) {
361 renderTarget = this->drawState()->getRenderTarget();
bsalomon49f085d2014-09-05 13:34:00 -0700362 SkASSERT(renderTarget);
bsalomon@google.com1b3ce472012-08-17 13:43:08 +0000363 }
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000364 if (NULL == rect) {
365 // We could do something smart and remove previous draws and clears to
366 // the current render target. If we get that smart we have to make sure
367 // those draws aren't read before this clear (render-to-texture).
bsalomon@google.com1b3ce472012-08-17 13:43:08 +0000368 r.setLTRB(0, 0, renderTarget->width(), renderTarget->height());
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000369 rect = &r;
370 }
cdalton6819df32014-10-15 13:43:48 -0700371 Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget));
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000372 GrColorIsPMAssert(color);
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000373 clr->fColor = color;
374 clr->fRect = *rect;
robertphillips@google.com56ce48a2013-10-31 21:44:25 +0000375 clr->fCanIgnoreRect = canIgnoreRect;
cdalton6819df32014-10-15 13:43:48 -0700376 this->recordTraceMarkersIfNecessary();
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000377}
378
joshualitt6db519c2014-10-29 08:48:18 -0700379void GrInOrderDrawBuffer::clearStencilClip(const SkIRect& rect,
380 bool insideClip,
381 GrRenderTarget* renderTarget) {
382 if (NULL == renderTarget) {
383 renderTarget = this->drawState()->getRenderTarget();
384 SkASSERT(renderTarget);
385 }
386 ClearStencilClip* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, ClearStencilClip, (renderTarget));
387 clr->fRect = rect;
388 clr->fInsideClip = insideClip;
389 this->recordTraceMarkersIfNecessary();
390}
391
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000392void GrInOrderDrawBuffer::discard(GrRenderTarget* renderTarget) {
bsalomon89c62982014-11-03 12:08:42 -0800393 SkASSERT(renderTarget);
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000394 if (!this->caps()->discardRenderTargetSupport()) {
395 return;
396 }
cdalton6819df32014-10-15 13:43:48 -0700397 Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget));
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000398 clr->fColor = GrColor_ILLEGAL;
cdalton6819df32014-10-15 13:43:48 -0700399 this->recordTraceMarkersIfNecessary();
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000400}
401
reed@google.comac10a2d2010-12-22 21:39:39 +0000402void GrInOrderDrawBuffer::reset() {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000403 SkASSERT(1 == fGeoPoolStateStack.count());
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000404 this->resetVertexSource();
405 this->resetIndexSource();
cdalton6819df32014-10-15 13:43:48 -0700406
407 fCmdBuffer.reset();
408 fLastState = NULL;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000409 fVertexPool.reset();
410 fIndexPool.reset();
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000411 fGpuCmdMarkers.reset();
reed@google.comac10a2d2010-12-22 21:39:39 +0000412}
413
robertphillips@google.com1267fbd2013-07-03 18:37:27 +0000414void GrInOrderDrawBuffer::flush() {
415 if (fFlushing) {
416 return;
417 }
418
jvanverth8e80d172014-06-19 12:01:10 -0700419 this->getContext()->getFontCache()->updateTextures();
420
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000421 SkASSERT(kReserved_GeometrySrcType != this->getGeomSrc().fVertexSrc);
422 SkASSERT(kReserved_GeometrySrcType != this->getGeomSrc().fIndexSrc);
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000423
cdalton6819df32014-10-15 13:43:48 -0700424 if (fCmdBuffer.empty()) {
robertphillips@google.com1267fbd2013-07-03 18:37:27 +0000425 return;
reed@google.comac10a2d2010-12-22 21:39:39 +0000426 }
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000427
428 GrAutoTRestore<bool> flushRestore(&fFlushing);
429 fFlushing = true;
reed@google.comac10a2d2010-12-22 21:39:39 +0000430
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000431 fVertexPool.unmap();
432 fIndexPool.unmap();
reed@google.comac10a2d2010-12-22 21:39:39 +0000433
cdalton6819df32014-10-15 13:43:48 -0700434 CmdBuffer::Iter iter(fCmdBuffer);
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000435
cdalton6819df32014-10-15 13:43:48 -0700436 int currCmdMarker = 0;
egdaniel3eee3832014-06-18 13:09:11 -0700437 fDstGpu->saveActiveTraceMarkers();
cdalton6819df32014-10-15 13:43:48 -0700438
joshualittd53a8272014-11-10 16:03:14 -0800439 // Gpu no longer maintains the current drawstate, so we track the setstate calls below.
440 // NOTE: we always record a new drawstate at flush boundaries
441 SkAutoTUnref<const GrOptDrawState> currentOptState;
442
cdalton6819df32014-10-15 13:43:48 -0700443 while (iter.next()) {
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000444 GrGpuTraceMarker newMarker("", -1);
egdanield78a1682014-07-09 10:41:26 -0700445 SkString traceString;
cdalton6819df32014-10-15 13:43:48 -0700446 if (cmd_has_trace_marker(iter->fType)) {
egdanield78a1682014-07-09 10:41:26 -0700447 traceString = fGpuCmdMarkers[currCmdMarker].toString();
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000448 newMarker.fMarker = traceString.c_str();
449 fDstGpu->addGpuTraceMarker(&newMarker);
450 ++currCmdMarker;
451 }
cdalton6819df32014-10-15 13:43:48 -0700452
joshualittd53a8272014-11-10 16:03:14 -0800453 if (kSetState_Cmd == strip_trace_bit(iter->fType)) {
454 const SetState* ss = reinterpret_cast<const SetState*>(iter.get());
455 currentOptState.reset(GrOptDrawState::Create(ss->fState,
456 fDstGpu,
457 &ss->fDstCopy,
458 ss->fDrawType));
459 } else {
460 iter->execute(fDstGpu, currentOptState.get());
461 }
cdalton6819df32014-10-15 13:43:48 -0700462
463 if (cmd_has_trace_marker(iter->fType)) {
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000464 fDstGpu->removeGpuTraceMarker(&newMarker);
465 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000466 }
mtkleinf439c772014-10-14 14:29:30 -0700467
cdalton6819df32014-10-15 13:43:48 -0700468 fDstGpu->restoreActiveTraceMarkers();
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000469 SkASSERT(fGpuCmdMarkers.count() == currCmdMarker);
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000470
bsalomon@google.com55e4a202013-01-11 13:54:21 +0000471 this->reset();
commit-bot@chromium.orga8916ff2013-08-16 15:53:46 +0000472 ++fDrawID;
reed@google.comac10a2d2010-12-22 21:39:39 +0000473}
474
joshualittd53a8272014-11-10 16:03:14 -0800475void GrInOrderDrawBuffer::Draw::execute(GrGpu* gpu, const GrOptDrawState* optState) {
476 if (!optState) {
477 return;
478 }
479 gpu->setVertexSourceToBuffer(this->vertexBuffer(), optState->getVertexStride());
cdalton6819df32014-10-15 13:43:48 -0700480 if (fInfo.isIndexed()) {
481 gpu->setIndexSourceToBuffer(this->indexBuffer());
482 }
joshualittd53a8272014-11-10 16:03:14 -0800483 gpu->draw(*optState, fInfo, fScissorState);
cdalton6819df32014-10-15 13:43:48 -0700484}
485
joshualittd53a8272014-11-10 16:03:14 -0800486void GrInOrderDrawBuffer::StencilPath::execute(GrGpu* gpu, const GrOptDrawState* optState) {
487 if (!optState) {
488 return;
489 }
490 gpu->stencilPath(*optState, this->path(), fScissorState, fStencilSettings);
cdalton6819df32014-10-15 13:43:48 -0700491}
492
joshualittd53a8272014-11-10 16:03:14 -0800493void GrInOrderDrawBuffer::DrawPath::execute(GrGpu* gpu, const GrOptDrawState* optState) {
494 if (!optState) {
495 return;
496 }
497 gpu->drawPath(*optState, this->path(), fScissorState, fStencilSettings,
498 fDstCopy.texture() ? &fDstCopy : NULL);
cdalton6819df32014-10-15 13:43:48 -0700499}
500
joshualittd53a8272014-11-10 16:03:14 -0800501void GrInOrderDrawBuffer::DrawPaths::execute(GrGpu* gpu, const GrOptDrawState* optState) {
502 if (!optState) {
503 return;
504 }
505 gpu->drawPaths(*optState, this->pathRange(), this->indices(), fCount, this->transforms(),
506 fTransformsType, fScissorState, fStencilSettings,
507 fDstCopy.texture() ? &fDstCopy : NULL);
cdalton6819df32014-10-15 13:43:48 -0700508}
509
joshualittd53a8272014-11-10 16:03:14 -0800510void GrInOrderDrawBuffer::SetState::execute(GrGpu* gpu, const GrOptDrawState*) {
cdalton6819df32014-10-15 13:43:48 -0700511}
512
joshualittd53a8272014-11-10 16:03:14 -0800513void GrInOrderDrawBuffer::Clear::execute(GrGpu* gpu, const GrOptDrawState*) {
cdalton6819df32014-10-15 13:43:48 -0700514 if (GrColor_ILLEGAL == fColor) {
515 gpu->discard(this->renderTarget());
516 } else {
517 gpu->clear(&fRect, fColor, fCanIgnoreRect, this->renderTarget());
518 }
519}
520
joshualittd53a8272014-11-10 16:03:14 -0800521void GrInOrderDrawBuffer::ClearStencilClip::execute(GrGpu* gpu, const GrOptDrawState*) {
522 gpu->clearStencilClip(fRect, fInsideClip, this->renderTarget());
joshualitt6db519c2014-10-29 08:48:18 -0700523}
524
joshualittd53a8272014-11-10 16:03:14 -0800525void GrInOrderDrawBuffer::CopySurface::execute(GrGpu* gpu, const GrOptDrawState*){
cdalton6819df32014-10-15 13:43:48 -0700526 gpu->copySurface(this->dst(), this->src(), fSrcRect, fDstPoint);
527}
528
joshualitta7024152014-11-03 14:16:35 -0800529bool GrInOrderDrawBuffer::copySurface(GrSurface* dst,
530 GrSurface* src,
531 const SkIRect& srcRect,
532 const SkIPoint& dstPoint) {
bsalomon@google.com116ad842013-04-09 15:38:19 +0000533 if (fDstGpu->canCopySurface(dst, src, srcRect, dstPoint)) {
cdalton6819df32014-10-15 13:43:48 -0700534 CopySurface* cs = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, CopySurface, (dst, src));
bsalomon@google.com116ad842013-04-09 15:38:19 +0000535 cs->fSrcRect = srcRect;
536 cs->fDstPoint = dstPoint;
cdalton6819df32014-10-15 13:43:48 -0700537 this->recordTraceMarkersIfNecessary();
bsalomon@google.com116ad842013-04-09 15:38:19 +0000538 return true;
joshualitta7024152014-11-03 14:16:35 -0800539 } else if (GrDrawTarget::canCopySurface(dst, src, srcRect, dstPoint)) {
540 GrDrawTarget::copySurface(dst, src, srcRect, dstPoint);
541 return true;
bsalomon@google.com116ad842013-04-09 15:38:19 +0000542 } else {
543 return false;
544 }
545}
546
joshualitta7024152014-11-03 14:16:35 -0800547bool GrInOrderDrawBuffer::canCopySurface(GrSurface* dst,
548 GrSurface* src,
549 const SkIRect& srcRect,
550 const SkIPoint& dstPoint) {
551 return fDstGpu->canCopySurface(dst, src, srcRect, dstPoint) ||
552 GrDrawTarget::canCopySurface(dst, src, srcRect, dstPoint);
bsalomon@google.com116ad842013-04-09 15:38:19 +0000553}
554
bsalomonf2703d82014-10-28 14:33:06 -0700555void GrInOrderDrawBuffer::initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc) {
bsalomon@google.comeb851172013-04-15 13:51:00 +0000556 fDstGpu->initCopySurfaceDstDesc(src, desc);
557}
558
robertphillips@google.com9528bdb2013-09-18 22:33:57 +0000559void GrInOrderDrawBuffer::willReserveVertexAndIndexSpace(int vertexCount,
560 int indexCount) {
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000561 // We use geometryHints() to know whether to flush the draw buffer. We
562 // can't flush if we are inside an unbalanced pushGeometrySource.
563 // Moreover, flushing blows away vertex and index data that was
564 // previously reserved. So if the vertex or index data is pulled from
565 // reserved space and won't be released by this request then we can't
566 // flush.
567 bool insideGeoPush = fGeoPoolStateStack.count() > 1;
bsalomon@google.com97805382012-03-13 14:32:07 +0000568
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000569 bool unreleasedVertexSpace =
570 !vertexCount &&
571 kReserved_GeometrySrcType == this->getGeomSrc().fVertexSrc;
bsalomon@google.com97805382012-03-13 14:32:07 +0000572
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000573 bool unreleasedIndexSpace =
574 !indexCount &&
575 kReserved_GeometrySrcType == this->getGeomSrc().fIndexSrc;
bsalomon@google.com97805382012-03-13 14:32:07 +0000576
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000577 int vcount = vertexCount;
578 int icount = indexCount;
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000579
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000580 if (!insideGeoPush &&
581 !unreleasedVertexSpace &&
582 !unreleasedIndexSpace &&
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000583 this->geometryHints(&vcount, &icount)) {
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000584 this->flush();
bsalomon@google.com97805382012-03-13 14:32:07 +0000585 }
586}
587
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000588bool GrInOrderDrawBuffer::geometryHints(int* vertexCount,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000589 int* indexCount) const {
590 // we will recommend a flush if the data could fit in a single
591 // preallocated buffer but none are left and it can't fit
592 // in the current buffer (which may not be prealloced).
reed@google.comac10a2d2010-12-22 21:39:39 +0000593 bool flush = false;
bsalomon49f085d2014-09-05 13:34:00 -0700594 if (indexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000595 int32_t currIndices = fIndexPool.currentBufferIndices();
596 if (*indexCount > currIndices &&
597 (!fIndexPool.preallocatedBuffersRemaining() &&
598 *indexCount <= fIndexPool.preallocatedBufferIndices())) {
599
600 flush = true;
601 }
602 *indexCount = currIndices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000603 }
bsalomon49f085d2014-09-05 13:34:00 -0700604 if (vertexCount) {
egdaniel7b3d5ee2014-08-28 05:41:14 -0700605 size_t vertexStride = this->getDrawState().getVertexStride();
606 int32_t currVertices = fVertexPool.currentBufferVertices(vertexStride);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000607 if (*vertexCount > currVertices &&
608 (!fVertexPool.preallocatedBuffersRemaining() &&
egdaniel7b3d5ee2014-08-28 05:41:14 -0700609 *vertexCount <= fVertexPool.preallocatedBufferVertices(vertexStride))) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000610
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000611 flush = true;
reed@google.comac10a2d2010-12-22 21:39:39 +0000612 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000613 *vertexCount = currVertices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000614 }
615 return flush;
616}
617
jvanverth@google.coma6338982013-01-31 21:34:25 +0000618bool GrInOrderDrawBuffer::onReserveVertexSpace(size_t vertexSize,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000619 int vertexCount,
620 void** vertices) {
621 GeometryPoolState& poolState = fGeoPoolStateStack.back();
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000622 SkASSERT(vertexCount > 0);
bsalomon49f085d2014-09-05 13:34:00 -0700623 SkASSERT(vertices);
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000624 SkASSERT(0 == poolState.fUsedPoolVertexBytes);
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000625
jvanverth@google.coma6338982013-01-31 21:34:25 +0000626 *vertices = fVertexPool.makeSpace(vertexSize,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000627 vertexCount,
628 &poolState.fPoolVertexBuffer,
629 &poolState.fPoolStartVertex);
bsalomon49f085d2014-09-05 13:34:00 -0700630 return SkToBool(*vertices);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000631}
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000632
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000633bool GrInOrderDrawBuffer::onReserveIndexSpace(int indexCount, void** indices) {
634 GeometryPoolState& poolState = fGeoPoolStateStack.back();
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000635 SkASSERT(indexCount > 0);
bsalomon49f085d2014-09-05 13:34:00 -0700636 SkASSERT(indices);
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000637 SkASSERT(0 == poolState.fUsedPoolIndexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000638
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000639 *indices = fIndexPool.makeSpace(indexCount,
640 &poolState.fPoolIndexBuffer,
641 &poolState.fPoolStartIndex);
bsalomon49f085d2014-09-05 13:34:00 -0700642 return SkToBool(*indices);
reed@google.comac10a2d2010-12-22 21:39:39 +0000643}
644
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000645void GrInOrderDrawBuffer::releaseReservedVertexSpace() {
646 GeometryPoolState& poolState = fGeoPoolStateStack.back();
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000647 const GeometrySrcState& geoSrc = this->getGeomSrc();
bsalomon@google.comd57d71a2012-08-16 16:26:33 +0000648
649 // If we get a release vertex space call then our current source should either be reserved
650 // or array (which we copied into reserved space).
joshualittd1aa8ff2014-11-04 07:47:55 -0800651 SkASSERT(kReserved_GeometrySrcType == geoSrc.fVertexSrc);
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000652
653 // When the caller reserved vertex buffer space we gave it back a pointer
654 // provided by the vertex buffer pool. At each draw we tracked the largest
655 // offset into the pool's pointer that was referenced. Now we return to the
656 // pool any portion at the tail of the allocation that no draw referenced.
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000657 size_t reservedVertexBytes = geoSrc.fVertexSize * geoSrc.fVertexCount;
joshualittd53a8272014-11-10 16:03:14 -0800658 fVertexPool.putBack(reservedVertexBytes - poolState.fUsedPoolVertexBytes);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000659 poolState.fUsedPoolVertexBytes = 0;
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000660 poolState.fPoolVertexBuffer = NULL;
661 poolState.fPoolStartVertex = 0;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000662}
663
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000664void GrInOrderDrawBuffer::releaseReservedIndexSpace() {
665 GeometryPoolState& poolState = fGeoPoolStateStack.back();
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000666 const GeometrySrcState& geoSrc = this->getGeomSrc();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000667
bsalomon@google.comd57d71a2012-08-16 16:26:33 +0000668 // If we get a release index space call then our current source should either be reserved
669 // or array (which we copied into reserved space).
joshualittd1aa8ff2014-11-04 07:47:55 -0800670 SkASSERT(kReserved_GeometrySrcType == geoSrc.fIndexSrc);
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000671
672 // Similar to releaseReservedVertexSpace we return any unused portion at
673 // the tail
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000674 size_t reservedIndexBytes = sizeof(uint16_t) * geoSrc.fIndexCount;
675 fIndexPool.putBack(reservedIndexBytes - poolState.fUsedPoolIndexBytes);
676 poolState.fUsedPoolIndexBytes = 0;
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000677 poolState.fPoolIndexBuffer = NULL;
678 poolState.fPoolStartIndex = 0;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000679}
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000680
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000681void GrInOrderDrawBuffer::geometrySourceWillPush() {
682 GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
683 poolState.fUsedPoolVertexBytes = 0;
684 poolState.fUsedPoolIndexBytes = 0;
commit-bot@chromium.org515dcd32013-08-28 14:17:03 +0000685#ifdef SK_DEBUG
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000686 poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0;
687 poolState.fPoolStartVertex = ~0;
688 poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0;
689 poolState.fPoolStartIndex = ~0;
690#endif
691}
692
bsalomonb3e3a952014-09-19 11:10:40 -0700693void GrInOrderDrawBuffer::geometrySourceWillPop(const GeometrySrcState& restoredState) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000694 SkASSERT(fGeoPoolStateStack.count() > 1);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000695 fGeoPoolStateStack.pop_back();
696 GeometryPoolState& poolState = fGeoPoolStateStack.back();
697 // we have to assume that any slack we had in our vertex/index data
698 // is now unreleasable because data may have been appended later in the
699 // pool.
joshualittd1aa8ff2014-11-04 07:47:55 -0800700 if (kReserved_GeometrySrcType == restoredState.fVertexSrc) {
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000701 poolState.fUsedPoolVertexBytes = restoredState.fVertexSize * restoredState.fVertexCount;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000702 }
joshualittd1aa8ff2014-11-04 07:47:55 -0800703 if (kReserved_GeometrySrcType == restoredState.fIndexSrc) {
joshualittd53a8272014-11-10 16:03:14 -0800704 poolState.fUsedPoolIndexBytes = sizeof(uint16_t) * restoredState.fIndexCount;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000705 }
706}
707
joshualittd53a8272014-11-10 16:03:14 -0800708void GrInOrderDrawBuffer::recordStateIfNecessary(GrGpu::DrawType drawType,
709 const GrDeviceCoordTexture* dstCopy) {
cdalton6819df32014-10-15 13:43:48 -0700710 if (!fLastState) {
711 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (this->getDrawState()));
712 fLastState = &ss->fState;
joshualittd53a8272014-11-10 16:03:14 -0800713 if (dstCopy) {
714 ss->fDstCopy = *dstCopy;
715 }
716 ss->fDrawType = drawType;
cdalton6819df32014-10-15 13:43:48 -0700717 this->convertDrawStateToPendingExec(fLastState);
718 this->recordTraceMarkersIfNecessary();
bsalomon838f62d2014-08-05 07:15:57 -0700719 return;
720 }
721 const GrDrawState& curr = this->getDrawState();
cdalton6819df32014-10-15 13:43:48 -0700722 switch (GrDrawState::CombineIfPossible(*fLastState, curr, *this->caps())) {
joshualittd53a8272014-11-10 16:03:14 -0800723 case GrDrawState::kIncompatible_CombinedState: {
724 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (curr));
725 fLastState = &ss->fState;
726 if (dstCopy) {
727 ss->fDstCopy = *dstCopy;
728 }
729 ss->fDrawType = drawType;
cdalton6819df32014-10-15 13:43:48 -0700730 this->convertDrawStateToPendingExec(fLastState);
731 this->recordTraceMarkersIfNecessary();
bsalomon838f62d2014-08-05 07:15:57 -0700732 break;
joshualittd53a8272014-11-10 16:03:14 -0800733 }
bsalomon838f62d2014-08-05 07:15:57 -0700734 case GrDrawState::kA_CombinedState:
735 case GrDrawState::kAOrB_CombinedState: // Treat the same as kA.
736 break;
737 case GrDrawState::kB_CombinedState:
bsalomon2a9ca782014-09-05 14:27:43 -0700738 // prev has already been converted to pending execution. That is a one-way ticket.
cdalton6819df32014-10-15 13:43:48 -0700739 // So here we just destruct the previous state and reinit with a new copy of curr.
740 // Note that this goes away when we move GrIODB over to taking optimized snapshots
741 // of draw states.
742 fLastState->~GrDrawState();
743 SkNEW_PLACEMENT_ARGS(fLastState, GrDrawState, (curr));
744 this->convertDrawStateToPendingExec(fLastState);
bsalomon838f62d2014-08-05 07:15:57 -0700745 break;
746 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000747}
748
cdalton6819df32014-10-15 13:43:48 -0700749void GrInOrderDrawBuffer::recordTraceMarkersIfNecessary() {
750 SkASSERT(!fCmdBuffer.empty());
751 SkASSERT(!cmd_has_trace_marker(fCmdBuffer.back().fType));
mtkleinf439c772014-10-14 14:29:30 -0700752 const GrTraceMarkerSet& activeTraceMarkers = this->getActiveTraceMarkers();
753 if (activeTraceMarkers.count() > 0) {
cdalton6819df32014-10-15 13:43:48 -0700754 fCmdBuffer.back().fType = add_trace_bit(fCmdBuffer.back().fType);
mtkleinf439c772014-10-14 14:29:30 -0700755 fGpuCmdMarkers.push_back(activeTraceMarkers);
mtklein07894c42014-10-13 14:00:42 -0700756 }
mtklein07894c42014-10-13 14:00:42 -0700757}