Start fleshing out skgpu::v2 Device and SurfaceDrawContext

Bug: skia:11837
Change-Id: I42ad29e3b5765a81ef9366ebdf1e95739cd90b78
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/445297
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/BaseDevice.cpp b/src/gpu/BaseDevice.cpp
index 8b01c2c..5253162 100644
--- a/src/gpu/BaseDevice.cpp
+++ b/src/gpu/BaseDevice.cpp
@@ -11,6 +11,7 @@
 #include "src/gpu/GrProxyProvider.h"
 #include "src/gpu/GrRecordingContextPriv.h"
 #include "src/gpu/GrSurfaceProxyView.h"
+#include "src/gpu/SurfaceContext.h"
 
 #define ASSERT_SINGLE_OWNER GR_ASSERT_SINGLE_OWNER(fContext->priv().singleOwner())
 
@@ -44,6 +45,14 @@
     return true;
 }
 
+SkImageInfo BaseDevice::MakeInfo(SurfaceContext* sc, DeviceFlags flags) {
+    SkColorType colorType = GrColorTypeToSkColorType(sc->colorInfo().colorType());
+    return SkImageInfo::Make(sc->width(), sc->height(), colorType,
+                             flags & DeviceFlags::kIsOpaque ? kOpaque_SkAlphaType
+                                                            : kPremul_SkAlphaType,
+                             sc->colorInfo().refColorSpace());
+}
+
 GrRenderTargetProxy* BaseDevice::targetProxy() {
     return this->readSurfaceView().asRenderTargetProxy();
 }
diff --git a/src/gpu/BaseDevice.h b/src/gpu/BaseDevice.h
index 0a7cbf4..c8f8a73 100644
--- a/src/gpu/BaseDevice.h
+++ b/src/gpu/BaseDevice.h
@@ -17,6 +17,7 @@
 
 namespace skgpu {
 
+class SurfaceContext;
 class SurfaceFillContext;
 #if SK_GPU_V1
 namespace v1 { class SurfaceDrawContext; }
@@ -87,6 +88,7 @@
     GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(DeviceFlags);
 
     static bool CheckAlphaTypeAndGetFlags(SkAlphaType, InitContents, DeviceFlags*);
+    static SkImageInfo MakeInfo(SurfaceContext*,  DeviceFlags);
 
     sk_sp<GrRecordingContext> fContext;
 
diff --git a/src/gpu/v1/Device.cpp b/src/gpu/v1/Device.cpp
index 9628226..e84e83f 100644
--- a/src/gpu/v1/Device.cpp
+++ b/src/gpu/v1/Device.cpp
@@ -54,13 +54,6 @@
 
 namespace {
 
-SkImageInfo make_info(skgpu::v1::SurfaceDrawContext* sdc, bool opaque) {
-    SkColorType colorType = GrColorTypeToSkColorType(sdc->colorInfo().colorType());
-    return SkImageInfo::Make(sdc->width(), sdc->height(), colorType,
-                             opaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType,
-                             sdc->colorInfo().refColorSpace());
-}
-
 bool force_aa_clip(const skgpu::v1::SurfaceDrawContext* sdc) {
     return sdc->numSamples() > 1 || sdc->alwaysAntialias();
 }
@@ -172,22 +165,28 @@
                                GrSurfaceOrigin origin,
                                const SkSurfaceProps& props,
                                InitContents init) {
-    auto sdc = MakeSurfaceDrawContext(rContext,
-                                      budgeted,
-                                      ii,
-                                      fit,
-                                      sampleCount,
-                                      mipMapped,
-                                      isProtected,
-                                      origin,
-                                      props);
+    if (!rContext) {
+        return nullptr;
+    }
+
+    auto sdc = SurfaceDrawContext::Make(rContext,
+                                        SkColorTypeToGrColorType(ii.colorType()),
+                                        ii.refColorSpace(),
+                                        fit,
+                                        ii.dimensions(),
+                                        props,
+                                        sampleCount,
+                                        mipMapped,
+                                        isProtected,
+                                        origin,
+                                        budgeted);
 
     return Device::Make(std::move(sdc), ii.alphaType(), init);
 }
 
 Device::Device(std::unique_ptr<SurfaceDrawContext> sdc, DeviceFlags flags)
         : INHERITED(sk_ref_sp(sdc->recordingContext()),
-                    make_info(sdc.get(), SkToBool(flags & DeviceFlags::kIsOpaque)),
+                    MakeInfo(sdc.get(), flags),
                     sdc->surfaceProps())
         , fSurfaceDrawContext(std::move(sdc))
         , fClip(SkIRect::MakeSize(fSurfaceDrawContext->dimensions()),
@@ -198,28 +197,6 @@
     }
 }
 
