blob: d9926fd50aa7694c496b921bd85ad4fb16b160d0 [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
joshualitt6db519c2014-10-29 08:48:18 -0700471void GrInOrderDrawBuffer::Draw::execute(GrClipTarget* gpu) {
cdalton6819df32014-10-15 13:43:48 -0700472 gpu->setVertexSourceToBuffer(this->vertexBuffer());
473 if (fInfo.isIndexed()) {
474 gpu->setIndexSourceToBuffer(this->indexBuffer());
475 }
joshualitt2c93efe2014-11-06 12:57:13 -0800476 gpu->executeDraw(fInfo, fScissorState);
cdalton6819df32014-10-15 13:43:48 -0700477}
478
joshualitt6db519c2014-10-29 08:48:18 -0700479void GrInOrderDrawBuffer::StencilPath::execute(GrClipTarget* gpu) {
joshualitt2c93efe2014-11-06 12:57:13 -0800480 gpu->executeStencilPath(this->path(), fScissorState, fStencilSettings);
cdalton6819df32014-10-15 13:43:48 -0700481}
482
joshualitt6db519c2014-10-29 08:48:18 -0700483void GrInOrderDrawBuffer::DrawPath::execute(GrClipTarget* gpu) {
joshualitt2c93efe2014-11-06 12:57:13 -0800484 gpu->executeDrawPath(this->path(), fScissorState, fStencilSettings,
485 fDstCopy.texture() ? &fDstCopy : NULL);
cdalton6819df32014-10-15 13:43:48 -0700486}
487
joshualitt6db519c2014-10-29 08:48:18 -0700488void GrInOrderDrawBuffer::DrawPaths::execute(GrClipTarget* gpu) {
cdalton6819df32014-10-15 13:43:48 -0700489 gpu->executeDrawPaths(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
joshualitt6db519c2014-10-29 08:48:18 -0700494void GrInOrderDrawBuffer::SetState::execute(GrClipTarget* gpu) {
cdalton6819df32014-10-15 13:43:48 -0700495 gpu->setDrawState(&fState);
496}
497
joshualitt6db519c2014-10-29 08:48:18 -0700498void GrInOrderDrawBuffer::Clear::execute(GrClipTarget* 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
joshualitt6db519c2014-10-29 08:48:18 -0700506void GrInOrderDrawBuffer::ClearStencilClip::execute(GrClipTarget* gpu) {
507 gpu->clearStencilClip(fRect, fInsideClip, this->renderTarget());
508}
509
510void GrInOrderDrawBuffer::CopySurface::execute(GrClipTarget* 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 // we don't want to finalize any reserved geom on the target since
563 // we don't know that the client has finished writing to it.
564 bool targetHasReservedGeom = fDstGpu->hasReservedVerticesOrIndices();
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000565
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000566 int vcount = vertexCount;
567 int icount = indexCount;
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000568
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000569 if (!insideGeoPush &&
570 !unreleasedVertexSpace &&
571 !unreleasedIndexSpace &&
572 !targetHasReservedGeom &&
573 this->geometryHints(&vcount, &icount)) {
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000574 this->flush();
bsalomon@google.com97805382012-03-13 14:32:07 +0000575 }
576}
577
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000578bool GrInOrderDrawBuffer::geometryHints(int* vertexCount,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000579 int* indexCount) const {
580 // we will recommend a flush if the data could fit in a single
581 // preallocated buffer but none are left and it can't fit
582 // in the current buffer (which may not be prealloced).
reed@google.comac10a2d2010-12-22 21:39:39 +0000583 bool flush = false;
bsalomon49f085d2014-09-05 13:34:00 -0700584 if (indexCount) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000585 int32_t currIndices = fIndexPool.currentBufferIndices();
586 if (*indexCount > currIndices &&
587 (!fIndexPool.preallocatedBuffersRemaining() &&
588 *indexCount <= fIndexPool.preallocatedBufferIndices())) {
589
590 flush = true;
591 }
592 *indexCount = currIndices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000593 }
bsalomon49f085d2014-09-05 13:34:00 -0700594 if (vertexCount) {
egdaniel7b3d5ee2014-08-28 05:41:14 -0700595 size_t vertexStride = this->getDrawState().getVertexStride();
596 int32_t currVertices = fVertexPool.currentBufferVertices(vertexStride);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000597 if (*vertexCount > currVertices &&
598 (!fVertexPool.preallocatedBuffersRemaining() &&
egdaniel7b3d5ee2014-08-28 05:41:14 -0700599 *vertexCount <= fVertexPool.preallocatedBufferVertices(vertexStride))) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000600
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000601 flush = true;
reed@google.comac10a2d2010-12-22 21:39:39 +0000602 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000603 *vertexCount = currVertices;
reed@google.comac10a2d2010-12-22 21:39:39 +0000604 }
605 return flush;
606}
607
jvanverth@google.coma6338982013-01-31 21:34:25 +0000608bool GrInOrderDrawBuffer::onReserveVertexSpace(size_t vertexSize,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000609 int vertexCount,
610 void** vertices) {
611 GeometryPoolState& poolState = fGeoPoolStateStack.back();
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000612 SkASSERT(vertexCount > 0);
bsalomon49f085d2014-09-05 13:34:00 -0700613 SkASSERT(vertices);
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000614 SkASSERT(0 == poolState.fUsedPoolVertexBytes);
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000615
jvanverth@google.coma6338982013-01-31 21:34:25 +0000616 *vertices = fVertexPool.makeSpace(vertexSize,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000617 vertexCount,
618 &poolState.fPoolVertexBuffer,
619 &poolState.fPoolStartVertex);
bsalomon49f085d2014-09-05 13:34:00 -0700620 return SkToBool(*vertices);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000621}
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000622
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000623bool GrInOrderDrawBuffer::onReserveIndexSpace(int indexCount, void** indices) {
624 GeometryPoolState& poolState = fGeoPoolStateStack.back();
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000625 SkASSERT(indexCount > 0);
bsalomon49f085d2014-09-05 13:34:00 -0700626 SkASSERT(indices);
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000627 SkASSERT(0 == poolState.fUsedPoolIndexBytes);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000628
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000629 *indices = fIndexPool.makeSpace(indexCount,
630 &poolState.fPoolIndexBuffer,
631 &poolState.fPoolStartIndex);
bsalomon49f085d2014-09-05 13:34:00 -0700632 return SkToBool(*indices);
reed@google.comac10a2d2010-12-22 21:39:39 +0000633}
634
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000635void GrInOrderDrawBuffer::releaseReservedVertexSpace() {
636 GeometryPoolState& poolState = fGeoPoolStateStack.back();
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000637 const GeometrySrcState& geoSrc = this->getGeomSrc();
bsalomon@google.comd57d71a2012-08-16 16:26:33 +0000638
639 // If we get a release vertex space call then our current source should either be reserved
640 // or array (which we copied into reserved space).
joshualittd1aa8ff2014-11-04 07:47:55 -0800641 SkASSERT(kReserved_GeometrySrcType == geoSrc.fVertexSrc);
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000642
643 // When the caller reserved vertex buffer space we gave it back a pointer
644 // provided by the vertex buffer pool. At each draw we tracked the largest
645 // offset into the pool's pointer that was referenced. Now we return to the
646 // pool any portion at the tail of the allocation that no draw referenced.
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000647 size_t reservedVertexBytes = geoSrc.fVertexSize * geoSrc.fVertexCount;
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000648 fVertexPool.putBack(reservedVertexBytes -
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000649 poolState.fUsedPoolVertexBytes);
650 poolState.fUsedPoolVertexBytes = 0;
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000651 poolState.fPoolVertexBuffer = NULL;
652 poolState.fPoolStartVertex = 0;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000653}
654
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000655void GrInOrderDrawBuffer::releaseReservedIndexSpace() {
656 GeometryPoolState& poolState = fGeoPoolStateStack.back();
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000657 const GeometrySrcState& geoSrc = this->getGeomSrc();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000658
bsalomon@google.comd57d71a2012-08-16 16:26:33 +0000659 // If we get a release index space call then our current source should either be reserved
660 // or array (which we copied into reserved space).
joshualittd1aa8ff2014-11-04 07:47:55 -0800661 SkASSERT(kReserved_GeometrySrcType == geoSrc.fIndexSrc);
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000662
663 // Similar to releaseReservedVertexSpace we return any unused portion at
664 // the tail
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000665 size_t reservedIndexBytes = sizeof(uint16_t) * geoSrc.fIndexCount;
666 fIndexPool.putBack(reservedIndexBytes - poolState.fUsedPoolIndexBytes);
667 poolState.fUsedPoolIndexBytes = 0;
bsalomon@google.com3f5a95e2012-03-08 16:41:42 +0000668 poolState.fPoolIndexBuffer = NULL;
669 poolState.fPoolStartIndex = 0;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000670}
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000671
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000672void GrInOrderDrawBuffer::geometrySourceWillPush() {
673 GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
674 poolState.fUsedPoolVertexBytes = 0;
675 poolState.fUsedPoolIndexBytes = 0;
commit-bot@chromium.org515dcd32013-08-28 14:17:03 +0000676#ifdef SK_DEBUG
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000677 poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0;
678 poolState.fPoolStartVertex = ~0;
679 poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0;
680 poolState.fPoolStartIndex = ~0;
681#endif
682}
683
bsalomonb3e3a952014-09-19 11:10:40 -0700684void GrInOrderDrawBuffer::geometrySourceWillPop(const GeometrySrcState& restoredState) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000685 SkASSERT(fGeoPoolStateStack.count() > 1);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000686 fGeoPoolStateStack.pop_back();
687 GeometryPoolState& poolState = fGeoPoolStateStack.back();
688 // we have to assume that any slack we had in our vertex/index data
689 // is now unreleasable because data may have been appended later in the
690 // pool.
joshualittd1aa8ff2014-11-04 07:47:55 -0800691 if (kReserved_GeometrySrcType == restoredState.fVertexSrc) {
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000692 poolState.fUsedPoolVertexBytes = restoredState.fVertexSize * restoredState.fVertexCount;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000693 }
joshualittd1aa8ff2014-11-04 07:47:55 -0800694 if (kReserved_GeometrySrcType == restoredState.fIndexSrc) {
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000695 poolState.fUsedPoolIndexBytes = sizeof(uint16_t) *
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000696 restoredState.fIndexCount;
697 }
698}
699
bsalomon838f62d2014-08-05 07:15:57 -0700700void GrInOrderDrawBuffer::recordStateIfNecessary() {
cdalton6819df32014-10-15 13:43:48 -0700701 if (!fLastState) {
702 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (this->getDrawState()));
703 fLastState = &ss->fState;
704 this->convertDrawStateToPendingExec(fLastState);
705 this->recordTraceMarkersIfNecessary();
bsalomon838f62d2014-08-05 07:15:57 -0700706 return;
707 }
708 const GrDrawState& curr = this->getDrawState();
cdalton6819df32014-10-15 13:43:48 -0700709 switch (GrDrawState::CombineIfPossible(*fLastState, curr, *this->caps())) {
bsalomon838f62d2014-08-05 07:15:57 -0700710 case GrDrawState::kIncompatible_CombinedState:
cdalton6819df32014-10-15 13:43:48 -0700711 fLastState = &GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (curr))->fState;
712 this->convertDrawStateToPendingExec(fLastState);
713 this->recordTraceMarkersIfNecessary();
bsalomon838f62d2014-08-05 07:15:57 -0700714 break;
715 case GrDrawState::kA_CombinedState:
716 case GrDrawState::kAOrB_CombinedState: // Treat the same as kA.
717 break;
718 case GrDrawState::kB_CombinedState:
bsalomon2a9ca782014-09-05 14:27:43 -0700719 // prev has already been converted to pending execution. That is a one-way ticket.
cdalton6819df32014-10-15 13:43:48 -0700720 // So here we just destruct the previous state and reinit with a new copy of curr.
721 // Note that this goes away when we move GrIODB over to taking optimized snapshots
722 // of draw states.
723 fLastState->~GrDrawState();
724 SkNEW_PLACEMENT_ARGS(fLastState, GrDrawState, (curr));
725 this->convertDrawStateToPendingExec(fLastState);
bsalomon838f62d2014-08-05 07:15:57 -0700726 break;
727 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000728}
729
cdalton6819df32014-10-15 13:43:48 -0700730void GrInOrderDrawBuffer::recordTraceMarkersIfNecessary() {
731 SkASSERT(!fCmdBuffer.empty());
732 SkASSERT(!cmd_has_trace_marker(fCmdBuffer.back().fType));
mtkleinf439c772014-10-14 14:29:30 -0700733 const GrTraceMarkerSet& activeTraceMarkers = this->getActiveTraceMarkers();
734 if (activeTraceMarkers.count() > 0) {
cdalton6819df32014-10-15 13:43:48 -0700735 fCmdBuffer.back().fType = add_trace_bit(fCmdBuffer.back().fType);
mtkleinf439c772014-10-14 14:29:30 -0700736 fGpuCmdMarkers.push_back(activeTraceMarkers);
mtklein07894c42014-10-13 14:00:42 -0700737 }
mtklein07894c42014-10-13 14:00:42 -0700738}