Feed all top-level GPU accessors through skgpu::BaseDevice

This pulls the GPU-specific accessors off of SkCanvas and SkDevice - moving them all to skgpu::BaseDevice and SkCanvasPriv.

This will allow us to more easily change the gpu class hierarchy (esp. changing GrSurfaceDrawContext to skgpu::v1:SurfaceDrawContext) w/o churning the public API.

Bug: skia:11837
Change-Id: I4e205255706680ac58ffe40f714884c2ee7ac799
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/431036
Reviewed-by: Brian Osman <brianosman@google.com>
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/BUILD.gn b/BUILD.gn
index b8c1632..aeb46b46 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -2000,6 +2000,9 @@
   import("gn/bench.gni")
   test_lib("bench") {
     sources = bench_sources
+    if (!skia_enable_skgpu_v1) {
+      sources -= skgpu_v1_bench_sources
+    }
     deps = [
       ":flags",
       ":gm",
diff --git a/gn/bench.gni b/gn/bench.gni
index 3546bfc..9207ded 100644
--- a/gn/bench.gni
+++ b/gn/bench.gni
@@ -20,11 +20,9 @@
   "$_bench/BlurImageFilterBench.cpp",
   "$_bench/BlurRectBench.cpp",
   "$_bench/BlurRectsBench.cpp",
-  "$_bench/BulkRectBench.cpp",
   "$_bench/ChartBench.cpp",
   "$_bench/ChecksumBench.cpp",
   "$_bench/ChromeBench.cpp",
-  "$_bench/ClearBench.cpp",
   "$_bench/ClipMaskBench.cpp",
   "$_bench/ClipStrategyBench.cpp",
   "$_bench/CmapBench.cpp",
@@ -129,3 +127,10 @@
   "$_bench/WritePixelsBench.cpp",
   "$_bench/WriterBench.cpp",
 ]
+
+skgpu_v1_bench_sources = [
+  "$_bench/BulkRectBench.cpp",
+  "$_bench/ClearBench.cpp",
+]
+
+bench_sources += skgpu_v1_bench_sources
diff --git a/gn/gm.gni b/gn/gm.gni
index 14d8e7f..3c36037 100644
--- a/gn/gm.gni
+++ b/gn/gm.gni
@@ -307,7 +307,6 @@
   "$_gm/roundrects.cpp",
   "$_gm/rrect.cpp",
   "$_gm/rrectclipdrawpaint.cpp",
-  "$_gm/rrects.cpp",
   "$_gm/rsxtext.cpp",
   "$_gm/runtimecolorfilter.cpp",
   "$_gm/runtimeeffectimage.cpp",
@@ -415,6 +414,7 @@
   "$_gm/gpu_blur_utils.cpp",
   "$_gm/lazytiling.cpp",
   "$_gm/preservefillrule.cpp",
+  "$_gm/rrects.cpp",
   "$_gm/tessellation.cpp",
   "$_gm/texelsubset.cpp",
   "$_gm/widebuttcaps.cpp",
diff --git a/gn/tests.gni b/gn/tests.gni
index f5e7797..b1c5c5c 100644
--- a/gn/tests.gni
+++ b/gn/tests.gni
@@ -26,7 +26,6 @@
   "$_tests/BlendTest.cpp",
   "$_tests/BlitMaskClip.cpp",
   "$_tests/BlurTest.cpp",
-  "$_tests/BulkRectTest.cpp",
   "$_tests/CTest.cpp",
   "$_tests/CachedDataTest.cpp",
   "$_tests/CachedDecodingPixelRefTest.cpp",
@@ -117,7 +116,6 @@
   "$_tests/GrTBlockListTest.cpp",
   "$_tests/GrTextBlobTest.cpp",
   "$_tests/GrTextureMipMapInvalidationTest.cpp",
-  "$_tests/GrThreadSafeCacheTest.cpp",
   "$_tests/GrVxTest.cpp",
   "$_tests/GradientTest.cpp",
   "$_tests/HSVRoundTripTest.cpp",
@@ -404,9 +402,11 @@
 ]
 
 skgpu_v1_tests_sources = [
+  "$_tests/BulkRectTest.cpp",
   "$_tests/GrClipStackTest.cpp",
   "$_tests/GrMeshTest.cpp",
   "$_tests/GrPipelineDynamicStateTest.cpp",
+  "$_tests/GrThreadSafeCacheTest.cpp",
   "$_tests/OpChainTest.cpp",
   "$_tests/PathRendererCacheTests.cpp",
   "$_tests/ProgramsTest.cpp",
diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h
index 157889f..1a3d8e0 100644
--- a/include/core/SkCanvas.h
+++ b/include/core/SkCanvas.h
@@ -39,7 +39,6 @@
 
 class GrBackendRenderTarget;
 class GrRecordingContext;
-class GrSurfaceDrawContext;
 class SkBaseDevice;
 class SkBitmap;
 class SkData;
@@ -63,13 +62,6 @@
 class SkTextBlob;
 class SkVertices;
 
-// This declaration must match the one in SkDeferredDisplayList.h
-#if SK_SUPPORT_GPU
-class GrRenderTargetProxy;
-#else
-using GrRenderTargetProxy = SkRefCnt;
-#endif
-
 /** \class SkCanvas
     SkCanvas provides an interface for drawing, and how the drawing is clipped and transformed.
     SkCanvas contains a stack of SkMatrix and clip values.
@@ -2294,8 +2286,6 @@
     // The top-most device in the stack, will change within saveLayer()'s. All drawing and clipping
     // operations should route to this device.
     SkBaseDevice* topDevice() const;
-    virtual GrSurfaceDrawContext* topDeviceSurfaceDrawContext();
-    virtual GrRenderTargetProxy* topDeviceTargetProxy();
 
     class MCRec;
 
diff --git a/include/utils/SkPaintFilterCanvas.h b/include/utils/SkPaintFilterCanvas.h
index f9a0383..43b7291 100644
--- a/include/utils/SkPaintFilterCanvas.h
+++ b/include/utils/SkPaintFilterCanvas.h
@@ -97,8 +97,6 @@
 
     SkCanvas* proxy() const { SkASSERT(fList.count() == 1); return fList[0]; }
 
-    GrSurfaceDrawContext* topDeviceSurfaceDrawContext() override;
-    GrRenderTargetProxy* topDeviceTargetProxy() override;
     SkPaintFilterCanvas* internal_private_asPaintFilterCanvas() const override {
         return const_cast<SkPaintFilterCanvas*>(this);
     }
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 61bbead..50efaa8 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -53,6 +53,7 @@
 
 #if SK_SUPPORT_GPU
 #include "include/gpu/GrDirectContext.h"
+#include "src/gpu/BaseDevice.h"
 #include "src/gpu/SkGr.h"
 #if defined(SK_BUILD_FOR_ANDROID_FRAMEWORK)
 #   include "src/gpu/GrRenderTarget.h"
@@ -558,14 +559,6 @@
     return fMCRec->fDevice;
 }
 
-GrSurfaceDrawContext* SkCanvas::topDeviceSurfaceDrawContext() {
-    return this->topDevice()->surfaceDrawContext();
-}
-
-GrRenderTargetProxy* SkCanvas::topDeviceTargetProxy() {
-    return this->topDevice()->targetProxy();
-}
-
 bool SkCanvas::readPixels(const SkPixmap& pm, int x, int y) {
     return pm.addr() && this->baseDevice()->readPixels(pm, x, y);
 }
@@ -1671,7 +1664,13 @@
 #endif
 
 GrRecordingContext* SkCanvas::recordingContext() {
-    return this->topDevice()->recordingContext();
+#if SK_SUPPORT_GPU
+    if (auto gpuDevice = this->topDevice()->asGpuDevice()) {
+        return gpuDevice->recordingContext();
+    }
+#endif
+
+    return nullptr;
 }
 
 void SkCanvas::drawDRRect(const SkRRect& outer, const SkRRect& inner,
diff --git a/src/core/SkCanvasPriv.cpp b/src/core/SkCanvasPriv.cpp
index 888e06c..09398d7 100644
--- a/src/core/SkCanvasPriv.cpp
+++ b/src/core/SkCanvasPriv.cpp
@@ -118,26 +118,44 @@
     return true;
 }
 
+#if GR_TEST_UTILS
+
 #if SK_SUPPORT_GPU
-#include "src/gpu/GrSurfaceDrawContext.h"
+#include "src/gpu/BaseDevice.h"
 
+#if SK_GPU_V1
 GrSurfaceDrawContext* SkCanvasPriv::TopDeviceSurfaceDrawContext(SkCanvas* canvas) {
-    return canvas->topDeviceSurfaceDrawContext();
+    if (auto gpuDevice = canvas->topDevice()->asGpuDevice()) {
+        return gpuDevice->surfaceDrawContext();
+    }
+
+    return nullptr;
 }
+#endif // SK_GPU_V1
 
 GrSurfaceFillContext* SkCanvasPriv::TopDeviceSurfaceFillContext(SkCanvas* canvas) {
-    return canvas->topDeviceSurfaceDrawContext();
+    if (auto gpuDevice = canvas->topDevice()->asGpuDevice()) {
+        return gpuDevice->surfaceFillContext();
+    }
+
+    return nullptr;
 }
 
 GrRenderTargetProxy* SkCanvasPriv::TopDeviceTargetProxy(SkCanvas* canvas) {
-    return canvas->topDeviceTargetProxy();
+    if (auto gpuDevice = canvas->topDevice()->asGpuDevice()) {
+        return gpuDevice->targetProxy();
+    }
+
+    return nullptr;
 }
 
-#else
+#else // SK_SUPPORT_GPU
 
+#if SK_GPU_V1
 GrSurfaceDrawContext* SkCanvasPriv::TopDeviceSurfaceDrawContext(SkCanvas* canvas) {
     return nullptr;
 }
+#endif // SK_GPU_V1
 
 GrSurfaceFillContext* SkCanvasPriv::TopDeviceSurfaceFillContext(SkCanvas* canvas) {
     return nullptr;
@@ -147,4 +165,6 @@
     return nullptr;
 }
 
-#endif
+#endif // SK_SUPPORT_GPU
+
+#endif // GR_TEST_UTILS
diff --git a/src/core/SkCanvasPriv.h b/src/core/SkCanvasPriv.h
index 35158ec..34cb065 100644
--- a/src/core/SkCanvasPriv.h
+++ b/src/core/SkCanvasPriv.h
@@ -14,8 +14,16 @@
 class SkReadBuffer;
 class SkWriteBuffer;
 
+#if GR_TEST_UTILS
+// This declaration must match the one in SkDeferredDisplayList.h
+#if SK_SUPPORT_GPU
+class GrRenderTargetProxy;
+#else
+using GrRenderTargetProxy = SkRefCnt;
+#endif
 class GrSurfaceDrawContext;
 class GrSurfaceFillContext;
+#endif // GR_TEST_UTILS
 
 class SkAutoCanvasMatrixPaint : SkNoncopyable {
 public:
@@ -50,9 +58,13 @@
         canvas->androidFramework_replaceClip(rect);
     }
 
+#if GR_TEST_UTILS
+#if SK_GPU_V1
     static GrSurfaceDrawContext* TopDeviceSurfaceDrawContext(SkCanvas*);
+#endif
     static GrSurfaceFillContext* TopDeviceSurfaceFillContext(SkCanvas*);
     static GrRenderTargetProxy* TopDeviceTargetProxy(SkCanvas*);
+#endif // GR_TEST_UTILS
 
     // The experimental_DrawEdgeAAImageSet API accepts separate dstClips and preViewMatrices arrays,
     // where entries refer into them, but no explicit size is provided. Given a set of entries,
diff --git a/src/core/SkDevice.h b/src/core/SkDevice.h
index 9c99e19..b00a485 100644
--- a/src/core/SkDevice.h
+++ b/src/core/SkDevice.h
@@ -31,9 +31,8 @@
 class SkRasterHandleAllocator;
 class SkSpecialImage;
 
-namespace skif {
-    class Mapping;
-} // namespace skif
+namespace skif { class Mapping; }
+namespace skgpu { class BaseDevice; }
 
 class SkBaseDevice : public SkRefCnt, public SkMatrixProvider {
 public:
@@ -198,9 +197,7 @@
 
     virtual bool android_utils_clipWithStencil() { return false; }
 
-    virtual GrRecordingContext* recordingContext() const { return nullptr; }
-    virtual GrSurfaceDrawContext* surfaceDrawContext() { return nullptr; }
-    virtual GrRenderTargetProxy* targetProxy() { return nullptr; }
+    virtual skgpu::BaseDevice* asGpuDevice() { return nullptr; }
 
     // Ensure that non-RSXForm runs are passed to onDrawGlyphRunList.
     void drawGlyphRunList(const SkGlyphRunList& glyphRunList, const SkPaint& paint);
diff --git a/src/gpu/BaseDevice.cpp b/src/gpu/BaseDevice.cpp
index 4da8e99..efeea35 100644
--- a/src/gpu/BaseDevice.cpp
+++ b/src/gpu/BaseDevice.cpp
@@ -16,6 +16,13 @@
 
 namespace skgpu {
 
+BaseDevice::BaseDevice(sk_sp<GrRecordingContext> rContext,
+                       const SkImageInfo& ii,
+                       const SkSurfaceProps& props)
+    : INHERITED(ii, props)
+    , fContext(std::move(rContext)) {
+}
+
 GrRenderTargetProxy* BaseDevice::targetProxy() {
     return this->readSurfaceView().asRenderTargetProxy();
 }
diff --git a/src/gpu/BaseDevice.h b/src/gpu/BaseDevice.h
index fbd28c5..1427921 100644
--- a/src/gpu/BaseDevice.h
+++ b/src/gpu/BaseDevice.h
@@ -11,6 +11,9 @@
 #include "include/core/SkImage.h"
 #include "include/private/GrTypesPriv.h"
 
+class GrRenderTargetProxy;
+class GrSurfaceDrawContext;
+class GrSurfaceFillContext;
 class GrSurfaceProxyView;
 
 // NOTE: when not defined, SkGpuDevice extends SkBaseDevice directly and manages its clip stack
@@ -40,17 +43,20 @@
         kUninit_InitContents
     };
 
-    BaseDevice(sk_sp<GrRecordingContext> rContext,
-               const SkImageInfo& ii,
-               const SkSurfaceProps& props)
-        : INHERITED(ii, props)
-        , fContext(std::move(rContext)) {
-    }
+    BaseDevice(sk_sp<GrRecordingContext>, const SkImageInfo&, const SkSurfaceProps&);
 
     virtual GrSurfaceProxyView readSurfaceView() = 0;
-    GrRenderTargetProxy* targetProxy() override;
 
-    GrRecordingContext* recordingContext() const override { return fContext.get(); }
+    BaseDevice* asGpuDevice() override { return this; }
+
+#if SK_GPU_V1
+    // TODO: make this return a skgpu::v1:SurfaceDrawContext
+    virtual GrSurfaceDrawContext* surfaceDrawContext() { return nullptr; }
+#endif
+
+    virtual GrSurfaceFillContext* surfaceFillContext() = 0;
+    GrRenderTargetProxy* targetProxy();
+    GrRecordingContext* recordingContext() const { return fContext.get(); }
 
     virtual bool wait(int numSemaphores,
                       const GrBackendSemaphore* waitSemaphores,
diff --git a/src/gpu/v1/Device.cpp b/src/gpu/v1/Device.cpp
index b7af9cd..05e23fb 100644
--- a/src/gpu/v1/Device.cpp
+++ b/src/gpu/v1/Device.cpp
@@ -291,6 +291,11 @@
     return fSurfaceDrawContext.get();
 }
 
+GrSurfaceFillContext* Device::surfaceFillContext() {
+    ASSERT_SINGLE_OWNER
+    return fSurfaceDrawContext.get();
+}
+
 void Device::clearAll() {
     ASSERT_SINGLE_OWNER
     GR_CREATE_TRACE_MARKER_CONTEXT("skgpu::v1::Device", "clearAll", fContext.get());
diff --git a/src/gpu/v1/Device_v1.h b/src/gpu/v1/Device_v1.h
index 203307a..5c7fd1e 100644
--- a/src/gpu/v1/Device_v1.h
+++ b/src/gpu/v1/Device_v1.h
@@ -106,6 +106,7 @@
 
     GrSurfaceDrawContext* surfaceDrawContext() override;
     const GrSurfaceDrawContext* surfaceDrawContext() const;
+    GrSurfaceFillContext* surfaceFillContext() override;
 
     // set all pixels to 0
     void clearAll();
diff --git a/src/gpu/v2/Device.cpp b/src/gpu/v2/Device.cpp
index d9bedfc..bb1f365 100644
--- a/src/gpu/v2/Device.cpp
+++ b/src/gpu/v2/Device.cpp
@@ -26,6 +26,10 @@
 
 GrSurfaceProxyView Device::readSurfaceView() { return {}; }
 
+GrSurfaceFillContext* Device::surfaceFillContext() {
+    return nullptr;
+}
+
 void Device::asyncRescaleAndReadPixels(const SkImageInfo& info,
                                        const SkIRect& srcRect,
                                        RescaleGamma rescaleGamma,
diff --git a/src/gpu/v2/Device_v2.h b/src/gpu/v2/Device_v2.h
index b4431f4..f3f1a6e 100644
--- a/src/gpu/v2/Device_v2.h
+++ b/src/gpu/v2/Device_v2.h
@@ -44,6 +44,8 @@
 
     GrSurfaceProxyView readSurfaceView() override;
 
+    GrSurfaceFillContext* surfaceFillContext() override;
+
     bool wait(int numSemaphores,
               const GrBackendSemaphore* waitSemaphores,
               bool deleteSemaphoresAfterWait) override {
@@ -77,8 +79,6 @@
                                          ReadPixelsCallback,
                                          ReadPixelsContext) override;
 
-    GrSurfaceDrawContext* surfaceDrawContext() override { return nullptr; }
-
 protected:
     void onSave() override;
     void onRestore() override;
diff --git a/src/utils/SkPaintFilterCanvas.cpp b/src/utils/SkPaintFilterCanvas.cpp
index 156c4e6..982c2e3 100644
--- a/src/utils/SkPaintFilterCanvas.cpp
+++ b/src/utils/SkPaintFilterCanvas.cpp
@@ -279,11 +279,3 @@
 bool SkPaintFilterCanvas::onGetProps(SkSurfaceProps* props) const {
     return this->proxy()->getProps(props);
 }
-
-GrSurfaceDrawContext* SkPaintFilterCanvas::topDeviceSurfaceDrawContext() {
-    return SkCanvasPriv::TopDeviceSurfaceDrawContext(this->proxy());
-}
-
-GrRenderTargetProxy* SkPaintFilterCanvas::topDeviceTargetProxy() {
-    return SkCanvasPriv::TopDeviceTargetProxy(this->proxy());
-}
diff --git a/tests/SurfaceTest.cpp b/tests/SurfaceTest.cpp
index 67a1577..aafce04 100644
--- a/tests/SurfaceTest.cpp
+++ b/tests/SurfaceTest.cpp
@@ -755,7 +755,8 @@
 
 static void test_surface_context_clear(skiatest::Reporter* reporter,
                                        GrDirectContext* dContext,
-                                       GrSurfaceContext* surfaceContext, uint32_t expectedValue) {
+                                       GrSurfaceContext* surfaceContext,
+                                       uint32_t expectedValue) {
     int w = surfaceContext->width();
     int h = surfaceContext->height();
 
@@ -803,12 +804,12 @@
             ERRORF(reporter, "Could not create GPU SkSurface.");
             return;
         }
-        auto sdc = SkCanvasPriv::TopDeviceSurfaceDrawContext(surface->getCanvas());
-        if (!sdc) {
+        auto sfc = SkCanvasPriv::TopDeviceSurfaceFillContext(surface->getCanvas());
+        if (!sfc) {
             ERRORF(reporter, "Could access surface context of GPU SkSurface.");
             return;
         }
-        test_surface_context_clear(reporter, dContext, sdc, 0x0);
+        test_surface_context_clear(reporter, dContext, sfc, 0x0);
         auto imageSurfaceCtx = makeImageSurfaceContext(surface.get());
         test_surface_context_clear(reporter, dContext, imageSurfaceCtx.get(), 0x0);
     }
@@ -822,12 +823,12 @@
             ERRORF(reporter, "Could not create GPU SkSurface.");
             return;
         }
-        auto sdc = SkCanvasPriv::TopDeviceSurfaceDrawContext(surface->getCanvas());
-        if (!sdc) {
+        auto sfc = SkCanvasPriv::TopDeviceSurfaceFillContext(surface->getCanvas());
+        if (!sfc) {
             ERRORF(reporter, "Could access surface context of GPU SkSurface.");
             return;
         }
-        test_surface_context_clear(reporter, dContext, sdc, kOrigColor.toSkColor());
+        test_surface_context_clear(reporter, dContext, sfc, kOrigColor.toSkColor());
         auto imageSurfaceCtx = makeImageSurfaceContext(surface.get());
         test_surface_context_clear(reporter, dContext, imageSurfaceCtx.get(),
                                    kOrigColor.toSkColor());