Chromium Code Reviews| 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 | 9 |
| 10 | 10 |
| (...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 405 } | 405 } |
| 406 return true; | 406 return true; |
| 407 } | 407 } |
| 408 | 408 |
| 409 bool GrDrawTarget::setupDstReadIfNecessary(DrawInfo* info) { | 409 bool GrDrawTarget::setupDstReadIfNecessary(DrawInfo* info) { |
| 410 if (!this->getDrawState().willEffectReadDst()) { | 410 if (!this->getDrawState().willEffectReadDst()) { |
| 411 return true; | 411 return true; |
| 412 } | 412 } |
| 413 GrRenderTarget* rt = this->drawState()->getRenderTarget(); | 413 GrRenderTarget* rt = this->drawState()->getRenderTarget(); |
| 414 // If the dst is not a texture then we don't currently have a way of copying the | 414 // If the dst is not a texture then we don't currently have a way of copying the |
| 415 // texture. TODO: make copying RT->Tex (or Surface->Surface) a GrDrawTarget operation that can | 415 // texture. TODO: API-specific impl of onCopySurface that can handle more ca ses. |
| 416 // be built on top of GL/D3D APIs. | |
| 417 if (NULL == rt->asTexture()) { | 416 if (NULL == rt->asTexture()) { |
| 418 GrPrintf("Reading Dst of non-texture render target is not currently supp orted.\n"); | 417 GrPrintf("Reading Dst of non-texture render target is not currently supp orted.\n"); |
| 419 return false; | 418 return false; |
| 420 } | 419 } |
| 421 | 420 |
| 422 const GrClipData* clip = this->getClip(); | 421 const GrClipData* clip = this->getClip(); |
| 423 GrIRect copyRect; | 422 GrIRect copyRect; |
| 424 clip->getConservativeBounds(this->getDrawState().getRenderTarget(), ©Rec t); | 423 clip->getConservativeBounds(this->getDrawState().getRenderTarget(), ©Rec t); |
| 425 SkIRect drawIBounds; | 424 SkIRect drawIBounds; |
| 426 if (info->getDevIBounds(&drawIBounds)) { | 425 if (info->getDevIBounds(&drawIBounds)) { |
| 427 if (!copyRect.intersect(drawIBounds)) { | 426 if (!copyRect.intersect(drawIBounds)) { |
| 428 #if GR_DEBUG | 427 #if GR_DEBUG |
| 429 GrPrintf("Missed an early reject. Bailing on draw from setupDstReadI fNecessary.\n"); | 428 GrPrintf("Missed an early reject. Bailing on draw from setupDstReadI fNecessary.\n"); |
| 430 #endif | 429 #endif |
| 431 return false; | 430 return false; |
| 432 } | 431 } |
| 433 } else { | 432 } else { |
| 434 #if GR_DEBUG | 433 #if GR_DEBUG |
| 435 //GrPrintf("No dev bounds when dst copy is made.\n"); | 434 //GrPrintf("No dev bounds when dst copy is made.\n"); |
| 436 #endif | 435 #endif |
| 437 } | 436 } |
| 438 | 437 |
| 439 GrDrawTarget::AutoGeometryAndStatePush agasp(this, kReset_ASRInit); | |
| 440 | |
| 441 // The draw will resolve dst if it has MSAA. Two things to consider in the f uture: | 438 // The draw will resolve dst if it has MSAA. Two things to consider in the f uture: |
| 442 // 1) to make the dst values be pre-resolve we'd need to be able to copy to MSAA | 439 // 1) to make the dst values be pre-resolve we'd need to be able to copy to MSAA |
| 443 // texture and sample it correctly in the shader. 2) If 1 isn't available th en we | 440 // texture and sample it correctly in the shader. 2) If 1 isn't available th en we |
| 444 // should just resolve and use the resolved texture directly rather than mak ing a | 441 // should just resolve and use the resolved texture directly rather than mak ing a |
| 445 // copy of it. | 442 // copy of it. |
| 446 GrTextureDesc desc; | 443 GrTextureDesc desc; |
| 447 desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit; | 444 desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit; |
| 448 desc.fWidth = copyRect.width(); | 445 desc.fWidth = copyRect.width(); |
| 449 desc.fHeight = copyRect.height(); | 446 desc.fHeight = copyRect.height(); |
| 450 desc.fSampleCnt = 0; | 447 desc.fSampleCnt = 0; |
| 451 desc.fConfig = rt->config(); | 448 desc.fConfig = rt->config(); |
| 452 | 449 |
| 453 GrAutoScratchTexture ast(fContext, desc, GrContext::kApprox_ScratchTexMatch) ; | 450 GrAutoScratchTexture ast(fContext, desc, GrContext::kApprox_ScratchTexMatch) ; |
| 454 | 451 |
| 455 if (NULL == ast.texture()) { | 452 if (NULL == ast.texture()) { |
| 456 GrPrintf("Failed to create temporary copy of destination texture.\n"); | 453 GrPrintf("Failed to create temporary copy of destination texture.\n"); |
| 457 return false; | 454 return false; |
| 458 } | 455 } |
| 459 this->drawState()->disableState(GrDrawState::kClip_StateBit); | 456 SkIPoint dstPoint = {0, 0}; |
| 460 this->drawState()->setRenderTarget(ast.texture()->asRenderTarget()); | 457 if (this->copySurface(ast.texture(), rt, copyRect, dstPoint)) { |
| 461 static const int kTextureStage = 0; | 458 info->fDstCopy.setTexture(ast.texture()); |
| 462 SkMatrix matrix; | 459 info->fDstCopy.setOffset(copyRect.fLeft, copyRect.fTop); |
| 463 matrix.setIDiv(rt->width(), rt->height()); | 460 return true; |
| 464 this->drawState()->createTextureEffect(kTextureStage, rt->asTexture(), matri x); | 461 } else { |
| 465 | 462 return false; |
| 466 SkRect srcRect = SkRect::MakeFromIRect(copyRect); | 463 } |
| 467 SkRect dstRect = SkRect::MakeWH(SkIntToScalar(copyRect.width()), | |
| 468 SkIntToScalar(copyRect.height())); | |
| 469 this->drawRect(dstRect, NULL, &srcRect, NULL); | |
| 470 | |
| 471 info->fDstCopy.setTexture(ast.texture()); | |
| 472 info->fDstCopy.setOffset(copyRect.fLeft, copyRect.fTop); | |
| 473 return true; | |
| 474 } | 464 } |
| 475 | 465 |
| 476 void GrDrawTarget::drawIndexed(GrPrimitiveType type, | 466 void GrDrawTarget::drawIndexed(GrPrimitiveType type, |
| 477 int startVertex, | 467 int startVertex, |
| 478 int startIndex, | 468 int startIndex, |
| 479 int vertexCount, | 469 int vertexCount, |
| 480 int indexCount, | 470 int indexCount, |
| 481 const SkRect* devBounds) { | 471 const SkRect* devBounds) { |
| 482 if (indexCount > 0 && this->checkDraw(type, startVertex, startIndex, vertexC ount, indexCount)) { | 472 if (indexCount > 0 && this->checkDraw(type, startVertex, startIndex, vertexC ount, indexCount)) { |
| 483 DrawInfo info; | 473 DrawInfo info; |
| (...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 754 | 744 |
| 755 GrDrawTarget::AutoClipRestore::AutoClipRestore(GrDrawTarget* target, const SkIRe ct& newClip) { | 745 GrDrawTarget::AutoClipRestore::AutoClipRestore(GrDrawTarget* target, const SkIRe ct& newClip) { |
| 756 fTarget = target; | 746 fTarget = target; |
| 757 fClip = fTarget->getClip(); | 747 fClip = fTarget->getClip(); |
| 758 fStack.init(); | 748 fStack.init(); |
| 759 fStack.get()->clipDevRect(newClip, SkRegion::kReplace_Op); | 749 fStack.get()->clipDevRect(newClip, SkRegion::kReplace_Op); |
| 760 fReplacementClip.fClipStack = fStack.get(); | 750 fReplacementClip.fClipStack = fStack.get(); |
| 761 target->setClip(&fReplacementClip); | 751 target->setClip(&fReplacementClip); |
| 762 } | 752 } |
| 763 | 753 |
| 754 bool GrDrawTarget::copySurface(GrSurface* dst, | |
| 755 GrSurface* src, | |
| 756 const SkIRect& srcRect, | |
| 757 const SkIPoint& dstPoint) { | |
| 758 SkIRect clippedSrcRect(srcRect); | |
| 759 SkIPoint clippedDstPoint(dstPoint); | |
| 760 | |
| 761 // clip the left edge to src and dst bounds, adjusting dstPoint if neceessar y | |
| 762 if (clippedSrcRect.fLeft < 0) { | |
| 763 clippedDstPoint.fX -= clippedSrcRect.fLeft; | |
| 764 clippedSrcRect.fLeft = 0; | |
| 765 } | |
| 766 if (clippedDstPoint.fX < 0) { | |
| 767 clippedSrcRect.fLeft -= clippedDstPoint.fX; | |
| 768 clippedDstPoint.fX = 0; | |
| 769 } | |
| 770 | |
| 771 // clip the top edge to src and dst bounds, adjusting dstPoint if neceessary | |
| 772 if (clippedSrcRect.fTop < 0) { | |
| 773 clippedDstPoint.fY -= clippedSrcRect.fTop; | |
| 774 clippedSrcRect.fTop = 0; | |
| 775 } | |
| 776 if (clippedDstPoint.fY < 0) { | |
| 777 clippedSrcRect.fTop -= clippedDstPoint.fY; | |
| 778 clippedDstPoint.fY = 0; | |
| 779 } | |
| 780 | |
| 781 // clip the right edge to the src and dst bounds. | |
| 782 if (clippedSrcRect.fRight > src->width()) { | |
| 783 clippedSrcRect.fRight = src->width(); | |
| 784 } | |
| 785 if (clippedDstPoint.fX + clippedSrcRect.width() > dst->width()) { | |
| 786 clippedSrcRect.fRight = clippedSrcRect.fLeft + dst->width() - clippedDst Point.fX; | |
| 787 } | |
| 788 | |
| 789 // clip the bottom edge to the src and dst bounds. | |
| 790 if (clippedSrcRect.fBottom > src->height()) { | |
| 791 clippedSrcRect.fBottom = src->height(); | |
| 792 } | |
| 793 if (clippedDstPoint.fY + clippedSrcRect.height() > dst->height()) { | |
| 794 clippedSrcRect.fBottom = clippedSrcRect.fTop + dst->height() - clippedDs tPoint.fY; | |
| 795 } | |
| 796 | |
| 797 // The above clipping steps may have inverted the rect if it didn't intersec t either the src or | |
| 798 // dst bounds. | |
| 799 if (clippedSrcRect.isEmpty()) { | |
| 800 return true; | |
| 801 } | |
| 802 | |
| 803 bool result = this->onCopySurface(dst, src, clippedSrcRect, clippedDstPoint) ; | |
| 804 GrAssert(result == this->canCopySurface(dst, src, clippedSrcRect, clippedDst Point)); | |
| 805 return result; | |
| 806 } | |
| 807 | |
| 808 bool GrDrawTarget::canCopySurface(GrSurface* dst, | |
| 809 GrSurface* src, | |
| 810 const SkIRect& srcRect, | |
| 811 const SkIPoint& dstPoint) { | |
|
robertphillips
2013/04/03 12:21:27
asserts here r.e. srcRect & dstPoint being clipped
bsalomon
2013/04/03 12:51:53
Will add.
| |
| 812 return NULL != dst->asRenderTarget() && NULL != src->asTexture(); | |
| 813 } | |
| 814 | |
| 815 bool GrDrawTarget::onCopySurface(GrSurface* dst, | |
| 816 GrSurface* src, | |
| 817 const SkIRect& srcRect, | |
| 818 const SkIPoint& dstPoint) { | |
| 819 if (!GrDrawTarget::canCopySurface(dst, src, srcRect, dstPoint)) { | |
| 820 return false; | |
| 821 } | |
| 822 | |
| 823 GrRenderTarget* rt = dst->asRenderTarget(); | |
| 824 GrTexture* tex = src->asTexture(); | |
| 825 | |
| 826 GrDrawTarget::AutoStateRestore asr(this, kReset_ASRInit); | |
| 827 this->drawState()->setRenderTarget(rt); | |
| 828 SkMatrix matrix; | |
| 829 matrix.setTranslate(SkIntToScalar(srcRect.fLeft - dstPoint.fX), | |
| 830 SkIntToScalar(srcRect.fTop - dstPoint.fY)); | |
| 831 matrix.postIDiv(tex->width(), tex->height()); | |
| 832 this->drawState()->createTextureEffect(0, tex, matrix); | |
| 833 SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, | |
| 834 dstPoint.fY, | |
| 835 srcRect.width(), | |
| 836 srcRect.height()); | |
| 837 this->drawSimpleRect(dstRect); | |
| 838 return true; | |
| 839 } | |
| 840 | |
| 764 /////////////////////////////////////////////////////////////////////////////// | 841 /////////////////////////////////////////////////////////////////////////////// |
| 765 | 842 |
| 766 SK_DEFINE_INST_COUNT(GrDrawTargetCaps) | 843 SK_DEFINE_INST_COUNT(GrDrawTargetCaps) |
| 767 | 844 |
| 768 void GrDrawTargetCaps::reset() { | 845 void GrDrawTargetCaps::reset() { |
| 769 f8BitPaletteSupport = false; | 846 f8BitPaletteSupport = false; |
| 770 fNPOTTextureTileSupport = false; | 847 fNPOTTextureTileSupport = false; |
| 771 fTwoSidedStencilSupport = false; | 848 fTwoSidedStencilSupport = false; |
| 772 fStencilWrapOpsSupport = false; | 849 fStencilWrapOpsSupport = false; |
| 773 fHWAALineSupport = false; | 850 fHWAALineSupport = false; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 810 GrPrintf("HW AA Lines Support : %s\n", gNY[fHWAALineSupport]); | 887 GrPrintf("HW AA Lines Support : %s\n", gNY[fHWAALineSupport]); |
| 811 GrPrintf("Shader Derivative Support : %s\n", gNY[fShaderDerivativeSupport] ); | 888 GrPrintf("Shader Derivative Support : %s\n", gNY[fShaderDerivativeSupport] ); |
| 812 GrPrintf("Geometry Shader Support : %s\n", gNY[fGeometryShaderSupport]); | 889 GrPrintf("Geometry Shader Support : %s\n", gNY[fGeometryShaderSupport]); |
| 813 GrPrintf("Dual Source Blending Support: %s\n", gNY[fDualSourceBlendingSuppor t]); | 890 GrPrintf("Dual Source Blending Support: %s\n", gNY[fDualSourceBlendingSuppor t]); |
| 814 GrPrintf("Buffer Lock Support : %s\n", gNY[fBufferLockSupport]); | 891 GrPrintf("Buffer Lock Support : %s\n", gNY[fBufferLockSupport]); |
| 815 GrPrintf("Path Stenciling Support : %s\n", gNY[fPathStencilingSupport]); | 892 GrPrintf("Path Stenciling Support : %s\n", gNY[fPathStencilingSupport]); |
| 816 GrPrintf("Max Texture Size : %d\n", fMaxTextureSize); | 893 GrPrintf("Max Texture Size : %d\n", fMaxTextureSize); |
| 817 GrPrintf("Max Render Target Size : %d\n", fMaxRenderTargetSize); | 894 GrPrintf("Max Render Target Size : %d\n", fMaxRenderTargetSize); |
| 818 GrPrintf("Max Sample Count : %d\n", fMaxSampleCount); | 895 GrPrintf("Max Sample Count : %d\n", fMaxSampleCount); |
| 819 } | 896 } |
| OLD | NEW |