Move CopyOps to CopyRenderTask.
This also means copies are no longer part of OpList or GpuCommandBuffer.
Change-Id: I234de2c93ca13e069d7e4423a3c8b292be2eb500
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/235831
Commit-Queue: Greg Daniel <egdaniel@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/GrCopyRenderTask.cpp b/src/gpu/GrCopyRenderTask.cpp
new file mode 100644
index 0000000..6c41370
--- /dev/null
+++ b/src/gpu/GrCopyRenderTask.cpp
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "src/gpu/GrCopyRenderTask.h"
+
+#include "src/gpu/GrGpu.h"
+#include "src/gpu/GrOpFlushState.h"
+#include "src/gpu/GrResourceAllocator.h"
+
+sk_sp<GrRenderTask> GrCopyRenderTask::Make(sk_sp<GrSurfaceProxy> srcProxy,
+ const SkIRect& srcRect,
+ sk_sp<GrSurfaceProxy> dstProxy,
+ const SkIPoint& dstPoint) {
+ SkASSERT(dstProxy);
+ SkASSERT(srcProxy);
+ SkIRect clippedSrcRect;
+ SkIPoint clippedDstPoint;
+ // If the rect is outside the srcProxy or dstProxy then we've already succeeded.
+ if (!GrClipSrcRectAndDstPoint(dstProxy->isize(), srcProxy->isize(), srcRect, dstPoint,
+ &clippedSrcRect, &clippedDstPoint)) {
+ return nullptr;
+ }
+ if (GrPixelConfigIsCompressed(dstProxy->config())) {
+ return nullptr;
+ }
+
+ SkASSERT(dstProxy->origin() == srcProxy->origin());
+ if (srcProxy->origin() == kBottomLeft_GrSurfaceOrigin) {
+ int rectHeight = clippedSrcRect.height();
+ clippedSrcRect.fTop = srcProxy->height() - clippedSrcRect.fBottom;
+ clippedSrcRect.fBottom = clippedSrcRect.fTop + rectHeight;
+ clippedDstPoint.fY = dstProxy->height() - clippedDstPoint.fY - rectHeight;
+ }
+
+ sk_sp<GrCopyRenderTask> task(new GrCopyRenderTask(
+ std::move(srcProxy), clippedSrcRect, std::move(dstProxy), clippedDstPoint));
+ return task;
+}
+
+GrCopyRenderTask::GrCopyRenderTask(sk_sp<GrSurfaceProxy> srcProxy,
+ const SkIRect& srcRect,
+ sk_sp<GrSurfaceProxy> dstProxy,
+ const SkIPoint& dstPoint)
+ : GrRenderTask(std::move(dstProxy))
+ , fSrcProxy(std::move(srcProxy))
+ , fSrcRect(srcRect)
+ , fDstPoint(dstPoint) {
+ fTarget->setLastRenderTask(this);
+}
+
+void GrCopyRenderTask::gatherProxyIntervals(GrResourceAllocator* alloc) const {
+ // This renderTask doesn't have "normal" ops. In this case we still need to add an interval (so
+ // fEndOfOpListOpIndices will remain in sync), so we create a fake op# to capture the fact that
+ // we read fSrcProxy and copy to fTarget.
+ alloc->addInterval(fSrcProxy.get(), alloc->curOp(), alloc->curOp(),
+ GrResourceAllocator::ActualUse::kYes);
+ alloc->addInterval(fTarget.get(), alloc->curOp(), alloc->curOp(),
+ GrResourceAllocator::ActualUse::kYes);
+ alloc->incOps();
+}
+
+bool GrCopyRenderTask::onExecute(GrOpFlushState* flushState) {
+ if (!fSrcProxy->isInstantiated() || !fTarget->isInstantiated()) {
+ return false;
+ }
+ GrSurface* srcSurface = fSrcProxy->peekSurface();
+ GrSurface* dstSurface = fTarget->peekSurface();
+ if (fSrcProxy->origin() == kBottomLeft_GrSurfaceOrigin) {
+ if (fSrcProxy->height() != srcSurface->height()) {
+ fSrcRect.offset(0, srcSurface->height() - fSrcProxy->height());
+ }
+ if (fTarget->height() != dstSurface->height()) {
+ fDstPoint.fY = fDstPoint.fY + (dstSurface->height() - fTarget->height());
+ }
+ }
+ return flushState->gpu()->copySurface(dstSurface, srcSurface, fSrcRect, fDstPoint);
+}
+