blob: 9835200598d76ddadb1cd94661b8d299b24c961b [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"
jvanverth8e80d172014-06-19 12:01:10 -070012#include "GrTextStrike.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"
reed@google.comac10a2d2010-12-22 21:39:39 +000015#include "GrTexture.h"
reed@google.comac10a2d2010-12-22 21:39:39 +000016
bsalomon@google.com6e4e6502013-02-25 20:12:45 +000017GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrGpu* gpu,
bsalomon@google.com471d4712011-08-23 15:45:25 +000018 GrVertexBufferAllocPool* vertexPool,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000019 GrIndexBufferAllocPool* indexPool)
joshualitt6db519c2014-10-29 08:48:18 -070020 : INHERITED(gpu->getContext())
cdalton6819df32014-10-15 13:43:48 -070021 , fCmdBuffer(kCmdBufferInitialSizeInBytes)
22 , fLastState(NULL)
bsalomon@google.com6e4e6502013-02-25 20:12:45 +000023 , fDstGpu(gpu)
robertphillips@google.com69705572012-03-21 19:46:50 +000024 , fVertexPool(*vertexPool)
25 , fIndexPool(*indexPool)
commit-bot@chromium.orga8916ff2013-08-16 15:53:46 +000026 , fFlushing(false)
27 , fDrawID(0) {
bsalomon@google.com18c9c192011-09-22 21:01:31 +000028
bsalomon@google.com6e4e6502013-02-25 20:12:45 +000029 fDstGpu->ref();
bsalomon@google.combcce8922013-03-25 15:38:39 +000030 fCaps.reset(SkRef(fDstGpu->caps()));
bsalomon@google.com18c9c192011-09-22 21:01:31 +000031
bsalomon49f085d2014-09-05 13:34:00 -070032 SkASSERT(vertexPool);
33 SkASSERT(indexPool);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000034
35 GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
36 poolState.fUsedPoolVertexBytes = 0;
37 poolState.fUsedPoolIndexBytes = 0;
commit-bot@chromium.org515dcd32013-08-28 14:17:03 +000038#ifdef SK_DEBUG
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000039 poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0;
40 poolState.fPoolStartVertex = ~0;
41 poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0;
42 poolState.fPoolStartIndex = ~0;
43#endif
bsalomon@google.coma4f6b102012-06-26 21:04:22 +000044 this->reset();
reed@google.comac10a2d2010-12-22 21:39:39 +000045}
46
47GrInOrderDrawBuffer::~GrInOrderDrawBuffer() {
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000048 this->reset();
bsalomon@google.com4a018bb2011-10-28 19:50:21 +000049 // This must be called by before the GrDrawTarget destructor
50 this->releaseGeometry();
bsalomon@google.com6e4e6502013-02-25 20:12:45 +000051 fDstGpu->unref();
reed@google.comac10a2d2010-12-22 21:39:39 +000052}
53
bsalomon@google.com934c5702012-03-20 21:17:58 +000054////////////////////////////////////////////////////////////////////////////////
55
bsalomon@google.comd62e88e2013-02-01 14:19:27 +000056namespace {
57void get_vertex_bounds(const void* vertices,
58 size_t vertexSize,
59 int vertexCount,
60 SkRect* bounds) {
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +000061 SkASSERT(vertexSize >= sizeof(SkPoint));
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +000062 SkASSERT(vertexCount > 0);
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +000063 const SkPoint* point = static_cast<const SkPoint*>(vertices);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +000064 bounds->fLeft = bounds->fRight = point->fX;
65 bounds->fTop = bounds->fBottom = point->fY;
66 for (int i = 1; i < vertexCount; ++i) {
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +000067 point = reinterpret_cast<SkPoint*>(reinterpret_cast<intptr_t>(point) + vertexSize);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +000068 bounds->growToInclude(point->fX, point->fY);
69 }
70}
bsalomon@google.com934c5702012-03-20 21:17:58 +000071}
72
robertphillips@google.com42903302013-04-20 12:26:07 +000073
74namespace {
75
bsalomon62c447d2014-08-08 08:08:50 -070076extern const GrVertexAttrib kRectAttribs[] = {
77 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding},
78 {kVec4ub_GrVertexAttribType, sizeof(SkPoint), kColor_GrVertexAttribBinding},
79 {kVec2f_GrVertexAttribType, sizeof(SkPoint)+sizeof(GrColor), kLocalCoord_GrVertexAttribBinding},
robertphillips@google.com42903302013-04-20 12:26:07 +000080};
robertphillips@google.com42903302013-04-20 12:26:07 +000081}
82
bsalomon62c447d2014-08-08 08:08:50 -070083/** We always use per-vertex colors so that rects can be batched across color changes. Sometimes we
84 have explicit local coords and sometimes not. We *could* always provide explicit local coords
85 and just duplicate the positions when the caller hasn't provided a local coord rect, but we
86 haven't seen a use case which frequently switches between local rect and no local rect draws.
87
88 The color param is used to determine whether the opaque hint can be set on the draw state.
89 The caller must populate the vertex colors itself.
90
91 The vertex attrib order is always pos, color, [local coords].
92 */
93static void set_vertex_attributes(GrDrawState* drawState, bool hasLocalCoords, GrColor color) {
94 if (hasLocalCoords) {
egdaniel7b3d5ee2014-08-28 05:41:14 -070095 drawState->setVertexAttribs<kRectAttribs>(3, 2 * sizeof(SkPoint) + sizeof(SkColor));
bsalomon62c447d2014-08-08 08:08:50 -070096 } else {
egdaniel7b3d5ee2014-08-28 05:41:14 -070097 drawState->setVertexAttribs<kRectAttribs>(2, sizeof(SkPoint) + sizeof(SkColor));
bsalomon62c447d2014-08-08 08:08:50 -070098 }
99 if (0xFF == GrColorUnpackA(color)) {
100 drawState->setHint(GrDrawState::kVertexColorsAreOpaque_Hint, true);
101 }
102}
robertphillips@google.com42903302013-04-20 12:26:07 +0000103
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000104enum {
105 kTraceCmdBit = 0x80,
106 kCmdMask = 0x7f,
107};
108
bsalomon62c447d2014-08-08 08:08:50 -0700109static inline uint8_t add_trace_bit(uint8_t cmd) { return cmd | kTraceCmdBit; }
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000110
bsalomon62c447d2014-08-08 08:08:50 -0700111static inline uint8_t strip_trace_bit(uint8_t cmd) { return cmd & kCmdMask; }
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000112
bsalomon62c447d2014-08-08 08:08:50 -0700113static inline bool cmd_has_trace_marker(uint8_t cmd) { return SkToBool(cmd & kTraceCmdBit); }
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000114
commit-bot@chromium.orgfd03d4a2013-07-17 21:39:42 +0000115void GrInOrderDrawBuffer::onDrawRect(const SkRect& rect,
commit-bot@chromium.orgfd03d4a2013-07-17 21:39:42 +0000116 const SkRect* localRect,
bsalomon@google.com0406b9e2013-04-02 21:00:15 +0000117 const SkMatrix* localMatrix) {
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000118 GrDrawState* drawState = this->drawState();
119
120 GrColor color = drawState->getColor();
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000121
bsalomon49f085d2014-09-05 13:34:00 -0700122 set_vertex_attributes(drawState, SkToBool(localRect), color);
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000123
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000124 AutoReleaseGeometry geo(this, 4, 0);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000125 if (!geo.succeeded()) {
tfarina38406c82014-10-31 07:11:12 -0700126 SkDebugf("Failed to get space for vertices!\n");
bsalomon@google.com934c5702012-03-20 21:17:58 +0000127 return;
128 }
129
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000130 // Go to device coords to allow batching across matrix changes
bsalomon01c8da12014-08-04 09:21:30 -0700131 SkMatrix matrix = drawState->getViewMatrix();
132
jvanverth@google.com39768252013-02-14 15:25:44 +0000133 // 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 +0000134 // modify that stage's matrix. Otherwise if the effect is generating its source rect from
135 // the vertex positions then we have to account for the view matrix change.
bsalomon@google.com137f1342013-05-29 21:27:53 +0000136 GrDrawState::AutoViewMatrixRestore avmr;
137 if (!avmr.setIdentity(drawState)) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000138 return;
139 }
140
egdaniel7b3d5ee2014-08-28 05:41:14 -0700141 size_t vstride = drawState->getVertexStride();
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000142
egdaniel7b3d5ee2014-08-28 05:41:14 -0700143 geo.positions()->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, vstride);
144 matrix.mapPointsWithStride(geo.positions(), vstride, 4);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000145
146 SkRect devBounds;
147 // since we already computed the dev verts, set the bounds hint. This will help us avoid
148 // unnecessary clipping in our onDraw().
egdaniel7b3d5ee2014-08-28 05:41:14 -0700149 get_vertex_bounds(geo.vertices(), vstride, 4, &devBounds);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000150
bsalomon49f085d2014-09-05 13:34:00 -0700151 if (localRect) {
bsalomon62c447d2014-08-08 08:08:50 -0700152 static const int kLocalOffset = sizeof(SkPoint) + sizeof(GrColor);
153 SkPoint* coords = GrTCast<SkPoint*>(GrTCast<intptr_t>(geo.vertices()) + kLocalOffset);
bsalomon@google.comc7818882013-03-20 19:19:53 +0000154 coords->setRectFan(localRect->fLeft, localRect->fTop,
155 localRect->fRight, localRect->fBottom,
egdaniel7b3d5ee2014-08-28 05:41:14 -0700156 vstride);
bsalomon49f085d2014-09-05 13:34:00 -0700157 if (localMatrix) {
egdaniel7b3d5ee2014-08-28 05:41:14 -0700158 localMatrix->mapPointsWithStride(coords, vstride, 4);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000159 }
160 }
161
bsalomon62c447d2014-08-08 08:08:50 -0700162 static const int kColorOffset = sizeof(SkPoint);
163 GrColor* vertColor = GrTCast<GrColor*>(GrTCast<intptr_t>(geo.vertices()) + kColorOffset);
164 for (int i = 0; i < 4; ++i) {
165 *vertColor = color;
egdaniel7b3d5ee2014-08-28 05:41:14 -0700166 vertColor = (GrColor*) ((intptr_t) vertColor + vstride);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000167 }
168
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000169 this->setIndexSourceToBuffer(this->getContext()->getQuadIndexBuffer());
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000170 this->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 4, 6, &devBounds);
jvanverth@google.com9b855c72013-03-01 18:21:22 +0000171
172 // to ensure that stashing the drawState ptr is valid
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000173 SkASSERT(this->drawState() == drawState);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000174}
175
joshualitt2c93efe2014-11-06 12:57:13 -0800176int GrInOrderDrawBuffer::concatInstancedDraw(const DrawInfo& info,
177 const GrClipMaskManager::ScissorState& scissorState) {
cdalton6819df32014-10-15 13:43:48 -0700178 SkASSERT(!fCmdBuffer.empty());
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000179 SkASSERT(info.isInstanced());
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000180
bsalomon@google.com934c5702012-03-20 21:17:58 +0000181 const GeometrySrcState& geomSrc = this->getGeomSrc();
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000182 const GrDrawState& drawState = this->getDrawState();
bsalomon@google.com934c5702012-03-20 21:17:58 +0000183
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000184 // we only attempt to concat the case when reserved verts are used with a client-specified index
185 // buffer. To make this work with client-specified VBs we'd need to know if the VB was updated
186 // between draws.
187 if (kReserved_GeometrySrcType != geomSrc.fVertexSrc ||
188 kBuffer_GeometrySrcType != geomSrc.fIndexSrc) {
189 return 0;
bsalomon@google.com934c5702012-03-20 21:17:58 +0000190 }
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000191 // Check if there is a draw info that is compatible that uses the same VB from the pool and
192 // the same IB
cdalton6819df32014-10-15 13:43:48 -0700193 if (kDraw_Cmd != strip_trace_bit(fCmdBuffer.back().fType)) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000194 return 0;
195 }
196
cdalton6819df32014-10-15 13:43:48 -0700197 Draw* draw = static_cast<Draw*>(&fCmdBuffer.back());
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000198 GeometryPoolState& poolState = fGeoPoolStateStack.back();
199 const GrVertexBuffer* vertexBuffer = poolState.fPoolVertexBuffer;
200
cdalton6819df32014-10-15 13:43:48 -0700201 if (!draw->fInfo.isInstanced() ||
202 draw->fInfo.verticesPerInstance() != info.verticesPerInstance() ||
203 draw->fInfo.indicesPerInstance() != info.indicesPerInstance() ||
bsalomonb3e3a952014-09-19 11:10:40 -0700204 draw->vertexBuffer() != vertexBuffer ||
joshualitt2c93efe2014-11-06 12:57:13 -0800205 draw->indexBuffer() != geomSrc.fIndexBuffer ||
206 draw->fScissorState != scissorState) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000207 return 0;
208 }
209 // info does not yet account for the offset from the start of the pool's VB while the previous
210 // draw record does.
211 int adjustedStartVertex = poolState.fPoolStartVertex + info.startVertex();
cdalton6819df32014-10-15 13:43:48 -0700212 if (draw->fInfo.startVertex() + draw->fInfo.vertexCount() != adjustedStartVertex) {
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000213 return 0;
214 }
215
cdalton6819df32014-10-15 13:43:48 -0700216 SkASSERT(poolState.fPoolStartVertex == draw->fInfo.startVertex() + draw->fInfo.vertexCount());
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000217
218 // how many instances can be concat'ed onto draw given the size of the index buffer
219 int instancesToConcat = this->indexCountInCurrentSource() / info.indicesPerInstance();
cdalton6819df32014-10-15 13:43:48 -0700220 instancesToConcat -= draw->fInfo.instanceCount();
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000221 instancesToConcat = SkTMin(instancesToConcat, info.instanceCount());
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000222
223 // update the amount of reserved vertex data actually referenced in draws
skia.committer@gmail.comae683922013-02-06 07:01:54 +0000224 size_t vertexBytes = instancesToConcat * info.verticesPerInstance() *
egdaniel7b3d5ee2014-08-28 05:41:14 -0700225 drawState.getVertexStride();
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000226 poolState.fUsedPoolVertexBytes = SkTMax(poolState.fUsedPoolVertexBytes, vertexBytes);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000227
cdalton6819df32014-10-15 13:43:48 -0700228 draw->fInfo.adjustInstanceCount(instancesToConcat);
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000229
230 // update last fGpuCmdMarkers to include any additional trace markers that have been added
231 if (this->getActiveTraceMarkers().count() > 0) {
cdalton6819df32014-10-15 13:43:48 -0700232 if (cmd_has_trace_marker(draw->fType)) {
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000233 fGpuCmdMarkers.back().addSet(this->getActiveTraceMarkers());
234 } else {
235 fGpuCmdMarkers.push_back(this->getActiveTraceMarkers());
cdalton6819df32014-10-15 13:43:48 -0700236 draw->fType = add_trace_bit(draw->fType);
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000237 }
238 }
239
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000240 return instancesToConcat;
bsalomon@google.com934c5702012-03-20 21:17:58 +0000241}
242
joshualitt2c93efe2014-11-06 12:57:13 -0800243void GrInOrderDrawBuffer::onDraw(const DrawInfo& info,
244 const GrClipMaskManager::ScissorState& scissorState) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000245
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000246 GeometryPoolState& poolState = fGeoPoolStateStack.back();
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000247 const GrDrawState& drawState = this->getDrawState();
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000248
bsalomon838f62d2014-08-05 07:15:57 -0700249 this->recordStateIfNecessary();
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000250
bsalomonb3e3a952014-09-19 11:10:40 -0700251 const GrVertexBuffer* vb;
252 if (kBuffer_GeometrySrcType == this->getGeomSrc().fVertexSrc) {
253 vb = this->getGeomSrc().fVertexBuffer;
254 } else {
255 vb = poolState.fPoolVertexBuffer;
256 }
257
258 const GrIndexBuffer* ib = NULL;
259 if (info.isIndexed()) {
260 if (kBuffer_GeometrySrcType == this->getGeomSrc().fIndexSrc) {
261 ib = this->getGeomSrc().fIndexBuffer;
262 } else {
263 ib = poolState.fPoolIndexBuffer;
264 }
265 }
266
267 Draw* draw;
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000268 if (info.isInstanced()) {
joshualitt2c93efe2014-11-06 12:57:13 -0800269 int instancesConcated = this->concatInstancedDraw(info, scissorState);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000270 if (info.instanceCount() > instancesConcated) {
joshualitt2c93efe2014-11-06 12:57:13 -0800271 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info, scissorState, vb, ib));
cdalton6819df32014-10-15 13:43:48 -0700272 draw->fInfo.adjustInstanceCount(-instancesConcated);
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000273 } else {
274 return;
275 }
276 } else {
joshualitt2c93efe2014-11-06 12:57:13 -0800277 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info, scissorState, vb, ib));
bsalomon@google.comd62e88e2013-02-01 14:19:27 +0000278 }
cdalton6819df32014-10-15 13:43:48 -0700279 this->recordTraceMarkersIfNecessary();
bsalomon@google.com74749cd2013-01-30 16:12:41 +0000280
bsalomonb3e3a952014-09-19 11:10:40 -0700281 // Adjust the starting vertex and index when we are using reserved or array sources to
282 // compensate for the fact that the data was inserted into a larger vb/ib owned by the pool.
283 if (kBuffer_GeometrySrcType != this->getGeomSrc().fVertexSrc) {
284 size_t bytes = (info.vertexCount() + info.startVertex()) * drawState.getVertexStride();
285 poolState.fUsedPoolVertexBytes = SkTMax(poolState.fUsedPoolVertexBytes, bytes);
cdalton6819df32014-10-15 13:43:48 -0700286 draw->fInfo.adjustStartVertex(poolState.fPoolStartVertex);
reed@google.comac10a2d2010-12-22 21:39:39 +0000287 }
bsalomonb3e3a952014-09-19 11:10:40 -0700288
289 if (info.isIndexed() && kBuffer_GeometrySrcType != this->getGeomSrc().fIndexSrc) {
290 size_t bytes = (info.indexCount() + info.startIndex()) * sizeof(uint16_t);
291 poolState.fUsedPoolIndexBytes = SkTMax(poolState.fUsedPoolIndexBytes, bytes);
cdalton6819df32014-10-15 13:43:48 -0700292 draw->fInfo.adjustStartIndex(poolState.fPoolStartIndex);
commit-bot@chromium.org9b62aa12014-03-25 11:59:40 +0000293 }
commit-bot@chromium.org9b62aa12014-03-25 11:59:40 +0000294}
sugoi@google.com5f74cf82012-12-17 21:16:45 +0000295
joshualitt2c93efe2014-11-06 12:57:13 -0800296void GrInOrderDrawBuffer::onStencilPath(const GrPath* path,
297 const GrClipMaskManager::ScissorState& scissorState,
298 const GrStencilSettings& stencilSettings) {
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000299 // Only compare the subset of GrDrawState relevant to path stenciling?
bsalomon838f62d2014-08-05 07:15:57 -0700300 this->recordStateIfNecessary();
cdalton6819df32014-10-15 13:43:48 -0700301 StencilPath* sp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, StencilPath, (path));
joshualitt2c93efe2014-11-06 12:57:13 -0800302 sp->fScissorState = scissorState;
303 sp->fStencilSettings = stencilSettings;
cdalton6819df32014-10-15 13:43:48 -0700304 this->recordTraceMarkersIfNecessary();
bsalomon@google.com64aef2b2012-06-11 15:36:13 +0000305}
306
commit-bot@chromium.org32184d82013-10-09 15:14:18 +0000307void GrInOrderDrawBuffer::onDrawPath(const GrPath* path,
joshualitt2c93efe2014-11-06 12:57:13 -0800308 const GrClipMaskManager::ScissorState& scissorState,
309 const GrStencilSettings& stencilSettings,
joshualitt92e496f2014-10-31 13:56:50 -0700310 const GrDeviceCoordTexture* dstCopy) {
commit-bot@chromium.orgc4dc0ad2013-10-09 14:11:33 +0000311 // TODO: Only compare the subset of GrDrawState relevant to path covering?
bsalomon838f62d2014-08-05 07:15:57 -0700312 this->recordStateIfNecessary();
cdalton6819df32014-10-15 13:43:48 -0700313 DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (path));
bsalomon49f085d2014-09-05 13:34:00 -0700314 if (dstCopy) {
cdalton6819df32014-10-15 13:43:48 -0700315 dp->fDstCopy = *dstCopy;
commit-bot@chromium.orgc4dc0ad2013-10-09 14:11:33 +0000316 }
joshualitt2c93efe2014-11-06 12:57:13 -0800317 dp->fScissorState = scissorState;
318 dp->fStencilSettings = stencilSettings;
cdalton6819df32014-10-15 13:43:48 -0700319 this->recordTraceMarkersIfNecessary();
commit-bot@chromium.orgc4dc0ad2013-10-09 14:11:33 +0000320}
321
cdaltonb85a0aa2014-07-21 15:32:44 -0700322void GrInOrderDrawBuffer::onDrawPaths(const GrPathRange* pathRange,
joshualitt2c93efe2014-11-06 12:57:13 -0800323 const uint32_t indices[],
324 int count,
325 const float transforms[],
326 PathTransformType transformsType,
327 const GrClipMaskManager::ScissorState& scissorState,
328 const GrStencilSettings& stencilSettings,
joshualitt92e496f2014-10-31 13:56:50 -0700329 const GrDeviceCoordTexture* dstCopy) {
bsalomon49f085d2014-09-05 13:34:00 -0700330 SkASSERT(pathRange);
331 SkASSERT(indices);
332 SkASSERT(transforms);
commit-bot@chromium.org9b62aa12014-03-25 11:59:40 +0000333
bsalomon838f62d2014-08-05 07:15:57 -0700334 this->recordStateIfNecessary();
cdalton6819df32014-10-15 13:43:48 -0700335
336 int sizeOfIndices = sizeof(uint32_t) * count;
337 int sizeOfTransforms = sizeof(float) * count *
338 GrPathRendering::PathTransformSize(transformsType);
339
340 DrawPaths* dp = GrNEW_APPEND_WITH_DATA_TO_RECORDER(fCmdBuffer, DrawPaths, (pathRange),
341 sizeOfIndices + sizeOfTransforms);
342 memcpy(dp->indices(), indices, sizeOfIndices);
cdaltonb85a0aa2014-07-21 15:32:44 -0700343 dp->fCount = count;
cdalton6819df32014-10-15 13:43:48 -0700344 memcpy(dp->transforms(), transforms, sizeOfTransforms);
cdaltonb85a0aa2014-07-21 15:32:44 -0700345 dp->fTransformsType = transformsType;
joshualitt2c93efe2014-11-06 12:57:13 -0800346 dp->fScissorState = scissorState;
347 dp->fStencilSettings = stencilSettings;
bsalomon49f085d2014-09-05 13:34:00 -0700348 if (dstCopy) {
commit-bot@chromium.org9b62aa12014-03-25 11:59:40 +0000349 dp->fDstCopy = *dstCopy;
350 }
cdalton6819df32014-10-15 13:43:48 -0700351
352 this->recordTraceMarkersIfNecessary();
commit-bot@chromium.org9b62aa12014-03-25 11:59:40 +0000353}
354
bsalomon63b21962014-11-05 07:05:34 -0800355void GrInOrderDrawBuffer::onClear(const SkIRect* rect, GrColor color,
356 bool canIgnoreRect, GrRenderTarget* renderTarget) {
commit-bot@chromium.orgfd03d4a2013-07-17 21:39:42 +0000357 SkIRect r;
bsalomon@google.com1b3ce472012-08-17 13:43:08 +0000358 if (NULL == renderTarget) {
359 renderTarget = this->drawState()->getRenderTarget();
bsalomon49f085d2014-09-05 13:34:00 -0700360 SkASSERT(renderTarget);
bsalomon@google.com1b3ce472012-08-17 13:43:08 +0000361 }
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000362 if (NULL == rect) {
363 // We could do something smart and remove previous draws and clears to
364 // the current render target. If we get that smart we have to make sure
365 // those draws aren't read before this clear (render-to-texture).
bsalomon@google.com1b3ce472012-08-17 13:43:08 +0000366 r.setLTRB(0, 0, renderTarget->width(), renderTarget->height());
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000367 rect = &r;
368 }
cdalton6819df32014-10-15 13:43:48 -0700369 Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget));
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000370 GrColorIsPMAssert(color);
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000371 clr->fColor = color;
372 clr->fRect = *rect;
robertphillips@google.com56ce48a2013-10-31 21:44:25 +0000373 clr->fCanIgnoreRect = canIgnoreRect;
cdalton6819df32014-10-15 13:43:48 -0700374 this->recordTraceMarkersIfNecessary();
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000375}
376
joshualitt6db519c2014-10-29 08:48:18 -0700377void GrInOrderDrawBuffer::clearStencilClip(const SkIRect& rect,
378 bool insideClip,
379 GrRenderTarget* renderTarget) {
380 if (NULL == renderTarget) {
381 renderTarget = this->drawState()->getRenderTarget();
382 SkASSERT(renderTarget);
383 }
384 ClearStencilClip* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, ClearStencilClip, (renderTarget));
385 clr->fRect = rect;
386 clr->fInsideClip = insideClip;
387 this->recordTraceMarkersIfNecessary();
388}
389
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000390void GrInOrderDrawBuffer::discard(GrRenderTarget* renderTarget) {
bsalomon89c62982014-11-03 12:08:42 -0800391 SkASSERT(renderTarget);
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000392 if (!this->caps()->discardRenderTargetSupport()) {
393 return;
394 }
cdalton6819df32014-10-15 13:43:48 -0700395 Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget));
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000396 clr->fColor = GrColor_ILLEGAL;
cdalton6819df32014-10-15 13:43:48 -0700397 this->recordTraceMarkersIfNecessary();
commit-bot@chromium.org28361fa2014-03-28 16:08:05 +0000398}
399
reed@google.comac10a2d2010-12-22 21:39:39 +0000400void GrInOrderDrawBuffer::reset() {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000401 SkASSERT(1 == fGeoPoolStateStack.count());
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000402 this->resetVertexSource();
403 this->resetIndexSource();
cdalton6819df32014-10-15 13:43:48 -0700404
405 fCmdBuffer.reset();
406 fLastState = NULL;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000407 fVertexPool.reset();
408 fIndexPool.reset();
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000409 fGpuCmdMarkers.reset();
reed@google.comac10a2d2010-12-22 21:39:39 +0000410}
411
robertphillips@google.com1267fbd2013-07-03 18:37:27 +0000412void GrInOrderDrawBuffer::flush() {
413 if (fFlushing) {
414 return;
415 }
416
jvanverth8e80d172014-06-19 12:01:10 -0700417 this->getContext()->getFontCache()->updateTextures();
418
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000419 SkASSERT(kReserved_GeometrySrcType != this->getGeomSrc().fVertexSrc);
420 SkASSERT(kReserved_GeometrySrcType != this->getGeomSrc().fIndexSrc);
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000421
cdalton6819df32014-10-15 13:43:48 -0700422 if (fCmdBuffer.empty()) {
robertphillips@google.com1267fbd2013-07-03 18:37:27 +0000423 return;
reed@google.comac10a2d2010-12-22 21:39:39 +0000424 }
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000425
426 GrAutoTRestore<bool> flushRestore(&fFlushing);
427 fFlushing = true;
reed@google.comac10a2d2010-12-22 21:39:39 +0000428
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000429 fVertexPool.unmap();
430 fIndexPool.unmap();
reed@google.comac10a2d2010-12-22 21:39:39 +0000431
bsalomona70353e2014-07-07 08:15:07 -0700432 GrDrawState* prevDrawState = SkRef(fDstGpu->drawState());
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
439 while (iter.next()) {
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000440 GrGpuTraceMarker newMarker("", -1);
egdanield78a1682014-07-09 10:41:26 -0700441 SkString traceString;
cdalton6819df32014-10-15 13:43:48 -0700442 if (cmd_has_trace_marker(iter->fType)) {
egdanield78a1682014-07-09 10:41:26 -0700443 traceString = fGpuCmdMarkers[currCmdMarker].toString();
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000444 newMarker.fMarker = traceString.c_str();
445 fDstGpu->addGpuTraceMarker(&newMarker);
446 ++currCmdMarker;
447 }
cdalton6819df32014-10-15 13:43:48 -0700448
449 SkDEBUGCODE(bool isDraw = kDraw_Cmd == strip_trace_bit(iter->fType) ||
450 kStencilPath_Cmd == strip_trace_bit(iter->fType) ||
451 kDrawPath_Cmd == strip_trace_bit(iter->fType) ||
452 kDrawPaths_Cmd == strip_trace_bit(iter->fType));
453 SkASSERT(!isDraw || fDstGpu->drawState() != prevDrawState);
454
455 iter->execute(fDstGpu);
456
457 if (cmd_has_trace_marker(iter->fType)) {
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000458 fDstGpu->removeGpuTraceMarker(&newMarker);
459 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000460 }
mtkleinf439c772014-10-14 14:29:30 -0700461
cdalton6819df32014-10-15 13:43:48 -0700462 fDstGpu->restoreActiveTraceMarkers();
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +0000463 SkASSERT(fGpuCmdMarkers.count() == currCmdMarker);
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000464
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000465 fDstGpu->setDrawState(prevDrawState);
bsalomon@google.coma5d056a2012-03-27 15:59:58 +0000466 prevDrawState->unref();
bsalomon@google.com55e4a202013-01-11 13:54:21 +0000467 this->reset();
commit-bot@chromium.orga8916ff2013-08-16 15:53:46 +0000468 ++fDrawID;
reed@google.comac10a2d2010-12-22 21:39:39 +0000469}
470
joshualitt3322fa42014-11-07 08:48:51 -0800471void GrInOrderDrawBuffer::Draw::execute(GrGpu* gpu) {
cdalton6819df32014-10-15 13:43:48 -0700472 gpu->setVertexSourceToBuffer(this->vertexBuffer());
473 if (fInfo.isIndexed()) {
474 gpu->setIndexSourceToBuffer(this->indexBuffer());
475 }
joshualitt4b68ec02014-11-07 14:11:45 -0800476 gpu->draw(fInfo, fScissorState);
cdalton6819df32014-10-15 13:43:48 -0700477}
478
joshualitt3322fa42014-11-07 08:48:51 -0800479void GrInOrderDrawBuffer::StencilPath::execute(GrGpu* gpu) {
joshualitt4b68ec02014-11-07 14:11:45 -0800480 gpu->stencilPath(this->path(), fScissorState, fStencilSettings);
cdalton6819df32014-10-15 13:43:48 -0700481}
482
joshualitt3322fa42014-11-07 08:48:51 -0800483void GrInOrderDrawBuffer::DrawPath::execute(GrGpu* gpu) {
joshualitt4b68ec02014-11-07 14:11:45 -0800484 gpu->drawPath(this->path(), fScissorState, fStencilSettings,
joshualitt2c93efe2014-11-06 12:57:13 -0800485 fDstCopy.texture() ? &fDstCopy : NULL);
cdalton6819df32014-10-15 13:43:48 -0700486}
487
joshualitt3322fa42014-11-07 08:48:51 -0800488void GrInOrderDrawBuffer::DrawPaths::execute(GrGpu* gpu) {
joshualitt4b68ec02014-11-07 14:11:45 -0800489 gpu->drawPaths(this->pathRange(), this->indices(), fCount, this->transforms(),
joshualitt2c93efe2014-11-06 12:57:13 -0800490 fTransformsType, fScissorState, fStencilSettings,
491 fDstCopy.texture() ? &fDstCopy : NULL);
cdalton6819df32014-10-15 13:43:48 -0700492}
493
joshualitt3322fa42014-11-07 08:48:51 -0800494void GrInOrderDrawBuffer::SetState::execute(GrGpu* gpu) {
cdalton6819df32014-10-15 13:43:48 -0700495 gpu->setDrawState(&fState);
496}
497
joshualitt3322fa42014-11-07 08:48:51 -0800498void GrInOrderDrawBuffer::Clear::execute(GrGpu* gpu) {
cdalton6819df32014-10-15 13:43:48 -0700499 if (GrColor_ILLEGAL == fColor) {
500 gpu->discard(this->renderTarget());
501 } else {
502 gpu->clear(&fRect, fColor, fCanIgnoreRect, this->renderTarget());
503 }
504}
505
joshualitt3322fa42014-11-07 08:48:51 -0800506void GrInOrderDrawBuffer::ClearStencilClip::execute(GrGpu* gpu) {
joshualitt6db519c2014-10-29 08:48:18 -0700507 gpu->clearStencilClip(fRect, fInsideClip, this->renderTarget());
508}
509
joshualitt3322fa42014-11-07 08:48:51 -0800510void GrInOrderDrawBuffer::CopySurface::execute(GrGpu* gpu) {
cdalton6819df32014-10-15 13:43:48 -0700511 gpu->copySurface(this->dst(), this->src(), fSrcRect, fDstPoint);
512}
513
joshualitta7024152014-11-03 14:16:35 -0800514bool GrInOrderDrawBuffer::copySurface(GrSurface* dst,
515 GrSurface* src,
516 const SkIRect& srcRect,
517 const SkIPoint& dstPoint) {
bsalomon@google.com116ad842013-04-09 15:38:19 +0000518 if (fDstGpu->canCopySurface(dst, src, srcRect, dstPoint)) {
cdalton6819df32014-10-15 13:43:48 -0700519 CopySurface* cs = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, CopySurface, (dst, src));
bsalomon@google.com116ad842013-04-09 15:38:19 +0000520 cs->fSrcRect = srcRect;
521 cs->fDstPoint = dstPoint;
cdalton6819df32014-10-15 13:43:48 -0700522 this->recordTraceMarkersIfNecessary();
bsalomon@google.com116ad842013-04-09 15:38:19 +0000523 return true;
joshualitta7024152014-11-03 14:16:35 -0800524 } else if (GrDrawTarget::canCopySurface(dst, src, srcRect, dstPoint)) {
525 GrDrawTarget::copySurface(dst, src, srcRect, dstPoint);
526 return true;
bsalomon@google.com116ad842013-04-09 15:38:19 +0000527 } else {
528 return false;
529 }
530}
531
joshualitta7024152014-11-03 14:16:35 -0800532bool GrInOrderDrawBuffer::canCopySurface(GrSurface* dst,
533 GrSurface* src,
534 const SkIRect& srcRect,
535 const SkIPoint& dstPoint) {
536 return fDstGpu->canCopySurface(dst, src, srcRect, dstPoint) ||
537 GrDrawTarget::canCopySurface(dst, src, srcRect, dstPoint);
bsalomon@google.com116ad842013-04-09 15:38:19 +0000538}
539
bsalomonf2703d82014-10-28 14:33:06 -0700540void GrInOrderDrawBuffer::initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc) {
bsalomon@google.comeb851172013-04-15 13:51:00 +0000541 fDstGpu->initCopySurfaceDstDesc(src, desc);
542}
543
robertphillips@google.com9528bdb2013-09-18 22:33:57 +0000544void GrInOrderDrawBuffer::willReserveVertexAndIndexSpace(int vertexCount,
545 int indexCount) {
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000546 // We use geometryHints() to know whether to flush the draw buffer. We
547 // can't flush if we are inside an unbalanced pushGeometrySource.
548 // Moreover, flushing blows away vertex and index data that was
549 // previously reserved. So if the vertex or index data is pulled from
550 // reserved space and won't be released by this request then we can't
551 // flush.
552 bool insideGeoPush = fGeoPoolStateStack.count() > 1;
bsalomon@google.com97805382012-03-13 14:32:07 +0000553
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000554 bool unreleasedVertexSpace =
555 !vertexCount &&
556 kReserved_GeometrySrcType == this->getGeomSrc().fVertexSrc;
bsalomon@google.com97805382012-03-13 14:32:07 +0000557
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000558 bool unreleasedIndexSpace =
559 !indexCount &&
560 kReserved_GeometrySrcType == this->getGeomSrc().fIndexSrc;
bsalomon@google.com97805382012-03-13 14:32:07 +0000561
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000562 int vcount = vertexCount;
563 int icount = indexCount;
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000564
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000565 if (!insideGeoPush &&
566 !unreleasedVertexSpace &&
567 !unreleasedIndexSpace &&
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000568 this->geometryHints(&vcount, &icount)) {
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000569 this->flush();
bsalomon@google.com97805382012-03-13 14:32:07 +0000570 }
571}
572
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000573bool GrInOrderDrawBuffer::geometryHints(int* vertexCount,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000574 int* indexCount) const {
575 // we will recommend a flush if the data could fit in a single
576 // preallocated buffer but none are left and it can't fit
577 // in the current buffer (which may not be prealloced).
reed@google.comac10a2d2010-12-22 21:39:39 +0000578 bool flush = false;
bsalomon49f085d2014-09-05 13:34:00 -0700579 if (indexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000580 int32_t currIndices = fIndexPool.currentBufferIndices();
581 if (*indexCount > currIndices &&
582 (!fIndexPool.preallocatedBuffersRemaining() &&
583 *indexCount <= fIndexPool.preallocatedBufferIndices())) {
584
585 flush = true;
586 }
587 *indexCount = currIndices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000588 }
bsalomon49f085d2014-09-05 13:34:00 -0700589 if (vertexCount) {
egdaniel7b3d5ee2014-08-28 05:41:14 -0700590 size_t vertexStride = this->getDrawState().getVertexStride();
591 int32_t currVertices = fVertexPool.currentBufferVertices(vertexStride);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000592 if (*vertexCount > currVertices &&
593 (!fVertexPool.preallocatedBuffersRemaining() &&
egdaniel7b3d5ee2014-08-28 05:41:14 -0700594 *vertexCount <= fVertexPool.preallocatedBufferVertices(vertexStride))) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000595
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000596 flush = true;
reed@google.comac10a2d2010-12-22 21:39:39 +0000597 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000598 *vertexCount = currVertices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000599 }
600 return flush;
601}
602
jvanverth@google.coma6338982013-01-31 21:34:25 +0000603bool GrInOrderDrawBuffer::onReserveVertexSpace(size_t vertexSize,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000604 int vertexCount,
605 void** vertices) {
606 GeometryPoolState& poolState = fGeoPoolStateStack.back();
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000607 SkASSERT(vertexCount > 0);
bsalomon49f085d2014-09-05 13:34:00 -0700608 SkASSERT(vertices);
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000609 SkASSERT(0 == poolState.fUsedPoolVertexBytes);
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000610
jvanverth@google.coma6338982013-01-31 21:34:25 +0000611 *vertices = fVertexPool.makeSpace(vertexSize,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000612 vertexCount,
613 &poolState.fPoolVertexBuffer,
614 &poolState.fPoolStartVertex);
bsalomon49f085d2014-09-05 13:34:00 -0700615 return SkToBool(*vertices);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000616}
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000617
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000618bool GrInOrderDrawBuffer::onReserveIndexSpace(int indexCount, void** indices) {
619 GeometryPoolState& poolState = fGeoPoolStateStack.back();
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000620 SkASSERT(indexCount > 0);
bsalomon49f085d2014-09-05 13:34:00 -0700621 SkASSERT(indices);
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000622 SkASSERT(0 == poolState.fUsedPoolIndexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000623
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000624 *indices = fIndexPool.makeSpace(indexCount,
625 &poolState.fPoolIndexBuffer,
626 &poolState.fPoolStartIndex);
bsalomon49f085d2014-09-05 13:34:00 -0700627 return SkToBool(*indices);
reed@google.comac10a2d2010-12-22 21:39:39 +0000628}
629
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000630void GrInOrderDrawBuffer::releaseReservedVertexSpace() {
631 GeometryPoolState& poolState = fGeoPoolStateStack.back();
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000632 const GeometrySrcState& geoSrc = this->getGeomSrc();
bsalomon@google.comd57d71a2012-08-16 16:26:33 +0000633
634 // If we get a release vertex space call then our current source should either be reserved
635 // or array (which we copied into reserved space).
joshualittd1aa8ff2014-11-04 07:47:55 -0800636 SkASSERT(kReserved_GeometrySrcType == geoSrc.fVertexSrc);
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000637
638 // When the caller reserved vertex buffer space we gave it back a pointer
639 // provided by the vertex buffer pool. At each draw we tracked the largest
640 // offset into the pool's pointer that was referenced. Now we return to the
641 // pool any portion at the tail of the allocation that no draw referenced.
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000642 size_t reservedVertexBytes = geoSrc.fVertexSize * geoSrc.fVertexCount;
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000643 fVertexPool.putBack(reservedVertexBytes -
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000644 poolState.fUsedPoolVertexBytes);
645 poolState.fUsedPoolVertexBytes = 0;
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000646 poolState.fPoolVertexBuffer = NULL;
647 poolState.fPoolStartVertex = 0;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000648}
649
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000650void GrInOrderDrawBuffer::releaseReservedIndexSpace() {
651 GeometryPoolState& poolState = fGeoPoolStateStack.back();
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000652 const GeometrySrcState& geoSrc = this->getGeomSrc();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000653
bsalomon@google.comd57d71a2012-08-16 16:26:33 +0000654 // If we get a release index space call then our current source should either be reserved
655 // or array (which we copied into reserved space).
joshualittd1aa8ff2014-11-04 07:47:55 -0800656 SkASSERT(kReserved_GeometrySrcType == geoSrc.fIndexSrc);
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000657
658 // Similar to releaseReservedVertexSpace we return any unused portion at
659 // the tail
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000660 size_t reservedIndexBytes = sizeof(uint16_t) * geoSrc.fIndexCount;
661 fIndexPool.putBack(reservedIndexBytes - poolState.fUsedPoolIndexBytes);
662 poolState.fUsedPoolIndexBytes = 0;
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000663 poolState.fPoolIndexBuffer = NULL;
664 poolState.fPoolStartIndex = 0;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000665}
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000666
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000667void GrInOrderDrawBuffer::geometrySourceWillPush() {
668 GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
669 poolState.fUsedPoolVertexBytes = 0;
670 poolState.fUsedPoolIndexBytes = 0;
commit-bot@chromium.org515dcd32013-08-28 14:17:03 +0000671#ifdef SK_DEBUG
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000672 poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0;
673 poolState.fPoolStartVertex = ~0;
674 poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0;
675 poolState.fPoolStartIndex = ~0;
676#endif
677}
678
bsalomonb3e3a952014-09-19 11:10:40 -0700679void GrInOrderDrawBuffer::geometrySourceWillPop(const GeometrySrcState& restoredState) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000680 SkASSERT(fGeoPoolStateStack.count() > 1);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000681 fGeoPoolStateStack.pop_back();
682 GeometryPoolState& poolState = fGeoPoolStateStack.back();
683 // we have to assume that any slack we had in our vertex/index data
684 // is now unreleasable because data may have been appended later in the
685 // pool.
joshualittd1aa8ff2014-11-04 07:47:55 -0800686 if (kReserved_GeometrySrcType == restoredState.fVertexSrc) {
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000687 poolState.fUsedPoolVertexBytes = restoredState.fVertexSize * restoredState.fVertexCount;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000688 }
joshualittd1aa8ff2014-11-04 07:47:55 -0800689 if (kReserved_GeometrySrcType == restoredState.fIndexSrc) {
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000690 poolState.fUsedPoolIndexBytes = sizeof(uint16_t) *
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000691 restoredState.fIndexCount;
692 }
693}
694
bsalomon838f62d2014-08-05 07:15:57 -0700695void GrInOrderDrawBuffer::recordStateIfNecessary() {
cdalton6819df32014-10-15 13:43:48 -0700696 if (!fLastState) {
697 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (this->getDrawState()));
698 fLastState = &ss->fState;
699 this->convertDrawStateToPendingExec(fLastState);
700 this->recordTraceMarkersIfNecessary();
bsalomon838f62d2014-08-05 07:15:57 -0700701 return;
702 }
703 const GrDrawState& curr = this->getDrawState();
cdalton6819df32014-10-15 13:43:48 -0700704 switch (GrDrawState::CombineIfPossible(*fLastState, curr, *this->caps())) {
bsalomon838f62d2014-08-05 07:15:57 -0700705 case GrDrawState::kIncompatible_CombinedState:
cdalton6819df32014-10-15 13:43:48 -0700706 fLastState = &GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (curr))->fState;
707 this->convertDrawStateToPendingExec(fLastState);
708 this->recordTraceMarkersIfNecessary();
bsalomon838f62d2014-08-05 07:15:57 -0700709 break;
710 case GrDrawState::kA_CombinedState:
711 case GrDrawState::kAOrB_CombinedState: // Treat the same as kA.
712 break;
713 case GrDrawState::kB_CombinedState:
bsalomon2a9ca782014-09-05 14:27:43 -0700714 // prev has already been converted to pending execution. That is a one-way ticket.
cdalton6819df32014-10-15 13:43:48 -0700715 // So here we just destruct the previous state and reinit with a new copy of curr.
716 // Note that this goes away when we move GrIODB over to taking optimized snapshots
717 // of draw states.
718 fLastState->~GrDrawState();
719 SkNEW_PLACEMENT_ARGS(fLastState, GrDrawState, (curr));
720 this->convertDrawStateToPendingExec(fLastState);
bsalomon838f62d2014-08-05 07:15:57 -0700721 break;
722 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000723}
724
cdalton6819df32014-10-15 13:43:48 -0700725void GrInOrderDrawBuffer::recordTraceMarkersIfNecessary() {
726 SkASSERT(!fCmdBuffer.empty());
727 SkASSERT(!cmd_has_trace_marker(fCmdBuffer.back().fType));
mtkleinf439c772014-10-14 14:29:30 -0700728 const GrTraceMarkerSet& activeTraceMarkers = this->getActiveTraceMarkers();
729 if (activeTraceMarkers.count() > 0) {
cdalton6819df32014-10-15 13:43:48 -0700730 fCmdBuffer.back().fType = add_trace_bit(fCmdBuffer.back().fType);
mtkleinf439c772014-10-14 14:29:30 -0700731 fGpuCmdMarkers.push_back(activeTraceMarkers);
mtklein07894c42014-10-13 14:00:42 -0700732 }
mtklein07894c42014-10-13 14:00:42 -0700733}