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) { |
| 812 // Check that the read/write rects are contained within the src/dst bounds. |
| 813 GrAssert(!srcRect.isEmpty()); |
| 814 GrAssert(SkIRect::MakeWH(src->width(), src->height()).contains(srcRect)); |
| 815 GrAssert(dstPoint.fX >= 0 && dstPoint.fY >= 0); |
| 816 GrAssert(dstPoint.fX + srcRect.width() <= dst->width() && |
| 817 dstPoint.fY + srcRect.height() <= dst->height()); |
| 818 |
| 819 return NULL != dst->asRenderTarget() && NULL != src->asTexture(); |
| 820 } |
| 821 |
| 822 bool GrDrawTarget::onCopySurface(GrSurface* dst, |
| 823 GrSurface* src, |
| 824 const SkIRect& srcRect, |
| 825 const SkIPoint& dstPoint) { |
| 826 if (!GrDrawTarget::canCopySurface(dst, src, srcRect, dstPoint)) { |
| 827 return false; |
| 828 } |
| 829 |
| 830 GrRenderTarget* rt = dst->asRenderTarget(); |
| 831 GrTexture* tex = src->asTexture(); |
| 832 |
| 833 GrDrawTarget::AutoStateRestore asr(this, kReset_ASRInit); |
| 834 this->drawState()->setRenderTarget(rt); |
| 835 SkMatrix matrix; |
| 836 matrix.setTranslate(SkIntToScalar(srcRect.fLeft - dstPoint.fX), |
| 837 SkIntToScalar(srcRect.fTop - dstPoint.fY)); |
| 838 matrix.postIDiv(tex->width(), tex->height()); |
| 839 this->drawState()->createTextureEffect(0, tex, matrix); |
| 840 SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX, |
| 841 dstPoint.fY, |
| 842 srcRect.width(), |
| 843 srcRect.height()); |
| 844 this->drawSimpleRect(dstRect); |
| 845 return true; |
| 846 } |
| 847 |
764 /////////////////////////////////////////////////////////////////////////////// | 848 /////////////////////////////////////////////////////////////////////////////// |
765 | 849 |
766 SK_DEFINE_INST_COUNT(GrDrawTargetCaps) | 850 SK_DEFINE_INST_COUNT(GrDrawTargetCaps) |
767 | 851 |
768 void GrDrawTargetCaps::reset() { | 852 void GrDrawTargetCaps::reset() { |
769 f8BitPaletteSupport = false; | 853 f8BitPaletteSupport = false; |
770 fNPOTTextureTileSupport = false; | 854 fNPOTTextureTileSupport = false; |
771 fTwoSidedStencilSupport = false; | 855 fTwoSidedStencilSupport = false; |
772 fStencilWrapOpsSupport = false; | 856 fStencilWrapOpsSupport = false; |
773 fHWAALineSupport = false; | 857 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]); | 894 GrPrintf("HW AA Lines Support : %s\n", gNY[fHWAALineSupport]); |
811 GrPrintf("Shader Derivative Support : %s\n", gNY[fShaderDerivativeSupport]
); | 895 GrPrintf("Shader Derivative Support : %s\n", gNY[fShaderDerivativeSupport]
); |
812 GrPrintf("Geometry Shader Support : %s\n", gNY[fGeometryShaderSupport]); | 896 GrPrintf("Geometry Shader Support : %s\n", gNY[fGeometryShaderSupport]); |
813 GrPrintf("Dual Source Blending Support: %s\n", gNY[fDualSourceBlendingSuppor
t]); | 897 GrPrintf("Dual Source Blending Support: %s\n", gNY[fDualSourceBlendingSuppor
t]); |
814 GrPrintf("Buffer Lock Support : %s\n", gNY[fBufferLockSupport]); | 898 GrPrintf("Buffer Lock Support : %s\n", gNY[fBufferLockSupport]); |
815 GrPrintf("Path Stenciling Support : %s\n", gNY[fPathStencilingSupport]); | 899 GrPrintf("Path Stenciling Support : %s\n", gNY[fPathStencilingSupport]); |
816 GrPrintf("Max Texture Size : %d\n", fMaxTextureSize); | 900 GrPrintf("Max Texture Size : %d\n", fMaxTextureSize); |
817 GrPrintf("Max Render Target Size : %d\n", fMaxRenderTargetSize); | 901 GrPrintf("Max Render Target Size : %d\n", fMaxRenderTargetSize); |
818 GrPrintf("Max Sample Count : %d\n", fMaxSampleCount); | 902 GrPrintf("Max Sample Count : %d\n", fMaxSampleCount); |
819 } | 903 } |
OLD | NEW |