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