blob: 34af9a1b4c4490038a1de155e58c5e610db6e53b [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"
13
14sk_sp<GrRenderTask> GrCopyRenderTask::Make(sk_sp<GrSurfaceProxy> srcProxy,
15 const SkIRect& srcRect,
16 sk_sp<GrSurfaceProxy> dstProxy,
17 const SkIPoint& dstPoint) {
18 SkASSERT(dstProxy);
19 SkASSERT(srcProxy);
20 SkIRect clippedSrcRect;
21 SkIPoint clippedDstPoint;
22 // If the rect is outside the srcProxy or dstProxy then we've already succeeded.
23 if (!GrClipSrcRectAndDstPoint(dstProxy->isize(), srcProxy->isize(), srcRect, dstPoint,
24 &clippedSrcRect, &clippedDstPoint)) {
25 return nullptr;
26 }
27 if (GrPixelConfigIsCompressed(dstProxy->config())) {
28 return nullptr;
29 }
30
31 SkASSERT(dstProxy->origin() == srcProxy->origin());
32 if (srcProxy->origin() == kBottomLeft_GrSurfaceOrigin) {
33 int rectHeight = clippedSrcRect.height();
34 clippedSrcRect.fTop = srcProxy->height() - clippedSrcRect.fBottom;
35 clippedSrcRect.fBottom = clippedSrcRect.fTop + rectHeight;
36 clippedDstPoint.fY = dstProxy->height() - clippedDstPoint.fY - rectHeight;
37 }
38
39 sk_sp<GrCopyRenderTask> task(new GrCopyRenderTask(
40 std::move(srcProxy), clippedSrcRect, std::move(dstProxy), clippedDstPoint));
41 return task;
42}
43
44GrCopyRenderTask::GrCopyRenderTask(sk_sp<GrSurfaceProxy> srcProxy,
45 const SkIRect& srcRect,
46 sk_sp<GrSurfaceProxy> dstProxy,
47 const SkIPoint& dstPoint)
48 : GrRenderTask(std::move(dstProxy))
49 , fSrcProxy(std::move(srcProxy))
50 , fSrcRect(srcRect)
51 , fDstPoint(dstPoint) {
52 fTarget->setLastRenderTask(this);
53}
54
55void GrCopyRenderTask::gatherProxyIntervals(GrResourceAllocator* alloc) const {
56 // 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
Greg Daniele227fe42019-08-21 13:52:24 -040058 // we read fSrcProxy and copy to fTarget.
59 alloc->addInterval(fSrcProxy.get(), alloc->curOp(), alloc->curOp(),
60 GrResourceAllocator::ActualUse::kYes);
61 alloc->addInterval(fTarget.get(), alloc->curOp(), alloc->curOp(),
62 GrResourceAllocator::ActualUse::kYes);
63 alloc->incOps();
64}
65
66bool GrCopyRenderTask::onExecute(GrOpFlushState* flushState) {
67 if (!fSrcProxy->isInstantiated() || !fTarget->isInstantiated()) {
68 return false;
69 }
70 GrSurface* srcSurface = fSrcProxy->peekSurface();
71 GrSurface* dstSurface = fTarget->peekSurface();
72 if (fSrcProxy->origin() == kBottomLeft_GrSurfaceOrigin) {
73 if (fSrcProxy->height() != srcSurface->height()) {
74 fSrcRect.offset(0, srcSurface->height() - fSrcProxy->height());
75 }
76 if (fTarget->height() != dstSurface->height()) {
77 fDstPoint.fY = fDstPoint.fY + (dstSurface->height() - fTarget->height());
78 }
79 }
80 return flushState->gpu()->copySurface(dstSurface, srcSurface, fSrcRect, fDstPoint);
81}
82