Retract GrSurfaceDrawContext when creating SkGpuDevices

This adds a new SkGpuDevice factory function that absorbs the
creation of the GrSurfaceDrawContext and updates a second factory
function to handle more cases.

Change-Id: If7bd33aa18d1ed5dd72288e7b4db3b97302640cf
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/410077
Commit-Queue: Robert Phillips <robertphillips@google.com>
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
diff --git a/src/core/SkDeferredDisplayListRecorder.cpp b/src/core/SkDeferredDisplayListRecorder.cpp
index e22dad7..a1dd373 100644
--- a/src/core/SkDeferredDisplayListRecorder.cpp
+++ b/src/core/SkDeferredDisplayListRecorder.cpp
@@ -86,7 +86,6 @@
     }
 }
 
-
 bool SkDeferredDisplayListRecorder::init() {
     SkASSERT(fContext);
     SkASSERT(!fTargetProxy);
@@ -185,14 +184,13 @@
     }
     fTargetProxy->priv().setIsDDLTarget();
 
-    auto sdc = GrSurfaceDrawContext::Make(fContext.get(),
-                                          grColorType,
-                                          fCharacterization.refColorSpace(),
-                                          fTargetProxy,
-                                          fCharacterization.origin(),
-                                          fCharacterization.surfaceProps());
-
-    auto device = SkGpuDevice::Make(std::move(sdc), SkGpuDevice::kUninit_InitContents);
+    auto device = SkGpuDevice::Make(fContext.get(),
+                                    grColorType,
+                                    fCharacterization.refColorSpace(),
+                                    fTargetProxy,
+                                    fCharacterization.origin(),
+                                    fCharacterization.surfaceProps(),
+                                    SkBaseGpuDevice::kUninit_InitContents);
     if (!device) {
         return false;
     }
diff --git a/src/core/SkSpecialSurface.cpp b/src/core/SkSpecialSurface.cpp
index 571b4ba..0fcacfb 100644
--- a/src/core/SkSpecialSurface.cpp
+++ b/src/core/SkSpecialSurface.cpp
@@ -128,7 +128,7 @@
             : INHERITED(subset, surfaceDrawContext->surfaceProps())
             , fReadView(surfaceDrawContext->readSurfaceView()) {
         auto device = SkGpuDevice::Make(std::move(surfaceDrawContext),
-                                        SkGpuDevice::kUninit_InitContents);
+                                        SkBaseGpuDevice::kUninit_InitContents);
         if (!device) {
             return;
         }
diff --git a/src/gpu/GrSurfaceDrawContext.cpp b/src/gpu/GrSurfaceDrawContext.cpp
index 323e5e6..f4f362e 100644
--- a/src/gpu/GrSurfaceDrawContext.cpp
+++ b/src/gpu/GrSurfaceDrawContext.cpp
@@ -247,24 +247,6 @@
                                       origin, surfaceProps);
 }
 
-std::unique_ptr<GrSurfaceDrawContext> GrSurfaceDrawContext::MakeFromBackendRenderTarget(
-        GrRecordingContext* context,
-        GrColorType colorType,
-        sk_sp<SkColorSpace> colorSpace,
-        const GrBackendRenderTarget& rt,
-        GrSurfaceOrigin origin,
-        const SkSurfaceProps& surfaceProps,
-        sk_sp<GrRefCntedCallback> releaseHelper) {
-    sk_sp<GrSurfaceProxy> proxy(
-            context->priv().proxyProvider()->wrapBackendRenderTarget(rt, std::move(releaseHelper)));
-    if (!proxy) {
-        return nullptr;
-    }
-
-    return GrSurfaceDrawContext::Make(context, colorType, std::move(colorSpace), std::move(proxy),
-                                      origin, surfaceProps);
-}
-
 std::unique_ptr<GrSurfaceDrawContext> GrSurfaceDrawContext::MakeFromVulkanSecondaryCB(
         GrRecordingContext* context,
         const SkImageInfo& imageInfo,
diff --git a/src/gpu/GrSurfaceDrawContext.h b/src/gpu/GrSurfaceDrawContext.h
index 2b9dc83..65cac64 100644
--- a/src/gpu/GrSurfaceDrawContext.h
+++ b/src/gpu/GrSurfaceDrawContext.h
@@ -123,15 +123,6 @@
             int sampleCnt, GrSurfaceOrigin, const SkSurfaceProps&,
             sk_sp<GrRefCntedCallback> releaseHelper);
 
