blob: 0a8fbdd3b09fd5b48018e136acd60a6f7c7b6487 [file] [log] [blame]
Greg Daniele227fe42019-08-21 13:52:24 -04001/*
2 * Copyright 2019 Google LLC
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "src/gpu/GrCopyRenderTask.h"
9
10#include "src/gpu/GrGpu.h"
11#include "src/gpu/GrOpFlushState.h"
12#include "src/gpu/GrResourceAllocator.h"
Robert Phillips550de7f2021-07-06 16:28:52 -040013#include "src/gpu/geometry/GrRect.h"
Greg Daniele227fe42019-08-21 13:52:24 -040014
Adlai Hollerd71b7b02020-06-08 15:55:00 -040015sk_sp<GrRenderTask> GrCopyRenderTask::Make(GrDrawingManager* drawingMgr,
Brian Salomon982127b2021-01-21 10:43:35 -050016 sk_sp<GrSurfaceProxy> src,
17 SkIRect srcRect,
18 sk_sp<GrSurfaceProxy> dst,
19 SkIPoint dstPoint,
Brian Salomon0f9f8002021-01-22 16:30:50 -050020 GrSurfaceOrigin origin) {
Brian Salomon982127b2021-01-21 10:43:35 -050021 SkASSERT(src);
22 SkASSERT(dst);
Brian Salomone4bce012019-09-20 15:34:23 -040023
Brian Salomon0f9f8002021-01-22 16:30:50 -050024 if (!GrClipSrcRectAndDstPoint(dst->dimensions(),
25 src->dimensions(),
26 srcRect,
27 dstPoint,
28 &srcRect,
29 &dstPoint)) {
30 return nullptr;
31 }
Greg Daniele227fe42019-08-21 13:52:24 -040032
Brian Salomond63638b2021-03-05 14:00:07 -050033 return sk_sp<GrRenderTask>(new GrCopyRenderTask(drawingMgr,
34 std::move(src),
35 srcRect,
36 std::move(dst),
37 dstPoint,
38 origin));
Greg Daniele227fe42019-08-21 13:52:24 -040039}
40
Adlai Hollerd71b7b02020-06-08 15:55:00 -040041GrCopyRenderTask::GrCopyRenderTask(GrDrawingManager* drawingMgr,
Brian Salomon982127b2021-01-21 10:43:35 -050042 sk_sp<GrSurfaceProxy> src,
43 SkIRect srcRect,
44 sk_sp<GrSurfaceProxy> dst,
Brian Salomon0f9f8002021-01-22 16:30:50 -050045 SkIPoint dstPoint,
46 GrSurfaceOrigin origin)
47 : fSrc(std::move(src)), fSrcRect(srcRect), fDstPoint(dstPoint), fOrigin(origin) {
Brian Salomon982127b2021-01-21 10:43:35 -050048 this->addTarget(drawingMgr, std::move(dst));
Greg Daniele227fe42019-08-21 13:52:24 -040049}
50
51void GrCopyRenderTask::gatherProxyIntervals(GrResourceAllocator* alloc) const {
Brian Salomond63638b2021-03-05 14:00:07 -050052 if (!fSrc) {
53 alloc->incOps();
54 return;
55 }
Greg Daniele227fe42019-08-21 13:52:24 -040056 // This renderTask doesn't have "normal" ops. In this case we still need to add an interval (so
Greg Danielf41b2bd2019-08-22 16:19:24 -040057 // fEndOfOpsTaskOpIndices will remain in sync), so we create a fake op# to capture the fact that
Adlai Holler33d569e2020-06-16 14:30:08 -040058 // we read fSrcView and copy to target view.
Adlai Holler7f7a5df2021-02-09 17:41:10 +000059 alloc->addInterval(fSrc.get(), alloc->curOp(), alloc->curOp(),
60 GrResourceAllocator::ActualUse::kYes);
61 alloc->addInterval(this->target(0), alloc->curOp(), alloc->curOp(),
62 GrResourceAllocator::ActualUse::kYes);
Greg Daniele227fe42019-08-21 13:52:24 -040063 alloc->incOps();
64}
65
Chris Daltonaa938ce2021-06-23 18:13:59 -060066GrRenderTask::ExpectedOutcome GrCopyRenderTask::onMakeClosed(GrRecordingContext*,
Brian Salomon0f9f8002021-01-22 16:30:50 -050067 SkIRect* targetUpdateBounds) {
Brian Salomond63638b2021-03-05 14:00:07 -050068 // We don't expect to be marked skippable before being closed.
69 SkASSERT(fSrc);
Brian Salomon0f9f8002021-01-22 16:30:50 -050070 *targetUpdateBounds = GrNativeRect::MakeIRectRelativeTo(
71 fOrigin,
72 this->target(0)->height(),
73 SkIRect::MakePtSize(fDstPoint, fSrcRect.size()));
74 return ExpectedOutcome::kTargetDirty;
75}
76
Greg Daniele227fe42019-08-21 13:52:24 -040077bool GrCopyRenderTask::onExecute(GrOpFlushState* flushState) {
Brian Salomond63638b2021-03-05 14:00:07 -050078 if (!fSrc) {
79 // Did nothing, just like we're supposed to.
80 return true;
81 }
Brian Salomon982127b2021-01-21 10:43:35 -050082 GrSurfaceProxy* dstProxy = this->target(0);
83 if (!fSrc->isInstantiated() || !dstProxy->isInstantiated()) {
Greg Daniele227fe42019-08-21 13:52:24 -040084 return false;
85 }
Brian Salomon982127b2021-01-21 10:43:35 -050086 GrSurface* srcSurface = fSrc->peekSurface();
Greg Daniel16f5c652019-10-29 11:26:01 -040087 GrSurface* dstSurface = dstProxy->peekSurface();
Brian Salomon0f9f8002021-01-22 16:30:50 -050088 SkIRect srcRect = GrNativeRect::MakeIRectRelativeTo(fOrigin, srcSurface->height(), fSrcRect);
89 SkIPoint dstPoint = fDstPoint;
90 if (fOrigin == kBottomLeft_GrSurfaceOrigin) {
91 dstPoint.fY = dstSurface->height() - dstPoint.fY - srcRect.height();
92 }
93 return flushState->gpu()->copySurface(dstSurface, srcSurface, srcRect, dstPoint);
Greg Daniele227fe42019-08-21 13:52:24 -040094}
95