xref: /aosp_15_r20/external/skia/src/gpu/ganesh/GrCopyRenderTask.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
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/ganesh/GrCopyRenderTask.h"
9 
10 #include "include/private/base/SkAssert.h"
11 #include "src/gpu/ganesh/GrGpu.h"
12 #include "src/gpu/ganesh/GrNativeRect.h"
13 #include "src/gpu/ganesh/GrOpFlushState.h"
14 #include "src/gpu/ganesh/GrResourceAllocator.h"
15 #include "src/gpu/ganesh/GrSurface.h"
16 
17 #include <utility>
18 
19 class GrDrawingManager;
20 class GrRecordingContext;
21 
Make(GrDrawingManager * drawingMgr,sk_sp<GrSurfaceProxy> dst,SkIRect dstRect,sk_sp<GrSurfaceProxy> src,SkIRect srcRect,GrSamplerState::Filter filter,GrSurfaceOrigin origin)22 sk_sp<GrRenderTask> GrCopyRenderTask::Make(GrDrawingManager* drawingMgr,
23                                            sk_sp<GrSurfaceProxy> dst,
24                                            SkIRect dstRect,
25                                            sk_sp<GrSurfaceProxy> src,
26                                            SkIRect srcRect,
27                                            GrSamplerState::Filter filter,
28                                            GrSurfaceOrigin origin) {
29     SkASSERT(src);
30     SkASSERT(dst);
31 
32     // canCopySurface() should have returned true, guaranteeing this property.
33     SkASSERT(SkIRect::MakeSize(dst->dimensions()).contains(dstRect));
34     SkASSERT(SkIRect::MakeSize(src->dimensions()).contains(srcRect));
35 
36     return sk_sp<GrRenderTask>(new GrCopyRenderTask(drawingMgr,
37                                                     std::move(dst),
38                                                     dstRect,
39                                                     std::move(src),
40                                                     srcRect,
41                                                     filter,
42                                                     origin));
43 }
44 
GrCopyRenderTask(GrDrawingManager * drawingMgr,sk_sp<GrSurfaceProxy> dst,SkIRect dstRect,sk_sp<GrSurfaceProxy> src,SkIRect srcRect,GrSamplerState::Filter filter,GrSurfaceOrigin origin)45 GrCopyRenderTask::GrCopyRenderTask(GrDrawingManager* drawingMgr,
46                                    sk_sp<GrSurfaceProxy> dst,
47                                    SkIRect dstRect,
48                                    sk_sp<GrSurfaceProxy> src,
49                                    SkIRect srcRect,
50                                    GrSamplerState::Filter filter,
51                                    GrSurfaceOrigin origin)
52         : fSrc(std::move(src))
53         , fSrcRect(srcRect)
54         , fDstRect(dstRect)
55         , fFilter(filter)
56         , fOrigin(origin) {
57     this->addTarget(drawingMgr, std::move(dst));
58 }
59 
gatherProxyIntervals(GrResourceAllocator * alloc) const60 void GrCopyRenderTask::gatherProxyIntervals(GrResourceAllocator* alloc) const {
61     if (!fSrc) {
62         alloc->incOps();
63         return;
64     }
65     // This renderTask doesn't have "normal" ops. In this case we still need to add an interval (so
66     // fEndOfOpsTaskOpIndices will remain in sync), so we create a fake op# to capture the fact that
67     // we read fSrcView and copy to target view.
68     alloc->addInterval(fSrc.get(), alloc->curOp(), alloc->curOp(),
69                        GrResourceAllocator::ActualUse::kYes,
70                        GrResourceAllocator::AllowRecycling::kYes);
71     alloc->addInterval(this->target(0), alloc->curOp(), alloc->curOp(),
72                        GrResourceAllocator::ActualUse::kYes,
73                        GrResourceAllocator::AllowRecycling::kYes);
74     alloc->incOps();
75 }
76 
onMakeClosed(GrRecordingContext *,SkIRect * targetUpdateBounds)77 GrRenderTask::ExpectedOutcome GrCopyRenderTask::onMakeClosed(GrRecordingContext*,
78                                                              SkIRect* targetUpdateBounds) {
79     // We don't expect to be marked skippable before being closed.
80     SkASSERT(fSrc);
81     *targetUpdateBounds = GrNativeRect::MakeIRectRelativeTo(
82             fOrigin,
83             this->target(0)->height(),
84             fDstRect);
85     return ExpectedOutcome::kTargetDirty;
86 }
87 
onExecute(GrOpFlushState * flushState)88 bool GrCopyRenderTask::onExecute(GrOpFlushState* flushState) {
89     if (!fSrc) {
90         // Did nothing, just like we're supposed to.
91         return true;
92     }
93     GrSurfaceProxy* dstProxy = this->target(0);
94     if (!fSrc->isInstantiated() || !dstProxy->isInstantiated()) {
95         return false;
96     }
97     GrSurface* srcSurface = fSrc->peekSurface();
98     GrSurface* dstSurface = dstProxy->peekSurface();
99     SkIRect srcRect = GrNativeRect::MakeIRectRelativeTo(fOrigin, srcSurface->height(), fSrcRect);
100     SkIRect dstRect = GrNativeRect::MakeIRectRelativeTo(fOrigin, dstSurface->height(), fDstRect);
101     return flushState->gpu()->copySurface(dstSurface, dstRect, srcSurface, srcRect, fFilter);
102 }
103