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 | |
parent | 2a378433ebd16cd0dc034d291dea2983b82378e2 (diff) |
GrCopySurfaceBatch
Review URL: https://codereview.chromium.org/1289673004
Diffstat (limited to 'src/gpu/batches')
-rw-r--r-- | src/gpu/batches/GrCopySurfaceBatch.cpp | 79 | ||||
-rw-r--r-- | src/gpu/batches/GrCopySurfaceBatch.h | 63 |
2 files changed, 142 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)); +} diff --git a/src/gpu/batches/GrCopySurfaceBatch.h b/src/gpu/batches/GrCopySurfaceBatch.h new file mode 100644 index 0000000000..584bbab5d7 --- /dev/null +++ b/src/gpu/batches/GrCopySurfaceBatch.h @@ -0,0 +1,63 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef GrCopySurfaceBatch_DEFINED +#define GrCopySurfaceBatch_DEFINED + +#include "GrBatch.h" +#include "GrBatchFlushState.h" +#include "GrGpu.h" +#include "GrRenderTarget.h" + +class GrCopySurfaceBatch final : public GrBatch { +public: + static GrBatch* Create(GrSurface* dst, GrSurface* src, const SkIRect& srcRect, + const SkIPoint& dstPoint); + + const char* name() const override { return "CopySurface"; } + + uint32_t renderTargetUniqueID() const override { + GrRenderTarget* rt = fDst.get()->asRenderTarget(); + return rt ? rt->getUniqueID() : 0; + } + + SkString dumpInfo() const override { + SkString string; + string.printf("SRC: 0x%p, DST: 0x%p, SRECT: [L: %d, T: %d, R: %d, B: %d], " + "DPT:[X: %d, Y: %d]", + fDst.get(), fSrc.get(), fSrcRect.fLeft, fSrcRect.fTop, fSrcRect.fRight, + fSrcRect.fBottom, fDstPoint.fX, fDstPoint.fY); + return string; + } + +private: + GrCopySurfaceBatch(GrSurface* dst, GrSurface* src, const SkIRect& srcRect, + const SkIPoint& dstPoint) + : fDst(dst) + , fSrc(src) + , fSrcRect(srcRect) + , fDstPoint(dstPoint) { + this->initClassID<GrCopySurfaceBatch>(); + fBounds = SkRect::MakeXYWH(SkIntToScalar(dstPoint.fX), SkIntToScalar(dstPoint.fY), + SkIntToScalar(srcRect.width()), SkIntToScalar(srcRect.height())); + } + + bool onCombineIfPossible(GrBatch* that, const GrCaps& caps) override { return false; } + + void onPrepare(GrBatchFlushState*) override {} + + void onDraw(GrBatchFlushState* state) override { + state->gpu()->copySurface(fDst.get(), fSrc.get(), fSrcRect, fDstPoint); + } + + GrPendingIOResource<GrSurface, kWrite_GrIOType> fDst; + GrPendingIOResource<GrSurface, kRead_GrIOType> fSrc; + SkIRect fSrcRect; + SkIPoint fDstPoint; +}; + +#endif |