Index: src/gpu/GrDrawTarget.cpp |
diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp |
index 7565cd1df865aaeca1ce55d479de2a3ef8b449e1..549ab374c8f71940f77b5a003a69b575b14c4972 100644 |
--- a/src/gpu/GrDrawTarget.cpp |
+++ b/src/gpu/GrDrawTarget.cpp |
@@ -100,10 +100,13 @@ |
return false; |
} |
SkIPoint dstPoint = {0, 0}; |
- this->copySurface(copy, rt, copyRect, dstPoint); |
- dstCopy->setTexture(copy); |
- dstCopy->setOffset(copyRect.fLeft, copyRect.fTop); |
- return true; |
+ if (this->copySurface(copy, rt, copyRect, dstPoint)) { |
+ dstCopy->setTexture(copy); |
+ dstCopy->setOffset(copyRect.fLeft, copyRect.fTop); |
+ return true; |
+ } else { |
+ return false; |
+ } |
} |
void GrDrawTarget::flush() { |
@@ -418,7 +421,7 @@ |
} |
} |
-void GrDrawTarget::copySurface(GrSurface* dst, |
+bool GrDrawTarget::copySurface(GrSurface* dst, |
GrSurface* src, |
const SkIRect& srcRect, |
const SkIPoint& dstPoint) { |
@@ -434,10 +437,56 @@ |
dstPoint, |
&clippedSrcRect, |
&clippedDstPoint)) { |
- return; |
- } |
- |
- this->onCopySurface(dst, src, clippedSrcRect, clippedDstPoint); |
+ return true; |
+ } |
+ |
+ if (this->getGpu()->canCopySurface(dst, src, clippedSrcRect, clippedDstPoint)) { |
+ this->onCopySurface(dst, src, clippedSrcRect, clippedDstPoint); |
+ return true; |
+ } |
+ |
+ GrRenderTarget* rt = dst->asRenderTarget(); |
+ GrTexture* tex = src->asTexture(); |
+ |
+ if ((dst == src) || !rt || !tex) { |
+ return false; |
+ } |
+ |
+ GrPipelineBuilder pipelineBuilder; |
+ pipelineBuilder.setRenderTarget(rt); |
+ SkMatrix matrix; |
+ matrix.setTranslate(SkIntToScalar(clippedSrcRect.fLeft - clippedDstPoint.fX), |
+ SkIntToScalar(clippedSrcRect.fTop - clippedDstPoint.fY)); |
+ matrix.postIDiv(tex->width(), tex->height()); |
+ pipelineBuilder.addColorTextureProcessor(tex, matrix); |
+ SkIRect dstRect = SkIRect::MakeXYWH(clippedDstPoint.fX, |
+ clippedDstPoint.fY, |
+ clippedSrcRect.width(), |
+ clippedSrcRect.height()); |
+ this->drawSimpleRect(&pipelineBuilder, GrColor_WHITE, SkMatrix::I(), dstRect); |
+ return true; |
+} |
+ |
+bool GrDrawTarget::canCopySurface(const GrSurface* dst, |
+ const GrSurface* src, |
+ const SkIRect& srcRect, |
+ const SkIPoint& dstPoint) { |
+ SkASSERT(dst); |
+ SkASSERT(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 ((dst != src) && dst->asRenderTarget() && src->asTexture()) || |
+ this->getGpu()->canCopySurface(dst, src, clippedSrcRect, clippedDstPoint); |
} |
void GrDrawTarget::setupPipeline(const PipelineInfo& pipelineInfo, |