Replace replaceSurfaceDrawContext with replaceBackingProxy

Change-Id: Iba2641f71bdc541d1a55a22c022031949c326c27
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/414444
Commit-Queue: Robert Phillips <robertphillips@google.com>
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
diff --git a/src/gpu/SkBaseGpuDevice.cpp b/src/gpu/SkBaseGpuDevice.cpp
new file mode 100644
index 0000000..35e3fdf
--- /dev/null
+++ b/src/gpu/SkBaseGpuDevice.cpp
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2021 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/SkBaseGpuDevice.h"
+
+#include "include/gpu/GrRecordingContext.h"
+#include "src/gpu/GrProxyProvider.h"
+#include "src/gpu/GrRecordingContextPriv.h"
+
+#define ASSERT_SINGLE_OWNER GR_ASSERT_SINGLE_OWNER(fContext->priv().singleOwner())
+
+bool SkBaseGpuDevice::replaceBackingProxy(SkSurface::ContentChangeMode mode) {
+    ASSERT_SINGLE_OWNER
+
+    const SkImageInfo& ii = this->imageInfo();
+    GrRenderTargetProxy* oldRTP = this->targetProxy();
+    GrSurfaceProxyView oldView = this->readSurfaceView();
+
+    auto grColorType = SkColorTypeToGrColorType(ii.colorType());
+    auto format = fContext->priv().caps()->getDefaultBackendFormat(grColorType, GrRenderable::kYes);
+    if (!format.isValid()) {
+        return false;
+    }
+
+    GrProxyProvider* proxyProvider = fContext->priv().proxyProvider();
+    // This entry point is used by SkSurface_Gpu::onCopyOnWrite so it must create a
+    // kExact-backed render target proxy
+    sk_sp<GrTextureProxy> proxy = proxyProvider->createProxy(format,
+                                                             ii.dimensions(),
+                                                             GrRenderable::kYes,
+                                                             oldRTP->numSamples(),
+                                                             oldView.mipmapped(),
+                                                             SkBackingFit::kExact,
+                                                             oldRTP->isBudgeted(),
+                                                             GrProtected::kNo);
+    if (!proxy) {
+        return false;
+    }
+
+    return this->replaceBackingProxy(mode, sk_ref_sp(proxy->asRenderTargetProxy()),
+                                     grColorType, ii.refColorSpace(), oldView.origin(),
+                                     this->surfaceProps());
+}
diff --git a/src/gpu/SkBaseGpuDevice.h b/src/gpu/SkBaseGpuDevice.h
index f4ef10c..50dc66a 100644
--- a/src/gpu/SkBaseGpuDevice.h
+++ b/src/gpu/SkBaseGpuDevice.h
@@ -53,6 +53,14 @@
                       const GrBackendSemaphore* waitSemaphores,
                       bool deleteSemaphoresAfterWait) = 0;
 
+    virtual bool replaceBackingProxy(SkSurface::ContentChangeMode,
+                                     sk_sp<GrRenderTargetProxy>,
+                                     GrColorType,
+                                     sk_sp<SkColorSpace>,
+                                     GrSurfaceOrigin,
+                                     const SkSurfaceProps&) = 0;
+    bool replaceBackingProxy(SkSurface::ContentChangeMode);
+
 protected:
     sk_sp<GrRecordingContext> fContext;
 
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index b56d07f..06a2112 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -236,47 +236,6 @@
     fSurfaceDrawContext->clearAtLeast(rect, SK_PMColor4fTRANSPARENT);
 }
 
