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 |