-    static std::unique_ptr<GrSurfaceDrawContext> MakeFromBackendRenderTarget(
-            GrRecordingContext*,
-            GrColorType,
-            sk_sp<SkColorSpace>,
-            const GrBackendRenderTarget&,
-            GrSurfaceOrigin,
-            const SkSurfaceProps&,
-            sk_sp<GrRefCntedCallback> releaseHelper);
-
     static std::unique_ptr<GrSurfaceDrawContext> MakeFromVulkanSecondaryCB(
             GrRecordingContext*, const SkImageInfo&, const GrVkDrawableInfo&,
             const SkSurfaceProps&);
diff --git a/src/gpu/SkBaseGpuDevice.h b/src/gpu/SkBaseGpuDevice.h
index bb1ea1a..b97da0d 100644
--- a/src/gpu/SkBaseGpuDevice.h
+++ b/src/gpu/SkBaseGpuDevice.h
@@ -30,6 +30,11 @@
 
 class SkBaseGpuDevice : public BASE_DEVICE {
 public:
+    enum InitContents {
+        kClear_InitContents,
+        kUninit_InitContents
+    };
+
     SkBaseGpuDevice(const SkImageInfo& ii, const SkSurfaceProps& props)
         : INHERITED(ii, props) {
     }
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 058f733..7a21434 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -72,6 +72,26 @@
     return true;
 }
 