-void SkGpuDevice::replaceSurfaceDrawContext(std::unique_ptr<GrSurfaceDrawContext> sdc,
-                                            SkSurface::ContentChangeMode mode) {
-    SkASSERT(sdc->dimensions() == fSurfaceDrawContext->dimensions());
-    SkASSERT(sdc->numSamples() == fSurfaceDrawContext->numSamples());
-    SkASSERT(sdc->asSurfaceProxy()->priv().isExact());
-    if (mode == SkSurface::kRetain_ContentChangeMode) {
-        if (this->recordingContext()->abandoned()) {
-            return;
-        }
-
-        SkASSERT(fSurfaceDrawContext->asTextureProxy());
-        SkAssertResult(sdc->blitTexture(fSurfaceDrawContext->readSurfaceView(),
-                                        SkIRect::MakeWH(this->width(), this->height()),
-                                        SkIPoint::Make(0, 0)));
-    }
-
-    fSurfaceDrawContext = std::move(sdc);
-}
-
-void SkGpuDevice::replaceSurfaceDrawContext(SkSurface::ContentChangeMode mode) {
-    ASSERT_SINGLE_OWNER
-
-    SkBudgeted budgeted = fSurfaceDrawContext->isBudgeted();
-
-    // This entry point is used by SkSurface_Gpu::onCopyOnWrite so it must create a
-    // kExact-backed surface draw context
-    auto newSDC = MakeSurfaceDrawContext(this->recordingContext(),
-                                         budgeted,
-                                         this->imageInfo(),
-                                         SkBackingFit::kExact,
-                                         fSurfaceDrawContext->numSamples(),
-                                         fSurfaceDrawContext->mipmapped(),
-                                         GrProtected::kNo,
-                                         fSurfaceDrawContext->origin(),
-                                         this->surfaceProps());
-    if (!newSDC) {
-        return;
-    }
-    this->replaceSurfaceDrawContext(std::move(newSDC), mode);
-}
-
 ///////////////////////////////////////////////////////////////////////////////
 
 #if !defined(SK_DISABLE_NEW_GR_CLIP_STACK)
@@ -1005,6 +964,36 @@
                                                  deleteSemaphoresAfterWait);
 }
 