-std::unique_ptr<SurfaceDrawContext> Device::MakeSurfaceDrawContext(
-        GrRecordingContext* rContext,
-        SkBudgeted budgeted,
-        const SkImageInfo& origInfo,
-        SkBackingFit fit,
-        int sampleCount,
-        GrMipmapped mipmapped,
-        GrProtected isProtected,
-        GrSurfaceOrigin origin,
-        const SkSurfaceProps& surfaceProps) {
-    if (!rContext) {
-        return nullptr;
-    }
-
-    // This method is used to create SkGpuDevice's for SkSurface_Gpus. In this case
-    // they need to be exact.
-    return SurfaceDrawContext::Make(
-            rContext, SkColorTypeToGrColorType(origInfo.colorType()), origInfo.refColorSpace(),
-            fit, origInfo.dimensions(), surfaceProps,
-            sampleCount, mipmapped, isProtected, origin, budgeted);
-}
-
 ///////////////////////////////////////////////////////////////////////////////
 
 bool Device::onReadPixels(const SkPixmap& pm, int x, int y) {
diff --git a/src/gpu/v1/Device_v1.h b/src/gpu/v1/Device_v1.h
index 0a15c4d..e513a20 100644
--- a/src/gpu/v1/Device_v1.h
+++ b/src/gpu/v1/Device_v1.h
@@ -219,16 +219,6 @@
                          SkFilterMode,
                          const SkPaint&);
 
-    static std::unique_ptr<SurfaceDrawContext> MakeSurfaceDrawContext(GrRecordingContext*,
-                                                                      SkBudgeted,
-                                                                      const SkImageInfo&,
-                                                                      SkBackingFit,
-                                                                      int sampleCount,
-                                                                      GrMipmapped,
-                                                                      GrProtected,
-                                                                      GrSurfaceOrigin,
-                                                                      const SkSurfaceProps&);
-
     friend class ::SkSurface_Gpu;      // for access to surfaceProps
     using INHERITED = BaseDevice;
 };
