| 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(GrPipelineBuilder* pipelineBuilder, | 387 bool GrDrawTarget::setupDstReadIfNecessary(const GrPipelineBuilder& pipelineBuil
der, |
| 388 GrDeviceCoordTexture* dstCopy, | 388 GrDeviceCoordTexture* dstCopy, |
| 389 const SkRect* drawBounds) { | 389 const SkRect* drawBounds) { |
| 390 if (this->caps()->dstReadInShaderSupport() || !pipelineBuilder->willEffectRe
adDstColor()) { | 390 if (!pipelineBuilder.willXPNeedDstCopy(*this->caps())) { |
| 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; |
| 419 | 422 |
| 420 SkAutoTUnref<GrTexture> copy( | 423 SkAutoTUnref<GrTexture> copy( |
| 421 fContext->refScratchTexture(desc, GrContext::kApprox_ScratchTexMatch)); | 424 fContext->refScratchTexture(desc, GrContext::kApprox_ScratchTexMatch)); |
| 422 | 425 |
| 423 if (!copy) { | 426 if (!copy) { |
| 424 SkDebugf("Failed to create temporary copy of destination texture.\n"); | 427 SkDebugf("Failed to create temporary copy of destination texture.\n"); |
| 425 return false; | 428 return false; |
| 426 } | 429 } |
| 427 SkIPoint dstPoint = {0, 0}; | 430 SkIPoint dstPoint = {0, 0}; |
| 428 if (this->copySurface(copy, rt, copyRect, dstPoint)) { | 431 if (this->copySurface(copy, rt, copyRect, dstPoint)) { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 463 info.fIndexCount = indexCount; | 466 info.fIndexCount = indexCount; |
| 464 | 467 |
| 465 info.fInstanceCount = 0; | 468 info.fInstanceCount = 0; |
| 466 info.fVerticesPerInstance = 0; | 469 info.fVerticesPerInstance = 0; |
| 467 info.fIndicesPerInstance = 0; | 470 info.fIndicesPerInstance = 0; |
| 468 | 471 |
| 469 if (devBounds) { | 472 if (devBounds) { |
| 470 info.setDevBounds(*devBounds); | 473 info.setDevBounds(*devBounds); |
| 471 } | 474 } |
| 472 | 475 |
| 473 // TODO: We should continue with incorrect blending. | |
| 474 GrDeviceCoordTexture dstCopy; | |
| 475 if (!this->setupDstReadIfNecessary(pipelineBuilder, &dstCopy, devBounds)
) { | |
| 476 return; | |
| 477 } | |
| 478 this->setDrawBuffers(&info, gp->getVertexStride()); | 476 this->setDrawBuffers(&info, gp->getVertexStride()); |
| 479 | 477 |
| 480 this->onDraw(*pipelineBuilder, gp, info, scissorState, dstCopy.texture()
? &dstCopy : NULL); | 478 this->onDraw(*pipelineBuilder, gp, info, scissorState); |
| 481 } | 479 } |
| 482 } | 480 } |
| 483 | 481 |
| 484 void GrDrawTarget::drawNonIndexed(GrPipelineBuilder* pipelineBuilder, | 482 void GrDrawTarget::drawNonIndexed(GrPipelineBuilder* pipelineBuilder, |
| 485 const GrGeometryProcessor* gp, | 483 const GrGeometryProcessor* gp, |
| 486 GrPrimitiveType type, | 484 GrPrimitiveType type, |
| 487 int startVertex, | 485 int startVertex, |
| 488 int vertexCount, | 486 int vertexCount, |
| 489 const SkRect* devBounds) { | 487 const SkRect* devBounds) { |
| 490 SkASSERT(pipelineBuilder); | 488 SkASSERT(pipelineBuilder); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 507 info.fIndexCount = 0; | 505 info.fIndexCount = 0; |
| 508 | 506 |
| 509 info.fInstanceCount = 0; | 507 info.fInstanceCount = 0; |
| 510 info.fVerticesPerInstance = 0; | 508 info.fVerticesPerInstance = 0; |
| 511 info.fIndicesPerInstance = 0; | 509 info.fIndicesPerInstance = 0; |
| 512 | 510 |
| 513 if (devBounds) { | 511 if (devBounds) { |
| 514 info.setDevBounds(*devBounds); | 512 info.setDevBounds(*devBounds); |
| 515 } | 513 } |
| 516 | 514 |
| 517 // TODO: We should continue with incorrect blending. | |
| 518 GrDeviceCoordTexture dstCopy; | |
| 519 if (!this->setupDstReadIfNecessary(pipelineBuilder, &dstCopy, devBounds)
) { | |
| 520 return; | |
| 521 } | |
| 522 | |
| 523 this->setDrawBuffers(&info, gp->getVertexStride()); | 515 this->setDrawBuffers(&info, gp->getVertexStride()); |
| 524 | 516 |
| 525 this->onDraw(*pipelineBuilder, gp, info, scissorState, dstCopy.texture()
? &dstCopy : NULL); | 517 this->onDraw(*pipelineBuilder, gp, info, scissorState); |
| 526 } | 518 } |
| 527 } | 519 } |
| 528 | 520 |
| 529 | 521 |
| 530 void GrDrawTarget::drawBatch(GrPipelineBuilder* pipelineBuilder, | 522 void GrDrawTarget::drawBatch(GrPipelineBuilder* pipelineBuilder, |
| 531 GrBatch* batch, | 523 GrBatch* batch, |
| 532 const SkRect* devBounds) { | 524 const SkRect* devBounds) { |
| 533 SkASSERT(pipelineBuilder); | 525 SkASSERT(pipelineBuilder); |
| 534 // TODO some kind of checkdraw, but not at this level | 526 // TODO some kind of checkdraw, but not at this level |
| 535 | 527 |
| 536 // Setup clip | 528 // Setup clip |
| 537 GrScissorState scissorState; | 529 GrScissorState scissorState; |
| 538 GrPipelineBuilder::AutoRestoreEffects are; | 530 GrPipelineBuilder::AutoRestoreEffects are; |
| 539 GrPipelineBuilder::AutoRestoreStencil ars; | 531 GrPipelineBuilder::AutoRestoreStencil ars; |
| 540 if (!this->setupClip(pipelineBuilder, &are, &ars, &scissorState, devBounds))
{ | 532 if (!this->setupClip(pipelineBuilder, &are, &ars, &scissorState, devBounds))
{ |
| 541 return; | 533 return; |
| 542 } | 534 } |
| 543 | 535 |
| 544 GrDeviceCoordTexture dstCopy; | 536 this->onDrawBatch(batch, *pipelineBuilder, scissorState, devBounds); |
| 545 if (!this->setupDstReadIfNecessary(pipelineBuilder, &dstCopy, devBounds)) { | |
| 546 return; | |
| 547 } | |
| 548 | |
| 549 this->onDrawBatch(batch, *pipelineBuilder, scissorState, dstCopy.texture() ?
&dstCopy : NULL); | |
| 550 } | 537 } |
| 551 | 538 |
| 552 static const GrStencilSettings& winding_path_stencil_settings() { | 539 static const GrStencilSettings& winding_path_stencil_settings() { |
| 553 GR_STATIC_CONST_SAME_STENCIL_STRUCT(gSettings, | 540 GR_STATIC_CONST_SAME_STENCIL_STRUCT(gSettings, |
| 554 kIncClamp_StencilOp, | 541 kIncClamp_StencilOp, |
| 555 kIncClamp_StencilOp, | 542 kIncClamp_StencilOp, |
| 556 kAlwaysIfInClip_StencilFunc, | 543 kAlwaysIfInClip_StencilFunc, |
| 557 0xFFFF, 0xFFFF, 0xFFFF); | 544 0xFFFF, 0xFFFF, 0xFFFF); |
| 558 return *GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(&gSettings); | 545 return *GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(&gSettings); |
| 559 } | 546 } |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 629 if (!this->setupClip(pipelineBuilder, &are, &ars, &scissorState, &devBounds)
) { | 616 if (!this->setupClip(pipelineBuilder, &are, &ars, &scissorState, &devBounds)
) { |
| 630 return; | 617 return; |
| 631 } | 618 } |
| 632 | 619 |
| 633 // set stencil settings for path | 620 // set stencil settings for path |
| 634 GrStencilSettings stencilSettings; | 621 GrStencilSettings stencilSettings; |
| 635 this->getPathStencilSettingsForFilltype(fill, | 622 this->getPathStencilSettingsForFilltype(fill, |
| 636 pipelineBuilder->getRenderTarget()->
getStencilBuffer(), | 623 pipelineBuilder->getRenderTarget()->
getStencilBuffer(), |
| 637 &stencilSettings); | 624 &stencilSettings); |
| 638 | 625 |
| 639 GrDeviceCoordTexture dstCopy; | |
| 640 if (!this->setupDstReadIfNecessary(pipelineBuilder, &dstCopy, &devBounds)) { | |
| 641 return; | |
| 642 } | |
| 643 | |
| 644 this->onDrawPath(*pipelineBuilder, pathProc, path, scissorState, stencilSett
ings, | 626 this->onDrawPath(*pipelineBuilder, pathProc, path, scissorState, stencilSett
ings, |
| 645 dstCopy.texture() ? &dstCopy : NULL); | 627 &devBounds); |
| 646 } | 628 } |
| 647 | 629 |
| 648 void GrDrawTarget::drawPaths(GrPipelineBuilder* pipelineBuilder, | 630 void GrDrawTarget::drawPaths(GrPipelineBuilder* pipelineBuilder, |
| 649 const GrPathProcessor* pathProc, | 631 const GrPathProcessor* pathProc, |
| 650 const GrPathRange* pathRange, | 632 const GrPathRange* pathRange, |
| 651 const void* indices, | 633 const void* indices, |
| 652 PathIndexType indexType, | 634 PathIndexType indexType, |
| 653 const float transformValues[], | 635 const float transformValues[], |
| 654 PathTransformType transformType, | 636 PathTransformType transformType, |
| 655 int count, | 637 int count, |
| (...skipping 13 matching lines...) Expand all Loading... |
| 669 if (!this->setupClip(pipelineBuilder, &are, &ars, &scissorState, NULL)) { | 651 if (!this->setupClip(pipelineBuilder, &are, &ars, &scissorState, NULL)) { |
| 670 return; | 652 return; |
| 671 } | 653 } |
| 672 | 654 |
| 673 // set stencil settings for path | 655 // set stencil settings for path |
| 674 GrStencilSettings stencilSettings; | 656 GrStencilSettings stencilSettings; |
| 675 this->getPathStencilSettingsForFilltype(fill, | 657 this->getPathStencilSettingsForFilltype(fill, |
| 676 pipelineBuilder->getRenderTarget()->
getStencilBuffer(), | 658 pipelineBuilder->getRenderTarget()->
getStencilBuffer(), |
| 677 &stencilSettings); | 659 &stencilSettings); |
| 678 | 660 |
| 679 // Don't compute a bounding box for setupDstReadIfNecessary(), we'll opt | 661 // Don't compute a bounding box for dst copy texture, we'll opt |
| 680 // instead for it to just copy the entire dst. Realistically this is a moot | 662 // instead for it to just copy the entire dst. Realistically this is a moot |
| 681 // point, because any context that supports NV_path_rendering will also | 663 // point, because any context that supports NV_path_rendering will also |
| 682 // support NV_blend_equation_advanced. | 664 // support NV_blend_equation_advanced. |
| 683 GrDeviceCoordTexture dstCopy; | |
| 684 if (!this->setupDstReadIfNecessary(pipelineBuilder, &dstCopy, NULL)) { | |
| 685 return; | |
| 686 } | |
| 687 | |
| 688 this->onDrawPaths(*pipelineBuilder, pathProc, pathRange, indices, indexType,
transformValues, | 665 this->onDrawPaths(*pipelineBuilder, pathProc, pathRange, indices, indexType,
transformValues, |
| 689 transformType, count, scissorState, stencilSettings, | 666 transformType, count, scissorState, stencilSettings, NULL)
; |
| 690 dstCopy.texture() ? &dstCopy : NULL); | |
| 691 } | 667 } |
| 692 | 668 |
| 693 void GrDrawTarget::clear(const SkIRect* rect, | 669 void GrDrawTarget::clear(const SkIRect* rect, |
| 694 GrColor color, | 670 GrColor color, |
| 695 bool canIgnoreRect, | 671 bool canIgnoreRect, |
| 696 GrRenderTarget* renderTarget) { | 672 GrRenderTarget* renderTarget) { |
| 697 if (fCaps->useDrawInsteadOfClear()) { | 673 if (fCaps->useDrawInsteadOfClear()) { |
| 698 // This works around a driver bug with clear by drawing a rect instead. | 674 // This works around a driver bug with clear by drawing a rect instead. |
| 699 // The driver will ignore a clear if it is the only thing rendered to a | 675 // The driver will ignore a clear if it is the only thing rendered to a |
| 700 // target before the target is read. | 676 // target before the target is read. |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 786 info.fStartIndex = 0; | 762 info.fStartIndex = 0; |
| 787 info.fStartVertex = 0; | 763 info.fStartVertex = 0; |
| 788 info.fIndicesPerInstance = indicesPerInstance; | 764 info.fIndicesPerInstance = indicesPerInstance; |
| 789 info.fVerticesPerInstance = verticesPerInstance; | 765 info.fVerticesPerInstance = verticesPerInstance; |
| 790 | 766 |
| 791 // Set the same bounds for all the draws. | 767 // Set the same bounds for all the draws. |
| 792 if (devBounds) { | 768 if (devBounds) { |
| 793 info.setDevBounds(*devBounds); | 769 info.setDevBounds(*devBounds); |
| 794 } | 770 } |
| 795 | 771 |
| 796 // TODO: We should continue with incorrect blending. | |
| 797 GrDeviceCoordTexture dstCopy; | |
| 798 if (!this->setupDstReadIfNecessary(pipelineBuilder, &dstCopy, devBounds)) { | |
| 799 return; | |
| 800 } | |
| 801 | |
| 802 while (instanceCount) { | 772 while (instanceCount) { |
| 803 info.fInstanceCount = SkTMin(instanceCount, maxInstancesPerDraw); | 773 info.fInstanceCount = SkTMin(instanceCount, maxInstancesPerDraw); |
| 804 info.fVertexCount = info.fInstanceCount * verticesPerInstance; | 774 info.fVertexCount = info.fInstanceCount * verticesPerInstance; |
| 805 info.fIndexCount = info.fInstanceCount * indicesPerInstance; | 775 info.fIndexCount = info.fInstanceCount * indicesPerInstance; |
| 806 | 776 |
| 807 if (this->checkDraw(*pipelineBuilder, | 777 if (this->checkDraw(*pipelineBuilder, |
| 808 gp, | 778 gp, |
| 809 type, | 779 type, |
| 810 info.fStartVertex, | 780 info.fStartVertex, |
| 811 info.fStartIndex, | 781 info.fStartIndex, |
| 812 info.fVertexCount, | 782 info.fVertexCount, |
| 813 info.fIndexCount)) { | 783 info.fIndexCount)) { |
| 814 this->setDrawBuffers(&info, gp->getVertexStride()); | 784 this->setDrawBuffers(&info, gp->getVertexStride()); |
| 815 this->onDraw(*pipelineBuilder, gp, info, scissorState, | 785 this->onDraw(*pipelineBuilder, gp, info, scissorState); |
| 816 dstCopy.texture() ? &dstCopy : NULL); | |
| 817 } | 786 } |
| 818 info.fStartVertex += info.fVertexCount; | 787 info.fStartVertex += info.fVertexCount; |
| 819 instanceCount -= info.fInstanceCount; | 788 instanceCount -= info.fInstanceCount; |
| 820 } | 789 } |
| 821 } | 790 } |
| 822 | 791 |
| 823 //////////////////////////////////////////////////////////////////////////////// | 792 //////////////////////////////////////////////////////////////////////////////// |
| 824 | 793 |
| 825 GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry( | 794 GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry( |
| 826 GrDrawTarget* target, | 795 GrDrawTarget* target, |
| (...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1244 GrPipelineBuilder::AutoRestoreStencil* ars, | 1213 GrPipelineBuilder::AutoRestoreStencil* ars, |
| 1245 GrScissorState* scissorState, | 1214 GrScissorState* scissorState, |
| 1246 const SkRect* devBounds) { | 1215 const SkRect* devBounds) { |
| 1247 return fClipMaskManager.setupClipping(pipelineBuilder, | 1216 return fClipMaskManager.setupClipping(pipelineBuilder, |
| 1248 are, | 1217 are, |
| 1249 ars, | 1218 ars, |
| 1250 scissorState, | 1219 scissorState, |
| 1251 this->getClip(), | 1220 this->getClip(), |
| 1252 devBounds); | 1221 devBounds); |
| 1253 } | 1222 } |
| OLD | NEW |