+sk_sp<SkGpuDevice> SkGpuDevice::Make(GrRecordingContext* rContext,
+                                     GrColorType colorType,
+                                     sk_sp<SkColorSpace> colorSpace,
+                                     sk_sp<GrSurfaceProxy> proxy,
+                                     GrSurfaceOrigin origin,
+                                     const SkSurfaceProps& surfaceProps,
+                                     InitContents init) {
+    auto sdc = GrSurfaceDrawContext::Make(rContext,
+                                          colorType,
+                                          std::move(colorSpace),
+                                          std::move(proxy),
+                                          origin,
+                                          surfaceProps);
+    if (!sdc) {
+        return nullptr;
+    }
+
+    return SkGpuDevice::Make(std::move(sdc), init);
+}
+
 sk_sp<SkGpuDevice> SkGpuDevice::Make(std::unique_ptr<GrSurfaceDrawContext> surfaceDrawContext,
                                      InitContents init) {
     if (!surfaceDrawContext) {
@@ -93,23 +113,24 @@
     return sk_sp<SkGpuDevice>(new SkGpuDevice(std::move(surfaceDrawContext), flags));
 }
 
-sk_sp<SkGpuDevice> SkGpuDevice::Make(GrRecordingContext* context, SkBudgeted budgeted,
+sk_sp<SkGpuDevice> SkGpuDevice::Make(GrRecordingContext* rContext, SkBudgeted budgeted,
                                      const SkImageInfo& info, int sampleCount,
                                      GrSurfaceOrigin origin, const SkSurfaceProps* props,
-                                     GrMipmapped mipMapped, InitContents init) {
+                                     GrMipmapped mipMapped, GrProtected isProtected,
+                                     InitContents init) {
     unsigned flags;
-    if (!context->colorTypeSupportedAsSurface(info.colorType()) ||
+    if (!rContext->colorTypeSupportedAsSurface(info.colorType()) ||
         !CheckAlphaTypeAndGetFlags(&info, init, &flags)) {
         return nullptr;
     }
 
-    auto surfaceDrawContext =
-            MakeSurfaceDrawContext(context, budgeted, info, sampleCount, origin, props, mipMapped);
-    if (!surfaceDrawContext) {
+    auto sdc = MakeSurfaceDrawContext(rContext, budgeted, info, sampleCount, origin,
+                                      props, mipMapped, isProtected);
+    if (!sdc) {
         return nullptr;
     }
 
-    return sk_sp<SkGpuDevice>(new SkGpuDevice(std::move(surfaceDrawContext), flags));
+    return sk_sp<SkGpuDevice>(new SkGpuDevice(std::move(sdc), flags));
 }
 
 static SkImageInfo make_info(GrSurfaceDrawContext* context, bool opaque) {
@@ -144,23 +165,24 @@
 }
 
 std::unique_ptr<GrSurfaceDrawContext> SkGpuDevice::MakeSurfaceDrawContext(
-        GrRecordingContext* context,
+        GrRecordingContext* rContext,
         SkBudgeted budgeted,
         const SkImageInfo& origInfo,
         int sampleCount,
         GrSurfaceOrigin origin,
         const SkSurfaceProps* surfaceProps,
-        GrMipmapped mipmapped) {
-    if (!context) {
+        GrMipmapped mipmapped,
+        GrProtected isProtected) {
+    if (!rContext) {
         return nullptr;
     }
 
     // This method is used to create SkGpuDevice's for SkSurface_Gpus. In this case
     // they need to be exact.
     return GrSurfaceDrawContext::Make(
-            context, SkColorTypeToGrColorType(origInfo.colorType()), origInfo.refColorSpace(),
+            rContext, SkColorTypeToGrColorType(origInfo.colorType()), origInfo.refColorSpace(),
             SkBackingFit::kExact, origInfo.dimensions(), SkSurfacePropsCopyOrDefault(surfaceProps),
-            sampleCount, mipmapped, GrProtected::kNo, origin, budgeted);
+            sampleCount, mipmapped, isProtected, origin, budgeted);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -244,7 +266,8 @@
                                          fSurfaceDrawContext->numSamples(),
                                          fSurfaceDrawContext->origin(),
                                          &this->surfaceProps(),
-                                         fSurfaceDrawContext->mipmapped());
+                                         fSurfaceDrawContext->mipmapped(),
+                                         GrProtected::kNo);
     if (!newSDC) {
         return;
     }
diff --git a/src/gpu/SkGpuDevice.h b/src/gpu/SkGpuDevice.h
index 6d0baf1..e23185e 100644
--- a/src/gpu/SkGpuDevice.h
+++ b/src/gpu/SkGpuDevice.h
@@ -38,10 +38,17 @@
         return this->surfaceDrawContext()->readSurfaceView();
     }
 
-    enum InitContents {
-        kClear_InitContents,
-        kUninit_InitContents
-    };
+    /**
+     * This factory uses the origin, surface properties, color space and initialization
+     * method along with the provided proxy to create the gpu device.
+     */
+    static sk_sp<SkGpuDevice> Make(GrRecordingContext*,
+                                   GrColorType,
+                                   sk_sp<SkColorSpace>,
+                                   sk_sp<GrSurfaceProxy>,
+                                   GrSurfaceOrigin,
+                                   const SkSurfaceProps&,
+                                   InitContents);
 
     /**
      * Creates an SkGpuDevice from a GrSurfaceDrawContext whose backing width/height is
@@ -50,16 +57,20 @@
     static sk_sp<SkGpuDevice> Make(std::unique_ptr<GrSurfaceDrawContext>, InitContents);
 
     /**
-     * New device that will create an offscreen renderTarget based on the ImageInfo and
-     * sampleCount. The mipMapped flag tells the gpu to create the underlying render target with
-     * mips. The Budgeted param controls whether the device's backing store counts against the
-     * resource cache budget. On failure, returns nullptr.
-     * This entry point creates a kExact backing store. It is used when creating SkGpuDevices
-     * for SkSurfaces.
+     * This factory uses the budgeted, imageInfo, sampleCount, mipmapped, and isProtected
+     * parameters to create and exact-fit proxy to back the gpu device. The origin, surface
+     * properties, color space (from the image info) and initialization method are then used
+     * (with the created proxy) to create the device.
      */
-    static sk_sp<SkGpuDevice> Make(GrRecordingContext*, SkBudgeted, const SkImageInfo&,
-                                   int sampleCount, GrSurfaceOrigin, const SkSurfaceProps*,
-                                   GrMipmapped mipMapped, InitContents);
+    static sk_sp<SkGpuDevice> Make(GrRecordingContext*,
+                                   SkBudgeted,
+                                   const SkImageInfo&,
+                                   int sampleCount,
+                                   GrSurfaceOrigin,
+                                   const SkSurfaceProps*,
+                                   GrMipmapped,
+                                   GrProtected,
+                                   InitContents);
 
     ~SkGpuDevice() override {}
 
@@ -209,7 +220,8 @@
                                                                         int sampleCount,
                                                                         GrSurfaceOrigin,
                                                                         const SkSurfaceProps*,
-                                                                        GrMipmapped);
+                                                                        GrMipmapped,
+                                                                        GrProtected);
 
     friend class SkSurface_Gpu;      // for access to surfaceProps
     using INHERITED = SkBaseGpuDevice;
diff --git a/src/gpu/vk/GrVkSecondaryCBDrawContext.cpp b/src/gpu/vk/GrVkSecondaryCBDrawContext.cpp
index 7684cc3..d36b6a6 100644
--- a/src/gpu/vk/GrVkSecondaryCBDrawContext.cpp
+++ b/src/gpu/vk/GrVkSecondaryCBDrawContext.cpp
@@ -35,7 +35,7 @@
                                                                SkSurfacePropsCopyOrDefault(props));
     SkASSERT(rtc->asSurfaceProxy()->isInstantiated());
 
