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