diff options
author | 2015-08-18 12:12:35 -0700 | |
---|---|---|
committer | 2015-08-18 12:12:35 -0700 | |
commit | 872062cab802a824328b3402ea6f502fbb73a2be (patch) | |
tree | 32e8df92304323cfde00f12dc51d0d94a6e2674e /src/gpu/batches/GrCopySurfaceBatch.cpp | |
parent | 2a378433ebd16cd0dc034d291dea2983b82378e2 (diff) |
GrCopySurfaceBatch
Review URL: https://codereview.chromium.org/1289673004
Diffstat (limited to 'src/gpu/batches/GrCopySurfaceBatch.cpp')
-rw-r--r-- | src/gpu/batches/GrCopySurfaceBatch.cpp | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/src/gpu/batches/GrCopySurfaceBatch.cpp b/src/gpu/batches/GrCopySurfaceBatch.cpp new file mode 100644 index 0000000000..2c859f8e46 --- /dev/null +++ b/src/gpu/batches/GrCopySurfaceBatch.cpp @@ -0,0 +1,79 @@ +/* + * 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 "GrCopySurfaceBatch.h" + +// returns true if the read/written rect intersects the src/dst and false if not. +static bool clip_srcrect_and_dstpoint(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(); +} + +GrBatch* GrCopySurfaceBatch::Create(GrSurface* dst, 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've already succeeded. + if (!clip_srcrect_and_dstpoint(dst, + src, + srcRect, + dstPoint, + &clippedSrcRect, + &clippedDstPoint)) { + return NULL; + } + return SkNEW_ARGS(GrCopySurfaceBatch, (dst, src, clippedSrcRect, clippedDstPoint)); +} |