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 9 #include "GrCopySurfaceBatch.h" 10 11 // returns true if the read/written rect intersects the src/dst and false if not. 12 bool GrCopySurfaceBatch::ClipSrcRectAndDstPoint(const GrSurface* dst, 13 const GrSurface* 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 GrBatch* GrCopySurfaceBatch::Create(GrSurface* dst, GrSurface* src, const SkIRect& srcRect, 63 const SkIPoint& dstPoint) { 64 SkASSERT(dst); 65 SkASSERT(src); 66 67 SkIRect clippedSrcRect; 68 SkIPoint clippedDstPoint; 69 // If the rect is outside the src or dst then we've already succeeded. 70 if (!ClipSrcRectAndDstPoint(dst, src, srcRect, dstPoint, &clippedSrcRect, &clippedDstPoint)) { 71 return nullptr; 72 } 73 return new GrCopySurfaceBatch(dst, src, clippedSrcRect, clippedDstPoint); 74 } 75