1 /* 2 * Copyright 2015 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "GrCopySurfaceOp.h" 9 #include "GrGpu.h" 10 11 // returns true if the read/written rect intersects the src/dst and false if not. 12 static bool clip_src_rect_and_dst_point(const GrSurfaceProxy* dst, 13 const GrSurfaceProxy* src, 14 const SkIRect& srcRect, 15 const SkIPoint& dstPoint, 16 SkIRect* clippedSrcRect, 17 SkIPoint* clippedDstPoint) { 18 *clippedSrcRect = srcRect; 19 *clippedDstPoint = dstPoint; 20 21 // clip the left edge to src and dst bounds, adjusting dstPoint if necessary 22 if (clippedSrcRect->fLeft < 0) { 23 clippedDstPoint->fX -= clippedSrcRect->fLeft; 24 clippedSrcRect->fLeft = 0; 25 } 26 if (clippedDstPoint->fX < 0) { 27 clippedSrcRect->fLeft -= clippedDstPoint->fX; 28 clippedDstPoint->fX = 0; 29 } 30 31 // clip the top edge to src and dst bounds, adjusting dstPoint if necessary 32 if (clippedSrcRect->fTop < 0) { 33 clippedDstPoint->fY -= clippedSrcRect->fTop; 34 clippedSrcRect->fTop = 0; 35 } 36 if (clippedDstPoint->fY < 0) { 37 clippedSrcRect->fTop -= clippedDstPoint->fY; 38 clippedDstPoint->fY = 0; 39 } 40 41 // clip the right edge to the src and dst bounds. 42 if (clippedSrcRect->fRight > src->width()) { 43 clippedSrcRect->fRight = src->width(); 44 } 45 if (clippedDstPoint->fX + clippedSrcRect->width() > dst->width()) { 46 clippedSrcRect->fRight = clippedSrcRect->fLeft + dst->width() - clippedDstPoint->fX; 47 } 48 49 // clip the bottom edge to the src and dst bounds. 50 if (clippedSrcRect->fBottom > src->height()) { 51 clippedSrcRect->fBottom = src->height(); 52 } 53 if (clippedDstPoint->fY + clippedSrcRect->height() > dst->height()) { 54 clippedSrcRect->fBottom = clippedSrcRect->fTop + dst->height() - clippedDstPoint->fY; 55 } 56 57 // The above clipping steps may have inverted the rect if it didn't intersect either the src or 58 // dst bounds. 59 return !clippedSrcRect->isEmpty(); 60 } 61 62 std::unique_ptr<GrOp> GrCopySurfaceOp::Make(GrSurfaceProxy* dstProxy, GrSurfaceProxy* srcProxy, 63 const SkIRect& srcRect, 64 const SkIPoint& dstPoint) { 65 SkASSERT(dstProxy); 66 SkASSERT(srcProxy); 67 SkIRect clippedSrcRect; 68 SkIPoint clippedDstPoint; 69 // If the rect is outside the srcProxy or dstProxy then we've already succeeded. 70 if (!clip_src_rect_and_dst_point(dstProxy, srcProxy, srcRect, dstPoint, 71 &clippedSrcRect, &clippedDstPoint)) { 72 return nullptr; 73 } 74 75 return std::unique_ptr<GrOp>(new GrCopySurfaceOp(dstProxy, srcProxy, 76 clippedSrcRect, clippedDstPoint)); 77 } 78 79 void GrCopySurfaceOp::onExecute(GrOpFlushState* state) { 80 if (!fSrc.get()->instantiate(state->resourceProvider())) { 81 return; 82 } 83 84 state->commandBuffer()->copy(fSrc.get()->priv().peekSurface(), fSrc.get()->origin(), 85 fSrcRect, fDstPoint); 86 } 87