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