diff options
Diffstat (limited to 'src/gpu/ops/GrCopySurfaceOp.cpp')
-rw-r--r-- | src/gpu/ops/GrCopySurfaceOp.cpp | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/src/gpu/ops/GrCopySurfaceOp.cpp b/src/gpu/ops/GrCopySurfaceOp.cpp new file mode 100644 index 0000000000..3283517efe --- /dev/null +++ b/src/gpu/ops/GrCopySurfaceOp.cpp @@ -0,0 +1,78 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "GrCopySurfaceOp.h" + +// returns true if the read/written rect intersects the src/dst and false if not. +bool GrCopySurfaceOp::ClipSrcRectAndDstPoint(const GrSurface* dst, + const GrSurface* src, + const SkIRect& srcRect, + 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; + } + + // 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; + } + + // clip the right edge to the src and dst bounds. + if (clippedSrcRect->fRight > src->width()) { + clippedSrcRect->fRight = src->width(); + } + 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 (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. + return !clippedSrcRect->isEmpty(); +} + +sk_sp<GrOp> GrCopySurfaceOp::Make(GrSurface* dst, GrSurface* src, const SkIRect& srcRect, + const SkIPoint& dstPoint) { + SkASSERT(dst); + SkASSERT(src); + if (GrPixelConfigIsSint(dst->config()) != GrPixelConfigIsSint(src->config())) { + return nullptr; + } + if (GrPixelConfigIsCompressed(dst->config())) { + return nullptr; + } + SkIRect clippedSrcRect; + SkIPoint clippedDstPoint; + // If the rect is outside the src or dst then we've already succeeded. + if (!ClipSrcRectAndDstPoint(dst, src, srcRect, dstPoint, &clippedSrcRect, &clippedDstPoint)) { + return nullptr; + } + return sk_sp<GrOp>(new GrCopySurfaceOp(dst, src, clippedSrcRect, clippedDstPoint)); +} |