Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(214)

Side by Side Diff: src/gpu/GrDrawTarget.cpp

Issue 13428004: Add GrDrawTarget::copySurface. (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: add asserts Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/gpu/GrDrawTarget.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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(), &copyRec t); 423 clip->getConservativeBounds(this->getDrawState().getRenderTarget(), &copyRec 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
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
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 }
OLDNEW
« no previous file with comments | « src/gpu/GrDrawTarget.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698