OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2015 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
| 8 #include "GrTargetCommands.h" |
| 9 |
| 10 #include "GrColor.h" |
| 11 #include "GrDefaultGeoProcFactory.h" |
8 #include "GrInOrderDrawBuffer.h" | 12 #include "GrInOrderDrawBuffer.h" |
9 | |
10 #include "GrBufferAllocPool.h" | |
11 #include "GrDefaultGeoProcFactory.h" | |
12 #include "GrDrawTargetCaps.h" | |
13 #include "GrGpu.h" | |
14 #include "GrTemplates.h" | 13 #include "GrTemplates.h" |
15 #include "GrFontCache.h" | 14 #include "SkPoint.h" |
16 #include "GrTexture.h" | |
17 | |
18 GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrGpu* gpu, | |
19 GrVertexBufferAllocPool* vertexPool, | |
20 GrIndexBufferAllocPool* indexPool) | |
21 : INHERITED(gpu, vertexPool, indexPool) | |
22 , fCommands(gpu, vertexPool, indexPool) | |
23 , fPathIndexBuffer(kPathIdxBufferMinReserve * sizeof(char)/4) | |
24 , fPathTransformBuffer(kPathXformBufferMinReserve * sizeof(float)/4) | |
25 , fDrawID(0) { | |
26 | |
27 SkASSERT(vertexPool); | |
28 SkASSERT(indexPool); | |
29 } | |
30 | |
31 GrInOrderDrawBuffer::~GrInOrderDrawBuffer() { | |
32 this->reset(); | |
33 } | |
34 | 15 |
35 void GrTargetCommands::closeBatch() { | 16 void GrTargetCommands::closeBatch() { |
36 if (fDrawBatch) { | 17 if (fDrawBatch) { |
37 fBatchTarget.resetNumberOfDraws(); | 18 fBatchTarget.resetNumberOfDraws(); |
38 fDrawBatch->execute(NULL, fPrevState); | 19 fDrawBatch->execute(NULL, fPrevState); |
39 fDrawBatch->fBatch->setNumberOfDraws(fBatchTarget.numberOfDraws()); | 20 fDrawBatch->fBatch->setNumberOfDraws(fBatchTarget.numberOfDraws()); |
40 fDrawBatch = NULL; | 21 fDrawBatch = NULL; |
41 } | 22 } |
42 } | 23 } |
43 | 24 |
44 //////////////////////////////////////////////////////////////////////////////// | |
45 | |
46 /** We always use per-vertex colors so that rects can be batched across color ch
anges. Sometimes we | |
47 have explicit local coords and sometimes not. We *could* always provide expl
icit local coords | |
48 and just duplicate the positions when the caller hasn't provided a local coo
rd rect, but we | |
49 haven't seen a use case which frequently switches between local rect and no
local rect draws. | |
50 | |
51 The color param is used to determine whether the opaque hint can be set on t
he draw state. | |
52 The caller must populate the vertex colors itself. | |
53 | |
54 The vertex attrib order is always pos, color, [local coords]. | |
55 */ | |
56 static const GrGeometryProcessor* create_rect_gp(bool hasExplicitLocalCoords, | |
57 GrColor color, | |
58 const SkMatrix* localMatrix) { | |
59 uint32_t flags = GrDefaultGeoProcFactory::kPosition_GPType | | |
60 GrDefaultGeoProcFactory::kColor_GPType; | |
61 flags |= hasExplicitLocalCoords ? GrDefaultGeoProcFactory::kLocalCoord_GPTyp
e : 0; | |
62 if (localMatrix) { | |
63 return GrDefaultGeoProcFactory::Create(flags, color, SkMatrix::I(), *loc
alMatrix, | |
64 GrColorIsOpaque(color)); | |
65 } else { | |
66 return GrDefaultGeoProcFactory::Create(flags, color, SkMatrix::I(), SkMa
trix::I(), | |
67 GrColorIsOpaque(color)); | |
68 } | |
69 } | |
70 | |
71 static bool path_fill_type_is_winding(const GrStencilSettings& pathStencilSettin
gs) { | 25 static bool path_fill_type_is_winding(const GrStencilSettings& pathStencilSettin
gs) { |
72 static const GrStencilSettings::Face pathFace = GrStencilSettings::kFront_Fa
ce; | 26 static const GrStencilSettings::Face pathFace = GrStencilSettings::kFront_Fa
ce; |
73 bool isWinding = kInvert_StencilOp != pathStencilSettings.passOp(pathFace); | 27 bool isWinding = kInvert_StencilOp != pathStencilSettings.passOp(pathFace); |
74 if (isWinding) { | 28 if (isWinding) { |
75 // Double check that it is in fact winding. | 29 // Double check that it is in fact winding. |
76 SkASSERT(kIncClamp_StencilOp == pathStencilSettings.passOp(pathFace)); | 30 SkASSERT(kIncClamp_StencilOp == pathStencilSettings.passOp(pathFace)); |
77 SkASSERT(kIncClamp_StencilOp == pathStencilSettings.failOp(pathFace)); | 31 SkASSERT(kIncClamp_StencilOp == pathStencilSettings.failOp(pathFace)); |
78 SkASSERT(0x1 != pathStencilSettings.writeMask(pathFace)); | 32 SkASSERT(0x1 != pathStencilSettings.writeMask(pathFace)); |
79 SkASSERT(!pathStencilSettings.isTwoSided()); | 33 SkASSERT(!pathStencilSettings.isTwoSided()); |
80 } | 34 } |
81 return isWinding; | 35 return isWinding; |
82 } | 36 } |
83 | 37 |
84 class RectBatch : public GrBatch { | |
85 public: | |
86 struct Geometry { | |
87 GrColor fColor; | |
88 SkMatrix fViewMatrix; | |
89 SkRect fRect; | |
90 bool fHasLocalRect; | |
91 bool fHasLocalMatrix; | |
92 SkRect fLocalRect; | |
93 SkMatrix fLocalMatrix; | |
94 }; | |
95 | |
96 static GrBatch* Create(const Geometry& geometry) { | |
97 return SkNEW_ARGS(RectBatch, (geometry)); | |
98 } | |
99 | |
100 const char* name() const SK_OVERRIDE { return "RectBatch"; } | |
101 | |
102 void getInvariantOutputColor(GrInitInvariantOutput* out) const SK_OVERRIDE { | |
103 // When this is called on a batch, there is only one geometry bundle | |
104 out->setKnownFourComponents(fGeoData[0].fColor); | |
105 } | |
106 | |
107 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const SK_OVERRID
E { | |
108 out->setKnownSingleComponent(0xff); | |
109 } | |
110 | |
111 void initBatchTracker(const GrPipelineInfo& init) SK_OVERRIDE { | |
112 // Handle any color overrides | |
113 if (init.fColorIgnored) { | |
114 fGeoData[0].fColor = GrColor_ILLEGAL; | |
115 } else if (GrColor_ILLEGAL != init.fOverrideColor) { | |
116 fGeoData[0].fColor = init.fOverrideColor; | |
117 } | |
118 | |
119 // setup batch properties | |
120 fBatch.fColorIgnored = init.fColorIgnored; | |
121 fBatch.fColor = fGeoData[0].fColor; | |
122 fBatch.fUsesLocalCoords = init.fUsesLocalCoords; | |
123 fBatch.fCoverageIgnored = init.fCoverageIgnored; | |
124 } | |
125 | |
126 void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline
) SK_OVERRIDE { | |
127 // Go to device coords to allow batching across matrix changes | |
128 SkMatrix invert = SkMatrix::I(); | |
129 | |
130 // if we have a local rect, then we apply the localMatrix directly to th
e localRect to | |
131 // generate vertex local coords | |
132 bool hasExplicitLocalCoords = this->hasLocalRect(); | |
133 if (!hasExplicitLocalCoords) { | |
134 if (!this->viewMatrix().isIdentity() && !this->viewMatrix().invert(&
invert)) { | |
135 SkDebugf("Could not invert\n"); | |
136 return; | |
137 } | |
138 | |
139 if (this->hasLocalMatrix()) { | |
140 invert.preConcat(this->localMatrix()); | |
141 } | |
142 } | |
143 | |
144 SkAutoTUnref<const GrGeometryProcessor> gp(create_rect_gp(hasExplicitLoc
alCoords, | |
145 this->color(), | |
146 &invert)); | |
147 | |
148 batchTarget->initDraw(gp, pipeline); | |
149 | |
150 // TODO this is hacky, but the only way we have to initialize the GP is
to use the | |
151 // GrPipelineInfo struct so we can generate the correct shader. Once we
have GrBatch | |
152 // everywhere we can remove this nastiness | |
153 GrPipelineInfo init; | |
154 init.fColorIgnored = fBatch.fColorIgnored; | |
155 init.fOverrideColor = GrColor_ILLEGAL; | |
156 init.fCoverageIgnored = fBatch.fCoverageIgnored; | |
157 init.fUsesLocalCoords = this->usesLocalCoords(); | |
158 gp->initBatchTracker(batchTarget->currentBatchTracker(), init); | |
159 | |
160 size_t vertexStride = gp->getVertexStride(); | |
161 | |
162 SkASSERT(hasExplicitLocalCoords ? | |
163 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorLo
calCoordAttr) : | |
164 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAt
tr)); | |
165 | |
166 int instanceCount = fGeoData.count(); | |
167 int vertexCount = kVertsPerRect * instanceCount; | |
168 | |
169 const GrVertexBuffer* vertexBuffer; | |
170 int firstVertex; | |
171 | |
172 void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride, | |
173 vertexCount, | |
174 &vertexBuffer, | |
175 &firstVertex); | |
176 | |
177 for (int i = 0; i < instanceCount; i++) { | |
178 const Geometry& args = fGeoData[i]; | |
179 | |
180 intptr_t offset = GrTCast<intptr_t>(vertices) + kVertsPerRect * i *
vertexStride; | |
181 SkPoint* positions = GrTCast<SkPoint*>(offset); | |
182 | |
183 positions->setRectFan(args.fRect.fLeft, args.fRect.fTop, | |
184 args.fRect.fRight, args.fRect.fBottom, vertexS
tride); | |
185 args.fViewMatrix.mapPointsWithStride(positions, vertexStride, kVerts
PerRect); | |
186 | |
187 if (args.fHasLocalRect) { | |
188 static const int kLocalOffset = sizeof(SkPoint) + sizeof(GrColor
); | |
189 SkPoint* coords = GrTCast<SkPoint*>(offset + kLocalOffset); | |
190 coords->setRectFan(args.fLocalRect.fLeft, args.fLocalRect.fTop, | |
191 args.fLocalRect.fRight, args.fLocalRect.fBott
om, | |
192 vertexStride); | |
193 if (args.fHasLocalMatrix) { | |
194 args.fLocalMatrix.mapPointsWithStride(coords, vertexStride,
kVertsPerRect); | |
195 } | |
196 } | |
197 | |
198 static const int kColorOffset = sizeof(SkPoint); | |
199 GrColor* vertColor = GrTCast<GrColor*>(offset + kColorOffset); | |
200 for (int j = 0; j < 4; ++j) { | |
201 *vertColor = args.fColor; | |
202 vertColor = (GrColor*) ((intptr_t) vertColor + vertexStride); | |
203 } | |
204 } | |
205 | |
206 const GrIndexBuffer* quadIndexBuffer = batchTarget->quadIndexBuffer(); | |
207 | |
208 GrDrawTarget::DrawInfo drawInfo; | |
209 drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType); | |
210 drawInfo.setStartVertex(0); | |
211 drawInfo.setStartIndex(0); | |
212 drawInfo.setVerticesPerInstance(kVertsPerRect); | |
213 drawInfo.setIndicesPerInstance(kIndicesPerRect); | |
214 drawInfo.adjustStartVertex(firstVertex); | |
215 drawInfo.setVertexBuffer(vertexBuffer); | |
216 drawInfo.setIndexBuffer(quadIndexBuffer); | |
217 | |
218 int maxInstancesPerDraw = quadIndexBuffer->maxQuads(); | |
219 while (instanceCount) { | |
220 drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw)
); | |
221 drawInfo.setVertexCount(drawInfo.instanceCount() * drawInfo.vertices
PerInstance()); | |
222 drawInfo.setIndexCount(drawInfo.instanceCount() * drawInfo.indicesPe
rInstance()); | |
223 | |
224 batchTarget->draw(drawInfo); | |
225 | |
226 drawInfo.setStartVertex(drawInfo.startVertex() + drawInfo.vertexCoun
t()); | |
227 instanceCount -= drawInfo.instanceCount(); | |
228 } | |
229 } | |
230 | |
231 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } | |
232 | |
233 private: | |
234 RectBatch(const Geometry& geometry) { | |
235 this->initClassID<RectBatch>(); | |
236 fGeoData.push_back(geometry); | |
237 } | |
238 | |
239 GrColor color() const { return fBatch.fColor; } | |
240 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } | |
241 bool colorIgnored() const { return fBatch.fColorIgnored; } | |
242 const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; } | |
243 const SkMatrix& localMatrix() const { return fGeoData[0].fLocalMatrix; } | |
244 bool hasLocalRect() const { return fGeoData[0].fHasLocalRect; } | |
245 bool hasLocalMatrix() const { return fGeoData[0].fHasLocalMatrix; } | |
246 | |
247 bool onCombineIfPossible(GrBatch* t) SK_OVERRIDE { | |
248 RectBatch* that = t->cast<RectBatch>(); | |
249 | |
250 if (this->hasLocalRect() != that->hasLocalRect()) { | |
251 return false; | |
252 } | |
253 | |
254 SkASSERT(this->usesLocalCoords() == that->usesLocalCoords()); | |
255 if (!this->hasLocalRect() && this->usesLocalCoords()) { | |
256 if (!this->viewMatrix().cheapEqualTo(that->viewMatrix())) { | |
257 return false; | |
258 } | |
259 | |
260 if (this->hasLocalMatrix() != that->hasLocalMatrix()) { | |
261 return false; | |
262 } | |
263 | |
264 if (this->hasLocalMatrix() && !this->localMatrix().cheapEqualTo(that
->localMatrix())) { | |
265 return false; | |
266 } | |
267 } | |
268 | |
269 if (this->color() != that->color()) { | |
270 fBatch.fColor = GrColor_ILLEGAL; | |
271 } | |
272 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin())
; | |
273 return true; | |
274 } | |
275 | |
276 struct BatchTracker { | |
277 GrColor fColor; | |
278 bool fUsesLocalCoords; | |
279 bool fColorIgnored; | |
280 bool fCoverageIgnored; | |
281 }; | |
282 | |
283 const static int kVertsPerRect = 4; | |
284 const static int kIndicesPerRect = 6; | |
285 | |
286 BatchTracker fBatch; | |
287 SkSTArray<1, Geometry, true> fGeoData; | |
288 }; | |
289 | |
290 void GrInOrderDrawBuffer::onDrawRect(GrPipelineBuilder* pipelineBuilder, | |
291 GrColor color, | |
292 const SkMatrix& viewMatrix, | |
293 const SkRect& rect, | |
294 const SkRect* localRect, | |
295 const SkMatrix* localMatrix) { | |
296 RectBatch::Geometry geometry; | |
297 geometry.fColor = color; | |
298 geometry.fViewMatrix = viewMatrix; | |
299 geometry.fRect = rect; | |
300 | |
301 if (localRect) { | |
302 geometry.fHasLocalRect = true; | |
303 geometry.fLocalRect = *localRect; | |
304 } else { | |
305 geometry.fHasLocalRect = false; | |
306 } | |
307 | |
308 if (localMatrix) { | |
309 geometry.fHasLocalMatrix = true; | |
310 geometry.fLocalMatrix = *localMatrix; | |
311 } else { | |
312 geometry.fHasLocalMatrix = false; | |
313 } | |
314 | |
315 SkAutoTUnref<GrBatch> batch(RectBatch::Create(geometry)); | |
316 | |
317 SkRect bounds = rect; | |
318 viewMatrix.mapRect(&bounds); | |
319 this->drawBatch(pipelineBuilder, batch, &bounds); | |
320 } | |
321 | |
322 int GrTargetCommands::concatInstancedDraw(GrInOrderDrawBuffer* iodb, | 38 int GrTargetCommands::concatInstancedDraw(GrInOrderDrawBuffer* iodb, |
323 const GrDrawTarget::DrawInfo& info) { | 39 const GrDrawTarget::DrawInfo& info) { |
324 SkASSERT(!fCmdBuffer.empty()); | 40 SkASSERT(!fCmdBuffer.empty()); |
325 SkASSERT(info.isInstanced()); | 41 SkASSERT(info.isInstanced()); |
326 | 42 |
327 const GrIndexBuffer* ib; | 43 const GrIndexBuffer* ib; |
328 if (!iodb->canConcatToIndexBuffer(&ib)) { | 44 if (!iodb->canConcatToIndexBuffer(&ib)) { |
329 return 0; | 45 return 0; |
330 } | 46 } |
331 | 47 |
(...skipping 22 matching lines...) Expand all Loading... |
354 instancesToConcat -= draw->fInfo.instanceCount(); | 70 instancesToConcat -= draw->fInfo.instanceCount(); |
355 instancesToConcat = SkTMin(instancesToConcat, info.instanceCount()); | 71 instancesToConcat = SkTMin(instancesToConcat, info.instanceCount()); |
356 | 72 |
357 draw->fInfo.adjustInstanceCount(instancesToConcat); | 73 draw->fInfo.adjustInstanceCount(instancesToConcat); |
358 | 74 |
359 // update last fGpuCmdMarkers to include any additional trace markers that h
ave been added | 75 // update last fGpuCmdMarkers to include any additional trace markers that h
ave been added |
360 iodb->recordTraceMarkersIfNecessary(draw); | 76 iodb->recordTraceMarkersIfNecessary(draw); |
361 return instancesToConcat; | 77 return instancesToConcat; |
362 } | 78 } |
363 | 79 |
364 void GrInOrderDrawBuffer::onDraw(const GrGeometryProcessor* gp, | |
365 const DrawInfo& info, | |
366 const PipelineInfo& pipelineInfo) { | |
367 GrTargetCommands::Cmd* cmd = fCommands.recordDraw(this, gp, info, pipelineIn
fo); | |
368 this->recordTraceMarkersIfNecessary(cmd); | |
369 } | |
370 | |
371 GrTargetCommands::Cmd* GrTargetCommands::recordDraw( | 80 GrTargetCommands::Cmd* GrTargetCommands::recordDraw( |
372 GrInOrderDrawBuffer* iodb, | 81 GrInOrderDrawBuffer* iodb, |
373 const GrGeometryProcessor* gp, | 82 const GrGeometryProcessor* gp, |
374 const GrDrawTarget::DrawInfo&
info, | 83 const GrDrawTarget::DrawInfo&
info, |
375 const GrDrawTarget::PipelineIn
fo& pipelineInfo) { | 84 const GrDrawTarget::PipelineIn
fo& pipelineInfo) { |
376 SkASSERT(info.vertexBuffer() && (!info.isIndexed() || info.indexBuffer())); | 85 SkASSERT(info.vertexBuffer() && (!info.isIndexed() || info.indexBuffer())); |
377 this->closeBatch(); | 86 this->closeBatch(); |
378 | 87 |
379 if (!this->setupPipelineAndShouldDraw(iodb, gp, pipelineInfo)) { | 88 if (!this->setupPipelineAndShouldDraw(iodb, gp, pipelineInfo)) { |
380 return NULL; | 89 return NULL; |
381 } | 90 } |
382 | 91 |
383 Draw* draw; | 92 Draw* draw; |
384 if (info.isInstanced()) { | 93 if (info.isInstanced()) { |
385 int instancesConcated = this->concatInstancedDraw(iodb, info); | 94 int instancesConcated = this->concatInstancedDraw(iodb, info); |
386 if (info.instanceCount() > instancesConcated) { | 95 if (info.instanceCount() > instancesConcated) { |
387 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info)); | 96 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info)); |
388 draw->fInfo.adjustInstanceCount(-instancesConcated); | 97 draw->fInfo.adjustInstanceCount(-instancesConcated); |
389 } else { | 98 } else { |
390 return NULL; | 99 return NULL; |
391 } | 100 } |
392 } else { | 101 } else { |
393 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info)); | 102 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info)); |
394 } | 103 } |
395 | 104 |
396 return draw; | 105 return draw; |
397 } | 106 } |
398 | 107 |
399 void GrInOrderDrawBuffer::onDrawBatch(GrBatch* batch, | |
400 const PipelineInfo& pipelineInfo) { | |
401 GrTargetCommands::Cmd* cmd = fCommands.recordDrawBatch(this, batch, pipeline
Info); | |
402 this->recordTraceMarkersIfNecessary(cmd); | |
403 } | |
404 | |
405 GrTargetCommands::Cmd* GrTargetCommands::recordDrawBatch( | 108 GrTargetCommands::Cmd* GrTargetCommands::recordDrawBatch( |
406 GrInOrderDrawBuffer* iodb, | 109 GrInOrderDrawBuffer* iodb, |
407 GrBatch* batch, | 110 GrBatch* batch, |
408 const GrDrawTarget::PipelineIn
fo& pipelineInfo) { | 111 const GrDrawTarget::PipelineIn
fo& pipelineInfo) { |
409 if (!this->setupPipelineAndShouldDraw(iodb, batch, pipelineInfo)) { | 112 if (!this->setupPipelineAndShouldDraw(iodb, batch, pipelineInfo)) { |
410 return NULL; | 113 return NULL; |
411 } | 114 } |
412 | 115 |
413 // Check if there is a Batch Draw we can batch with | 116 // Check if there is a Batch Draw we can batch with |
414 if (Cmd::kDrawBatch_Cmd != fCmdBuffer.back().type() || !fDrawBatch) { | 117 if (Cmd::kDrawBatch_Cmd != fCmdBuffer.back().type() || !fDrawBatch) { |
415 fDrawBatch = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawBatch, (batch, &fB
atchTarget)); | 118 fDrawBatch = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawBatch, (batch, &fB
atchTarget)); |
416 return fDrawBatch; | 119 return fDrawBatch; |
417 } | 120 } |
418 | 121 |
419 SkASSERT(&fCmdBuffer.back() == fDrawBatch); | 122 SkASSERT(&fCmdBuffer.back() == fDrawBatch); |
420 if (!fDrawBatch->fBatch->combineIfPossible(batch)) { | 123 if (!fDrawBatch->fBatch->combineIfPossible(batch)) { |
421 this->closeBatch(); | 124 this->closeBatch(); |
422 fDrawBatch = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawBatch, (batch, &fB
atchTarget)); | 125 fDrawBatch = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawBatch, (batch, &fB
atchTarget)); |
423 } | 126 } |
424 | 127 |
425 return fDrawBatch; | 128 return fDrawBatch; |
426 } | 129 } |
427 | 130 |
428 void GrInOrderDrawBuffer::onStencilPath(const GrPipelineBuilder& pipelineBuilder
, | |
429 const GrPathProcessor* pathProc, | |
430 const GrPath* path, | |
431 const GrScissorState& scissorState, | |
432 const GrStencilSettings& stencilSettings
) { | |
433 GrTargetCommands::Cmd* cmd = fCommands.recordStencilPath(this, pipelineBuild
er, | |
434 pathProc, path, sci
ssorState, | |
435 stencilSettings); | |
436 this->recordTraceMarkersIfNecessary(cmd); | |
437 } | |
438 | |
439 GrTargetCommands::Cmd* GrTargetCommands::recordStencilPath( | 131 GrTargetCommands::Cmd* GrTargetCommands::recordStencilPath( |
440 GrInOrderDrawBuffer* iod
b, | 132 GrInOrderDrawBuffer* iod
b, |
441 const GrPipelineBuilder&
pipelineBuilder, | 133 const GrPipelineBuilder&
pipelineBuilder, |
442 const GrPathProcessor* p
athProc, | 134 const GrPathProcessor* p
athProc, |
443 const GrPath* path, | 135 const GrPath* path, |
444 const GrScissorState& sc
issorState, | 136 const GrScissorState& sc
issorState, |
445 const GrStencilSettings&
stencilSettings) { | 137 const GrStencilSettings&
stencilSettings) { |
446 this->closeBatch(); | 138 this->closeBatch(); |
447 | 139 |
448 StencilPath* sp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, StencilPath, | 140 StencilPath* sp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, StencilPath, |
449 (path, pipelineBuilder.getRenderT
arget())); | 141 (path, pipelineBuilder.getRenderT
arget())); |
450 | 142 |
451 sp->fScissor = scissorState; | 143 sp->fScissor = scissorState; |
452 sp->fUseHWAA = pipelineBuilder.isHWAntialias(); | 144 sp->fUseHWAA = pipelineBuilder.isHWAntialias(); |
453 sp->fViewMatrix = pathProc->viewMatrix(); | 145 sp->fViewMatrix = pathProc->viewMatrix(); |
454 sp->fStencil = stencilSettings; | 146 sp->fStencil = stencilSettings; |
455 return sp; | 147 return sp; |
456 } | 148 } |
457 | 149 |
458 void GrInOrderDrawBuffer::onDrawPath(const GrPathProcessor* pathProc, | |
459 const GrPath* path, | |
460 const GrStencilSettings& stencilSettings, | |
461 const PipelineInfo& pipelineInfo) { | |
462 GrTargetCommands::Cmd* cmd = fCommands.recordDrawPath(this, pathProc, | |
463 path, stencilSettings, | |
464 pipelineInfo); | |
465 this->recordTraceMarkersIfNecessary(cmd); | |
466 } | |
467 | |
468 GrTargetCommands::Cmd* GrTargetCommands::recordDrawPath( | 150 GrTargetCommands::Cmd* GrTargetCommands::recordDrawPath( |
469 GrInOrderDrawBuffer* iodb, | 151 GrInOrderDrawBuffer* iodb, |
470 const GrPathProcessor* pathPro
c, | 152 const GrPathProcessor* pathPro
c, |
471 const GrPath* path, | 153 const GrPath* path, |
472 const GrStencilSettings& stenc
ilSettings, | 154 const GrStencilSettings& stenc
ilSettings, |
473 const GrDrawTarget::PipelineIn
fo& pipelineInfo) { | 155 const GrDrawTarget::PipelineIn
fo& pipelineInfo) { |
474 this->closeBatch(); | 156 this->closeBatch(); |
475 | 157 |
476 // TODO: Only compare the subset of GrPipelineBuilder relevant to path cover
ing? | 158 // TODO: Only compare the subset of GrPipelineBuilder relevant to path cover
ing? |
477 if (!this->setupPipelineAndShouldDraw(iodb, pathProc, pipelineInfo)) { | 159 if (!this->setupPipelineAndShouldDraw(iodb, pathProc, pipelineInfo)) { |
478 return NULL; | 160 return NULL; |
479 } | 161 } |
480 DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (path)); | 162 DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (path)); |
481 dp->fStencilSettings = stencilSettings; | 163 dp->fStencilSettings = stencilSettings; |
482 return dp; | 164 return dp; |
483 } | 165 } |
484 | 166 |
485 void GrInOrderDrawBuffer::onDrawPaths(const GrPathProcessor* pathProc, | |
486 const GrPathRange* pathRange, | |
487 const void* indices, | |
488 PathIndexType indexType, | |
489 const float transformValues[], | |
490 PathTransformType transformType, | |
491 int count, | |
492 const GrStencilSettings& stencilSettings, | |
493 const PipelineInfo& pipelineInfo) { | |
494 GrTargetCommands::Cmd* cmd = fCommands.recordDrawPaths(this, pathProc, pathR
ange, | |
495 indices, indexType, t
ransformValues, | |
496 transformType, count, | |
497 stencilSettings, pipe
lineInfo); | |
498 this->recordTraceMarkersIfNecessary(cmd); | |
499 } | |
500 | |
501 GrTargetCommands::Cmd* GrTargetCommands::recordDrawPaths( | 167 GrTargetCommands::Cmd* GrTargetCommands::recordDrawPaths( |
502 GrInOrderDrawBuffer* iodb, | 168 GrInOrderDrawBuffer* iodb, |
503 const GrPathProcessor* pathPro
c, | 169 const GrPathProcessor* pathPro
c, |
504 const GrPathRange* pathRange, | 170 const GrPathRange* pathRange, |
505 const void* indexValues, | 171 const void* indexValues, |
506 GrDrawTarget::PathIndexType in
dexType, | 172 GrDrawTarget::PathIndexType in
dexType, |
507 const float transformValues[], | 173 const float transformValues[], |
508 GrDrawTarget::PathTransformTyp
e transformType, | 174 GrDrawTarget::PathTransformTyp
e transformType, |
509 int count, | 175 int count, |
510 const GrStencilSettings& stenc
ilSettings, | 176 const GrStencilSettings& stenc
ilSettings, |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
555 DrawPaths* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPaths, (pathRange))
; | 221 DrawPaths* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPaths, (pathRange))
; |
556 dp->fIndices = savedIndices; | 222 dp->fIndices = savedIndices; |
557 dp->fIndexType = indexType; | 223 dp->fIndexType = indexType; |
558 dp->fTransforms = savedTransforms; | 224 dp->fTransforms = savedTransforms; |
559 dp->fTransformType = transformType; | 225 dp->fTransformType = transformType; |
560 dp->fCount = count; | 226 dp->fCount = count; |
561 dp->fStencilSettings = stencilSettings; | 227 dp->fStencilSettings = stencilSettings; |
562 return dp; | 228 return dp; |
563 } | 229 } |
564 | 230 |
565 void GrInOrderDrawBuffer::onClear(const SkIRect* rect, GrColor color, | |
566 bool canIgnoreRect, GrRenderTarget* renderTarg
et) { | |
567 GrTargetCommands::Cmd* cmd = fCommands.recordClear(this, rect, color, | |
568 canIgnoreRect, renderTarg
et); | |
569 this->recordTraceMarkersIfNecessary(cmd); | |
570 } | |
571 | |
572 GrTargetCommands::Cmd* GrTargetCommands::recordClear(GrInOrderDrawBuffer* iodb, | 231 GrTargetCommands::Cmd* GrTargetCommands::recordClear(GrInOrderDrawBuffer* iodb, |
573 const SkIRect* rect, | 232 const SkIRect* rect, |
574 GrColor color, | 233 GrColor color, |
575 bool canIgnoreRect, | 234 bool canIgnoreRect, |
576 GrRenderTarget* renderTarge
t) { | 235 GrRenderTarget* renderTarge
t) { |
577 SkASSERT(renderTarget); | 236 SkASSERT(renderTarget); |
578 this->closeBatch(); | 237 this->closeBatch(); |
579 | 238 |
580 SkIRect r; | 239 SkIRect r; |
581 if (NULL == rect) { | 240 if (NULL == rect) { |
582 // We could do something smart and remove previous draws and clears to | 241 // We could do something smart and remove previous draws and clears to |
583 // the current render target. If we get that smart we have to make sure | 242 // the current render target. If we get that smart we have to make sure |
584 // those draws aren't read before this clear (render-to-texture). | 243 // those draws aren't read before this clear (render-to-texture). |
585 r.setLTRB(0, 0, renderTarget->width(), renderTarget->height()); | 244 r.setLTRB(0, 0, renderTarget->width(), renderTarget->height()); |
586 rect = &r; | 245 rect = &r; |
587 } | 246 } |
588 Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget)); | 247 Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget)); |
589 GrColorIsPMAssert(color); | 248 GrColorIsPMAssert(color); |
590 clr->fColor = color; | 249 clr->fColor = color; |
591 clr->fRect = *rect; | 250 clr->fRect = *rect; |
592 clr->fCanIgnoreRect = canIgnoreRect; | 251 clr->fCanIgnoreRect = canIgnoreRect; |
593 return clr; | 252 return clr; |
594 } | 253 } |
595 | 254 |
596 void GrInOrderDrawBuffer::clearStencilClip(const SkIRect& rect, | |
597 bool insideClip, | |
598 GrRenderTarget* renderTarget) { | |
599 GrTargetCommands::Cmd* cmd = fCommands.recordClearStencilClip(this, rect, | |
600 insideClip, re
nderTarget); | |
601 this->recordTraceMarkersIfNecessary(cmd); | |
602 } | |
603 | |
604 GrTargetCommands::Cmd* GrTargetCommands::recordClearStencilClip(GrInOrderDrawBuf
fer* iodb, | 255 GrTargetCommands::Cmd* GrTargetCommands::recordClearStencilClip(GrInOrderDrawBuf
fer* iodb, |
605 const SkIRect& r
ect, | 256 const SkIRect& r
ect, |
606 bool insideClip, | 257 bool insideClip, |
607 GrRenderTarget*
renderTarget) { | 258 GrRenderTarget*
renderTarget) { |
608 SkASSERT(renderTarget); | 259 SkASSERT(renderTarget); |
609 this->closeBatch(); | 260 this->closeBatch(); |
610 | 261 |
611 ClearStencilClip* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, ClearStencilCli
p, (renderTarget)); | 262 ClearStencilClip* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, ClearStencilCli
p, (renderTarget)); |
612 clr->fRect = rect; | 263 clr->fRect = rect; |
613 clr->fInsideClip = insideClip; | 264 clr->fInsideClip = insideClip; |
614 return clr; | 265 return clr; |
615 } | 266 } |
616 | 267 |
617 void GrInOrderDrawBuffer::discard(GrRenderTarget* renderTarget) { | |
618 if (!this->caps()->discardRenderTargetSupport()) { | |
619 return; | |
620 } | |
621 | |
622 GrTargetCommands::Cmd* cmd = fCommands.recordDiscard(this, renderTarget); | |
623 this->recordTraceMarkersIfNecessary(cmd); | |
624 } | |
625 | |
626 GrTargetCommands::Cmd* GrTargetCommands::recordDiscard(GrInOrderDrawBuffer* iodb
, | 268 GrTargetCommands::Cmd* GrTargetCommands::recordDiscard(GrInOrderDrawBuffer* iodb
, |
627 GrRenderTarget* renderTar
get) { | 269 GrRenderTarget* renderTar
get) { |
628 SkASSERT(renderTarget); | 270 SkASSERT(renderTarget); |
629 this->closeBatch(); | 271 this->closeBatch(); |
630 | 272 |
631 Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget)); | 273 Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget)); |
632 clr->fColor = GrColor_ILLEGAL; | 274 clr->fColor = GrColor_ILLEGAL; |
633 return clr; | 275 return clr; |
634 } | 276 } |
635 | 277 |
636 void GrInOrderDrawBuffer::onReset() { | |
637 fCommands.reset(); | |
638 fPathIndexBuffer.rewind(); | |
639 fPathTransformBuffer.rewind(); | |
640 fGpuCmdMarkers.reset(); | |
641 } | |
642 | |
643 void GrTargetCommands::reset() { | 278 void GrTargetCommands::reset() { |
644 fCmdBuffer.reset(); | 279 fCmdBuffer.reset(); |
645 fPrevState = NULL; | 280 fPrevState = NULL; |
646 fDrawBatch = NULL; | 281 fDrawBatch = NULL; |
647 } | 282 } |
648 | 283 |
649 void GrInOrderDrawBuffer::onFlush() { | |
650 fCommands.flush(this); | |
651 ++fDrawID; | |
652 } | |
653 | |
654 void GrTargetCommands::flush(GrInOrderDrawBuffer* iodb) { | 284 void GrTargetCommands::flush(GrInOrderDrawBuffer* iodb) { |
655 if (fCmdBuffer.empty()) { | 285 if (fCmdBuffer.empty()) { |
656 return; | 286 return; |
657 } | 287 } |
658 | 288 |
659 // Updated every time we find a set state cmd to reflect the current state i
n the playback | 289 // Updated every time we find a set state cmd to reflect the current state i
n the playback |
660 // stream. | 290 // stream. |
661 SetState* currentState = NULL; | 291 SetState* currentState = NULL; |
662 | 292 |
663 // TODO this is temporary while batch is being rolled out | 293 // TODO this is temporary while batch is being rolled out |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
767 } | 397 } |
768 | 398 |
769 void GrTargetCommands::ClearStencilClip::execute(GrGpu* gpu, const SetState*) { | 399 void GrTargetCommands::ClearStencilClip::execute(GrGpu* gpu, const SetState*) { |
770 gpu->clearStencilClip(fRect, fInsideClip, this->renderTarget()); | 400 gpu->clearStencilClip(fRect, fInsideClip, this->renderTarget()); |
771 } | 401 } |
772 | 402 |
773 void GrTargetCommands::CopySurface::execute(GrGpu* gpu, const SetState*) { | 403 void GrTargetCommands::CopySurface::execute(GrGpu* gpu, const SetState*) { |
774 gpu->copySurface(this->dst(), this->src(), fSrcRect, fDstPoint); | 404 gpu->copySurface(this->dst(), this->src(), fSrcRect, fDstPoint); |
775 } | 405 } |
776 | 406 |
777 bool GrInOrderDrawBuffer::onCopySurface(GrSurface* dst, | |
778 GrSurface* src, | |
779 const SkIRect& srcRect, | |
780 const SkIPoint& dstPoint) { | |
781 GrTargetCommands::Cmd* cmd = fCommands.recordCopySurface(this, dst, src, | |
782 srcRect, dstPoint); | |
783 this->recordTraceMarkersIfNecessary(cmd); | |
784 return SkToBool(cmd); | |
785 } | |
786 | |
787 GrTargetCommands::Cmd* GrTargetCommands::recordCopySurface(GrInOrderDrawBuffer*
iodb, | 407 GrTargetCommands::Cmd* GrTargetCommands::recordCopySurface(GrInOrderDrawBuffer*
iodb, |
788 GrSurface* dst, | 408 GrSurface* dst, |
789 GrSurface* src, | 409 GrSurface* src, |
790 const SkIRect& srcRec
t, | 410 const SkIRect& srcRec
t, |
791 const SkIPoint& dstPo
int) { | 411 const SkIPoint& dstPo
int) { |
792 if (iodb->getGpu()->canCopySurface(dst, src, srcRect, dstPoint)) { | 412 if (iodb->getGpu()->canCopySurface(dst, src, srcRect, dstPoint)) { |
793 this->closeBatch(); | 413 this->closeBatch(); |
794 CopySurface* cs = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, CopySurface, (dst
, src)); | 414 CopySurface* cs = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, CopySurface, (dst
, src)); |
795 cs->fSrcRect = srcRect; | 415 cs->fSrcRect = srcRect; |
796 cs->fDstPoint = dstPoint; | 416 cs->fDstPoint = dstPoint; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
843 fPrevState->getPipeline()->isEqual(*ss->getPipeline())) { | 463 fPrevState->getPipeline()->isEqual(*ss->getPipeline())) { |
844 fCmdBuffer.pop_back(); | 464 fCmdBuffer.pop_back(); |
845 } else { | 465 } else { |
846 this->closeBatch(); | 466 this->closeBatch(); |
847 fPrevState = ss; | 467 fPrevState = ss; |
848 iodb->recordTraceMarkersIfNecessary(ss); | 468 iodb->recordTraceMarkersIfNecessary(ss); |
849 } | 469 } |
850 return true; | 470 return true; |
851 } | 471 } |
852 | 472 |
853 void GrInOrderDrawBuffer::recordTraceMarkersIfNecessary(GrTargetCommands::Cmd* c
md) { | |
854 if (!cmd) { | |
855 return; | |
856 } | |
857 const GrTraceMarkerSet& activeTraceMarkers = this->getActiveTraceMarkers(); | |
858 if (activeTraceMarkers.count() > 0) { | |
859 if (cmd->isTraced()) { | |
860 fGpuCmdMarkers.back().addSet(activeTraceMarkers); | |
861 } else { | |
862 cmd->makeTraced(); | |
863 fGpuCmdMarkers.push_back(activeTraceMarkers); | |
864 } | |
865 } | |
866 } | |
867 | |
868 void GrInOrderDrawBuffer::willReserveVertexAndIndexSpace(int vertexCount, | |
869 size_t vertexStride, | |
870 int indexCount) { | |
871 fCommands.closeBatch(); | |
872 | |
873 this->INHERITED::willReserveVertexAndIndexSpace(vertexCount, vertexStride, i
ndexCount); | |
874 } | |
OLD | NEW |