Chromium Code Reviews| 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 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 255 } | 254 } |
| 256 | 255 |
| 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 GeometryPoolState& poolState = fGeoPoolStateStack.back(); | 262 GeometryPoolState& poolState = fGeoPoolStateStack.back(); |
| 264 | 263 |
| 265 this->recordStateIfNecessary(ds, | 264 if (!this->recordStateAndShouldDraw(ds, |
| 266 GrGpu::PrimTypeToDrawType(info.primitiveType()) , | 265 GrGpu::PrimTypeToDrawType(info.primitiveT ype()), |
|
egdaniel
2014/11/19 15:00:36
align
bsalomon
2014/11/19 15:09:38
Done.
| |
| 267 info.getDstCopy()); | 266 info.getDstCopy())) { |
| 267 return; | |
| 268 } | |
| 268 | 269 |
| 269 const GrVertexBuffer* vb; | 270 const GrVertexBuffer* vb; |
| 270 if (kBuffer_GeometrySrcType == this->getGeomSrc().fVertexSrc) { | 271 if (kBuffer_GeometrySrcType == this->getGeomSrc().fVertexSrc) { |
| 271 vb = this->getGeomSrc().fVertexBuffer; | 272 vb = this->getGeomSrc().fVertexBuffer; |
| 272 } else { | 273 } else { |
| 273 vb = poolState.fPoolVertexBuffer; | 274 vb = poolState.fPoolVertexBuffer; |
| 274 } | 275 } |
| 275 | 276 |
| 276 const GrIndexBuffer* ib = NULL; | 277 const GrIndexBuffer* ib = NULL; |
| 277 if (info.isIndexed()) { | 278 if (info.isIndexed()) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 309 poolState.fUsedPoolIndexBytes = SkTMax(poolState.fUsedPoolIndexBytes, by tes); | 310 poolState.fUsedPoolIndexBytes = SkTMax(poolState.fUsedPoolIndexBytes, by tes); |
| 310 draw->fInfo.adjustStartIndex(poolState.fPoolStartIndex); | 311 draw->fInfo.adjustStartIndex(poolState.fPoolStartIndex); |
| 311 } | 312 } |
| 312 } | 313 } |
| 313 | 314 |
| 314 void GrInOrderDrawBuffer::onStencilPath(const GrDrawState& ds, | 315 void GrInOrderDrawBuffer::onStencilPath(const GrDrawState& ds, |
| 315 const GrPath* path, | 316 const GrPath* path, |
| 316 const GrClipMaskManager::ScissorState& s cissorState, | 317 const GrClipMaskManager::ScissorState& s cissorState, |
| 317 const GrStencilSettings& stencilSettings ) { | 318 const GrStencilSettings& stencilSettings ) { |
| 318 // Only compare the subset of GrDrawState relevant to path stenciling? | 319 // Only compare the subset of GrDrawState relevant to path stenciling? |
| 319 this->recordStateIfNecessary(ds, GrGpu::kStencilPath_DrawType, NULL); | 320 if (!this->recordStateAndShouldDraw(ds, GrGpu::kStencilPath_DrawType, NULL)) { |
| 321 return; | |
| 322 } | |
| 320 StencilPath* sp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, StencilPath, (path)); | 323 StencilPath* sp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, StencilPath, (path)); |
| 321 sp->fScissorState = scissorState; | 324 sp->fScissorState = scissorState; |
| 322 sp->fStencilSettings = stencilSettings; | 325 sp->fStencilSettings = stencilSettings; |
| 323 this->recordTraceMarkersIfNecessary(); | 326 this->recordTraceMarkersIfNecessary(); |
| 324 } | 327 } |
| 325 | 328 |
| 326 void GrInOrderDrawBuffer::onDrawPath(const GrDrawState& ds, | 329 void GrInOrderDrawBuffer::onDrawPath(const GrDrawState& ds, |
| 327 const GrPath* path, | 330 const GrPath* path, |
| 328 const GrClipMaskManager::ScissorState& scis sorState, | 331 const GrClipMaskManager::ScissorState& scis sorState, |
| 329 const GrStencilSettings& stencilSettings, | 332 const GrStencilSettings& stencilSettings, |
| 330 const GrDeviceCoordTexture* dstCopy) { | 333 const GrDeviceCoordTexture* dstCopy) { |
| 331 // TODO: Only compare the subset of GrDrawState relevant to path covering? | 334 // TODO: Only compare the subset of GrDrawState relevant to path covering? |
| 332 this->recordStateIfNecessary(ds, GrGpu::kDrawPath_DrawType, dstCopy); | 335 if (!this->recordStateAndShouldDraw(ds, GrGpu::kDrawPath_DrawType, dstCopy)) { |
| 336 return; | |
| 337 } | |
| 333 DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (path)); | 338 DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (path)); |
| 334 if (dstCopy) { | 339 if (dstCopy) { |
| 335 dp->fDstCopy = *dstCopy; | 340 dp->fDstCopy = *dstCopy; |
| 336 } | 341 } |
| 337 dp->fScissorState = scissorState; | 342 dp->fScissorState = scissorState; |
| 338 dp->fStencilSettings = stencilSettings; | 343 dp->fStencilSettings = stencilSettings; |
| 339 this->recordTraceMarkersIfNecessary(); | 344 this->recordTraceMarkersIfNecessary(); |
| 340 } | 345 } |
| 341 | 346 |
| 342 void GrInOrderDrawBuffer::onDrawPaths(const GrDrawState& ds, | 347 void GrInOrderDrawBuffer::onDrawPaths(const GrDrawState& ds, |
| 343 const GrPathRange* pathRange, | 348 const GrPathRange* pathRange, |
| 344 const uint32_t indices[], | 349 const uint32_t indices[], |
| 345 int count, | 350 int count, |
| 346 const float transforms[], | 351 const float transforms[], |
| 347 PathTransformType transformsType, | 352 PathTransformType transformsType, |
| 348 const GrClipMaskManager::ScissorState& sci ssorState, | 353 const GrClipMaskManager::ScissorState& sci ssorState, |
| 349 const GrStencilSettings& stencilSettings, | 354 const GrStencilSettings& stencilSettings, |
| 350 const GrDeviceCoordTexture* dstCopy) { | 355 const GrDeviceCoordTexture* dstCopy) { |
| 351 SkASSERT(pathRange); | 356 SkASSERT(pathRange); |
| 352 SkASSERT(indices); | 357 SkASSERT(indices); |
| 353 SkASSERT(transforms); | 358 SkASSERT(transforms); |
| 354 | 359 |
| 355 this->recordStateIfNecessary(ds, GrGpu::kDrawPaths_DrawType, dstCopy); | 360 if (!this->recordStateAndShouldDraw(ds, GrGpu::kDrawPath_DrawType, dstCopy)) { |
| 361 return; | |
| 362 } | |
| 356 | 363 |
| 357 uint32_t* savedIndices = fPathIndexBuffer.append(count, indices); | 364 uint32_t* savedIndices = fPathIndexBuffer.append(count, indices); |
| 358 float* savedTransforms = fPathTransformBuffer.append(count * | 365 float* savedTransforms = fPathTransformBuffer.append(count * |
| 359 GrPathRendering::PathTransformSize(transformsTy pe), transforms); | 366 GrPathRendering::PathTransformSize(transformsTy pe), transforms); |
| 360 | 367 |
| 361 if (kDrawPaths_Cmd == strip_trace_bit(fCmdBuffer.back().fType)) { | 368 if (kDrawPaths_Cmd == strip_trace_bit(fCmdBuffer.back().fType)) { |
| 362 // The previous command was also DrawPaths. Try to collapse this call in to the one | 369 // The previous command was also DrawPaths. Try to collapse this call in to the one |
| 363 // before. Note that stencilling all the paths at once, then covering, m ay not be | 370 // before. Note that stencilling all the paths at once, then covering, m ay not be |
| 364 // equivalent to two separate draw calls if there is overlap. Blending w on't work, | 371 // equivalent to two separate draw calls if there is overlap. Blending w on't work, |
| 365 // and the combined calls may also cancel each other's winding numbers i n some | 372 // and the combined calls may also cancel each other's winding numbers i n some |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 431 clr->fColor = GrColor_ILLEGAL; | 438 clr->fColor = GrColor_ILLEGAL; |
| 432 this->recordTraceMarkersIfNecessary(); | 439 this->recordTraceMarkersIfNecessary(); |
| 433 } | 440 } |
| 434 | 441 |
| 435 void GrInOrderDrawBuffer::reset() { | 442 void GrInOrderDrawBuffer::reset() { |
| 436 SkASSERT(1 == fGeoPoolStateStack.count()); | 443 SkASSERT(1 == fGeoPoolStateStack.count()); |
| 437 this->resetVertexSource(); | 444 this->resetVertexSource(); |
| 438 this->resetIndexSource(); | 445 this->resetIndexSource(); |
| 439 | 446 |
| 440 fCmdBuffer.reset(); | 447 fCmdBuffer.reset(); |
| 441 fLastState = NULL; | 448 fLastState.reset(NULL); |
| 442 fVertexPool.reset(); | 449 fVertexPool.reset(); |
| 443 fIndexPool.reset(); | 450 fIndexPool.reset(); |
| 444 reset_data_buffer(&fPathIndexBuffer, kPathIdxBufferMinReserve); | 451 reset_data_buffer(&fPathIndexBuffer, kPathIdxBufferMinReserve); |
| 445 reset_data_buffer(&fPathTransformBuffer, kPathXformBufferMinReserve); | 452 reset_data_buffer(&fPathTransformBuffer, kPathXformBufferMinReserve); |
| 446 fGpuCmdMarkers.reset(); | 453 fGpuCmdMarkers.reset(); |
| 447 } | 454 } |
| 448 | 455 |
| 449 void GrInOrderDrawBuffer::flush() { | 456 void GrInOrderDrawBuffer::flush() { |
| 450 if (fFlushing) { | 457 if (fFlushing) { |
| 451 return; | 458 return; |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 464 fFlushing = true; | 471 fFlushing = true; |
| 465 | 472 |
| 466 fVertexPool.unmap(); | 473 fVertexPool.unmap(); |
| 467 fIndexPool.unmap(); | 474 fIndexPool.unmap(); |
| 468 | 475 |
| 469 CmdBuffer::Iter iter(fCmdBuffer); | 476 CmdBuffer::Iter iter(fCmdBuffer); |
| 470 | 477 |
| 471 int currCmdMarker = 0; | 478 int currCmdMarker = 0; |
| 472 fDstGpu->saveActiveTraceMarkers(); | 479 fDstGpu->saveActiveTraceMarkers(); |
| 473 | 480 |
| 474 // Gpu no longer maintains the current drawstate, so we track the setstate c alls below. | 481 // Updated every time we find a set state cmd to reflect the current state i n the playback |
| 475 // NOTE: we always record a new drawstate at flush boundaries | 482 // stream. |
| 476 SkAutoTUnref<const GrOptDrawState> currentOptState; | 483 SkAutoTUnref<const GrOptDrawState> currentOptState; |
| 477 | 484 |
| 478 while (iter.next()) { | 485 while (iter.next()) { |
| 479 GrGpuTraceMarker newMarker("", -1); | 486 GrGpuTraceMarker newMarker("", -1); |
| 480 SkString traceString; | 487 SkString traceString; |
| 481 if (cmd_has_trace_marker(iter->fType)) { | 488 if (cmd_has_trace_marker(iter->fType)) { |
| 482 traceString = fGpuCmdMarkers[currCmdMarker].toString(); | 489 traceString = fGpuCmdMarkers[currCmdMarker].toString(); |
| 483 newMarker.fMarker = traceString.c_str(); | 490 newMarker.fMarker = traceString.c_str(); |
| 484 fDstGpu->addGpuTraceMarker(&newMarker); | 491 fDstGpu->addGpuTraceMarker(&newMarker); |
| 485 ++currCmdMarker; | 492 ++currCmdMarker; |
| 486 } | 493 } |
| 487 | 494 |
| 488 if (kSetState_Cmd == strip_trace_bit(iter->fType)) { | 495 if (kSetState_Cmd == strip_trace_bit(iter->fType)) { |
| 489 SetState* ss = reinterpret_cast<SetState*>(iter.get()); | 496 SetState* ss = reinterpret_cast<SetState*>(iter.get()); |
| 490 currentOptState.reset(GrOptDrawState::Create(ss->fState, | 497 currentOptState.reset(SkRef(ss->fState.get())); |
| 491 fDstGpu, | |
| 492 &ss->fDstCopy, | |
| 493 ss->fDrawType)); | |
| 494 } else { | 498 } else { |
| 495 iter->execute(this, currentOptState.get()); | 499 iter->execute(this, currentOptState.get()); |
| 496 } | 500 } |
| 497 | 501 |
| 498 if (cmd_has_trace_marker(iter->fType)) { | 502 if (cmd_has_trace_marker(iter->fType)) { |
| 499 fDstGpu->removeGpuTraceMarker(&newMarker); | 503 fDstGpu->removeGpuTraceMarker(&newMarker); |
| 500 } | 504 } |
| 501 } | 505 } |
| 502 | 506 |
| 503 fDstGpu->restoreActiveTraceMarkers(); | 507 fDstGpu->restoreActiveTraceMarkers(); |
| 504 SkASSERT(fGpuCmdMarkers.count() == currCmdMarker); | 508 SkASSERT(fGpuCmdMarkers.count() == currCmdMarker); |
| 505 | 509 |
| 506 this->reset(); | 510 this->reset(); |
| 507 ++fDrawID; | 511 ++fDrawID; |
| 508 } | 512 } |
| 509 | 513 |
| 510 void GrInOrderDrawBuffer::Draw::execute(GrInOrderDrawBuffer* buf, const GrOptDra wState* optState) { | 514 void GrInOrderDrawBuffer::Draw::execute(GrInOrderDrawBuffer* buf, const GrOptDra wState* optState) { |
| 511 if (!optState) { | 515 if (!optState) { |
| 512 return; | 516 return; |
| 513 } | 517 } |
|
joshualitt
2014/11/19 14:55:35
Are these checks still necessary?
bsalomon
2014/11/19 15:04:43
oh nice, catch. No, they're not.
| |
| 514 GrGpu* dstGpu = buf->fDstGpu; | 518 GrGpu* dstGpu = buf->fDstGpu; |
| 515 dstGpu->setVertexSourceToBuffer(this->vertexBuffer(), optState->getVertexStr ide()); | 519 dstGpu->setVertexSourceToBuffer(this->vertexBuffer(), optState->getVertexStr ide()); |
| 516 if (fInfo.isIndexed()) { | 520 if (fInfo.isIndexed()) { |
| 517 dstGpu->setIndexSourceToBuffer(this->indexBuffer()); | 521 dstGpu->setIndexSourceToBuffer(this->indexBuffer()); |
| 518 } | 522 } |
| 519 dstGpu->draw(*optState, fInfo, fScissorState); | 523 dstGpu->draw(*optState, fInfo, fScissorState); |
| 520 } | 524 } |
| 521 | 525 |
| 522 void GrInOrderDrawBuffer::StencilPath::execute(GrInOrderDrawBuffer* buf, | 526 void GrInOrderDrawBuffer::StencilPath::execute(GrInOrderDrawBuffer* buf, |
| 523 const GrOptDrawState* optState) { | 527 const GrOptDrawState* optState) { |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 740 // is now unreleasable because data may have been appended later in the | 744 // is now unreleasable because data may have been appended later in the |
| 741 // pool. | 745 // pool. |
| 742 if (kReserved_GeometrySrcType == restoredState.fVertexSrc) { | 746 if (kReserved_GeometrySrcType == restoredState.fVertexSrc) { |
| 743 poolState.fUsedPoolVertexBytes = restoredState.fVertexSize * restoredSta te.fVertexCount; | 747 poolState.fUsedPoolVertexBytes = restoredState.fVertexSize * restoredSta te.fVertexCount; |
| 744 } | 748 } |
| 745 if (kReserved_GeometrySrcType == restoredState.fIndexSrc) { | 749 if (kReserved_GeometrySrcType == restoredState.fIndexSrc) { |
| 746 poolState.fUsedPoolIndexBytes = sizeof(uint16_t) * restoredState.fIndexC ount; | 750 poolState.fUsedPoolIndexBytes = sizeof(uint16_t) * restoredState.fIndexC ount; |
| 747 } | 751 } |
| 748 } | 752 } |
| 749 | 753 |
| 750 void GrInOrderDrawBuffer::recordStateIfNecessary(const GrDrawState& ds, | 754 bool GrInOrderDrawBuffer::recordStateAndShouldDraw(const GrDrawState& ds, |
| 751 GrGpu::DrawType drawType, | 755 GrGpu::DrawType drawType, |
| 752 const GrDeviceCoordTexture* dst Copy) { | 756 const GrDeviceCoordTexture* d stCopy) { |
| 753 if (!fLastState) { | 757 SkAutoTUnref<GrOptDrawState> optState(GrOptDrawState::Create(ds, fDstGpu, ds tCopy, drawType)); |
| 754 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (ds)); | 758 if (!optState) { |
| 755 fLastState = &ss->fState; | 759 return false; |
| 760 } | |
| 761 if (!fLastState || *optState != *fLastState) { | |
| 762 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (optState) ); | |
| 763 fLastState.reset(SkRef(optState.get())); | |
| 756 if (dstCopy) { | 764 if (dstCopy) { |
| 757 ss->fDstCopy = *dstCopy; | 765 ss->fDstCopy = *dstCopy; |
| 758 } | 766 } |
| 759 ss->fDrawType = drawType; | 767 ss->fDrawType = drawType; |
| 760 this->convertDrawStateToPendingExec(fLastState); | |
| 761 this->recordTraceMarkersIfNecessary(); | 768 this->recordTraceMarkersIfNecessary(); |
| 762 return; | |
| 763 } | 769 } |
| 764 switch (GrDrawState::CombineIfPossible(*fLastState, ds, *this->caps())) { | 770 return true; |
| 765 case GrDrawState::kIncompatible_CombinedState: { | |
| 766 SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (ds)); | |
| 767 fLastState = &ss->fState; | |
| 768 if (dstCopy) { | |
| 769 ss->fDstCopy = *dstCopy; | |
| 770 } | |
| 771 ss->fDrawType = drawType; | |
| 772 this->convertDrawStateToPendingExec(fLastState); | |
| 773 this->recordTraceMarkersIfNecessary(); | |
| 774 break; | |
| 775 } | |
| 776 case GrDrawState::kA_CombinedState: | |
| 777 case GrDrawState::kAOrB_CombinedState: // Treat the same as kA. | |
| 778 break; | |
| 779 case GrDrawState::kB_CombinedState: | |
| 780 // prev has already been converted to pending execution. That is a o ne-way ticket. | |
| 781 // So here we just destruct the previous state and reinit with a new copy of curr. | |
| 782 // Note that this goes away when we move GrIODB over to taking optim ized snapshots | |
| 783 // of draw states. | |
| 784 fLastState->~GrDrawState(); | |
| 785 SkNEW_PLACEMENT_ARGS(fLastState, GrDrawState, (ds)); | |
| 786 this->convertDrawStateToPendingExec(fLastState); | |
| 787 break; | |
| 788 } | |
| 789 } | 771 } |
| 790 | 772 |
| 791 void GrInOrderDrawBuffer::recordTraceMarkersIfNecessary() { | 773 void GrInOrderDrawBuffer::recordTraceMarkersIfNecessary() { |
| 792 SkASSERT(!fCmdBuffer.empty()); | 774 SkASSERT(!fCmdBuffer.empty()); |
| 793 SkASSERT(!cmd_has_trace_marker(fCmdBuffer.back().fType)); | 775 SkASSERT(!cmd_has_trace_marker(fCmdBuffer.back().fType)); |
| 794 const GrTraceMarkerSet& activeTraceMarkers = this->getActiveTraceMarkers(); | 776 const GrTraceMarkerSet& activeTraceMarkers = this->getActiveTraceMarkers(); |
| 795 if (activeTraceMarkers.count() > 0) { | 777 if (activeTraceMarkers.count() > 0) { |
| 796 fCmdBuffer.back().fType = add_trace_bit(fCmdBuffer.back().fType); | 778 fCmdBuffer.back().fType = add_trace_bit(fCmdBuffer.back().fType); |
| 797 fGpuCmdMarkers.push_back(activeTraceMarkers); | 779 fGpuCmdMarkers.push_back(activeTraceMarkers); |
| 798 } | 780 } |
| 799 } | 781 } |
| OLD | NEW |