-    auto device = SkGpuDevice::Make(std::move(rtc), SkGpuDevice::kUninit_InitContents);
+    auto device = SkGpuDevice::Make(std::move(rtc), SkBaseGpuDevice::kUninit_InitContents);
     if (!device) {
         return nullptr;
     }
diff --git a/src/image/SkSurface_Gpu.cpp b/src/image/SkSurface_Gpu.cpp
index 156807b..808facf 100644
--- a/src/image/SkSurface_Gpu.cpp
+++ b/src/image/SkSurface_Gpu.cpp
@@ -19,6 +19,7 @@
 #include "src/gpu/GrCaps.h"
 #include "src/gpu/GrContextThreadSafeProxyPriv.h"
 #include "src/gpu/GrDirectContextPriv.h"
+#include "src/gpu/GrProxyProvider.h"
 #include "src/gpu/GrRecordingContextPriv.h"
 #include "src/gpu/GrRenderTarget.h"
 #include "src/gpu/GrTexture.h"
@@ -412,17 +413,9 @@
         return nullptr;
     }
 
-    GrColorType grColorType = SkColorTypeToGrColorType(c.colorType());
-
-    auto sdc = GrSurfaceDrawContext::Make(
-            rContext, grColorType, c.refColorSpace(), SkBackingFit::kExact,
-            c.dimensions(), c.surfaceProps(), c.sampleCount(), GrMipmapped(c.isMipMapped()),
-            c.isProtected(), c.origin(), budgeted);
-    if (!sdc) {
-        return nullptr;
-    }
-
-    auto device = SkGpuDevice::Make(std::move(sdc), SkGpuDevice::kClear_InitContents);
+    auto device = SkGpuDevice::Make(rContext, budgeted, c.imageInfo(), c.sampleCount(),
+                                    c.origin(), &c.surfaceProps(), GrMipmapped(c.isMipMapped()),
+                                    c.isProtected(), SkBaseGpuDevice::kClear_InitContents);
     if (!device) {
         return nullptr;
     }
@@ -478,18 +471,19 @@
         mipMapped = GrMipmapped::kNo;
     }
 
-    sk_sp<SkGpuDevice> device(SkGpuDevice::Make(
-            rContext, budgeted, info, sampleCount, origin, props, mipMapped,
-            SkGpuDevice::kClear_InitContents));
+    sk_sp<SkGpuDevice> device(SkGpuDevice::Make(rContext, budgeted, info, sampleCount, origin,
+                                                props, mipMapped, GrProtected::kNo,
+                                                SkBaseGpuDevice::kClear_InitContents));
     if (!device) {
         return nullptr;
     }
     return sk_make_sp<SkSurface_Gpu>(std::move(device));
 }
 