+bool SkGpuDevice::replaceBackingProxy(SkSurface::ContentChangeMode mode,
+                                      sk_sp<GrRenderTargetProxy> newRTP,
+                                      GrColorType grColorType,
+                                      sk_sp<SkColorSpace> colorSpace,
+                                      GrSurfaceOrigin origin,
+                                      const SkSurfaceProps& props) {
+    auto sdc = GrSurfaceDrawContext::Make(fContext.get(), grColorType, std::move(newRTP),
+                                          std::move(colorSpace), origin, props);
+    if (!sdc) {
+        return false;
+    }
+
+    SkASSERT(sdc->dimensions() == fSurfaceDrawContext->dimensions());
+    SkASSERT(sdc->numSamples() == fSurfaceDrawContext->numSamples());
+    SkASSERT(sdc->asSurfaceProxy()->priv().isExact());
+    if (mode == SkSurface::kRetain_ContentChangeMode) {
+        if (fContext->abandoned()) {
+            return false;
+        }
+
+        SkASSERT(fSurfaceDrawContext->asTextureProxy());
+        SkAssertResult(sdc->blitTexture(fSurfaceDrawContext->readSurfaceView(),
+                                        SkIRect::MakeWH(this->width(), this->height()),
+                                        SkIPoint::Make(0, 0)));
+    }
+
+    fSurfaceDrawContext = std::move(sdc);
+    return true;
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 
 SkBaseDevice* SkGpuDevice::onCreateDevice(const CreateInfo& cinfo, const SkPaint*) {
diff --git a/src/gpu/SkGpuDevice.h b/src/gpu/SkGpuDevice.h
index 57cdc3b..6f791a7 100644
--- a/src/gpu/SkGpuDevice.h
+++ b/src/gpu/SkGpuDevice.h
@@ -42,6 +42,14 @@
               const GrBackendSemaphore* waitSemaphores,
               bool deleteSemaphoresAfterWait) override;
 
+    bool replaceBackingProxy(SkSurface::ContentChangeMode,
+                             sk_sp<GrRenderTargetProxy>,
+                             GrColorType,
+                             sk_sp<SkColorSpace>,
+                             GrSurfaceOrigin,
+                             const SkSurfaceProps&) override;
+    using SkBaseGpuDevice::replaceBackingProxy;
+
     /**
      * This factory uses the color space, origin, surface properties, and initialization
      * method along with the provided proxy to create the gpu device.
@@ -79,10 +87,6 @@
     // set all pixels to 0
     void clearAll();
 
-    void replaceSurfaceDrawContext(SkSurface::ContentChangeMode mode);
-    void replaceSurfaceDrawContext(std::unique_ptr<GrSurfaceDrawContext>,
-                                   SkSurface::ContentChangeMode mode);
-
     void drawPaint(const SkPaint& paint) override;
     void drawPoints(SkCanvas::PointMode mode, size_t count, const SkPoint[],
                     const SkPaint& paint) override;
diff --git a/src/gpu/SkGpuDevice_nga.h b/src/gpu/SkGpuDevice_nga.h
index 06ee726..8d1636d 100644
--- a/src/gpu/SkGpuDevice_nga.h
+++ b/src/gpu/SkGpuDevice_nga.h
@@ -25,7 +25,16 @@
 
     bool wait(int numSemaphores,
               const GrBackendSemaphore* waitSemaphores,
-              bool deleteSemaphoresAfterWait) {
+              bool deleteSemaphoresAfterWait) override {
+        return false;
+    }
+
+    bool replaceBackingProxy(SkSurface::ContentChangeMode,
+                             sk_sp<GrRenderTargetProxy>,
+                             GrColorType,
+                             sk_sp<SkColorSpace>,
+                             GrSurfaceOrigin,
+                             const SkSurfaceProps&) override {
         return false;
     }
 
diff --git a/src/image/SkSurface_Gpu.cpp b/src/image/SkSurface_Gpu.cpp
index 02bd364..e45b573 100644
--- a/src/image/SkSurface_Gpu.cpp
+++ b/src/image/SkSurface_Gpu.cpp
@@ -206,7 +206,7 @@
     SkASSERT(image);
 
     if (static_cast<SkImage_Gpu*>(image.get())->surfaceMustCopyOnWrite(readSurfaceView.proxy())) {
-        fDevice->replaceSurfaceDrawContext(mode);
+        fDevice->replaceBackingProxy(mode);
     } else if (kDiscard_ContentChangeMode == mode) {
         this->SkSurface_Gpu::onDiscard();
     }
@@ -533,8 +533,8 @@
                                             ReleaseContext releaseContext) {
     auto releaseHelper = GrRefCntedCallback::Make(releaseProc, releaseContext);
 
-    auto context = this->fDevice->recordingContext();
-    if (context->abandoned()) {
+    auto rContext = fDevice->recordingContext();
+    if (rContext->abandoned()) {
         return false;
     }
     if (!backendTexture.isValid()) {
@@ -543,8 +543,8 @@
     if (backendTexture.width() != this->width() || backendTexture.height() != this->height()) {
         return false;
     }
-    auto* oldSDC = fDevice->surfaceDrawContext();
-    auto oldProxy = sk_ref_sp(oldSDC->asTextureProxy());
+    auto* oldRTP = fDevice->targetProxy();
+    auto oldProxy = sk_ref_sp(oldRTP->asTextureProxy());
     if (!oldProxy) {
         return false;
     }
@@ -564,19 +564,23 @@
     SkASSERT(oldTexture->asRenderTarget());
     int sampleCnt = oldTexture->asRenderTarget()->numSamples();
     GrColorType grColorType = SkColorTypeToGrColorType(this->getCanvas()->imageInfo().colorType());
-    auto colorSpace = sk_ref_sp(oldSDC->colorInfo().colorSpace());
-    if (!validate_backend_texture(context->priv().caps(), backendTexture,
+    if (!validate_backend_texture(rContext->priv().caps(), backendTexture,
                                   sampleCnt, grColorType, true)) {
         return false;
     }
-    auto sdc = GrSurfaceDrawContext::MakeFromBackendTexture(
-            context, oldSDC->colorInfo().colorType(), std::move(colorSpace), backendTexture,
-            sampleCnt, origin, this->props(), std::move(releaseHelper));
-    if (!sdc) {
+
+    sk_sp<SkColorSpace> colorSpace = fDevice->imageInfo().refColorSpace();
+
+    SkASSERT(sampleCnt > 0);
+    sk_sp<GrTextureProxy> proxy(rContext->priv().proxyProvider()->wrapRenderableBackendTexture(
+            backendTexture, sampleCnt, kBorrow_GrWrapOwnership, GrWrapCacheable::kNo,
+            std::move(releaseHelper)));
+    if (!proxy) {
         return false;
     }
-    fDevice->replaceSurfaceDrawContext(std::move(sdc), mode);
-    return true;
+
+    return fDevice->replaceBackingProxy(mode, sk_ref_sp(proxy->asRenderTargetProxy()), grColorType,
+                                        std::move(colorSpace), origin, this->props());
 }
 
 bool validate_backend_render_target(const GrCaps* caps, const GrBackendRenderTarget& rt,