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