diff --git a/src/gpu/v1/SurfaceDrawContext.cpp b/src/gpu/v1/SurfaceDrawContext.cpp
index 559df32..9be7eee 100644
--- a/src/gpu/v1/SurfaceDrawContext.cpp
+++ b/src/gpu/v1/SurfaceDrawContext.cpp
@@ -213,6 +213,10 @@
         GrProtected isProtected,
         GrSurfaceOrigin origin,
         SkBudgeted budgeted) {
+    if (!rContext) {
+        return nullptr;
+    }
+
     auto format = rContext->priv().caps()->getDefaultBackendFormat(colorType, GrRenderable::kYes);
     if (!format.isValid()) {
         return nullptr;
diff --git a/src/gpu/v1/SurfaceDrawContext_v1.h b/src/gpu/v1/SurfaceDrawContext_v1.h
index ec84fb7..a3cc0f8 100644
--- a/src/gpu/v1/SurfaceDrawContext_v1.h
+++ b/src/gpu/v1/SurfaceDrawContext_v1.h
@@ -60,7 +60,7 @@
 /**
  * A helper object to orchestrate commands (draws, etc...) for GrSurfaces that are GrRenderTargets.
  */
-class SurfaceDrawContext : public SurfaceFillContext {
+class SurfaceDrawContext final : public SurfaceFillContext {
 public:
     static std::unique_ptr<SurfaceDrawContext> Make(GrRecordingContext*,
                                                     GrColorType,
@@ -715,7 +715,6 @@
     bool fPreserveOpsOnFullClear_TestingOnly = false;
 #endif
     SkGlyphRunListPainter fGlyphPainter;
-    using INHERITED = SurfaceFillContext;
 };
 
 } // namespace skgpu::v1
diff --git a/src/gpu/v2/Device.cpp b/src/gpu/v2/Device.cpp
index b8ff373..fb880dd 100644
--- a/src/gpu/v2/Device.cpp
+++ b/src/gpu/v2/Device.cpp
@@ -11,19 +11,99 @@
 #include "src/core/SkImageFilterCache.h"
 #include "src/gpu/GrRecordingContextPriv.h"
 #include "src/gpu/GrTracing.h"
+#include "src/gpu/v2/SurfaceDrawContext_v2.h"
 
 #define ASSERT_SINGLE_OWNER GR_ASSERT_SINGLE_OWNER(fContext->priv().singleOwner())
 
 namespace skgpu::v2 {
 
-Device::Device(sk_sp<GrRecordingContext> rContext,
-               const SkImageInfo& ii,
-               const SkSurfaceProps& props)
-    : INHERITED(std::move(rContext), ii, props) {
+sk_sp<BaseDevice> Device::Make(std::unique_ptr<SurfaceDrawContext> sdc,
+                               SkAlphaType alphaType,
+                               InitContents init) {
+    if (!sdc) {
+        return nullptr;
+    }
+
+    GrRecordingContext* rContext = sdc->recordingContext();
+    if (rContext->abandoned()) {
+        return nullptr;
+    }
+
+    SkColorType ct = GrColorTypeToSkColorType(sdc->colorInfo().colorType());
+
+    DeviceFlags flags;
+    if (!rContext->colorTypeSupportedAsSurface(ct) ||
+        !CheckAlphaTypeAndGetFlags(alphaType, init, &flags)) {
+        return nullptr;
+    }
+    return sk_sp<Device>(new Device(std::move(sdc), flags));
+}
+
+sk_sp<BaseDevice> Device::Make(GrRecordingContext* rContext,
+                               GrColorType colorType,
+                               sk_sp<GrSurfaceProxy> proxy,
+                               sk_sp<SkColorSpace> colorSpace,
+                               GrSurfaceOrigin origin,
+                               const SkSurfaceProps& surfaceProps,
+                               InitContents init) {
+    if (!rContext || rContext->abandoned()) {
+        return nullptr;
+    }
+
+    std::unique_ptr<SurfaceDrawContext> sdc = SurfaceDrawContext::Make(rContext,
+                                                                       colorType,
+                                                                       std::move(proxy),
+                                                                       std::move(colorSpace),
+                                                                       origin,
+                                                                       surfaceProps);
+
+    return Device::Make(std::move(sdc), kPremul_SkAlphaType, init);
+}
+
+sk_sp<BaseDevice> Device::Make(GrRecordingContext* rContext,
+                               SkBudgeted budgeted,
+                               const SkImageInfo& ii,
+                               SkBackingFit fit,
+                               int sampleCount,
+                               GrMipmapped mipMapped,
+                               GrProtected isProtected,
+                               GrSurfaceOrigin origin,
+                               const SkSurfaceProps& surfaceProps,
+                               InitContents init) {
+    if (!rContext || rContext->abandoned()) {
+        return nullptr;
+    }
+
+    auto sdc = SurfaceDrawContext::Make(rContext,
+                                        SkColorTypeToGrColorType(ii.colorType()),
+                                        ii.refColorSpace(),
+                                        fit,
+                                        ii.dimensions(),
+                                        surfaceProps,
+                                        sampleCount,
+                                        mipMapped,
+                                        isProtected,
+                                        origin,
+                                        budgeted);
+
+    return Device::Make(std::move(sdc), ii.alphaType(), init);
+}
+
+Device::Device(std::unique_ptr<SurfaceDrawContext> sdc, DeviceFlags flags)
+        : BaseDevice(sk_ref_sp(sdc->recordingContext()),
+                     MakeInfo(sdc.get(), flags),
+                     sdc->surfaceProps())
+        , fSurfaceDrawContext(std::move(sdc)) {
+    if (flags & DeviceFlags::kNeedClear) {
+        // TODO: re-enable this once we decide what the V2 SDC does with clearAll calls
+//        this->clearAll();
+    }
 }
 
 Device::~Device() {}
 
+skgpu::SurfaceFillContext* Device::surfaceFillContext() { return fSurfaceDrawContext.get(); }
+
 GrSurfaceProxyView Device::readSurfaceView() { return {}; }
 
 void Device::asyncRescaleAndReadPixels(const SkImageInfo& info,
diff --git a/src/gpu/v2/Device_v2.h b/src/gpu/v2/Device_v2.h
index b55474c..82ff88f 100644
--- a/src/gpu/v2/Device_v2.h
+++ b/src/gpu/v2/Device_v2.h
@@ -12,10 +12,12 @@
 
 namespace skgpu::v2 {
 
+class SurfaceDrawContext;
+
 /**
  *  Subclass of BaseDevice, which directs all drawing to the GrGpu owned by the canvas.
  */
-class Device : public BaseDevice  {
+class Device final : public BaseDevice  {
 public:
     static sk_sp<BaseDevice> Make(GrRecordingContext*,
                                   GrColorType,
@@ -23,9 +25,7 @@
                                   sk_sp<SkColorSpace>,
                                   GrSurfaceOrigin,
                                   const SkSurfaceProps&,
-                                  InitContents) {
-        return nullptr;
-    }
+                                  InitContents);
 
     static sk_sp<BaseDevice> Make(GrRecordingContext*,
                                   SkBudgeted,
@@ -36,12 +36,11 @@
                                   GrProtected,
                                   GrSurfaceOrigin,
                                   const SkSurfaceProps&,
-                                  InitContents) {
-        return nullptr;
-    }
+                                  InitContents);
 
     ~Device() override;
 
+    skgpu::SurfaceFillContext* surfaceFillContext() override;
     GrSurfaceProxyView readSurfaceView() override;
 
     bool wait(int numSemaphores,
@@ -139,12 +138,18 @@
     /* isNoPixelsDevice */
 
 private:
-    Device(sk_sp<GrRecordingContext>, const SkImageInfo&, const SkSurfaceProps&);
+    static sk_sp<BaseDevice> Make(std::unique_ptr<SurfaceDrawContext>,
+                                  SkAlphaType,
+                                  InitContents);
+
+    Device(std::unique_ptr<SurfaceDrawContext>, DeviceFlags);
 
     /* replaceBitmapBackendForRasterSurface */
     bool forceConservativeRasterClip() const override;
     SkImageFilterCache* getImageFilterCache() override;
 
+    std::unique_ptr<SurfaceDrawContext> fSurfaceDrawContext;
+
     using INHERITED = BaseDevice;
 };
 
diff --git a/src/gpu/v2/SurfaceDrawContext.cpp b/src/gpu/v2/SurfaceDrawContext.cpp
index 50d5f7d..c91fe6d 100644
--- a/src/gpu/v2/SurfaceDrawContext.cpp
+++ b/src/gpu/v2/SurfaceDrawContext.cpp
@@ -7,20 +7,86 @@
 
 #include "src/gpu/v2/SurfaceDrawContext_v2.h"
 
+#include "src/gpu/GrProxyProvider.h"
+#include "src/gpu/GrRecordingContextPriv.h"
+
 namespace skgpu::v2 {
 
+std::unique_ptr<SurfaceDrawContext> SurfaceDrawContext::Make(GrRecordingContext* rContext,
+                                                             GrColorType colorType,
+                                                             sk_sp<GrSurfaceProxy> proxy,
+                                                             sk_sp<SkColorSpace> colorSpace,
+                                                             GrSurfaceOrigin origin,
+                                                             const SkSurfaceProps& surfaceProps) {
+    if (!rContext || !proxy || colorType == GrColorType::kUnknown) {
+        return nullptr;
+    }
+
+    const GrBackendFormat& format = proxy->backendFormat();
+    GrSwizzle readSwizzle = rContext->priv().caps()->getReadSwizzle(format, colorType);
+    GrSwizzle writeSwizzle = rContext->priv().caps()->getWriteSwizzle(format, colorType);
+
+    GrSurfaceProxyView readView (          proxy,  origin, readSwizzle);
+    GrSurfaceProxyView writeView(std::move(proxy), origin, writeSwizzle);
+
+    return std::make_unique<SurfaceDrawContext>(rContext,
+                                                std::move(readView),
+                                                std::move(writeView),
+                                                colorType,
+                                                std::move(colorSpace),
+                                                surfaceProps);
+}
+
+std::unique_ptr<SurfaceDrawContext> SurfaceDrawContext::Make(GrRecordingContext* rContext,
+                                                             GrColorType colorType,
+                                                             sk_sp<SkColorSpace> colorSpace,
+                                                             SkBackingFit fit,
+                                                             SkISize dimensions,
+                                                             const SkSurfaceProps& surfaceProps,
+                                                             int sampleCnt,
+                                                             GrMipmapped mipMapped,
+                                                             GrProtected isProtected,
+                                                             GrSurfaceOrigin origin,
+                                                             SkBudgeted budgeted) {
+    if (!rContext) {
+        return nullptr;
+    }
+
+    auto format = rContext->priv().caps()->getDefaultBackendFormat(colorType, GrRenderable::kYes);
+    if (!format.isValid()) {
+        return nullptr;
+    }
+    sk_sp<GrTextureProxy> proxy = rContext->priv().proxyProvider()->createProxy(format,
+                                                                                dimensions,
+                                                                                GrRenderable::kYes,
+                                                                                sampleCnt,
+                                                                                mipMapped,
+                                                                                fit,
+                                                                                budgeted,
+                                                                                isProtected);
+    if (!proxy) {
+        return nullptr;
+    }
+
+    return SurfaceDrawContext::Make(rContext,
+                                    colorType,
+                                    std::move(proxy),
+                                    std::move(colorSpace),
+                                    origin,
+                                    surfaceProps);
+}
+
 SurfaceDrawContext::SurfaceDrawContext(GrRecordingContext* rContext,
                                        GrSurfaceProxyView readView,
                                        GrSurfaceProxyView writeView,
                                        GrColorType colorType,
                                        sk_sp<SkColorSpace> colorSpace,
-                                       const SkSurfaceProps& surfaceProps,
-                                       bool flushTimeOpsTask)
-    : SurfaceFillContext(rContext,
-                         std::move(readView),
-                         std::move(writeView),
-                         {colorType, kPremul_SkAlphaType, std::move(colorSpace)},
-                         flushTimeOpsTask) {
+                                       const SkSurfaceProps& surfaceProps)
+        : SurfaceFillContext(rContext,
+                             std::move(readView),
+                             std::move(writeView),
+                             {colorType, kPremul_SkAlphaType, std::move(colorSpace)})
+        , fSurfaceProps(surfaceProps) {
 }
 
 } // namespace skgpu::v2
diff --git a/src/gpu/v2/SurfaceDrawContext_v2.h b/src/gpu/v2/SurfaceDrawContext_v2.h
index cb06cdf..67e8c44 100644
--- a/src/gpu/v2/SurfaceDrawContext_v2.h
+++ b/src/gpu/v2/SurfaceDrawContext_v2.h
@@ -12,18 +12,38 @@
 
 namespace skgpu::v2 {
 
-class SurfaceDrawContext : public SurfaceFillContext {
+class SurfaceDrawContext final : public SurfaceFillContext {
+public:
+    static std::unique_ptr<SurfaceDrawContext> Make(GrRecordingContext*,
+                                                    GrColorType,
+                                                    sk_sp<GrSurfaceProxy>,
+                                                    sk_sp<SkColorSpace>,
+                                                    GrSurfaceOrigin,
+                                                    const SkSurfaceProps&);
+
+    static std::unique_ptr<SurfaceDrawContext> Make(GrRecordingContext*,
+                                                    GrColorType,
+                                                    sk_sp<SkColorSpace>,
+                                                    SkBackingFit,
+                                                    SkISize dimensions,
+                                                    const SkSurfaceProps&,
+                                                    int sampleCnt,
+                                                    GrMipmapped,
+                                                    GrProtected,
+                                                    GrSurfaceOrigin,
+                                                    SkBudgeted);
+
+    const SkSurfaceProps& surfaceProps() const { return fSurfaceProps; }
+
 public:
     SurfaceDrawContext(GrRecordingContext*,
                        GrSurfaceProxyView readView,
                        GrSurfaceProxyView writeView,
                        GrColorType,
                        sk_sp<SkColorSpace>,
-                       const SkSurfaceProps&,
-                       bool flushTimeOpsTask = false);
+                       const SkSurfaceProps&);
 
-private:
-    using INHERITED = SurfaceFillContext;
+    const SkSurfaceProps fSurfaceProps;
 };
 
 } // namespace skgpu::v2
diff --git a/src/gpu/v2/SurfaceFillContext_v2.cpp b/src/gpu/v2/SurfaceFillContext_v2.cpp
index a36717a..d5bcf5e 100644
--- a/src/gpu/v2/SurfaceFillContext_v2.cpp
+++ b/src/gpu/v2/SurfaceFillContext_v2.cpp
@@ -12,8 +12,7 @@
 SurfaceFillContext::SurfaceFillContext(GrRecordingContext* rContext,
                                        GrSurfaceProxyView readView,
                                        GrSurfaceProxyView writeView,
-                                       const GrColorInfo& colorInfo,
-                                       bool flushTimeOpsTask)
+                                       const GrColorInfo& colorInfo)
     : skgpu::SurfaceFillContext(rContext,
                                 std::move(readView),
                                 std::move(writeView),
diff --git a/src/gpu/v2/SurfaceFillContext_v2.h b/src/gpu/v2/SurfaceFillContext_v2.h
index 3f5d0f3..db37067 100644
--- a/src/gpu/v2/SurfaceFillContext_v2.h
+++ b/src/gpu/v2/SurfaceFillContext_v2.h
@@ -17,8 +17,7 @@
     SurfaceFillContext(GrRecordingContext*,
                        GrSurfaceProxyView readView,
                        GrSurfaceProxyView writeView,
-                       const GrColorInfo&,
-                       bool flushTimeOpsTask = false);
+                       const GrColorInfo&);
 
     void discard() override;