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 |