Chromium Code Reviews| Index: src/gpu/GrDrawTarget.cpp |
| =================================================================== |
| --- src/gpu/GrDrawTarget.cpp (revision 8526) |
| +++ src/gpu/GrDrawTarget.cpp (working copy) |
| @@ -751,52 +751,76 @@ |
| target->setClip(&fReplacementClip); |
| } |
| -bool GrDrawTarget::copySurface(GrSurface* dst, |
| +namespace { |
| +// returns true if the read/written rect intersects the src/dst and false if not. |
|
robertphillips
2013/04/03 21:18:43
surely dst & src can be const here?
bsalomon
2013/04/09 15:47:42
Done.
|
| +bool clip_srcrect_and_dstpoint(GrSurface* dst, |
| GrSurface* src, |
| const SkIRect& srcRect, |
| - const SkIPoint& dstPoint) { |
| - SkIRect clippedSrcRect(srcRect); |
| - SkIPoint clippedDstPoint(dstPoint); |
| - |
| - // clip the left edge to src and dst bounds, adjusting dstPoint if neceessary |
| - if (clippedSrcRect.fLeft < 0) { |
| - clippedDstPoint.fX -= clippedSrcRect.fLeft; |
| - clippedSrcRect.fLeft = 0; |
| + const SkIPoint& dstPoint, |
| + SkIRect* clippedSrcRect, |
| + SkIPoint* clippedDstPoint) { |
| + *clippedSrcRect = srcRect; |
| + *clippedDstPoint = dstPoint; |
| + |
| + // clip the left edge to src and dst bounds, adjusting dstPoint if necessary |
| + if (clippedSrcRect->fLeft < 0) { |
| + clippedDstPoint->fX -= clippedSrcRect->fLeft; |
| + clippedSrcRect->fLeft = 0; |
| } |
| - if (clippedDstPoint.fX < 0) { |
| - clippedSrcRect.fLeft -= clippedDstPoint.fX; |
| - clippedDstPoint.fX = 0; |
| + if (clippedDstPoint->fX < 0) { |
| + clippedSrcRect->fLeft -= clippedDstPoint->fX; |
| + clippedDstPoint->fX = 0; |
| } |
| - // clip the top edge to src and dst bounds, adjusting dstPoint if neceessary |
| - if (clippedSrcRect.fTop < 0) { |
| - clippedDstPoint.fY -= clippedSrcRect.fTop; |
| - clippedSrcRect.fTop = 0; |
| + // clip the top edge to src and dst bounds, adjusting dstPoint if necessary |
| + if (clippedSrcRect->fTop < 0) { |
| + clippedDstPoint->fY -= clippedSrcRect->fTop; |
| + clippedSrcRect->fTop = 0; |
| } |
| - if (clippedDstPoint.fY < 0) { |
| - clippedSrcRect.fTop -= clippedDstPoint.fY; |
| - clippedDstPoint.fY = 0; |
| + if (clippedDstPoint->fY < 0) { |
| + clippedSrcRect->fTop -= clippedDstPoint->fY; |
| + clippedDstPoint->fY = 0; |
| } |
| // clip the right edge to the src and dst bounds. |
| - if (clippedSrcRect.fRight > src->width()) { |
| - clippedSrcRect.fRight = src->width(); |
| + if (clippedSrcRect->fRight > src->width()) { |
| + clippedSrcRect->fRight = src->width(); |
| } |
| - if (clippedDstPoint.fX + clippedSrcRect.width() > dst->width()) { |
| - clippedSrcRect.fRight = clippedSrcRect.fLeft + dst->width() - clippedDstPoint.fX; |
| + if (clippedDstPoint->fX + clippedSrcRect->width() > dst->width()) { |
| + clippedSrcRect->fRight = clippedSrcRect->fLeft + dst->width() - clippedDstPoint->fX; |
| } |
| // clip the bottom edge to the src and dst bounds. |
| - if (clippedSrcRect.fBottom > src->height()) { |
| - clippedSrcRect.fBottom = src->height(); |
| + if (clippedSrcRect->fBottom > src->height()) { |
| + clippedSrcRect->fBottom = src->height(); |
| } |
| - if (clippedDstPoint.fY + clippedSrcRect.height() > dst->height()) { |
| - clippedSrcRect.fBottom = clippedSrcRect.fTop + dst->height() - clippedDstPoint.fY; |
| + if (clippedDstPoint->fY + clippedSrcRect->height() > dst->height()) { |
| + clippedSrcRect->fBottom = clippedSrcRect->fTop + dst->height() - clippedDstPoint->fY; |
| } |
| // The above clipping steps may have inverted the rect if it didn't intersect either the src or |
| // dst bounds. |
| - if (clippedSrcRect.isEmpty()) { |
| + return !clippedSrcRect->isEmpty(); |
| +} |
| +} |
| + |
| +bool GrDrawTarget::copySurface(GrSurface* dst, |
| + GrSurface* src, |
| + const SkIRect& srcRect, |
| + const SkIPoint& dstPoint) { |
| + GrAssert(NULL != dst); |
| + GrAssert(NULL != src); |
| + |
| + SkIRect clippedSrcRect; |
| + SkIPoint clippedDstPoint; |
| + // If the rect is outside the src or dst then we've already succeeded. |
| + if (!clip_srcrect_and_dstpoint(dst, |
| + src, |
| + srcRect, |
| + dstPoint, |
| + &clippedSrcRect, |
| + &clippedDstPoint)) { |
| + GrAssert(this->canCopySurface(dst, src, srcRect, dstPoint)); |
| return true; |
| } |
| @@ -809,6 +833,27 @@ |
| GrSurface* src, |
| const SkIRect& srcRect, |
| const SkIPoint& dstPoint) { |
| + GrAssert(NULL != dst); |
| + GrAssert(NULL != src); |
| + |
| + SkIRect clippedSrcRect; |
| + SkIPoint clippedDstPoint; |
| + // If the rect is outside the src or dst then we're guaranteed success |
| + if (!clip_srcrect_and_dstpoint(dst, |
| + src, |
| + srcRect, |
| + dstPoint, |
| + &clippedSrcRect, |
| + &clippedDstPoint)) { |
| + return true; |
| + } |
| + return this->onCanCopySurface(dst, src, clippedSrcRect, clippedDstPoint); |
| +} |
| + |
| +bool GrDrawTarget::onCanCopySurface(GrSurface* dst, |
| + GrSurface* src, |
| + const SkIRect& srcRect, |
| + const SkIPoint& dstPoint) { |
| // Check that the read/write rects are contained within the src/dst bounds. |
| GrAssert(!srcRect.isEmpty()); |
| GrAssert(SkIRect::MakeWH(src->width(), src->height()).contains(srcRect)); |
| @@ -816,14 +861,14 @@ |
| GrAssert(dstPoint.fX + srcRect.width() <= dst->width() && |
| dstPoint.fY + srcRect.height() <= dst->height()); |
| - return NULL != dst->asRenderTarget() && NULL != src->asTexture(); |
| + return !dst->isSameAs(src) && NULL != dst->asRenderTarget() && NULL != src->asTexture(); |
| } |
| bool GrDrawTarget::onCopySurface(GrSurface* dst, |
| GrSurface* src, |
| const SkIRect& srcRect, |
| const SkIPoint& dstPoint) { |
| - if (!GrDrawTarget::canCopySurface(dst, src, srcRect, dstPoint)) { |
| + if (!GrDrawTarget::onCanCopySurface(dst, src, srcRect, dstPoint)) { |
| return false; |
| } |