-sk_sp<SkSurface> SkSurface::MakeFromBackendTexture(GrRecordingContext* context,
+sk_sp<SkSurface> SkSurface::MakeFromBackendTexture(GrRecordingContext* rContext,
                                                    const GrBackendTexture& tex,
-                                                   GrSurfaceOrigin origin, int sampleCnt,
+                                                   GrSurfaceOrigin origin,
+                                                   int sampleCnt,
                                                    SkColorType colorType,
                                                    sk_sp<SkColorSpace> colorSpace,
                                                    const SkSurfaceProps* props,
@@ -497,32 +491,35 @@
                                                    SkSurface::ReleaseContext releaseContext) {
     auto releaseHelper = GrRefCntedCallback::Make(textureReleaseProc, releaseContext);
 
-    if (!context) {
+    if (!rContext) {
         return nullptr;
     }
     sampleCnt = std::max(1, sampleCnt);
 
-    GrColorType grColorType = SkColorTypeAndFormatToGrColorType(context->priv().caps(), colorType,
+    GrColorType grColorType = SkColorTypeAndFormatToGrColorType(rContext->priv().caps(), colorType,
                                                                 tex.getBackendFormat());
     if (grColorType == GrColorType::kUnknown) {
         return nullptr;
     }
 
-    if (!validate_backend_texture(context->priv().caps(), tex, sampleCnt, grColorType, true)) {
+    if (!validate_backend_texture(rContext->priv().caps(), tex, sampleCnt, grColorType, true)) {
         return nullptr;
     }
 
-    auto sdc = GrSurfaceDrawContext::MakeFromBackendTexture(
-            context, grColorType, std::move(colorSpace), tex, sampleCnt, origin,
-            SkSurfacePropsCopyOrDefault(props), std::move(releaseHelper));
-    if (!sdc) {
+    sk_sp<GrTextureProxy> proxy(rContext->priv().proxyProvider()->wrapRenderableBackendTexture(
+            tex, sampleCnt, kBorrow_GrWrapOwnership, GrWrapCacheable::kNo,
+            std::move(releaseHelper)));
+    if (!proxy) {
         return nullptr;
     }
 
-    auto device = SkGpuDevice::Make(std::move(sdc), SkGpuDevice::kUninit_InitContents);
+    auto device = SkGpuDevice::Make(rContext, grColorType, std::move(colorSpace),
+                                    std::move(proxy), origin, SkSurfacePropsCopyOrDefault(props),
+                                    SkBaseGpuDevice::kUninit_InitContents);
     if (!device) {
         return nullptr;
     }
+
     return sk_make_sp<SkSurface_Gpu>(std::move(device));
 }
 
@@ -622,18 +619,15 @@
         return nullptr;
     }
 
-    auto sdc = GrSurfaceDrawContext::MakeFromBackendRenderTarget(context,
-                                                                 grColorType,
-                                                                 std::move(colorSpace),
-                                                                 rt,
-                                                                 origin,
-                                                                 SkSurfacePropsCopyOrDefault(props),
-                                                                 std::move(releaseHelper));
-    if (!sdc) {
+    sk_sp<GrSurfaceProxy> proxy(
+            context->priv().proxyProvider()->wrapBackendRenderTarget(rt, std::move(releaseHelper)));
+    if (!proxy) {
         return nullptr;
     }
 
-    auto device = SkGpuDevice::Make(std::move(sdc), SkGpuDevice::kUninit_InitContents);
+    auto device = SkGpuDevice::Make(context, grColorType, std::move(colorSpace), std::move(proxy),
+                                    origin, SkSurfacePropsCopyOrDefault(props),
+                                    SkBaseGpuDevice::kUninit_InitContents);
     if (!device) {
         return nullptr;
     }
diff --git a/src/image/SkSurface_GpuMtl.mm b/src/image/SkSurface_GpuMtl.mm
index 48aa35b..48b27b6 100644
--- a/src/image/SkSurface_GpuMtl.mm
+++ b/src/image/SkSurface_GpuMtl.mm
@@ -84,14 +84,13 @@
             false,
             GrSurfaceProxy::UseAllocator::kYes);
 
-    auto sdc = GrSurfaceDrawContext::Make(rContext,
-                                          grColorType,
-                                          std::move(colorSpace),
-                                          std::move(proxy),
-                                          origin,
-                                          SkSurfacePropsCopyOrDefault(surfaceProps));
-
-    auto device = SkGpuDevice::Make(std::move(sdc), SkGpuDevice::kUninit_InitContents);
+    auto device = SkGpuDevice::Make(rContext,
+                                    grColorType,
+                                    std::move(colorSpace),
+                                    std::move(proxy),
+                                    origin,
+                                    SkSurfacePropsCopyOrDefault(surfaceProps),
+                                    SkBaseGpuDevice::kUninit_InitContents);
     if (!device) {
         return nullptr;
     }
@@ -154,14 +153,13 @@
             false,
             GrSurfaceProxy::UseAllocator::kYes);
 
-    auto sdc = GrSurfaceDrawContext::Make(rContext,
-                                          grColorType,
-                                          std::move(colorSpace),
-                                          std::move(proxy),
-                                          origin,
-                                          SkSurfacePropsCopyOrDefault(surfaceProps));
-
-    auto device = SkGpuDevice::Make(std::move(sdc), SkGpuDevice::kUninit_InitContents);
+    auto device = SkGpuDevice::Make(rContext,
+                                    grColorType,
+                                    std::move(colorSpace),
+                                    std::move(proxy),
+                                    origin,
+                                    SkSurfacePropsCopyOrDefault(surfaceProps),
+                                    SkBaseGpuDevice::kUninit_InitContents);
     if (!device) {
         return nullptr;
     }
diff --git a/tests/DeviceTest.cpp b/tests/DeviceTest.cpp
index 0557ff6..9dccbc8 100644
--- a/tests/DeviceTest.cpp
+++ b/tests/DeviceTest.cpp
@@ -86,8 +86,8 @@
 
     sk_sp<SkBaseDevice> gpuDev(SkGpuDevice::Make(context, SkBudgeted::kNo, ii,
                                                  1, kBottomLeft_GrSurfaceOrigin, nullptr,
-                                                 GrMipmapped::kNo,
-                                                 SkGpuDevice::kClear_InitContents));
+                                                 GrMipmapped::kNo, GrProtected::kNo,
+                                                 SkBaseGpuDevice::kClear_InitContents));
 
     SkBitmap bm;
     SkAssertResult(bm.tryAllocN32Pixels(kWidth, kHeight));