OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2010 Google Inc. | 3 * Copyright 2010 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 #include "GrDrawTarget.h" | 9 #include "GrDrawTarget.h" |
10 | 10 |
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
377 } | 377 } |
378 } | 378 } |
379 | 379 |
380 #endif | 380 #endif |
381 if (NULL == pipelineBuilder.getRenderTarget()) { | 381 if (NULL == pipelineBuilder.getRenderTarget()) { |
382 return false; | 382 return false; |
383 } | 383 } |
384 return true; | 384 return true; |
385 } | 385 } |
386 | 386 |
387 bool GrDrawTarget::setupDstReadIfNecessary(const GrPipelineBuilder& pipelineBuil
der, | 387 bool GrDrawTarget::setupDstReadIfNecessary(GrPipelineBuilder* pipelineBuilder, |
388 GrDeviceCoordTexture* dstCopy, | 388 GrDeviceCoordTexture* dstCopy, |
389 const SkRect* drawBounds) { | 389 const SkRect* drawBounds) { |
390 if (!pipelineBuilder.willXPNeedDstCopy(*this->caps())) { | 390 if (this->caps()->dstReadInShaderSupport() || !pipelineBuilder->willEffectRe
adDstColor()) { |
391 return true; | 391 return true; |
392 } | 392 } |
393 SkIRect copyRect; | 393 SkIRect copyRect; |
394 const GrClipData* clip = this->getClip(); | 394 const GrClipData* clip = this->getClip(); |
395 GrRenderTarget* rt = pipelineBuilder.getRenderTarget(); | 395 GrRenderTarget* rt = pipelineBuilder->getRenderTarget(); |
396 clip->getConservativeBounds(rt, ©Rect); | 396 clip->getConservativeBounds(rt, ©Rect); |
397 | 397 |
398 if (drawBounds) { | 398 if (drawBounds) { |
399 SkIRect drawIBounds; | 399 SkIRect drawIBounds; |
400 drawBounds->roundOut(&drawIBounds); | 400 drawBounds->roundOut(&drawIBounds); |
401 if (!copyRect.intersect(drawIBounds)) { | 401 if (!copyRect.intersect(drawIBounds)) { |
402 #ifdef SK_DEBUG | 402 #ifdef SK_DEBUG |
403 SkDebugf("Missed an early reject. Bailing on draw from setupDstReadI
fNecessary.\n"); | 403 SkDebugf("Missed an early reject. Bailing on draw from setupDstReadI
fNecessary.\n"); |
404 #endif | 404 #endif |
405 return false; | 405 return false; |
406 } | 406 } |
407 } else { | 407 } else { |
408 #ifdef SK_DEBUG | 408 #ifdef SK_DEBUG |
409 //SkDebugf("No dev bounds when dst copy is made.\n"); | 409 //SkDebugf("No dev bounds when dst copy is made.\n"); |
410 #endif | 410 #endif |
411 } | 411 } |
412 | 412 |
413 // MSAA consideration: When there is support for reading MSAA samples in the
shader we could | 413 // MSAA consideration: When there is support for reading MSAA samples in the
shader we could |
414 // have per-sample dst values by making the copy multisampled. | 414 // have per-sample dst values by making the copy multisampled. |
415 GrSurfaceDesc desc; | 415 GrSurfaceDesc desc; |
416 this->initCopySurfaceDstDesc(rt, &desc); | 416 this->initCopySurfaceDstDesc(rt, &desc); |
417 desc.fWidth = copyRect.width(); | 417 desc.fWidth = copyRect.width(); |
418 desc.fHeight = copyRect.height(); | 418 desc.fHeight = copyRect.height(); |
419 // Only xfer processors can use dst copies, and the contract with the XP is
that we always | |
420 // supply a copy texture with origin in the top left. | |
421 desc.fOrigin = kTopLeft_GrSurfaceOrigin; | |
422 | 419 |
423 SkAutoTUnref<GrTexture> copy( | 420 SkAutoTUnref<GrTexture> copy( |
424 fContext->refScratchTexture(desc, GrContext::kApprox_ScratchTexMatch)); | 421 fContext->refScratchTexture(desc, GrContext::kApprox_ScratchTexMatch)); |
425 | 422 |
426 if (!copy) { | 423 if (!copy) { |
427 SkDebugf("Failed to create temporary copy of destination texture.\n"); | 424 SkDebugf("Failed to create temporary copy of destination texture.\n"); |
428 return false; | 425 return false; |
429 } | 426 } |
430 SkIPoint dstPoint = {0, 0}; | 427 SkIPoint dstPoint = {0, 0}; |
431 if (this->copySurface(copy, rt, copyRect, dstPoint)) { | 428 if (this->copySurface(copy, rt, copyRect, dstPoint)) { |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
466 info.fIndexCount = indexCount; | 463 info.fIndexCount = indexCount; |
467 | 464 |
468 info.fInstanceCount = 0; | 465 info.fInstanceCount = 0; |
469 info.fVerticesPerInstance = 0; | 466 info.fVerticesPerInstance = 0; |
470 info.fIndicesPerInstance = 0; | 467 info.fIndicesPerInstance = 0; |
471 | 468 |
472 if (devBounds) { | 469 if (devBounds) { |
473 info.setDevBounds(*devBounds); | 470 info.setDevBounds(*devBounds); |
474 } | 471 } |
475 | 472 |
| 473 // TODO: We should continue with incorrect blending. |
| 474 GrDeviceCoordTexture dstCopy; |
| 475 if (!this->setupDstReadIfNecessary(pipelineBuilder, &dstCopy, devBounds)
) { |
| 476 return; |
| 477 } |
476 this->setDrawBuffers(&info, gp->getVertexStride()); | 478 this->setDrawBuffers(&info, gp->getVertexStride()); |
477 | 479 |
478 this->onDraw(*pipelineBuilder, gp, info, scissorState); | 480 this->onDraw(*pipelineBuilder, gp, info, scissorState, dstCopy.texture()
? &dstCopy : NULL); |
479 } | 481 } |
480 } | 482 } |
481 | 483 |
482 void GrDrawTarget::drawNonIndexed(GrPipelineBuilder* pipelineBuilder, | 484 void GrDrawTarget::drawNonIndexed(GrPipelineBuilder* pipelineBuilder, |
483 const GrGeometryProcessor* gp, | 485 const GrGeometryProcessor* gp, |
484 GrPrimitiveType type, | 486 GrPrimitiveType type, |
485 int startVertex, | 487 int startVertex, |
486 int vertexCount, | 488 int vertexCount, |
487 const SkRect* devBounds) { | 489 const SkRect* devBounds) { |
488 SkASSERT(pipelineBuilder); | 490 SkASSERT(pipelineBuilder); |
(...skipping 16 matching lines...) Expand all Loading... |
505 info.fIndexCount = 0; | 507 info.fIndexCount = 0; |
506 | 508 |
507 info.fInstanceCount = 0; | 509 info.fInstanceCount = 0; |
508 info.fVerticesPerInstance = 0; | 510 info.fVerticesPerInstance = 0; |
509 info.fIndicesPerInstance = 0; | 511 info.fIndicesPerInstance = 0; |
510 | 512 |
511 if (devBounds) { | 513 if (devBounds) { |
512 info.setDevBounds(*devBounds); | 514 info.setDevBounds(*devBounds); |
513 } | 515 } |
514 | 516 |
| 517 // TODO: We should continue with incorrect blending. |
| 518 GrDeviceCoordTexture dstCopy; |
| 519 if (!this->setupDstReadIfNecessary(pipelineBuilder, &dstCopy, devBounds)
) { |
| 520 return; |
| 521 } |
| 522 |
515 this->setDrawBuffers(&info, gp->getVertexStride()); | 523 this->setDrawBuffers(&info, gp->getVertexStride()); |
516 | 524 |
517 this->onDraw(*pipelineBuilder, gp, info, scissorState); | 525 this->onDraw(*pipelineBuilder, gp, info, scissorState, dstCopy.texture()
? &dstCopy : NULL); |
518 } | 526 } |
519 } | 527 } |
520 | 528 |
521 | 529 |
522 void GrDrawTarget::drawBatch(GrPipelineBuilder* pipelineBuilder, | 530 void GrDrawTarget::drawBatch(GrPipelineBuilder* pipelineBuilder, |
523 GrBatch* batch, | 531 GrBatch* batch, |
524 const SkRect* devBounds) { | 532 const SkRect* devBounds) { |
525 SkASSERT(pipelineBuilder); | 533 SkASSERT(pipelineBuilder); |
526 // TODO some kind of checkdraw, but not at this level | 534 // TODO some kind of checkdraw, but not at this level |
527 | 535 |
528 // Setup clip | 536 // Setup clip |
529 GrScissorState scissorState; | 537 GrScissorState scissorState; |
530 GrPipelineBuilder::AutoRestoreEffects are; | 538 GrPipelineBuilder::AutoRestoreEffects are; |
531 GrPipelineBuilder::AutoRestoreStencil ars; | 539 GrPipelineBuilder::AutoRestoreStencil ars; |
532 if (!this->setupClip(pipelineBuilder, &are, &ars, &scissorState, devBounds))
{ | 540 if (!this->setupClip(pipelineBuilder, &are, &ars, &scissorState, devBounds))
{ |
533 return; | 541 return; |
534 } | 542 } |
535 | 543 |
536 this->onDrawBatch(batch, *pipelineBuilder, scissorState, devBounds); | 544 GrDeviceCoordTexture dstCopy; |
| 545 if (!this->setupDstReadIfNecessary(pipelineBuilder, &dstCopy, devBounds)) { |
| 546 return; |
| 547 } |
| 548 |
| 549 this->onDrawBatch(batch, *pipelineBuilder, scissorState, dstCopy.texture() ?
&dstCopy : NULL); |
537 } | 550 } |
538 | 551 |
539 static const GrStencilSettings& winding_path_stencil_settings() { | 552 static const GrStencilSettings& winding_path_stencil_settings() { |
540 GR_STATIC_CONST_SAME_STENCIL_STRUCT(gSettings, | 553 GR_STATIC_CONST_SAME_STENCIL_STRUCT(gSettings, |
541 kIncClamp_StencilOp, | 554 kIncClamp_StencilOp, |
542 kIncClamp_StencilOp, | 555 kIncClamp_StencilOp, |
543 kAlwaysIfInClip_StencilFunc, | 556 kAlwaysIfInClip_StencilFunc, |
544 0xFFFF, 0xFFFF, 0xFFFF); | 557 0xFFFF, 0xFFFF, 0xFFFF); |
545 return *GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(&gSettings); | 558 return *GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(&gSettings); |
546 } | 559 } |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
616 if (!this->setupClip(pipelineBuilder, &are, &ars, &scissorState, &devBounds)
) { | 629 if (!this->setupClip(pipelineBuilder, &are, &ars, &scissorState, &devBounds)
) { |
617 return; | 630 return; |
618 } | 631 } |
619 | 632 |
620 // set stencil settings for path | 633 // set stencil settings for path |
621 GrStencilSettings stencilSettings; | 634 GrStencilSettings stencilSettings; |
622 this->getPathStencilSettingsForFilltype(fill, | 635 this->getPathStencilSettingsForFilltype(fill, |
623 pipelineBuilder->getRenderTarget()->
getStencilBuffer(), | 636 pipelineBuilder->getRenderTarget()->
getStencilBuffer(), |
624 &stencilSettings); | 637 &stencilSettings); |
625 | 638 |
| 639 GrDeviceCoordTexture dstCopy; |
| 640 if (!this->setupDstReadIfNecessary(pipelineBuilder, &dstCopy, &devBounds)) { |
| 641 return; |
| 642 } |
| 643 |
626 this->onDrawPath(*pipelineBuilder, pathProc, path, scissorState, stencilSett
ings, | 644 this->onDrawPath(*pipelineBuilder, pathProc, path, scissorState, stencilSett
ings, |
627 &devBounds); | 645 dstCopy.texture() ? &dstCopy : NULL); |
628 } | 646 } |
629 | 647 |
630 void GrDrawTarget::drawPaths(GrPipelineBuilder* pipelineBuilder, | 648 void GrDrawTarget::drawPaths(GrPipelineBuilder* pipelineBuilder, |
631 const GrPathProcessor* pathProc, | 649 const GrPathProcessor* pathProc, |
632 const GrPathRange* pathRange, | 650 const GrPathRange* pathRange, |
633 const void* indices, | 651 const void* indices, |
634 PathIndexType indexType, | 652 PathIndexType indexType, |
635 const float transformValues[], | 653 const float transformValues[], |
636 PathTransformType transformType, | 654 PathTransformType transformType, |
637 int count, | 655 int count, |
(...skipping 13 matching lines...) Expand all Loading... |
651 if (!this->setupClip(pipelineBuilder, &are, &ars, &scissorState, NULL)) { | 669 if (!this->setupClip(pipelineBuilder, &are, &ars, &scissorState, NULL)) { |
652 return; | 670 return; |
653 } | 671 } |
654 | 672 |
655 // set stencil settings for path | 673 // set stencil settings for path |
656 GrStencilSettings stencilSettings; | 674 GrStencilSettings stencilSettings; |
657 this->getPathStencilSettingsForFilltype(fill, | 675 this->getPathStencilSettingsForFilltype(fill, |
658 pipelineBuilder->getRenderTarget()->
getStencilBuffer(), | 676 pipelineBuilder->getRenderTarget()->
getStencilBuffer(), |
659 &stencilSettings); | 677 &stencilSettings); |
660 | 678 |
661 // Don't compute a bounding box for dst copy texture, we'll opt | 679 // Don't compute a bounding box for setupDstReadIfNecessary(), we'll opt |
662 // instead for it to just copy the entire dst. Realistically this is a moot | 680 // instead for it to just copy the entire dst. Realistically this is a moot |
663 // point, because any context that supports NV_path_rendering will also | 681 // point, because any context that supports NV_path_rendering will also |
664 // support NV_blend_equation_advanced. | 682 // support NV_blend_equation_advanced. |
| 683 GrDeviceCoordTexture dstCopy; |
| 684 if (!this->setupDstReadIfNecessary(pipelineBuilder, &dstCopy, NULL)) { |
| 685 return; |
| 686 } |
| 687 |
665 this->onDrawPaths(*pipelineBuilder, pathProc, pathRange, indices, indexType,
transformValues, | 688 this->onDrawPaths(*pipelineBuilder, pathProc, pathRange, indices, indexType,
transformValues, |
666 transformType, count, scissorState, stencilSettings, NULL)
; | 689 transformType, count, scissorState, stencilSettings, |
| 690 dstCopy.texture() ? &dstCopy : NULL); |
667 } | 691 } |
668 | 692 |
669 void GrDrawTarget::clear(const SkIRect* rect, | 693 void GrDrawTarget::clear(const SkIRect* rect, |
670 GrColor color, | 694 GrColor color, |
671 bool canIgnoreRect, | 695 bool canIgnoreRect, |
672 GrRenderTarget* renderTarget) { | 696 GrRenderTarget* renderTarget) { |
673 if (fCaps->useDrawInsteadOfClear()) { | 697 if (fCaps->useDrawInsteadOfClear()) { |
674 // This works around a driver bug with clear by drawing a rect instead. | 698 // This works around a driver bug with clear by drawing a rect instead. |
675 // The driver will ignore a clear if it is the only thing rendered to a | 699 // The driver will ignore a clear if it is the only thing rendered to a |
676 // target before the target is read. | 700 // target before the target is read. |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
762 info.fStartIndex = 0; | 786 info.fStartIndex = 0; |
763 info.fStartVertex = 0; | 787 info.fStartVertex = 0; |
764 info.fIndicesPerInstance = indicesPerInstance; | 788 info.fIndicesPerInstance = indicesPerInstance; |
765 info.fVerticesPerInstance = verticesPerInstance; | 789 info.fVerticesPerInstance = verticesPerInstance; |
766 | 790 |
767 // Set the same bounds for all the draws. | 791 // Set the same bounds for all the draws. |
768 if (devBounds) { | 792 if (devBounds) { |
769 info.setDevBounds(*devBounds); | 793 info.setDevBounds(*devBounds); |
770 } | 794 } |
771 | 795 |
| 796 // TODO: We should continue with incorrect blending. |
| 797 GrDeviceCoordTexture dstCopy; |
| 798 if (!this->setupDstReadIfNecessary(pipelineBuilder, &dstCopy, devBounds)) { |
| 799 return; |
| 800 } |
| 801 |
772 while (instanceCount) { | 802 while (instanceCount) { |
773 info.fInstanceCount = SkTMin(instanceCount, maxInstancesPerDraw); | 803 info.fInstanceCount = SkTMin(instanceCount, maxInstancesPerDraw); |
774 info.fVertexCount = info.fInstanceCount * verticesPerInstance; | 804 info.fVertexCount = info.fInstanceCount * verticesPerInstance; |
775 info.fIndexCount = info.fInstanceCount * indicesPerInstance; | 805 info.fIndexCount = info.fInstanceCount * indicesPerInstance; |
776 | 806 |
777 if (this->checkDraw(*pipelineBuilder, | 807 if (this->checkDraw(*pipelineBuilder, |
778 gp, | 808 gp, |
779 type, | 809 type, |
780 info.fStartVertex, | 810 info.fStartVertex, |
781 info.fStartIndex, | 811 info.fStartIndex, |
782 info.fVertexCount, | 812 info.fVertexCount, |
783 info.fIndexCount)) { | 813 info.fIndexCount)) { |
784 this->setDrawBuffers(&info, gp->getVertexStride()); | 814 this->setDrawBuffers(&info, gp->getVertexStride()); |
785 this->onDraw(*pipelineBuilder, gp, info, scissorState); | 815 this->onDraw(*pipelineBuilder, gp, info, scissorState, |
| 816 dstCopy.texture() ? &dstCopy : NULL); |
786 } | 817 } |
787 info.fStartVertex += info.fVertexCount; | 818 info.fStartVertex += info.fVertexCount; |
788 instanceCount -= info.fInstanceCount; | 819 instanceCount -= info.fInstanceCount; |
789 } | 820 } |
790 } | 821 } |
791 | 822 |
792 //////////////////////////////////////////////////////////////////////////////// | 823 //////////////////////////////////////////////////////////////////////////////// |
793 | 824 |
794 GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry( | 825 GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry( |
795 GrDrawTarget* target, | 826 GrDrawTarget* target, |
(...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1213 GrPipelineBuilder::AutoRestoreStencil* ars, | 1244 GrPipelineBuilder::AutoRestoreStencil* ars, |
1214 GrScissorState* scissorState, | 1245 GrScissorState* scissorState, |
1215 const SkRect* devBounds) { | 1246 const SkRect* devBounds) { |
1216 return fClipMaskManager.setupClipping(pipelineBuilder, | 1247 return fClipMaskManager.setupClipping(pipelineBuilder, |
1217 are, | 1248 are, |
1218 ars, | 1249 ars, |
1219 scissorState, | 1250 scissorState, |
1220 this->getClip(), | 1251 this->getClip(), |
1221 devBounds); | 1252 devBounds); |
1222 } | 1253 } |
OLD | NEW |