OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 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 "GrInOrderDrawBuffer.h" | 8 #include "GrInOrderDrawBuffer.h" |
9 | 9 |
10 #include "GrBufferAllocPool.h" | 10 #include "GrBufferAllocPool.h" |
11 #include "GrDrawTargetCaps.h" | 11 #include "GrDrawTargetCaps.h" |
12 #include "GrTextStrike.h" | 12 #include "GrTextStrike.h" |
13 #include "GrGpu.h" | 13 #include "GrGpu.h" |
14 #include "GrTemplates.h" | 14 #include "GrTemplates.h" |
15 #include "GrTexture.h" | 15 #include "GrTexture.h" |
16 | 16 |
17 GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrGpu* gpu, | 17 GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrGpu* gpu, |
18 GrVertexBufferAllocPool* vertexPool, | 18 GrVertexBufferAllocPool* vertexPool, |
19 GrIndexBufferAllocPool* indexPool) | 19 GrIndexBufferAllocPool* indexPool) |
20 : GrDrawTarget(gpu->getContext()) | 20 : GrDrawTarget(gpu->getContext()) |
| 21 , fCmdBuffer(kCmdBufferInitialSizeInBytes) |
| 22 , fLastState(NULL) |
| 23 , fLastClip(NULL) |
21 , fDstGpu(gpu) | 24 , fDstGpu(gpu) |
22 , fClipSet(true) | 25 , fClipSet(true) |
23 , fClipProxyState(kUnknown_ClipProxyState) | 26 , fClipProxyState(kUnknown_ClipProxyState) |
24 , fVertexPool(*vertexPool) | 27 , fVertexPool(*vertexPool) |
25 , fIndexPool(*indexPool) | 28 , fIndexPool(*indexPool) |
26 , fFlushing(false) | 29 , fFlushing(false) |
27 , fDrawID(0) { | 30 , fDrawID(0) { |
28 | 31 |
29 fDstGpu->ref(); | 32 fDstGpu->ref(); |
30 fCaps.reset(SkRef(fDstGpu->caps())); | 33 fCaps.reset(SkRef(fDstGpu->caps())); |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
209 return fClipProxy.contains(devBounds); | 212 return fClipProxy.contains(devBounds); |
210 } | 213 } |
211 SkPoint originOffset = {SkIntToScalar(this->getClip()->fOrigin.fX), | 214 SkPoint originOffset = {SkIntToScalar(this->getClip()->fOrigin.fX), |
212 SkIntToScalar(this->getClip()->fOrigin.fY)}; | 215 SkIntToScalar(this->getClip()->fOrigin.fY)}; |
213 SkRect clipSpaceBounds = devBounds; | 216 SkRect clipSpaceBounds = devBounds; |
214 clipSpaceBounds.offset(originOffset); | 217 clipSpaceBounds.offset(originOffset); |
215 return this->getClip()->fClipStack->quickContains(clipSpaceBounds); | 218 return this->getClip()->fClipStack->quickContains(clipSpaceBounds); |
216 } | 219 } |
217 | 220 |
218 int GrInOrderDrawBuffer::concatInstancedDraw(const DrawInfo& info) { | 221 int GrInOrderDrawBuffer::concatInstancedDraw(const DrawInfo& info) { |
| 222 SkASSERT(!fCmdBuffer.empty()); |
219 SkASSERT(info.isInstanced()); | 223 SkASSERT(info.isInstanced()); |
220 | 224 |
221 const GeometrySrcState& geomSrc = this->getGeomSrc(); | 225 const GeometrySrcState& geomSrc = this->getGeomSrc(); |
222 const GrDrawState& drawState = this->getDrawState(); | 226 const GrDrawState& drawState = this->getDrawState(); |
223 | 227 |
224 // we only attempt to concat the case when reserved verts are used with a cl
ient-specified index | 228 // we only attempt to concat the case when reserved verts are used with a cl
ient-specified index |
225 // buffer. To make this work with client-specified VBs we'd need to know if
the VB was updated | 229 // buffer. To make this work with client-specified VBs we'd need to know if
the VB was updated |
226 // between draws. | 230 // between draws. |
227 if (kReserved_GeometrySrcType != geomSrc.fVertexSrc || | 231 if (kReserved_GeometrySrcType != geomSrc.fVertexSrc || |
228 kBuffer_GeometrySrcType != geomSrc.fIndexSrc) { | 232 kBuffer_GeometrySrcType != geomSrc.fIndexSrc) { |
229 return 0; | 233 return 0; |
230 } | 234 } |
231 // Check if there is a draw info that is compatible that uses the same VB fr
om the pool and | 235 // Check if there is a draw info that is compatible that uses the same VB fr
om the pool and |
232 // the same IB | 236 // the same IB |
233 if (kDraw_Cmd != strip_trace_bit(fCmds.back())) { | 237 if (kDraw_Cmd != strip_trace_bit(fCmdBuffer.back().fType)) { |
234 return 0; | 238 return 0; |
235 } | 239 } |
236 | 240 |
237 Draw* draw = &fDraws.back(); | 241 Draw* draw = static_cast<Draw*>(&fCmdBuffer.back()); |
238 GeometryPoolState& poolState = fGeoPoolStateStack.back(); | 242 GeometryPoolState& poolState = fGeoPoolStateStack.back(); |
239 const GrVertexBuffer* vertexBuffer = poolState.fPoolVertexBuffer; | 243 const GrVertexBuffer* vertexBuffer = poolState.fPoolVertexBuffer; |
240 | 244 |
241 if (!draw->isInstanced() || | 245 if (!draw->fInfo.isInstanced() || |
242 draw->verticesPerInstance() != info.verticesPerInstance() || | 246 draw->fInfo.verticesPerInstance() != info.verticesPerInstance() || |
243 draw->indicesPerInstance() != info.indicesPerInstance() || | 247 draw->fInfo.indicesPerInstance() != info.indicesPerInstance() || |
244 draw->vertexBuffer() != vertexBuffer || | 248 draw->vertexBuffer() != vertexBuffer || |
245 draw->indexBuffer() != geomSrc.fIndexBuffer) { | 249 draw->indexBuffer() != geomSrc.fIndexBuffer) { |
246 return 0; | 250 return 0; |
247 } | 251 } |
248 // info does not yet account for the offset from the start of the pool's VB
while the previous | 252 // info does not yet account for the offset from the start of the pool's VB
while the previous |
249 // draw record does. | 253 // draw record does. |
250 int adjustedStartVertex = poolState.fPoolStartVertex + info.startVertex(); | 254 int adjustedStartVertex = poolState.fPoolStartVertex + info.startVertex(); |
251 if (draw->startVertex() + draw->vertexCount() != adjustedStartVertex) { | 255 if (draw->fInfo.startVertex() + draw->fInfo.vertexCount() != adjustedStartVe
rtex) { |
252 return 0; | 256 return 0; |
253 } | 257 } |
254 | 258 |
255 SkASSERT(poolState.fPoolStartVertex == draw->startVertex() + draw->vertexCou
nt()); | 259 SkASSERT(poolState.fPoolStartVertex == draw->fInfo.startVertex() + draw->fIn
fo.vertexCount()); |
256 | 260 |
257 // how many instances can be concat'ed onto draw given the size of the index
buffer | 261 // how many instances can be concat'ed onto draw given the size of the index
buffer |
258 int instancesToConcat = this->indexCountInCurrentSource() / info.indicesPerI
nstance(); | 262 int instancesToConcat = this->indexCountInCurrentSource() / info.indicesPerI
nstance(); |
259 instancesToConcat -= draw->instanceCount(); | 263 instancesToConcat -= draw->fInfo.instanceCount(); |
260 instancesToConcat = SkTMin(instancesToConcat, info.instanceCount()); | 264 instancesToConcat = SkTMin(instancesToConcat, info.instanceCount()); |
261 | 265 |
262 // update the amount of reserved vertex data actually referenced in draws | 266 // update the amount of reserved vertex data actually referenced in draws |
263 size_t vertexBytes = instancesToConcat * info.verticesPerInstance() * | 267 size_t vertexBytes = instancesToConcat * info.verticesPerInstance() * |
264 drawState.getVertexStride(); | 268 drawState.getVertexStride(); |
265 poolState.fUsedPoolVertexBytes = SkTMax(poolState.fUsedPoolVertexBytes, vert
exBytes); | 269 poolState.fUsedPoolVertexBytes = SkTMax(poolState.fUsedPoolVertexBytes, vert
exBytes); |
266 | 270 |
267 draw->adjustInstanceCount(instancesToConcat); | 271 draw->fInfo.adjustInstanceCount(instancesToConcat); |
268 | 272 |
269 // update last fGpuCmdMarkers to include any additional trace markers that h
ave been added | 273 // update last fGpuCmdMarkers to include any additional trace markers that h
ave been added |
270 if (this->getActiveTraceMarkers().count() > 0) { | 274 if (this->getActiveTraceMarkers().count() > 0) { |
271 if (cmd_has_trace_marker(fCmds.back())) { | 275 if (cmd_has_trace_marker(draw->fType)) { |
272 fGpuCmdMarkers.back().addSet(this->getActiveTraceMarkers()); | 276 fGpuCmdMarkers.back().addSet(this->getActiveTraceMarkers()); |
273 } else { | 277 } else { |
274 fGpuCmdMarkers.push_back(this->getActiveTraceMarkers()); | 278 fGpuCmdMarkers.push_back(this->getActiveTraceMarkers()); |
275 fCmds.back() = add_trace_bit(fCmds.back()); | 279 draw->fType = add_trace_bit(draw->fType); |
276 } | 280 } |
277 } | 281 } |
278 | 282 |
279 return instancesToConcat; | 283 return instancesToConcat; |
280 } | 284 } |
281 | 285 |
282 class AutoClipReenable { | 286 class AutoClipReenable { |
283 public: | 287 public: |
284 AutoClipReenable() : fDrawState(NULL) {} | 288 AutoClipReenable() : fDrawState(NULL) {} |
285 ~AutoClipReenable() { | 289 ~AutoClipReenable() { |
(...skipping 16 matching lines...) Expand all Loading... |
302 GeometryPoolState& poolState = fGeoPoolStateStack.back(); | 306 GeometryPoolState& poolState = fGeoPoolStateStack.back(); |
303 const GrDrawState& drawState = this->getDrawState(); | 307 const GrDrawState& drawState = this->getDrawState(); |
304 AutoClipReenable acr; | 308 AutoClipReenable acr; |
305 | 309 |
306 if (drawState.isClipState() && | 310 if (drawState.isClipState() && |
307 info.getDevBounds() && | 311 info.getDevBounds() && |
308 this->quickInsideClip(*info.getDevBounds())) { | 312 this->quickInsideClip(*info.getDevBounds())) { |
309 acr.set(this->drawState()); | 313 acr.set(this->drawState()); |
310 } | 314 } |
311 | 315 |
312 if (this->needsNewClip()) { | 316 this->recordClipIfNecessary(); |
313 this->recordClip(); | |
314 } | |
315 this->recordStateIfNecessary(); | 317 this->recordStateIfNecessary(); |
316 | 318 |
317 const GrVertexBuffer* vb; | 319 const GrVertexBuffer* vb; |
318 if (kBuffer_GeometrySrcType == this->getGeomSrc().fVertexSrc) { | 320 if (kBuffer_GeometrySrcType == this->getGeomSrc().fVertexSrc) { |
319 vb = this->getGeomSrc().fVertexBuffer; | 321 vb = this->getGeomSrc().fVertexBuffer; |
320 } else { | 322 } else { |
321 vb = poolState.fPoolVertexBuffer; | 323 vb = poolState.fPoolVertexBuffer; |
322 } | 324 } |
323 | 325 |
324 const GrIndexBuffer* ib = NULL; | 326 const GrIndexBuffer* ib = NULL; |
325 if (info.isIndexed()) { | 327 if (info.isIndexed()) { |
326 if (kBuffer_GeometrySrcType == this->getGeomSrc().fIndexSrc) { | 328 if (kBuffer_GeometrySrcType == this->getGeomSrc().fIndexSrc) { |
327 ib = this->getGeomSrc().fIndexBuffer; | 329 ib = this->getGeomSrc().fIndexBuffer; |
328 } else { | 330 } else { |
329 ib = poolState.fPoolIndexBuffer; | 331 ib = poolState.fPoolIndexBuffer; |
330 } | 332 } |
331 } | 333 } |
332 | 334 |
333 Draw* draw; | 335 Draw* draw; |
334 if (info.isInstanced()) { | 336 if (info.isInstanced()) { |
335 int instancesConcated = this->concatInstancedDraw(info); | 337 int instancesConcated = this->concatInstancedDraw(info); |
336 if (info.instanceCount() > instancesConcated) { | 338 if (info.instanceCount() > instancesConcated) { |
337 draw = this->recordDraw(info, vb, ib); | 339 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info, vb, ib)); |
338 draw->adjustInstanceCount(-instancesConcated); | 340 draw->fInfo.adjustInstanceCount(-instancesConcated); |
339 } else { | 341 } else { |
340 return; | 342 return; |
341 } | 343 } |
342 } else { | 344 } else { |
343 draw = this->recordDraw(info, vb, ib); | 345 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info, vb, ib)); |
344 } | 346 } |
| 347 this->recordTraceMarkersIfNecessary(); |
345 | 348 |
346 // Adjust the starting vertex and index when we are using reserved or array
sources to | 349 // Adjust the starting vertex and index when we are using reserved or array
sources to |
347 // compensate for the fact that the data was inserted into a larger vb/ib ow
ned by the pool. | 350 // compensate for the fact that the data was inserted into a larger vb/ib ow
ned by the pool. |
348 if (kBuffer_GeometrySrcType != this->getGeomSrc().fVertexSrc) { | 351 if (kBuffer_GeometrySrcType != this->getGeomSrc().fVertexSrc) { |
349 size_t bytes = (info.vertexCount() + info.startVertex()) * drawState.get
VertexStride(); | 352 size_t bytes = (info.vertexCount() + info.startVertex()) * drawState.get
VertexStride(); |
350 poolState.fUsedPoolVertexBytes = SkTMax(poolState.fUsedPoolVertexBytes,
bytes); | 353 poolState.fUsedPoolVertexBytes = SkTMax(poolState.fUsedPoolVertexBytes,
bytes); |
351 draw->adjustStartVertex(poolState.fPoolStartVertex); | 354 draw->fInfo.adjustStartVertex(poolState.fPoolStartVertex); |
352 } | 355 } |
353 | 356 |
354 if (info.isIndexed() && kBuffer_GeometrySrcType != this->getGeomSrc().fIndex
Src) { | 357 if (info.isIndexed() && kBuffer_GeometrySrcType != this->getGeomSrc().fIndex
Src) { |
355 size_t bytes = (info.indexCount() + info.startIndex()) * sizeof(uint16_t
); | 358 size_t bytes = (info.indexCount() + info.startIndex()) * sizeof(uint16_t
); |
356 poolState.fUsedPoolIndexBytes = SkTMax(poolState.fUsedPoolIndexBytes, by
tes); | 359 poolState.fUsedPoolIndexBytes = SkTMax(poolState.fUsedPoolIndexBytes, by
tes); |
357 draw->adjustStartIndex(poolState.fPoolStartIndex); | 360 draw->fInfo.adjustStartIndex(poolState.fPoolStartIndex); |
358 } | 361 } |
359 } | 362 } |
360 | 363 |
361 void GrInOrderDrawBuffer::onStencilPath(const GrPath* path, SkPath::FillType fil
l) { | 364 void GrInOrderDrawBuffer::onStencilPath(const GrPath* path, SkPath::FillType fil
l) { |
362 if (this->needsNewClip()) { | 365 this->recordClipIfNecessary(); |
363 this->recordClip(); | |
364 } | |
365 // Only compare the subset of GrDrawState relevant to path stenciling? | 366 // Only compare the subset of GrDrawState relevant to path stenciling? |
366 this->recordStateIfNecessary(); | 367 this->recordStateIfNecessary(); |
367 StencilPath* sp = this->recordStencilPath(path); | 368 StencilPath* sp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, StencilPath, (path)); |
368 sp->fFill = fill; | 369 sp->fFill = fill; |
| 370 this->recordTraceMarkersIfNecessary(); |
369 } | 371 } |
370 | 372 |
371 void GrInOrderDrawBuffer::onDrawPath(const GrPath* path, | 373 void GrInOrderDrawBuffer::onDrawPath(const GrPath* path, |
372 SkPath::FillType fill, const GrDeviceCoordT
exture* dstCopy) { | 374 SkPath::FillType fill, const GrDeviceCoordT
exture* dstCopy) { |
373 if (this->needsNewClip()) { | 375 this->recordClipIfNecessary(); |
374 this->recordClip(); | |
375 } | |
376 // TODO: Only compare the subset of GrDrawState relevant to path covering? | 376 // TODO: Only compare the subset of GrDrawState relevant to path covering? |
377 this->recordStateIfNecessary(); | 377 this->recordStateIfNecessary(); |
378 DrawPath* cp = this->recordDrawPath(path); | 378 DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (path)); |
379 cp->fFill = fill; | 379 dp->fFill = fill; |
380 if (dstCopy) { | 380 if (dstCopy) { |
381 cp->fDstCopy = *dstCopy; | 381 dp->fDstCopy = *dstCopy; |
382 } | 382 } |
| 383 this->recordTraceMarkersIfNecessary(); |
383 } | 384 } |
384 | 385 |
385 void GrInOrderDrawBuffer::onDrawPaths(const GrPathRange* pathRange, | 386 void GrInOrderDrawBuffer::onDrawPaths(const GrPathRange* pathRange, |
386 const uint32_t indices[], int count, | 387 const uint32_t indices[], int count, |
387 const float transforms[], PathTransformTyp
e transformsType, | 388 const float transforms[], PathTransformTyp
e transformsType, |
388 SkPath::FillType fill, const GrDeviceCoord
Texture* dstCopy) { | 389 SkPath::FillType fill, const GrDeviceCoord
Texture* dstCopy) { |
389 SkASSERT(pathRange); | 390 SkASSERT(pathRange); |
390 SkASSERT(indices); | 391 SkASSERT(indices); |
391 SkASSERT(transforms); | 392 SkASSERT(transforms); |
392 | 393 |
393 if (this->needsNewClip()) { | 394 this->recordClipIfNecessary(); |
394 this->recordClip(); | |
395 } | |
396 this->recordStateIfNecessary(); | 395 this->recordStateIfNecessary(); |
397 DrawPaths* dp = this->recordDrawPaths(pathRange); | 396 |
398 dp->fIndices = SkNEW_ARRAY(uint32_t, count); // TODO: Accomplish this withou
t a malloc | 397 int sizeOfIndices = sizeof(uint32_t) * count; |
399 memcpy(dp->fIndices, indices, sizeof(uint32_t) * count); | 398 int sizeOfTransforms = sizeof(float) * count * |
| 399 GrPathRendering::PathTransformSize(transformsType); |
| 400 |
| 401 DrawPaths* dp = GrNEW_APPEND_WITH_DATA_TO_RECORDER(fCmdBuffer, DrawPaths, (p
athRange), |
| 402 sizeOfIndices + sizeOfTra
nsforms); |
| 403 memcpy(dp->indices(), indices, sizeOfIndices); |
400 dp->fCount = count; | 404 dp->fCount = count; |
401 | 405 memcpy(dp->transforms(), transforms, sizeOfTransforms); |
402 const int transformsLength = GrPathRendering::PathTransformSize(transformsTy
pe) * count; | |
403 dp->fTransforms = SkNEW_ARRAY(float, transformsLength); | |
404 memcpy(dp->fTransforms, transforms, sizeof(float) * transformsLength); | |
405 dp->fTransformsType = transformsType; | 406 dp->fTransformsType = transformsType; |
406 | |
407 dp->fFill = fill; | 407 dp->fFill = fill; |
408 | |
409 if (dstCopy) { | 408 if (dstCopy) { |
410 dp->fDstCopy = *dstCopy; | 409 dp->fDstCopy = *dstCopy; |
411 } | 410 } |
| 411 |
| 412 this->recordTraceMarkersIfNecessary(); |
412 } | 413 } |
413 | 414 |
414 void GrInOrderDrawBuffer::clear(const SkIRect* rect, GrColor color, | 415 void GrInOrderDrawBuffer::clear(const SkIRect* rect, GrColor color, |
415 bool canIgnoreRect, GrRenderTarget* renderTarget
) { | 416 bool canIgnoreRect, GrRenderTarget* renderTarget
) { |
416 SkIRect r; | 417 SkIRect r; |
417 if (NULL == renderTarget) { | 418 if (NULL == renderTarget) { |
418 renderTarget = this->drawState()->getRenderTarget(); | 419 renderTarget = this->drawState()->getRenderTarget(); |
419 SkASSERT(renderTarget); | 420 SkASSERT(renderTarget); |
420 } | 421 } |
421 if (NULL == rect) { | 422 if (NULL == rect) { |
422 // We could do something smart and remove previous draws and clears to | 423 // We could do something smart and remove previous draws and clears to |
423 // the current render target. If we get that smart we have to make sure | 424 // the current render target. If we get that smart we have to make sure |
424 // those draws aren't read before this clear (render-to-texture). | 425 // those draws aren't read before this clear (render-to-texture). |
425 r.setLTRB(0, 0, renderTarget->width(), renderTarget->height()); | 426 r.setLTRB(0, 0, renderTarget->width(), renderTarget->height()); |
426 rect = &r; | 427 rect = &r; |
427 } | 428 } |
428 Clear* clr = this->recordClear(renderTarget); | 429 Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget)); |
429 GrColorIsPMAssert(color); | 430 GrColorIsPMAssert(color); |
430 clr->fColor = color; | 431 clr->fColor = color; |
431 clr->fRect = *rect; | 432 clr->fRect = *rect; |
432 clr->fCanIgnoreRect = canIgnoreRect; | 433 clr->fCanIgnoreRect = canIgnoreRect; |
| 434 this->recordTraceMarkersIfNecessary(); |
433 } | 435 } |
434 | 436 |
435 void GrInOrderDrawBuffer::discard(GrRenderTarget* renderTarget) { | 437 void GrInOrderDrawBuffer::discard(GrRenderTarget* renderTarget) { |
436 if (!this->caps()->discardRenderTargetSupport()) { | 438 if (!this->caps()->discardRenderTargetSupport()) { |
437 return; | 439 return; |
438 } | 440 } |
439 if (NULL == renderTarget) { | 441 if (NULL == renderTarget) { |
440 renderTarget = this->drawState()->getRenderTarget(); | 442 renderTarget = this->drawState()->getRenderTarget(); |
441 SkASSERT(renderTarget); | 443 SkASSERT(renderTarget); |
442 } | 444 } |
443 Clear* clr = this->recordClear(renderTarget); | 445 Clear* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Clear, (renderTarget)); |
444 clr->fColor = GrColor_ILLEGAL; | 446 clr->fColor = GrColor_ILLEGAL; |
| 447 this->recordTraceMarkersIfNecessary(); |
445 } | 448 } |
446 | 449 |
447 void GrInOrderDrawBuffer::reset() { | 450 void GrInOrderDrawBuffer::reset() { |
448 SkASSERT(1 == fGeoPoolStateStack.count()); | 451 SkASSERT(1 == fGeoPoolStateStack.count()); |
449 this->resetVertexSource(); | 452 this->resetVertexSource(); |
450 this->resetIndexSource(); | 453 this->resetIndexSource(); |
451 | 454 |
452 fCmds.reset(); | 455 fCmdBuffer.reset(); |
453 fDraws.reset(); | 456 fLastState = NULL; |
454 fStencilPaths.reset(); | 457 fLastClip = NULL; |
455 fDrawPath.reset(); | |
456 fDrawPaths.reset(); | |
457 fStates.reset(); | |
458 fClears.reset(); | |
459 fVertexPool.reset(); | 458 fVertexPool.reset(); |
460 fIndexPool.reset(); | 459 fIndexPool.reset(); |
461 fClips.reset(); | |
462 fCopySurfaces.reset(); | |
463 fGpuCmdMarkers.reset(); | 460 fGpuCmdMarkers.reset(); |
464 fClipSet = true; | 461 fClipSet = true; |
465 } | 462 } |
466 | 463 |
467 void GrInOrderDrawBuffer::flush() { | 464 void GrInOrderDrawBuffer::flush() { |
468 if (fFlushing) { | 465 if (fFlushing) { |
469 return; | 466 return; |
470 } | 467 } |
471 | 468 |
472 this->getContext()->getFontCache()->updateTextures(); | 469 this->getContext()->getFontCache()->updateTextures(); |
473 | 470 |
474 SkASSERT(kReserved_GeometrySrcType != this->getGeomSrc().fVertexSrc); | 471 SkASSERT(kReserved_GeometrySrcType != this->getGeomSrc().fVertexSrc); |
475 SkASSERT(kReserved_GeometrySrcType != this->getGeomSrc().fIndexSrc); | 472 SkASSERT(kReserved_GeometrySrcType != this->getGeomSrc().fIndexSrc); |
476 | 473 |
477 int numCmds = fCmds.count(); | 474 if (fCmdBuffer.empty()) { |
478 if (0 == numCmds) { | |
479 return; | 475 return; |
480 } | 476 } |
481 | 477 |
482 GrAutoTRestore<bool> flushRestore(&fFlushing); | 478 GrAutoTRestore<bool> flushRestore(&fFlushing); |
483 fFlushing = true; | 479 fFlushing = true; |
484 | 480 |
485 fVertexPool.unmap(); | 481 fVertexPool.unmap(); |
486 fIndexPool.unmap(); | 482 fIndexPool.unmap(); |
487 | 483 |
488 GrDrawTarget::AutoClipRestore acr(fDstGpu); | 484 GrDrawTarget::AutoClipRestore acr(fDstGpu); |
489 AutoGeometryAndStatePush agasp(fDstGpu, kPreserve_ASRInit); | 485 AutoGeometryAndStatePush agasp(fDstGpu, kPreserve_ASRInit); |
490 | 486 |
491 GrDrawState* prevDrawState = SkRef(fDstGpu->drawState()); | 487 GrDrawState* prevDrawState = SkRef(fDstGpu->drawState()); |
492 | 488 |
493 GrClipData clipData; | 489 CmdBuffer::Iter iter(fCmdBuffer); |
494 | 490 |
495 StateAllocator::Iter stateIter(&fStates); | 491 int currCmdMarker = 0; |
496 ClipAllocator::Iter clipIter(&fClips); | 492 fDstGpu->saveActiveTraceMarkers(); |
497 ClearAllocator::Iter clearIter(&fClears); | |
498 DrawAllocator::Iter drawIter(&fDraws); | |
499 StencilPathAllocator::Iter stencilPathIter(&fStencilPaths); | |
500 DrawPathAllocator::Iter drawPathIter(&fDrawPath); | |
501 DrawPathsAllocator::Iter drawPathsIter(&fDrawPaths); | |
502 CopySurfaceAllocator::Iter copySurfaceIter(&fCopySurfaces); | |
503 | 493 |
504 int currCmdMarker = 0; | 494 while (iter.next()) { |
505 | |
506 fDstGpu->saveActiveTraceMarkers(); | |
507 for (int c = 0; c < numCmds; ++c) { | |
508 GrGpuTraceMarker newMarker("", -1); | 495 GrGpuTraceMarker newMarker("", -1); |
509 SkString traceString; | 496 SkString traceString; |
510 if (cmd_has_trace_marker(fCmds[c])) { | 497 if (cmd_has_trace_marker(iter->fType)) { |
511 traceString = fGpuCmdMarkers[currCmdMarker].toString(); | 498 traceString = fGpuCmdMarkers[currCmdMarker].toString(); |
512 newMarker.fMarker = traceString.c_str(); | 499 newMarker.fMarker = traceString.c_str(); |
513 fDstGpu->addGpuTraceMarker(&newMarker); | 500 fDstGpu->addGpuTraceMarker(&newMarker); |
514 ++currCmdMarker; | 501 ++currCmdMarker; |
515 } | 502 } |
516 switch (strip_trace_bit(fCmds[c])) { | 503 |
517 case kDraw_Cmd: { | 504 SkDEBUGCODE(bool isDraw = kDraw_Cmd == strip_trace_bit(iter->fType) || |
518 SkASSERT(fDstGpu->drawState() != prevDrawState); | 505 kStencilPath_Cmd == strip_trace_bit(iter->fTyp
e) || |
519 SkAssertResult(drawIter.next()); | 506 kDrawPath_Cmd == strip_trace_bit(iter->fType)
|| |
520 fDstGpu->setVertexSourceToBuffer(drawIter->vertexBuffer()); | 507 kDrawPaths_Cmd == strip_trace_bit(iter->fType)
); |
521 if (drawIter->isIndexed()) { | 508 SkASSERT(!isDraw || fDstGpu->drawState() != prevDrawState); |
522 fDstGpu->setIndexSourceToBuffer(drawIter->indexBuffer()); | 509 |
523 } | 510 iter->execute(fDstGpu); |
524 fDstGpu->executeDraw(*drawIter); | 511 |
525 break; | 512 if (cmd_has_trace_marker(iter->fType)) { |
526 } | |
527 case kStencilPath_Cmd: { | |
528 SkASSERT(fDstGpu->drawState() != prevDrawState); | |
529 SkAssertResult(stencilPathIter.next()); | |
530 fDstGpu->stencilPath(stencilPathIter->path(), stencilPathIter->f
Fill); | |
531 break; | |
532 } | |
533 case kDrawPath_Cmd: { | |
534 SkASSERT(fDstGpu->drawState() != prevDrawState); | |
535 SkAssertResult(drawPathIter.next()); | |
536 fDstGpu->executeDrawPath(drawPathIter->path(), drawPathIter->fFi
ll, | |
537 drawPathIter->fDstCopy.texture() ? | |
538 &drawPathIter->fDstCopy : | |
539 NULL); | |
540 break; | |
541 } | |
542 case kDrawPaths_Cmd: { | |
543 SkASSERT(fDstGpu->drawState() != prevDrawState); | |
544 SkAssertResult(drawPathsIter.next()); | |
545 const GrDeviceCoordTexture* dstCopy = | |
546 drawPathsIter->fDstCopy.texture() ? &drawPathsIter->fDstCopy
: NULL; | |
547 fDstGpu->executeDrawPaths(drawPathsIter->pathRange(), | |
548 drawPathsIter->fIndices, | |
549 drawPathsIter->fCount, | |
550 drawPathsIter->fTransforms, | |
551 drawPathsIter->fTransformsType, | |
552 drawPathsIter->fFill, | |
553 dstCopy); | |
554 break; | |
555 } | |
556 case kSetState_Cmd: | |
557 SkAssertResult(stateIter.next()); | |
558 fDstGpu->setDrawState(stateIter.get()); | |
559 break; | |
560 case kSetClip_Cmd: | |
561 SkAssertResult(clipIter.next()); | |
562 clipData.fClipStack = &clipIter->fStack; | |
563 clipData.fOrigin = clipIter->fOrigin; | |
564 fDstGpu->setClip(&clipData); | |
565 break; | |
566 case kClear_Cmd: | |
567 SkAssertResult(clearIter.next()); | |
568 if (GrColor_ILLEGAL == clearIter->fColor) { | |
569 fDstGpu->discard(clearIter->renderTarget()); | |
570 } else { | |
571 fDstGpu->clear(&clearIter->fRect, | |
572 clearIter->fColor, | |
573 clearIter->fCanIgnoreRect, | |
574 clearIter->renderTarget()); | |
575 } | |
576 break; | |
577 case kCopySurface_Cmd: | |
578 SkAssertResult(copySurfaceIter.next()); | |
579 fDstGpu->copySurface(copySurfaceIter->dst(), | |
580 copySurfaceIter->src(), | |
581 copySurfaceIter->fSrcRect, | |
582 copySurfaceIter->fDstPoint); | |
583 break; | |
584 } | |
585 if (cmd_has_trace_marker(fCmds[c])) { | |
586 fDstGpu->removeGpuTraceMarker(&newMarker); | 513 fDstGpu->removeGpuTraceMarker(&newMarker); |
587 } | 514 } |
588 } | 515 } |
| 516 |
589 fDstGpu->restoreActiveTraceMarkers(); | 517 fDstGpu->restoreActiveTraceMarkers(); |
590 // we should have consumed all the states, clips, etc. | |
591 SkASSERT(!stateIter.next()); | |
592 SkASSERT(!clipIter.next()); | |
593 SkASSERT(!clearIter.next()); | |
594 SkASSERT(!drawIter.next()); | |
595 SkASSERT(!copySurfaceIter.next()); | |
596 SkASSERT(!stencilPathIter.next()); | |
597 SkASSERT(!drawPathIter.next()); | |
598 SkASSERT(!drawPathsIter.next()); | |
599 | |
600 SkASSERT(fGpuCmdMarkers.count() == currCmdMarker); | 518 SkASSERT(fGpuCmdMarkers.count() == currCmdMarker); |
601 | 519 |
602 fDstGpu->setDrawState(prevDrawState); | 520 fDstGpu->setDrawState(prevDrawState); |
603 prevDrawState->unref(); | 521 prevDrawState->unref(); |
604 this->reset(); | 522 this->reset(); |
605 ++fDrawID; | 523 ++fDrawID; |
606 } | 524 } |
607 | 525 |
| 526 void GrInOrderDrawBuffer::Draw::execute(GrDrawTarget* gpu) { |
| 527 gpu->setVertexSourceToBuffer(this->vertexBuffer()); |
| 528 if (fInfo.isIndexed()) { |
| 529 gpu->setIndexSourceToBuffer(this->indexBuffer()); |
| 530 } |
| 531 gpu->executeDraw(fInfo); |
| 532 } |
| 533 |
| 534 void GrInOrderDrawBuffer::StencilPath::execute(GrDrawTarget* gpu) { |
| 535 gpu->stencilPath(this->path(), fFill); |
| 536 } |
| 537 |
| 538 void GrInOrderDrawBuffer::DrawPath::execute(GrDrawTarget* gpu) { |
| 539 gpu->executeDrawPath(this->path(), fFill, fDstCopy.texture() ? &fDstCopy : N
ULL); |
| 540 } |
| 541 |
| 542 void GrInOrderDrawBuffer::DrawPaths::execute(GrDrawTarget* gpu) { |
| 543 gpu->executeDrawPaths(this->pathRange(), this->indices(), fCount, this->tran
sforms(), |
| 544 fTransformsType, fFill, fDstCopy.texture() ? &fDstCopy
: NULL); |
| 545 } |
| 546 |
| 547 void GrInOrderDrawBuffer::SetState::execute(GrDrawTarget* gpu) { |
| 548 gpu->setDrawState(&fState); |
| 549 } |
| 550 |
| 551 void GrInOrderDrawBuffer::SetClip::execute(GrDrawTarget* gpu) { |
| 552 // Our fClipData is referenced directly, so we must remain alive for the ent
ire |
| 553 // duration of the flush (after which the gpu's previous clip is restored). |
| 554 gpu->setClip(&fClipData); |
| 555 } |
| 556 |
| 557 void GrInOrderDrawBuffer::Clear::execute(GrDrawTarget* gpu) { |
| 558 if (GrColor_ILLEGAL == fColor) { |
| 559 gpu->discard(this->renderTarget()); |
| 560 } else { |
| 561 gpu->clear(&fRect, fColor, fCanIgnoreRect, this->renderTarget()); |
| 562 } |
| 563 } |
| 564 |
| 565 void GrInOrderDrawBuffer::CopySurface::execute(GrDrawTarget* gpu) { |
| 566 gpu->copySurface(this->dst(), this->src(), fSrcRect, fDstPoint); |
| 567 } |
| 568 |
608 bool GrInOrderDrawBuffer::onCopySurface(GrSurface* dst, | 569 bool GrInOrderDrawBuffer::onCopySurface(GrSurface* dst, |
609 GrSurface* src, | 570 GrSurface* src, |
610 const SkIRect& srcRect, | 571 const SkIRect& srcRect, |
611 const SkIPoint& dstPoint) { | 572 const SkIPoint& dstPoint) { |
612 if (fDstGpu->canCopySurface(dst, src, srcRect, dstPoint)) { | 573 if (fDstGpu->canCopySurface(dst, src, srcRect, dstPoint)) { |
613 CopySurface* cs = this->recordCopySurface(dst, src); | 574 CopySurface* cs = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, CopySurface, (dst
, src)); |
614 cs->fSrcRect = srcRect; | 575 cs->fSrcRect = srcRect; |
615 cs->fDstPoint = dstPoint; | 576 cs->fDstPoint = dstPoint; |
| 577 this->recordTraceMarkersIfNecessary(); |
616 return true; | 578 return true; |
617 } else { | 579 } else { |
618 return false; | 580 return false; |
619 } | 581 } |
620 } | 582 } |
621 | 583 |
622 bool GrInOrderDrawBuffer::onCanCopySurface(GrSurface* dst, | 584 bool GrInOrderDrawBuffer::onCanCopySurface(GrSurface* dst, |
623 GrSurface* src, | 585 GrSurface* src, |
624 const SkIRect& srcRect, | 586 const SkIRect& srcRect, |
625 const SkIPoint& dstPoint) { | 587 const SkIPoint& dstPoint) { |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
825 poolState.fUsedPoolVertexBytes = restoredState.fVertexSize * restoredSta
te.fVertexCount; | 787 poolState.fUsedPoolVertexBytes = restoredState.fVertexSize * restoredSta
te.fVertexCount; |
826 } | 788 } |
827 if (kReserved_GeometrySrcType == restoredState.fIndexSrc || | 789 if (kReserved_GeometrySrcType == restoredState.fIndexSrc || |
828 kArray_GeometrySrcType == restoredState.fIndexSrc) { | 790 kArray_GeometrySrcType == restoredState.fIndexSrc) { |
829 poolState.fUsedPoolIndexBytes = sizeof(uint16_t) * | 791 poolState.fUsedPoolIndexBytes = sizeof(uint16_t) * |
830 restoredState.fIndexCount; | 792 restoredState.fIndexCount; |
831 } | 793 } |
832 } | 794 } |
833 | 795 |
834 void GrInOrderDrawBuffer::recordStateIfNecessary() { | 796 void GrInOrderDrawBuffer::recordStateIfNecessary() { |
835 if (fStates.empty()) { | 797 if (!fLastState) { |
836 this->convertDrawStateToPendingExec(&fStates.push_back(this->getDrawStat
e())); | 798 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (this->get
DrawState())); |
837 this->addToCmdBuffer(kSetState_Cmd); | 799 fLastState = &ss->fState; |
| 800 this->convertDrawStateToPendingExec(fLastState); |
| 801 this->recordTraceMarkersIfNecessary(); |
838 return; | 802 return; |
839 } | 803 } |
840 const GrDrawState& curr = this->getDrawState(); | 804 const GrDrawState& curr = this->getDrawState(); |
841 GrDrawState& prev = fStates.back(); | 805 switch (GrDrawState::CombineIfPossible(*fLastState, curr, *this->caps())) { |
842 switch (GrDrawState::CombineIfPossible(prev, curr, *this->caps())) { | |
843 case GrDrawState::kIncompatible_CombinedState: | 806 case GrDrawState::kIncompatible_CombinedState: |
844 this->convertDrawStateToPendingExec(&fStates.push_back(curr)); | 807 fLastState = &GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (curr))
->fState; |
845 this->addToCmdBuffer(kSetState_Cmd); | 808 this->convertDrawStateToPendingExec(fLastState); |
| 809 this->recordTraceMarkersIfNecessary(); |
846 break; | 810 break; |
847 case GrDrawState::kA_CombinedState: | 811 case GrDrawState::kA_CombinedState: |
848 case GrDrawState::kAOrB_CombinedState: // Treat the same as kA. | 812 case GrDrawState::kAOrB_CombinedState: // Treat the same as kA. |
849 break; | 813 break; |
850 case GrDrawState::kB_CombinedState: | 814 case GrDrawState::kB_CombinedState: |
851 // prev has already been converted to pending execution. That is a o
ne-way ticket. | 815 // prev has already been converted to pending execution. That is a o
ne-way ticket. |
852 // So here we just delete prev and push back a new copy of curr. Not
e that this | 816 // So here we just destruct the previous state and reinit with a new
copy of curr. |
853 // goes away when we move GrIODB over to taking optimized snapshots
of draw states. | 817 // Note that this goes away when we move GrIODB over to taking optim
ized snapshots |
854 fStates.pop_back(); | 818 // of draw states. |
855 this->convertDrawStateToPendingExec(&fStates.push_back(curr)); | 819 fLastState->~GrDrawState(); |
| 820 SkNEW_PLACEMENT_ARGS(fLastState, GrDrawState, (curr)); |
| 821 this->convertDrawStateToPendingExec(fLastState); |
856 break; | 822 break; |
857 } | 823 } |
858 } | 824 } |
859 | 825 |
860 bool GrInOrderDrawBuffer::needsNewClip() const { | 826 void GrInOrderDrawBuffer::recordClipIfNecessary() { |
861 if (this->getDrawState().isClipState()) { | 827 if (this->getDrawState().isClipState() && |
862 if (fClipSet && | 828 fClipSet && |
863 (fClips.empty() || | 829 (!fLastClip || *fLastClip != *this->getClip())) { |
864 fClips.back().fStack != *this->getClip()->fClipStack || | 830 fLastClip = &GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetClip, (this->getCli
p()))->fClipData; |
865 fClips.back().fOrigin != this->getClip()->fOrigin)) { | 831 this->recordTraceMarkersIfNecessary(); |
866 return true; | 832 fClipSet = false; |
867 } | |
868 } | |
869 return false; | |
870 } | |
871 | |
872 void GrInOrderDrawBuffer::addToCmdBuffer(uint8_t cmd) { | |
873 SkASSERT(!cmd_has_trace_marker(cmd)); | |
874 const GrTraceMarkerSet& activeTraceMarkers = this->getActiveTraceMarkers(); | |
875 if (activeTraceMarkers.count() > 0) { | |
876 fCmds.push_back(add_trace_bit(cmd)); | |
877 fGpuCmdMarkers.push_back(activeTraceMarkers); | |
878 } else { | |
879 fCmds.push_back(cmd); | |
880 } | 833 } |
881 } | 834 } |
882 | 835 |
883 void GrInOrderDrawBuffer::recordClip() { | 836 void GrInOrderDrawBuffer::recordTraceMarkersIfNecessary() { |
884 fClips.push_back().fStack = *this->getClip()->fClipStack; | 837 SkASSERT(!fCmdBuffer.empty()); |
885 fClips.back().fOrigin = this->getClip()->fOrigin; | 838 SkASSERT(!cmd_has_trace_marker(fCmdBuffer.back().fType)); |
886 fClipSet = false; | 839 const GrTraceMarkerSet& activeTraceMarkers = this->getActiveTraceMarkers(); |
887 this->addToCmdBuffer(kSetClip_Cmd); | 840 if (activeTraceMarkers.count() > 0) { |
888 } | 841 fCmdBuffer.back().fType = add_trace_bit(fCmdBuffer.back().fType); |
889 | 842 fGpuCmdMarkers.push_back(activeTraceMarkers); |
890 GrInOrderDrawBuffer::Draw* GrInOrderDrawBuffer::recordDraw(const DrawInfo& info, | 843 } |
891 const GrVertexBuffer*
vb, | |
892 const GrIndexBuffer*
ib) { | |
893 this->addToCmdBuffer(kDraw_Cmd); | |
894 return GrNEW_APPEND_TO_ALLOCATOR(&fDraws, Draw, (info, vb, ib)); | |
895 } | |
896 | |
897 GrInOrderDrawBuffer::StencilPath* GrInOrderDrawBuffer::recordStencilPath(const G
rPath* path) { | |
898 this->addToCmdBuffer(kStencilPath_Cmd); | |
899 return GrNEW_APPEND_TO_ALLOCATOR(&fStencilPaths, StencilPath, (path)); | |
900 } | |
901 | |
902 GrInOrderDrawBuffer::DrawPath* GrInOrderDrawBuffer::recordDrawPath(const GrPath*
path) { | |
903 this->addToCmdBuffer(kDrawPath_Cmd); | |
904 return GrNEW_APPEND_TO_ALLOCATOR(&fDrawPath, DrawPath, (path)); | |
905 } | |
906 | |
907 GrInOrderDrawBuffer::DrawPaths* GrInOrderDrawBuffer::recordDrawPaths(const GrPat
hRange* pathRange) { | |
908 this->addToCmdBuffer(kDrawPaths_Cmd); | |
909 return GrNEW_APPEND_TO_ALLOCATOR(&fDrawPaths, DrawPaths, (pathRange)); | |
910 } | |
911 | |
912 GrInOrderDrawBuffer::Clear* GrInOrderDrawBuffer::recordClear(GrRenderTarget* rt)
{ | |
913 this->addToCmdBuffer(kClear_Cmd); | |
914 return GrNEW_APPEND_TO_ALLOCATOR(&fClears, Clear, (rt)); | |
915 } | |
916 | |
917 GrInOrderDrawBuffer::CopySurface* GrInOrderDrawBuffer::recordCopySurface(GrSurfa
ce* dst, | |
918 GrSurfa
ce* src) { | |
919 this->addToCmdBuffer(kCopySurface_Cmd); | |
920 return GrNEW_APPEND_TO_ALLOCATOR(&fCopySurfaces, CopySurface, (dst, src)); | |
921 } | 844 } |
922 | 845 |
923 void GrInOrderDrawBuffer::clipWillBeSet(const GrClipData* newClipData) { | 846 void GrInOrderDrawBuffer::clipWillBeSet(const GrClipData* newClipData) { |
924 INHERITED::clipWillBeSet(newClipData); | 847 INHERITED::clipWillBeSet(newClipData); |
925 fClipSet = true; | 848 fClipSet = true; |
926 fClipProxyState = kUnknown_ClipProxyState; | 849 fClipProxyState = kUnknown_ClipProxyState; |
927 } | 850 } |
OLD | NEW |