1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2019 Google LLC 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "src/gpu/GrCopyRenderTask.h" 9cb93a386Sopenharmony_ci 10cb93a386Sopenharmony_ci#include "src/gpu/GrGpu.h" 11cb93a386Sopenharmony_ci#include "src/gpu/GrOpFlushState.h" 12cb93a386Sopenharmony_ci#include "src/gpu/GrResourceAllocator.h" 13cb93a386Sopenharmony_ci#include "src/gpu/geometry/GrRect.h" 14cb93a386Sopenharmony_ci 15cb93a386Sopenharmony_cisk_sp<GrRenderTask> GrCopyRenderTask::Make(GrDrawingManager* drawingMgr, 16cb93a386Sopenharmony_ci sk_sp<GrSurfaceProxy> src, 17cb93a386Sopenharmony_ci SkIRect srcRect, 18cb93a386Sopenharmony_ci sk_sp<GrSurfaceProxy> dst, 19cb93a386Sopenharmony_ci SkIPoint dstPoint, 20cb93a386Sopenharmony_ci GrSurfaceOrigin origin) { 21cb93a386Sopenharmony_ci SkASSERT(src); 22cb93a386Sopenharmony_ci SkASSERT(dst); 23cb93a386Sopenharmony_ci 24cb93a386Sopenharmony_ci if (!GrClipSrcRectAndDstPoint(dst->dimensions(), 25cb93a386Sopenharmony_ci src->dimensions(), 26cb93a386Sopenharmony_ci srcRect, 27cb93a386Sopenharmony_ci dstPoint, 28cb93a386Sopenharmony_ci &srcRect, 29cb93a386Sopenharmony_ci &dstPoint)) { 30cb93a386Sopenharmony_ci return nullptr; 31cb93a386Sopenharmony_ci } 32cb93a386Sopenharmony_ci 33cb93a386Sopenharmony_ci return sk_sp<GrRenderTask>(new GrCopyRenderTask(drawingMgr, 34cb93a386Sopenharmony_ci std::move(src), 35cb93a386Sopenharmony_ci srcRect, 36cb93a386Sopenharmony_ci std::move(dst), 37cb93a386Sopenharmony_ci dstPoint, 38cb93a386Sopenharmony_ci origin)); 39cb93a386Sopenharmony_ci} 40cb93a386Sopenharmony_ci 41cb93a386Sopenharmony_ciGrCopyRenderTask::GrCopyRenderTask(GrDrawingManager* drawingMgr, 42cb93a386Sopenharmony_ci sk_sp<GrSurfaceProxy> src, 43cb93a386Sopenharmony_ci SkIRect srcRect, 44cb93a386Sopenharmony_ci sk_sp<GrSurfaceProxy> dst, 45cb93a386Sopenharmony_ci SkIPoint dstPoint, 46cb93a386Sopenharmony_ci GrSurfaceOrigin origin) 47cb93a386Sopenharmony_ci : fSrc(std::move(src)), fSrcRect(srcRect), fDstPoint(dstPoint), fOrigin(origin) { 48cb93a386Sopenharmony_ci this->addTarget(drawingMgr, std::move(dst)); 49cb93a386Sopenharmony_ci} 50cb93a386Sopenharmony_ci 51cb93a386Sopenharmony_civoid GrCopyRenderTask::gatherProxyIntervals(GrResourceAllocator* alloc) const { 52cb93a386Sopenharmony_ci if (!fSrc) { 53cb93a386Sopenharmony_ci alloc->incOps(); 54cb93a386Sopenharmony_ci return; 55cb93a386Sopenharmony_ci } 56cb93a386Sopenharmony_ci // This renderTask doesn't have "normal" ops. In this case we still need to add an interval (so 57cb93a386Sopenharmony_ci // fEndOfOpsTaskOpIndices will remain in sync), so we create a fake op# to capture the fact that 58cb93a386Sopenharmony_ci // we read fSrcView and copy to target view. 59cb93a386Sopenharmony_ci alloc->addInterval(fSrc.get(), alloc->curOp(), alloc->curOp(), 60cb93a386Sopenharmony_ci GrResourceAllocator::ActualUse::kYes); 61cb93a386Sopenharmony_ci alloc->addInterval(this->target(0), alloc->curOp(), alloc->curOp(), 62cb93a386Sopenharmony_ci GrResourceAllocator::ActualUse::kYes); 63cb93a386Sopenharmony_ci alloc->incOps(); 64cb93a386Sopenharmony_ci} 65cb93a386Sopenharmony_ci 66cb93a386Sopenharmony_ciGrRenderTask::ExpectedOutcome GrCopyRenderTask::onMakeClosed(GrRecordingContext*, 67cb93a386Sopenharmony_ci SkIRect* targetUpdateBounds) { 68cb93a386Sopenharmony_ci // We don't expect to be marked skippable before being closed. 69cb93a386Sopenharmony_ci SkASSERT(fSrc); 70cb93a386Sopenharmony_ci *targetUpdateBounds = GrNativeRect::MakeIRectRelativeTo( 71cb93a386Sopenharmony_ci fOrigin, 72cb93a386Sopenharmony_ci this->target(0)->height(), 73cb93a386Sopenharmony_ci SkIRect::MakePtSize(fDstPoint, fSrcRect.size())); 74cb93a386Sopenharmony_ci return ExpectedOutcome::kTargetDirty; 75cb93a386Sopenharmony_ci} 76cb93a386Sopenharmony_ci 77cb93a386Sopenharmony_cibool GrCopyRenderTask::onExecute(GrOpFlushState* flushState) { 78cb93a386Sopenharmony_ci if (!fSrc) { 79cb93a386Sopenharmony_ci // Did nothing, just like we're supposed to. 80cb93a386Sopenharmony_ci return true; 81cb93a386Sopenharmony_ci } 82cb93a386Sopenharmony_ci GrSurfaceProxy* dstProxy = this->target(0); 83cb93a386Sopenharmony_ci if (!fSrc->isInstantiated() || !dstProxy->isInstantiated()) { 84cb93a386Sopenharmony_ci return false; 85cb93a386Sopenharmony_ci } 86cb93a386Sopenharmony_ci GrSurface* srcSurface = fSrc->peekSurface(); 87cb93a386Sopenharmony_ci GrSurface* dstSurface = dstProxy->peekSurface(); 88cb93a386Sopenharmony_ci SkIRect srcRect = GrNativeRect::MakeIRectRelativeTo(fOrigin, srcSurface->height(), fSrcRect); 89cb93a386Sopenharmony_ci SkIPoint dstPoint = fDstPoint; 90cb93a386Sopenharmony_ci if (fOrigin == kBottomLeft_GrSurfaceOrigin) { 91cb93a386Sopenharmony_ci dstPoint.fY = dstSurface->height() - dstPoint.fY - srcRect.height(); 92cb93a386Sopenharmony_ci } 93cb93a386Sopenharmony_ci return flushState->gpu()->copySurface(dstSurface, srcSurface, srcRect, dstPoint); 94cb93a386Sopenharmony_ci} 95cb93a386Sopenharmony_ci 96