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" |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 25 , fIndexPool(*indexPool) | 25 , fIndexPool(*indexPool) |
| 26 , fFlushing(false) | 26 , fFlushing(false) |
| 27 , fDrawID(0) { | 27 , fDrawID(0) { |
| 28 | 28 |
| 29 fDstGpu->ref(); | 29 fDstGpu->ref(); |
| 30 fCaps.reset(SkRef(fDstGpu->caps())); | 30 fCaps.reset(SkRef(fDstGpu->caps())); |
| 31 | 31 |
| 32 SkASSERT(vertexPool); | 32 SkASSERT(vertexPool); |
| 33 SkASSERT(indexPool); | 33 SkASSERT(indexPool); |
| 34 | 34 |
| 35 fPathIndexBuffer.setReserve(kPathIdxBufferMinReserve); | |
| 36 fPathTransformBuffer.setReserve(kPathXformBufferMinReserve); | |
| 37 | |
| 35 GeometryPoolState& poolState = fGeoPoolStateStack.push_back(); | 38 GeometryPoolState& poolState = fGeoPoolStateStack.push_back(); |
| 36 poolState.fUsedPoolVertexBytes = 0; | 39 poolState.fUsedPoolVertexBytes = 0; |
| 37 poolState.fUsedPoolIndexBytes = 0; | 40 poolState.fUsedPoolIndexBytes = 0; |
| 38 #ifdef SK_DEBUG | 41 #ifdef SK_DEBUG |
| 39 poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0; | 42 poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0; |
| 40 poolState.fPoolStartVertex = ~0; | 43 poolState.fPoolStartVertex = ~0; |
| 41 poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0; | 44 poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0; |
| 42 poolState.fPoolStartIndex = ~0; | 45 poolState.fPoolStartIndex = ~0; |
| 43 #endif | 46 #endif |
| 44 this->reset(); | 47 this->reset(); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 94 if (hasLocalCoords) { | 97 if (hasLocalCoords) { |
| 95 drawState->setVertexAttribs<kRectAttribs>(3, 2 * sizeof(SkPoint) + sizeo f(SkColor)); | 98 drawState->setVertexAttribs<kRectAttribs>(3, 2 * sizeof(SkPoint) + sizeo f(SkColor)); |
| 96 } else { | 99 } else { |
| 97 drawState->setVertexAttribs<kRectAttribs>(2, sizeof(SkPoint) + sizeof(Sk Color)); | 100 drawState->setVertexAttribs<kRectAttribs>(2, sizeof(SkPoint) + sizeof(Sk Color)); |
| 98 } | 101 } |
| 99 if (0xFF == GrColorUnpackA(color)) { | 102 if (0xFF == GrColorUnpackA(color)) { |
| 100 drawState->setHint(GrDrawState::kVertexColorsAreOpaque_Hint, true); | 103 drawState->setHint(GrDrawState::kVertexColorsAreOpaque_Hint, true); |
| 101 } | 104 } |
| 102 } | 105 } |
| 103 | 106 |
| 107 static bool path_fill_type_is_winding(const GrStencilSettings& pathStencilSettin gs) { | |
| 108 static const GrStencilSettings::Face pathFace = GrStencilSettings::kFront_Fa ce; | |
| 109 bool isWinding = kInvert_StencilOp != pathStencilSettings.passOp(pathFace); | |
| 110 if (isWinding) { | |
| 111 // Double check that it is in fact winding. | |
| 112 SkASSERT(kIncClamp_StencilOp == pathStencilSettings.passOp(pathFace)); | |
| 113 SkASSERT(kIncClamp_StencilOp == pathStencilSettings.failOp(pathFace)); | |
| 114 SkASSERT(0x1 != pathStencilSettings.writeMask(pathFace)); | |
| 115 SkASSERT(!pathStencilSettings.isTwoSided()); | |
| 116 } | |
| 117 return isWinding; | |
| 118 } | |
| 119 | |
| 120 static bool draw_uses_dst_color(const GrDrawState& drawState) { | |
| 121 GrBlendCoeff dstBlendCoeff = drawState.getDstBlendCoeff(); | |
| 122 if (kZero_GrBlendCoeff != dstBlendCoeff && | |
| 123 (kISA_GrBlendCoeff != dstBlendCoeff || !drawState.srcAlphaWillBeOne())) { | |
| 124 return true; | |
| 125 } | |
| 126 | |
| 127 return drawState.willEffectReadDstColor(); | |
|
Chris Dalton
2014/11/11 22:34:40
My understanding is that this should work. srcAlph
| |
| 128 } | |
| 129 | |
| 130 template<typename T> static void reset_data_buffer(SkTDArray<T>* buffer, int min Reserve) { | |
| 131 // Assume the next time this buffer fills up it will use approximately the s ame amount | |
| 132 // of space as last time. Only resize if we're using less than a third of th e | |
| 133 // allocated space, and leave enough for 50% growth over last time. | |
| 134 if (3 * buffer->count() < buffer->reserved() && buffer->reserved() > minRese rve) { | |
| 135 int reserve = SkTMax(minReserve, buffer->count() * 3 / 2); | |
| 136 buffer->reset(); | |
| 137 buffer->setReserve(reserve); | |
| 138 } else { | |
| 139 buffer->rewind(); | |
| 140 } | |
| 141 } | |
| 142 | |
| 104 enum { | 143 enum { |
| 105 kTraceCmdBit = 0x80, | 144 kTraceCmdBit = 0x80, |
| 106 kCmdMask = 0x7f, | 145 kCmdMask = 0x7f, |
| 107 }; | 146 }; |
| 108 | 147 |
| 109 static inline uint8_t add_trace_bit(uint8_t cmd) { return cmd | kTraceCmdBit; } | 148 static inline uint8_t add_trace_bit(uint8_t cmd) { return cmd | kTraceCmdBit; } |
| 110 | 149 |
| 111 static inline uint8_t strip_trace_bit(uint8_t cmd) { return cmd & kCmdMask; } | 150 static inline uint8_t strip_trace_bit(uint8_t cmd) { return cmd & kCmdMask; } |
| 112 | 151 |
| 113 static inline bool cmd_has_trace_marker(uint8_t cmd) { return SkToBool(cmd & kTr aceCmdBit); } | 152 static inline bool cmd_has_trace_marker(uint8_t cmd) { return SkToBool(cmd & kTr aceCmdBit); } |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 326 PathTransformType transformsType, | 365 PathTransformType transformsType, |
| 327 const GrClipMaskManager::ScissorState& sci ssorState, | 366 const GrClipMaskManager::ScissorState& sci ssorState, |
| 328 const GrStencilSettings& stencilSettings, | 367 const GrStencilSettings& stencilSettings, |
| 329 const GrDeviceCoordTexture* dstCopy) { | 368 const GrDeviceCoordTexture* dstCopy) { |
| 330 SkASSERT(pathRange); | 369 SkASSERT(pathRange); |
| 331 SkASSERT(indices); | 370 SkASSERT(indices); |
| 332 SkASSERT(transforms); | 371 SkASSERT(transforms); |
| 333 | 372 |
| 334 this->recordStateIfNecessary(); | 373 this->recordStateIfNecessary(); |
| 335 | 374 |
| 336 int sizeOfIndices = sizeof(uint32_t) * count; | 375 uint32_t* savedIndices = fPathIndexBuffer.append(count, indices); |
| 337 int sizeOfTransforms = sizeof(float) * count * | 376 float* savedTransforms = fPathTransformBuffer.append(count * |
| 338 GrPathRendering::PathTransformSize(transformsType); | 377 GrPathRendering::PathTransformSize(transformsTy pe), transforms); |
| 339 | 378 |
| 340 DrawPaths* dp = GrNEW_APPEND_WITH_DATA_TO_RECORDER(fCmdBuffer, DrawPaths, (p athRange), | 379 if (kDrawPaths_Cmd == fCmdBuffer.back().fType) { |
| 341 sizeOfIndices + sizeOfTra nsforms); | 380 // The previous command was also DrawPaths. Try to collapse this call in to the one |
| 342 memcpy(dp->indices(), indices, sizeOfIndices); | 381 // before. Note that stencilling all the paths at once, then covering, m ay not be |
| 382 // equivalent to two separate draw calls if there is overlap. Blending w on't work, | |
| 383 // and the combined calls may also cancel each other's winding numbers i n some | |
| 384 // places. For now the winding numbers are only an issue if the fill is even/odd, | |
| 385 // because DrawPaths is currently only used for glyphs, and glyphs in th e same | |
| 386 // font tend to all wind in the same direction. | |
| 387 DrawPaths* previous = static_cast<DrawPaths*>(&fCmdBuffer.back()); | |
| 388 if (pathRange == previous->pathRange() && | |
| 389 transformsType == previous->fTransformsType && | |
| 390 scissorState == previous->fScissorState && | |
| 391 stencilSettings == previous->fStencilSettings && | |
| 392 path_fill_type_is_winding(stencilSettings) && | |
| 393 !draw_uses_dst_color(this->getDrawState())) { | |
| 394 // Fold this DrawPaths call into the one previous. | |
| 395 previous->fCount += count; | |
| 396 return; | |
| 397 } | |
| 398 } | |
| 399 | |
| 400 DrawPaths* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPaths, (pathRange)) ; | |
| 401 dp->fIndicesLocation = savedIndices - fPathIndexBuffer.begin(); | |
| 343 dp->fCount = count; | 402 dp->fCount = count; |
| 344 memcpy(dp->transforms(), transforms, sizeOfTransforms); | 403 dp->fTransformsLocation = savedTransforms - fPathTransformBuffer.begin(); |
| 345 dp->fTransformsType = transformsType; | 404 dp->fTransformsType = transformsType; |
| 346 dp->fScissorState = scissorState; | 405 dp->fScissorState = scissorState; |
| 347 dp->fStencilSettings = stencilSettings; | 406 dp->fStencilSettings = stencilSettings; |
| 348 if (dstCopy) { | 407 if (dstCopy) { |
| 349 dp->fDstCopy = *dstCopy; | 408 dp->fDstCopy = *dstCopy; |
| 350 } | 409 } |
| 351 | 410 |
| 352 this->recordTraceMarkersIfNecessary(); | 411 this->recordTraceMarkersIfNecessary(); |
| 353 } | 412 } |
| 354 | 413 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 399 | 458 |
| 400 void GrInOrderDrawBuffer::reset() { | 459 void GrInOrderDrawBuffer::reset() { |
| 401 SkASSERT(1 == fGeoPoolStateStack.count()); | 460 SkASSERT(1 == fGeoPoolStateStack.count()); |
| 402 this->resetVertexSource(); | 461 this->resetVertexSource(); |
| 403 this->resetIndexSource(); | 462 this->resetIndexSource(); |
| 404 | 463 |
| 405 fCmdBuffer.reset(); | 464 fCmdBuffer.reset(); |
| 406 fLastState = NULL; | 465 fLastState = NULL; |
| 407 fVertexPool.reset(); | 466 fVertexPool.reset(); |
| 408 fIndexPool.reset(); | 467 fIndexPool.reset(); |
| 468 reset_data_buffer(&fPathIndexBuffer, kPathIdxBufferMinReserve); | |
| 469 reset_data_buffer(&fPathTransformBuffer, kPathXformBufferMinReserve); | |
| 409 fGpuCmdMarkers.reset(); | 470 fGpuCmdMarkers.reset(); |
| 410 } | 471 } |
| 411 | 472 |
| 412 void GrInOrderDrawBuffer::flush() { | 473 void GrInOrderDrawBuffer::flush() { |
| 413 if (fFlushing) { | 474 if (fFlushing) { |
| 414 return; | 475 return; |
| 415 } | 476 } |
| 416 | 477 |
| 417 this->getContext()->getFontCache()->updateTextures(); | 478 this->getContext()->getFontCache()->updateTextures(); |
| 418 | 479 |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 445 fDstGpu->addGpuTraceMarker(&newMarker); | 506 fDstGpu->addGpuTraceMarker(&newMarker); |
| 446 ++currCmdMarker; | 507 ++currCmdMarker; |
| 447 } | 508 } |
| 448 | 509 |
| 449 SkDEBUGCODE(bool isDraw = kDraw_Cmd == strip_trace_bit(iter->fType) || | 510 SkDEBUGCODE(bool isDraw = kDraw_Cmd == strip_trace_bit(iter->fType) || |
| 450 kStencilPath_Cmd == strip_trace_bit(iter->fTyp e) || | 511 kStencilPath_Cmd == strip_trace_bit(iter->fTyp e) || |
| 451 kDrawPath_Cmd == strip_trace_bit(iter->fType) || | 512 kDrawPath_Cmd == strip_trace_bit(iter->fType) || |
| 452 kDrawPaths_Cmd == strip_trace_bit(iter->fType) ); | 513 kDrawPaths_Cmd == strip_trace_bit(iter->fType) ); |
| 453 SkASSERT(!isDraw || fDstGpu->drawState() != prevDrawState); | 514 SkASSERT(!isDraw || fDstGpu->drawState() != prevDrawState); |
| 454 | 515 |
| 455 iter->execute(fDstGpu); | 516 iter->execute(this); |
| 456 | 517 |
| 457 if (cmd_has_trace_marker(iter->fType)) { | 518 if (cmd_has_trace_marker(iter->fType)) { |
| 458 fDstGpu->removeGpuTraceMarker(&newMarker); | 519 fDstGpu->removeGpuTraceMarker(&newMarker); |
| 459 } | 520 } |
| 460 } | 521 } |
| 461 | 522 |
| 462 fDstGpu->restoreActiveTraceMarkers(); | 523 fDstGpu->restoreActiveTraceMarkers(); |
| 463 SkASSERT(fGpuCmdMarkers.count() == currCmdMarker); | 524 SkASSERT(fGpuCmdMarkers.count() == currCmdMarker); |
| 464 | 525 |
| 465 fDstGpu->setDrawState(prevDrawState); | 526 fDstGpu->setDrawState(prevDrawState); |
| 466 prevDrawState->unref(); | 527 prevDrawState->unref(); |
| 467 this->reset(); | 528 this->reset(); |
| 468 ++fDrawID; | 529 ++fDrawID; |
| 469 } | 530 } |
| 470 | 531 |
| 471 void GrInOrderDrawBuffer::Draw::execute(GrGpu* gpu) { | 532 void GrInOrderDrawBuffer::Draw::execute(GrInOrderDrawBuffer* buf) { |
| 533 GrGpu* gpu = buf->dstGpu(); | |
| 472 gpu->setVertexSourceToBuffer(this->vertexBuffer()); | 534 gpu->setVertexSourceToBuffer(this->vertexBuffer()); |
| 473 if (fInfo.isIndexed()) { | 535 if (fInfo.isIndexed()) { |
| 474 gpu->setIndexSourceToBuffer(this->indexBuffer()); | 536 gpu->setIndexSourceToBuffer(this->indexBuffer()); |
| 475 } | 537 } |
| 476 gpu->draw(fInfo, fScissorState); | 538 gpu->draw(fInfo, fScissorState); |
| 477 } | 539 } |
| 478 | 540 |
| 479 void GrInOrderDrawBuffer::StencilPath::execute(GrGpu* gpu) { | 541 void GrInOrderDrawBuffer::StencilPath::execute(GrInOrderDrawBuffer* buf) { |
| 542 GrGpu* gpu = buf->dstGpu(); | |
| 480 gpu->stencilPath(this->path(), fScissorState, fStencilSettings); | 543 gpu->stencilPath(this->path(), fScissorState, fStencilSettings); |
| 481 } | 544 } |
| 482 | 545 |
| 483 void GrInOrderDrawBuffer::DrawPath::execute(GrGpu* gpu) { | 546 void GrInOrderDrawBuffer::DrawPath::execute(GrInOrderDrawBuffer* buf) { |
| 547 GrGpu* gpu = buf->dstGpu(); | |
| 484 gpu->drawPath(this->path(), fScissorState, fStencilSettings, | 548 gpu->drawPath(this->path(), fScissorState, fStencilSettings, |
| 485 fDstCopy.texture() ? &fDstCopy : NULL); | 549 fDstCopy.texture() ? &fDstCopy : NULL); |
| 486 } | 550 } |
| 487 | 551 |
| 488 void GrInOrderDrawBuffer::DrawPaths::execute(GrGpu* gpu) { | 552 void GrInOrderDrawBuffer::DrawPaths::execute(GrInOrderDrawBuffer* buf) { |
| 489 gpu->drawPaths(this->pathRange(), this->indices(), fCount, this->transforms( ), | 553 GrGpu* gpu = buf->dstGpu(); |
| 490 fTransformsType, fScissorState, fStencilSettings, | 554 gpu->drawPaths(this->pathRange(), buf->pathIndexBuffer() + fIndicesLocation, fCount, |
| 491 fDstCopy.texture() ? &fDstCopy : NULL); | 555 buf->pathTransformBuffer() + fTransformsLocation, fTransforms Type, |
| 556 fScissorState, fStencilSettings, fDstCopy.texture() ? &fDstCo py : NULL); | |
| 492 } | 557 } |
| 493 | 558 |
| 494 void GrInOrderDrawBuffer::SetState::execute(GrGpu* gpu) { | 559 void GrInOrderDrawBuffer::SetState::execute(GrInOrderDrawBuffer* buf) { |
| 560 GrGpu* gpu = buf->dstGpu(); | |
| 495 gpu->setDrawState(&fState); | 561 gpu->setDrawState(&fState); |
| 496 } | 562 } |
| 497 | 563 |
| 498 void GrInOrderDrawBuffer::Clear::execute(GrGpu* gpu) { | 564 void GrInOrderDrawBuffer::Clear::execute(GrInOrderDrawBuffer* buf) { |
| 565 GrGpu* gpu = buf->dstGpu(); | |
| 499 if (GrColor_ILLEGAL == fColor) { | 566 if (GrColor_ILLEGAL == fColor) { |
| 500 gpu->discard(this->renderTarget()); | 567 gpu->discard(this->renderTarget()); |
| 501 } else { | 568 } else { |
| 502 gpu->clear(&fRect, fColor, fCanIgnoreRect, this->renderTarget()); | 569 gpu->clear(&fRect, fColor, fCanIgnoreRect, this->renderTarget()); |
| 503 } | 570 } |
| 504 } | 571 } |
| 505 | 572 |
| 506 void GrInOrderDrawBuffer::ClearStencilClip::execute(GrGpu* gpu) { | 573 void GrInOrderDrawBuffer::ClearStencilClip::execute(GrInOrderDrawBuffer* buf) { |
| 507 gpu->clearStencilClip(fRect, fInsideClip, this->renderTarget()); | 574 GrGpu* gpu = buf->dstGpu(); |
| 575 gpu->clearStencilClip(fRect, fInsideClip, this->renderTarget()); | |
| 508 } | 576 } |
| 509 | 577 |
| 510 void GrInOrderDrawBuffer::CopySurface::execute(GrGpu* gpu) { | 578 void GrInOrderDrawBuffer::CopySurface::execute(GrInOrderDrawBuffer* buf) { |
| 579 GrGpu* gpu = buf->dstGpu(); | |
| 511 gpu->copySurface(this->dst(), this->src(), fSrcRect, fDstPoint); | 580 gpu->copySurface(this->dst(), this->src(), fSrcRect, fDstPoint); |
| 512 } | 581 } |
| 513 | 582 |
| 514 bool GrInOrderDrawBuffer::copySurface(GrSurface* dst, | 583 bool GrInOrderDrawBuffer::copySurface(GrSurface* dst, |
| 515 GrSurface* src, | 584 GrSurface* src, |
| 516 const SkIRect& srcRect, | 585 const SkIRect& srcRect, |
| 517 const SkIPoint& dstPoint) { | 586 const SkIPoint& dstPoint) { |
| 518 if (fDstGpu->canCopySurface(dst, src, srcRect, dstPoint)) { | 587 if (fDstGpu->canCopySurface(dst, src, srcRect, dstPoint)) { |
| 519 CopySurface* cs = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, CopySurface, (dst , src)); | 588 CopySurface* cs = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, CopySurface, (dst , src)); |
| 520 cs->fSrcRect = srcRect; | 589 cs->fSrcRect = srcRect; |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 724 | 793 |
| 725 void GrInOrderDrawBuffer::recordTraceMarkersIfNecessary() { | 794 void GrInOrderDrawBuffer::recordTraceMarkersIfNecessary() { |
| 726 SkASSERT(!fCmdBuffer.empty()); | 795 SkASSERT(!fCmdBuffer.empty()); |
| 727 SkASSERT(!cmd_has_trace_marker(fCmdBuffer.back().fType)); | 796 SkASSERT(!cmd_has_trace_marker(fCmdBuffer.back().fType)); |
| 728 const GrTraceMarkerSet& activeTraceMarkers = this->getActiveTraceMarkers(); | 797 const GrTraceMarkerSet& activeTraceMarkers = this->getActiveTraceMarkers(); |
| 729 if (activeTraceMarkers.count() > 0) { | 798 if (activeTraceMarkers.count() > 0) { |
| 730 fCmdBuffer.back().fType = add_trace_bit(fCmdBuffer.back().fType); | 799 fCmdBuffer.back().fType = add_trace_bit(fCmdBuffer.back().fType); |
| 731 fGpuCmdMarkers.push_back(activeTraceMarkers); | 800 fGpuCmdMarkers.push_back(activeTraceMarkers); |
| 732 } | 801 } |
| 733 } | 802 } |
| OLD | NEW |