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 "GrDefaultGeoProcFactory.h" | 11 #include "GrDefaultGeoProcFactory.h" |
12 #include "GrDrawTargetCaps.h" | 12 #include "GrDrawTargetCaps.h" |
13 #include "GrGpu.h" | 13 #include "GrGpu.h" |
14 #include "GrOptDrawState.h" | |
15 #include "GrTemplates.h" | 14 #include "GrTemplates.h" |
16 #include "GrTextStrike.h" | 15 #include "GrTextStrike.h" |
17 #include "GrTexture.h" | 16 #include "GrTexture.h" |
18 | 17 |
19 GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrGpu* gpu, | 18 GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrGpu* gpu, |
20 GrVertexBufferAllocPool* vertexPool, | 19 GrVertexBufferAllocPool* vertexPool, |
21 GrIndexBufferAllocPool* indexPool) | 20 GrIndexBufferAllocPool* indexPool) |
22 : INHERITED(gpu->getContext()) | 21 : INHERITED(gpu->getContext()) |
23 , fCmdBuffer(kCmdBufferInitialSizeInBytes) | 22 , fCmdBuffer(kCmdBufferInitialSizeInBytes) |
24 , fLastState(NULL) | 23 , fLastState(NULL) |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
257 return instancesToConcat; | 256 return instancesToConcat; |
258 } | 257 } |
259 | 258 |
260 void GrInOrderDrawBuffer::onDraw(const GrDrawState& ds, | 259 void GrInOrderDrawBuffer::onDraw(const GrDrawState& ds, |
261 const DrawInfo& info, | 260 const DrawInfo& info, |
262 const GrClipMaskManager::ScissorState& scissorS
tate) { | 261 const GrClipMaskManager::ScissorState& scissorS
tate) { |
263 SkASSERT(info.vertexBuffer() && (!info.isIndexed() || info.indexBuffer())); | 262 SkASSERT(info.vertexBuffer() && (!info.isIndexed() || info.indexBuffer())); |
264 | 263 |
265 GeometryPoolState& poolState = fGeoPoolStateStack.back(); | 264 GeometryPoolState& poolState = fGeoPoolStateStack.back(); |
266 | 265 |
267 this->recordStateIfNecessary(ds, | 266 if (!this->recordStateAndShouldDraw(ds, GrGpu::PrimTypeToDrawType(info.primi
tiveType()), |
268 GrGpu::PrimTypeToDrawType(info.primitiveType())
, | 267 info.getDstCopy())) { |
269 info.getDstCopy()); | 268 return; |
| 269 } |
270 | 270 |
271 Draw* draw; | 271 Draw* draw; |
272 if (info.isInstanced()) { | 272 if (info.isInstanced()) { |
273 int instancesConcated = this->concatInstancedDraw(ds, info, scissorState
); | 273 int instancesConcated = this->concatInstancedDraw(ds, info, scissorState
); |
274 if (info.instanceCount() > instancesConcated) { | 274 if (info.instanceCount() > instancesConcated) { |
275 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info, scissorStat
e)); | 275 draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info, scissorStat
e)); |
276 draw->fInfo.adjustInstanceCount(-instancesConcated); | 276 draw->fInfo.adjustInstanceCount(-instancesConcated); |
277 } else { | 277 } else { |
278 return; | 278 return; |
279 } | 279 } |
(...skipping 15 matching lines...) Expand all Loading... |
295 poolState.fUsedPoolIndexBytes = SkTMax(poolState.fUsedPoolIndexBytes, by
tes); | 295 poolState.fUsedPoolIndexBytes = SkTMax(poolState.fUsedPoolIndexBytes, by
tes); |
296 draw->fInfo.adjustStartIndex(poolState.fPoolStartIndex); | 296 draw->fInfo.adjustStartIndex(poolState.fPoolStartIndex); |
297 } | 297 } |
298 } | 298 } |
299 | 299 |
300 void GrInOrderDrawBuffer::onStencilPath(const GrDrawState& ds, | 300 void GrInOrderDrawBuffer::onStencilPath(const GrDrawState& ds, |
301 const GrPath* path, | 301 const GrPath* path, |
302 const GrClipMaskManager::ScissorState& s
cissorState, | 302 const GrClipMaskManager::ScissorState& s
cissorState, |
303 const GrStencilSettings& stencilSettings
) { | 303 const GrStencilSettings& stencilSettings
) { |
304 // Only compare the subset of GrDrawState relevant to path stenciling? | 304 // Only compare the subset of GrDrawState relevant to path stenciling? |
305 this->recordStateIfNecessary(ds, GrGpu::kStencilPath_DrawType, NULL); | 305 if (!this->recordStateAndShouldDraw(ds, GrGpu::kStencilPath_DrawType, NULL))
{ |
| 306 return; |
| 307 } |
306 StencilPath* sp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, StencilPath, (path)); | 308 StencilPath* sp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, StencilPath, (path)); |
307 sp->fScissorState = scissorState; | 309 sp->fScissorState = scissorState; |
308 sp->fStencilSettings = stencilSettings; | 310 sp->fStencilSettings = stencilSettings; |
309 this->recordTraceMarkersIfNecessary(); | 311 this->recordTraceMarkersIfNecessary(); |
310 } | 312 } |
311 | 313 |
312 void GrInOrderDrawBuffer::onDrawPath(const GrDrawState& ds, | 314 void GrInOrderDrawBuffer::onDrawPath(const GrDrawState& ds, |
313 const GrPath* path, | 315 const GrPath* path, |
314 const GrClipMaskManager::ScissorState& scis
sorState, | 316 const GrClipMaskManager::ScissorState& scis
sorState, |
315 const GrStencilSettings& stencilSettings, | 317 const GrStencilSettings& stencilSettings, |
316 const GrDeviceCoordTexture* dstCopy) { | 318 const GrDeviceCoordTexture* dstCopy) { |
317 // TODO: Only compare the subset of GrDrawState relevant to path covering? | 319 // TODO: Only compare the subset of GrDrawState relevant to path covering? |
318 this->recordStateIfNecessary(ds, GrGpu::kDrawPath_DrawType, dstCopy); | 320 if (!this->recordStateAndShouldDraw(ds, GrGpu::kDrawPath_DrawType, dstCopy))
{ |
| 321 return; |
| 322 } |
319 DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (path)); | 323 DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (path)); |
320 if (dstCopy) { | 324 if (dstCopy) { |
321 dp->fDstCopy = *dstCopy; | 325 dp->fDstCopy = *dstCopy; |
322 } | 326 } |
323 dp->fScissorState = scissorState; | 327 dp->fScissorState = scissorState; |
324 dp->fStencilSettings = stencilSettings; | 328 dp->fStencilSettings = stencilSettings; |
325 this->recordTraceMarkersIfNecessary(); | 329 this->recordTraceMarkersIfNecessary(); |
326 } | 330 } |
327 | 331 |
328 void GrInOrderDrawBuffer::onDrawPaths(const GrDrawState& ds, | 332 void GrInOrderDrawBuffer::onDrawPaths(const GrDrawState& ds, |
329 const GrPathRange* pathRange, | 333 const GrPathRange* pathRange, |
330 const uint32_t indices[], | 334 const uint32_t indices[], |
331 int count, | 335 int count, |
332 const float transforms[], | 336 const float transforms[], |
333 PathTransformType transformsType, | 337 PathTransformType transformsType, |
334 const GrClipMaskManager::ScissorState& sci
ssorState, | 338 const GrClipMaskManager::ScissorState& sci
ssorState, |
335 const GrStencilSettings& stencilSettings, | 339 const GrStencilSettings& stencilSettings, |
336 const GrDeviceCoordTexture* dstCopy) { | 340 const GrDeviceCoordTexture* dstCopy) { |
337 SkASSERT(pathRange); | 341 SkASSERT(pathRange); |
338 SkASSERT(indices); | 342 SkASSERT(indices); |
339 SkASSERT(transforms); | 343 SkASSERT(transforms); |
340 | 344 |
341 this->recordStateIfNecessary(ds, GrGpu::kDrawPaths_DrawType, dstCopy); | 345 if (!this->recordStateAndShouldDraw(ds, GrGpu::kDrawPath_DrawType, dstCopy))
{ |
| 346 return; |
| 347 } |
342 | 348 |
343 uint32_t* savedIndices = fPathIndexBuffer.append(count, indices); | 349 uint32_t* savedIndices = fPathIndexBuffer.append(count, indices); |
344 float* savedTransforms = fPathTransformBuffer.append(count * | 350 float* savedTransforms = fPathTransformBuffer.append(count * |
345 GrPathRendering::PathTransformSize(transformsTy
pe), transforms); | 351 GrPathRendering::PathTransformSize(transformsTy
pe), transforms); |
346 | 352 |
347 if (kDrawPaths_Cmd == strip_trace_bit(fCmdBuffer.back().fType)) { | 353 if (kDrawPaths_Cmd == strip_trace_bit(fCmdBuffer.back().fType)) { |
348 // The previous command was also DrawPaths. Try to collapse this call in
to the one | 354 // The previous command was also DrawPaths. Try to collapse this call in
to the one |
349 // before. Note that stencilling all the paths at once, then covering, m
ay not be | 355 // before. Note that stencilling all the paths at once, then covering, m
ay not be |
350 // equivalent to two separate draw calls if there is overlap. Blending w
on't work, | 356 // equivalent to two separate draw calls if there is overlap. Blending w
on't work, |
351 // and the combined calls may also cancel each other's winding numbers i
n some | 357 // and the combined calls may also cancel each other's winding numbers i
n some |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
434 } | 440 } |
435 } | 441 } |
436 } | 442 } |
437 | 443 |
438 void GrInOrderDrawBuffer::reset() { | 444 void GrInOrderDrawBuffer::reset() { |
439 SkASSERT(1 == fGeoPoolStateStack.count()); | 445 SkASSERT(1 == fGeoPoolStateStack.count()); |
440 this->resetVertexSource(); | 446 this->resetVertexSource(); |
441 this->resetIndexSource(); | 447 this->resetIndexSource(); |
442 | 448 |
443 fCmdBuffer.reset(); | 449 fCmdBuffer.reset(); |
444 fLastState = NULL; | 450 fLastState.reset(NULL); |
445 fVertexPool.reset(); | 451 fVertexPool.reset(); |
446 fIndexPool.reset(); | 452 fIndexPool.reset(); |
447 reset_data_buffer(&fPathIndexBuffer, kPathIdxBufferMinReserve); | 453 reset_data_buffer(&fPathIndexBuffer, kPathIdxBufferMinReserve); |
448 reset_data_buffer(&fPathTransformBuffer, kPathXformBufferMinReserve); | 454 reset_data_buffer(&fPathTransformBuffer, kPathXformBufferMinReserve); |
449 fGpuCmdMarkers.reset(); | 455 fGpuCmdMarkers.reset(); |
450 } | 456 } |
451 | 457 |
452 void GrInOrderDrawBuffer::flush() { | 458 void GrInOrderDrawBuffer::flush() { |
453 if (fFlushing) { | 459 if (fFlushing) { |
454 return; | 460 return; |
(...skipping 12 matching lines...) Expand all Loading... |
467 fFlushing = true; | 473 fFlushing = true; |
468 | 474 |
469 fVertexPool.unmap(); | 475 fVertexPool.unmap(); |
470 fIndexPool.unmap(); | 476 fIndexPool.unmap(); |
471 | 477 |
472 CmdBuffer::Iter iter(fCmdBuffer); | 478 CmdBuffer::Iter iter(fCmdBuffer); |
473 | 479 |
474 int currCmdMarker = 0; | 480 int currCmdMarker = 0; |
475 fDstGpu->saveActiveTraceMarkers(); | 481 fDstGpu->saveActiveTraceMarkers(); |
476 | 482 |
477 // Gpu no longer maintains the current drawstate, so we track the setstate c
alls below. | 483 // Updated every time we find a set state cmd to reflect the current state i
n the playback |
478 // NOTE: we always record a new drawstate at flush boundaries | 484 // stream. |
479 SkAutoTUnref<const GrOptDrawState> currentOptState; | 485 SkAutoTUnref<const GrOptDrawState> currentOptState; |
480 | 486 |
481 while (iter.next()) { | 487 while (iter.next()) { |
482 GrGpuTraceMarker newMarker("", -1); | 488 GrGpuTraceMarker newMarker("", -1); |
483 SkString traceString; | 489 SkString traceString; |
484 if (cmd_has_trace_marker(iter->fType)) { | 490 if (cmd_has_trace_marker(iter->fType)) { |
485 traceString = fGpuCmdMarkers[currCmdMarker].toString(); | 491 traceString = fGpuCmdMarkers[currCmdMarker].toString(); |
486 newMarker.fMarker = traceString.c_str(); | 492 newMarker.fMarker = traceString.c_str(); |
487 fDstGpu->addGpuTraceMarker(&newMarker); | 493 fDstGpu->addGpuTraceMarker(&newMarker); |
488 ++currCmdMarker; | 494 ++currCmdMarker; |
489 } | 495 } |
490 | 496 |
491 if (kSetState_Cmd == strip_trace_bit(iter->fType)) { | 497 if (kSetState_Cmd == strip_trace_bit(iter->fType)) { |
492 SetState* ss = reinterpret_cast<SetState*>(iter.get()); | 498 SetState* ss = reinterpret_cast<SetState*>(iter.get()); |
493 currentOptState.reset(GrOptDrawState::Create(ss->fState, | 499 currentOptState.reset(SkRef(ss->fState.get())); |
494 fDstGpu, | |
495 &ss->fDstCopy, | |
496 ss->fDrawType)); | |
497 } else { | 500 } else { |
498 iter->execute(this, currentOptState.get()); | 501 iter->execute(this, currentOptState.get()); |
499 } | 502 } |
500 | 503 |
501 if (cmd_has_trace_marker(iter->fType)) { | 504 if (cmd_has_trace_marker(iter->fType)) { |
502 fDstGpu->removeGpuTraceMarker(&newMarker); | 505 fDstGpu->removeGpuTraceMarker(&newMarker); |
503 } | 506 } |
504 } | 507 } |
505 | 508 |
506 fDstGpu->restoreActiveTraceMarkers(); | 509 fDstGpu->restoreActiveTraceMarkers(); |
507 SkASSERT(fGpuCmdMarkers.count() == currCmdMarker); | 510 SkASSERT(fGpuCmdMarkers.count() == currCmdMarker); |
508 | 511 |
509 this->reset(); | 512 this->reset(); |
510 ++fDrawID; | 513 ++fDrawID; |
511 } | 514 } |
512 | 515 |
513 void GrInOrderDrawBuffer::Draw::execute(GrInOrderDrawBuffer* buf, const GrOptDra
wState* optState) { | 516 void GrInOrderDrawBuffer::Draw::execute(GrInOrderDrawBuffer* buf, const GrOptDra
wState* optState) { |
514 if (!optState) { | |
515 return; | |
516 } | |
517 buf->fDstGpu->draw(*optState, fInfo, fScissorState); | 517 buf->fDstGpu->draw(*optState, fInfo, fScissorState); |
518 } | 518 } |
519 | 519 |
520 void GrInOrderDrawBuffer::StencilPath::execute(GrInOrderDrawBuffer* buf, | 520 void GrInOrderDrawBuffer::StencilPath::execute(GrInOrderDrawBuffer* buf, |
521 const GrOptDrawState* optState) { | 521 const GrOptDrawState* optState) { |
522 if (!optState) { | |
523 return; | |
524 } | |
525 buf->fDstGpu->stencilPath(*optState, this->path(), fScissorState, fStencilSe
ttings); | 522 buf->fDstGpu->stencilPath(*optState, this->path(), fScissorState, fStencilSe
ttings); |
526 } | 523 } |
527 | 524 |
528 void GrInOrderDrawBuffer::DrawPath::execute(GrInOrderDrawBuffer* buf, | 525 void GrInOrderDrawBuffer::DrawPath::execute(GrInOrderDrawBuffer* buf, |
529 const GrOptDrawState* optState) { | 526 const GrOptDrawState* optState) { |
530 if (!optState) { | |
531 return; | |
532 } | |
533 buf->fDstGpu->drawPath(*optState, this->path(), fScissorState, fStencilSetti
ngs, | 527 buf->fDstGpu->drawPath(*optState, this->path(), fScissorState, fStencilSetti
ngs, |
534 fDstCopy.texture() ? &fDstCopy : NULL); | 528 fDstCopy.texture() ? &fDstCopy : NULL); |
535 } | 529 } |
536 | 530 |
537 void GrInOrderDrawBuffer::DrawPaths::execute(GrInOrderDrawBuffer* buf, | 531 void GrInOrderDrawBuffer::DrawPaths::execute(GrInOrderDrawBuffer* buf, |
538 const GrOptDrawState* optState) { | 532 const GrOptDrawState* optState) { |
539 if (!optState) { | |
540 return; | |
541 } | |
542 buf->fDstGpu->drawPaths(*optState, this->pathRange(), | 533 buf->fDstGpu->drawPaths(*optState, this->pathRange(), |
543 &buf->fPathIndexBuffer[fIndicesLocation], fCount, | 534 &buf->fPathIndexBuffer[fIndicesLocation], fCount, |
544 &buf->fPathTransformBuffer[fTransformsLocation], fTr
ansformsType, | 535 &buf->fPathTransformBuffer[fTransformsLocation], fTr
ansformsType, |
545 fScissorState, fStencilSettings, fDstCopy.texture()
? &fDstCopy : NULL); | 536 fScissorState, fStencilSettings, fDstCopy.texture()
? &fDstCopy : NULL); |
546 } | 537 } |
547 | 538 |
548 void GrInOrderDrawBuffer::SetState::execute(GrInOrderDrawBuffer*, const GrOptDra
wState*) { | 539 void GrInOrderDrawBuffer::SetState::execute(GrInOrderDrawBuffer*, const GrOptDra
wState*) { |
549 } | 540 } |
550 | 541 |
551 void GrInOrderDrawBuffer::Clear::execute(GrInOrderDrawBuffer* buf, const GrOptDr
awState*) { | 542 void GrInOrderDrawBuffer::Clear::execute(GrInOrderDrawBuffer* buf, const GrOptDr
awState*) { |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
738 // is now unreleasable because data may have been appended later in the | 729 // is now unreleasable because data may have been appended later in the |
739 // pool. | 730 // pool. |
740 if (kReserved_GeometrySrcType == restoredState.fVertexSrc) { | 731 if (kReserved_GeometrySrcType == restoredState.fVertexSrc) { |
741 poolState.fUsedPoolVertexBytes = restoredState.fVertexSize * restoredSta
te.fVertexCount; | 732 poolState.fUsedPoolVertexBytes = restoredState.fVertexSize * restoredSta
te.fVertexCount; |
742 } | 733 } |
743 if (kReserved_GeometrySrcType == restoredState.fIndexSrc) { | 734 if (kReserved_GeometrySrcType == restoredState.fIndexSrc) { |
744 poolState.fUsedPoolIndexBytes = sizeof(uint16_t) * restoredState.fIndexC
ount; | 735 poolState.fUsedPoolIndexBytes = sizeof(uint16_t) * restoredState.fIndexC
ount; |
745 } | 736 } |
746 } | 737 } |
747 | 738 |
748 void GrInOrderDrawBuffer::recordStateIfNecessary(const GrDrawState& ds, | 739 bool GrInOrderDrawBuffer::recordStateAndShouldDraw(const GrDrawState& ds, |
749 GrGpu::DrawType drawType, | 740 GrGpu::DrawType drawType, |
750 const GrDeviceCoordTexture* dst
Copy) { | 741 const GrDeviceCoordTexture* d
stCopy) { |
751 if (!fLastState) { | 742 SkAutoTUnref<GrOptDrawState> optState(GrOptDrawState::Create(ds, fDstGpu, ds
tCopy, drawType)); |
752 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (ds)); | 743 if (!optState) { |
753 fLastState = &ss->fState; | 744 return false; |
| 745 } |
| 746 if (!fLastState || *optState != *fLastState) { |
| 747 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (optState)
); |
| 748 fLastState.reset(SkRef(optState.get())); |
754 if (dstCopy) { | 749 if (dstCopy) { |
755 ss->fDstCopy = *dstCopy; | 750 ss->fDstCopy = *dstCopy; |
756 } | 751 } |
757 ss->fDrawType = drawType; | 752 ss->fDrawType = drawType; |
758 this->convertDrawStateToPendingExec(fLastState); | |
759 this->recordTraceMarkersIfNecessary(); | 753 this->recordTraceMarkersIfNecessary(); |
760 return; | |
761 } | 754 } |
762 switch (GrDrawState::CombineIfPossible(*fLastState, ds, *this->caps())) { | 755 return true; |
763 case GrDrawState::kIncompatible_CombinedState: { | |
764 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (ds)); | |
765 fLastState = &ss->fState; | |
766 if (dstCopy) { | |
767 ss->fDstCopy = *dstCopy; | |
768 } | |
769 ss->fDrawType = drawType; | |
770 this->convertDrawStateToPendingExec(fLastState); | |
771 this->recordTraceMarkersIfNecessary(); | |
772 break; | |
773 } | |
774 case GrDrawState::kA_CombinedState: | |
775 case GrDrawState::kAOrB_CombinedState: // Treat the same as kA. | |
776 break; | |
777 case GrDrawState::kB_CombinedState: | |
778 // prev has already been converted to pending execution. That is a o
ne-way ticket. | |
779 // So here we just destruct the previous state and reinit with a new
copy of curr. | |
780 // Note that this goes away when we move GrIODB over to taking optim
ized snapshots | |
781 // of draw states. | |
782 fLastState->~GrDrawState(); | |
783 SkNEW_PLACEMENT_ARGS(fLastState, GrDrawState, (ds)); | |
784 this->convertDrawStateToPendingExec(fLastState); | |
785 break; | |
786 } | |
787 } | 756 } |
788 | 757 |
789 void GrInOrderDrawBuffer::recordTraceMarkersIfNecessary() { | 758 void GrInOrderDrawBuffer::recordTraceMarkersIfNecessary() { |
790 SkASSERT(!fCmdBuffer.empty()); | 759 SkASSERT(!fCmdBuffer.empty()); |
791 SkASSERT(!cmd_has_trace_marker(fCmdBuffer.back().fType)); | 760 SkASSERT(!cmd_has_trace_marker(fCmdBuffer.back().fType)); |
792 const GrTraceMarkerSet& activeTraceMarkers = this->getActiveTraceMarkers(); | 761 const GrTraceMarkerSet& activeTraceMarkers = this->getActiveTraceMarkers(); |
793 if (activeTraceMarkers.count() > 0) { | 762 if (activeTraceMarkers.count() > 0) { |
794 fCmdBuffer.back().fType = add_trace_bit(fCmdBuffer.back().fType); | 763 fCmdBuffer.back().fType = add_trace_bit(fCmdBuffer.back().fType); |
795 fGpuCmdMarkers.push_back(activeTraceMarkers); | 764 fGpuCmdMarkers.push_back(activeTraceMarkers); |
796 } | 765 } |
797 } | 766 } |
OLD | NEW |