Make GrCaps and graphite::Caps derive from SkCapabilities

Move allocation of Caps::fShaderCaps to the base class,
and add a finishInitialization method, like GrCaps.

Change-Id: I5353a03afea29390be3cce1fb371374532f5af3c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/541073
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Jim Van Verth <jvanverth@google.com>
diff --git a/include/core/SkCapabilities.h b/include/core/SkCapabilities.h
index 9f8b340..3edd6e2 100644
--- a/include/core/SkCapabilities.h
+++ b/include/core/SkCapabilities.h
@@ -11,21 +11,20 @@
 #include "include/core/SkRefCnt.h"
 #include "include/sksl/SkSLVersion.h"
 
-namespace skgpu::graphite { class Caps; }
+namespace SkSL { struct ShaderCaps; }
 
-class SK_API SkCapabilities : public SkNVRefCnt<SkCapabilities> {
+class SK_API SkCapabilities : public SkRefCnt {
 public:
-    static sk_sp<SkCapabilities> RasterBackend();
+    static sk_sp<const SkCapabilities> RasterBackend();
 
     SkSL::Version skslVersion() const { return fSkSLVersion; }
 
-private:
+protected:
     SkCapabilities() = default;
 
-    SkSL::Version fSkSLVersion = SkSL::Version::k100;
+    void initSkCaps(const SkSL::ShaderCaps*);
 
-    friend class GrCaps;
-    friend class skgpu::graphite::Caps;
+    SkSL::Version fSkSLVersion = SkSL::Version::k100;
 };
 
 #endif
diff --git a/include/core/SkSurface.h b/include/core/SkSurface.h
index 65c0567..f57d81e 100644
--- a/include/core/SkSurface.h
+++ b/include/core/SkSurface.h
@@ -605,7 +605,7 @@
 
         @return  SkCapabilities of SkSurface's device.
     */
-    sk_sp<SkCapabilities> capabilities();
+    sk_sp<const SkCapabilities> capabilities();
 
     /** Returns a compatible SkSurface, or nullptr. Returned SkSurface contains
         the same raster, GPU, or null properties as the original. Returned SkSurface
diff --git a/include/gpu/GrRecordingContext.h b/include/gpu/GrRecordingContext.h
index 8370a47..90de7ed 100644
--- a/include/gpu/GrRecordingContext.h
+++ b/include/gpu/GrRecordingContext.h
@@ -98,7 +98,7 @@
         return INHERITED::maxSurfaceSampleCountForColorType(colorType);
     }
 
-    SK_API sk_sp<SkCapabilities> skCapabilities() const;
+    SK_API sk_sp<const SkCapabilities> skCapabilities() const;
 
     // Provides access to functions that aren't part of the public API.
     GrRecordingContextPriv priv();
diff --git a/src/core/BUILD.bazel b/src/core/BUILD.bazel
index 76f940b..dcdc20a 100644
--- a/src/core/BUILD.bazel
+++ b/src/core/BUILD.bazel
@@ -5782,5 +5782,8 @@
     name = "SkCapabilities_src",
     srcs = ["SkCapabilities.cpp"],
     visibility = ["//:__subpackages__"],
-    deps = ["//include/core:SkCapabilities_hdr"],
+    deps = [
+        "//include/core:SkCapabilities_hdr",
+        "//src/sksl:SkSLUtil_hdr",
+    ],
 )
diff --git a/src/core/SkCapabilities.cpp b/src/core/SkCapabilities.cpp
index 4a329fd..353f93c 100644
--- a/src/core/SkCapabilities.cpp
+++ b/src/core/SkCapabilities.cpp
@@ -6,8 +6,9 @@
  */
 
 #include "include/core/SkCapabilities.h"
+#include "src/sksl/SkSLUtil.h"
 
-sk_sp<SkCapabilities> SkCapabilities::RasterBackend() {
+sk_sp<const SkCapabilities> SkCapabilities::RasterBackend() {
     static SkCapabilities* sCaps = [](){
         SkCapabilities* caps = new SkCapabilities;
         caps->fSkSLVersion = SkSL::Version::k100;
@@ -16,3 +17,7 @@
 
     return sk_ref_sp(sCaps);
 }
+
+void SkCapabilities::initSkCaps(const SkSL::ShaderCaps* shaderCaps) {
+    this->fSkSLVersion = shaderCaps->supportedSkSLVerion();
+}
diff --git a/src/gpu/ganesh/BUILD.bazel b/src/gpu/ganesh/BUILD.bazel
index de8d242..84e8f85 100644
--- a/src/gpu/ganesh/BUILD.bazel
+++ b/src/gpu/ganesh/BUILD.bazel
@@ -765,7 +765,6 @@
         ":GrSurface_hdr",
         ":GrTestUtils_hdr",
         ":GrWindowRectangles_hdr",
-        "//include/core:SkCapabilities_hdr",
         "//include/gpu:GrBackendSurface_hdr",
         "//include/gpu:GrContextOptions_hdr",
         "//include/private/gpu/ganesh:GrTypesPriv_hdr",
diff --git a/src/gpu/ganesh/GrCaps.cpp b/src/gpu/ganesh/GrCaps.cpp
index e27050f..14c3e73 100644
--- a/src/gpu/ganesh/GrCaps.cpp
+++ b/src/gpu/ganesh/GrCaps.cpp
@@ -7,7 +7,6 @@
 
 #include "src/gpu/ganesh/GrCaps.h"
 
-#include "include/core/SkCapabilities.h"
 #include "include/gpu/GrBackendSurface.h"
 #include "include/gpu/GrContextOptions.h"
 #include "include/private/gpu/ganesh/GrTypesPriv.h"
@@ -105,8 +104,7 @@
     fMaxRenderTargetSize = std::min(fMaxRenderTargetSize, fMaxTextureSize);
     fMaxPreferredRenderTargetSize = std::min(fMaxPreferredRenderTargetSize, fMaxRenderTargetSize);
 
-    fSkCaps.reset(new SkCapabilities);
-    fSkCaps->fSkSLVersion = this->shaderCaps()->supportedSkSLVerion();
+    this->initSkCaps(this->shaderCaps());
 }
 
 void GrCaps::applyOptionsOverrides(const GrContextOptions& options) {
@@ -484,8 +482,3 @@
     } while (ct != GrColorType::kUnknown);
     return {GrColorType::kUnknown, {}};
 }
-
-sk_sp<SkCapabilities> GrCaps::asSkCapabilities() const {
-    SkASSERTF(fSkCaps, "Calling asSkCapabilities before it's initialized");
-    return fSkCaps;
-}
diff --git a/src/gpu/ganesh/GrCaps.h b/src/gpu/ganesh/GrCaps.h
index 796cd10..5b1415c 100644
--- a/src/gpu/ganesh/GrCaps.h
+++ b/src/gpu/ganesh/GrCaps.h
@@ -38,11 +38,10 @@
 /**
  * Represents the capabilities of a GrContext.
  */
-class GrCaps : public SkRefCnt {
+class GrCaps : public SkCapabilities {
 public:
     GrCaps(const GrContextOptions&);
 
-    sk_sp<SkCapabilities> asSkCapabilities() const;
     void dumpJSON(SkJSONWriter*) const;
 
     const GrShaderCaps* shaderCaps() const { return fShaderCaps.get(); }
@@ -527,7 +526,6 @@
     virtual bool onSupportsDynamicMSAA(const GrRenderTargetProxy*) const { return false; }
 
     std::unique_ptr<GrShaderCaps> fShaderCaps;
-    sk_sp<SkCapabilities> fSkCaps;
 
     bool fNPOTTextureTileSupport                     : 1;
     bool fMipmapSupport                              : 1;
diff --git a/src/gpu/ganesh/GrRecordingContext.cpp b/src/gpu/ganesh/GrRecordingContext.cpp
index 29c8220..1acaf77 100644
--- a/src/gpu/ganesh/GrRecordingContext.cpp
+++ b/src/gpu/ganesh/GrRecordingContext.cpp
@@ -160,8 +160,8 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
-sk_sp<SkCapabilities> GrRecordingContext::skCapabilities() const {
-    return this->caps()->asSkCapabilities();
+sk_sp<const SkCapabilities> GrRecordingContext::skCapabilities() const {
+    return this->refCaps();
 }
 
 int GrRecordingContext::maxTextureSize() const { return this->caps()->maxTextureSize(); }
diff --git a/src/gpu/graphite/BUILD.bazel b/src/gpu/graphite/BUILD.bazel
index d04920a..c2d3b95 100644
--- a/src/gpu/graphite/BUILD.bazel
+++ b/src/gpu/graphite/BUILD.bazel
@@ -59,7 +59,6 @@
     visibility = ["//:__subpackages__"],
     deps = [
         ":Caps_hdr",
-        "//include/core:SkCapabilities_hdr",
         "//include/gpu/graphite:TextureInfo_hdr",
         "//src/sksl:SkSLUtil_hdr",
     ],
@@ -907,6 +906,7 @@
     srcs = ["RecorderPriv.cpp"],
     visibility = ["//:__subpackages__"],
     deps = [
+        ":Caps_hdr",
         ":Device_hdr",
         ":Gpu_hdr",
         ":RecorderPriv_hdr",
diff --git a/src/gpu/graphite/Caps.cpp b/src/gpu/graphite/Caps.cpp
index e92ca8b..cb54d07 100644
--- a/src/gpu/graphite/Caps.cpp
+++ b/src/gpu/graphite/Caps.cpp
@@ -7,15 +7,18 @@
 
 #include "src/gpu/graphite/Caps.h"
 
-#include "include/core/SkCapabilities.h"
 #include "include/gpu/graphite/TextureInfo.h"
 #include "src/sksl/SkSLUtil.h"
 
 namespace skgpu::graphite {
 
-Caps::Caps() {}
+Caps::Caps() : fShaderCaps(std::make_unique<SkSL::ShaderCaps>()) {}
 Caps::~Caps() {}
 
+void Caps::finishInitialization() {
+    this->initSkCaps(fShaderCaps.get());
+}
+
 bool Caps::isTexturable(const TextureInfo& info) const {
     if (info.numSamples() > 1) {
         return false;
@@ -53,12 +56,4 @@
     return colorTypeInfo->fWriteSwizzle;
 }
 
-sk_sp<SkCapabilities> Caps::asSkCapabilities() const {
-    if (!fSkCaps) {
-        fSkCaps.reset(new SkCapabilities);
-        fSkCaps->fSkSLVersion = this->shaderCaps()->supportedSkSLVerion();
-    }
-    return fSkCaps;
-}
-
 } // namespace skgpu::graphite
diff --git a/src/gpu/graphite/Caps.h b/src/gpu/graphite/Caps.h
index 5cd00a4..f8f6c0a 100644
--- a/src/gpu/graphite/Caps.h
+++ b/src/gpu/graphite/Caps.h
@@ -27,11 +27,10 @@
 struct RenderPassDesc;
 class TextureInfo;
 
-class Caps : public SkRefCnt {
+class Caps : public SkCapabilities {
 public:
     ~Caps() override;
 
-    sk_sp<SkCapabilities> asSkCapabilities() const;
     const SkSL::ShaderCaps* shaderCaps() const { return fShaderCaps.get(); }
 
     virtual TextureInfo getDefaultSampledTextureInfo(SkColorType,
@@ -82,6 +81,10 @@
 protected:
     Caps();
 
+    // Subclasses must call this at the end of their init method in order to do final processing on
+    // the caps.
+    void finishInitialization();
+
     // TODO: This value should be set by some context option. For now just making it 4.
     uint32_t defaultMSAASamples() const { return 4; }
 
@@ -105,7 +108,6 @@
     size_t fRequiredUniformBufferAlignment = 0;
 
     std::unique_ptr<SkSL::ShaderCaps> fShaderCaps;
-    mutable sk_sp<SkCapabilities> fSkCaps;
 
     bool fClampToBorderSupport = true;
 
diff --git a/src/gpu/graphite/RecorderPriv.cpp b/src/gpu/graphite/RecorderPriv.cpp
index 9c26f5a..acd5db4 100644
--- a/src/gpu/graphite/RecorderPriv.cpp
+++ b/src/gpu/graphite/RecorderPriv.cpp
@@ -7,6 +7,7 @@
 
 #include "src/gpu/graphite/RecorderPriv.h"
 
+#include "src/gpu/graphite/Caps.h"
 #include "src/gpu/graphite/Device.h"
 #include "src/gpu/graphite/Gpu.h"
 #include "src/gpu/graphite/TaskGraph.h"
@@ -31,6 +32,10 @@
     return fRecorder->fGpu->caps();
 }
 
+sk_sp<const Caps> RecorderPriv::refCaps() const {
+    return fRecorder->fGpu->refCaps();
+}
+
 DrawBufferManager* RecorderPriv::drawBufferManager() const {
     return fRecorder->fDrawBufferManager.get();
 }
diff --git a/src/gpu/graphite/RecorderPriv.h b/src/gpu/graphite/RecorderPriv.h
index 6b6fc00..f524125 100644
--- a/src/gpu/graphite/RecorderPriv.h
+++ b/src/gpu/graphite/RecorderPriv.h
@@ -22,6 +22,7 @@
     DrawBufferManager* drawBufferManager() const;
     UploadBufferManager* uploadBufferManager() const;
     const Caps* caps() const;
+    sk_sp<const Caps> refCaps() const;
 
     void flushTrackedDevices();
 
diff --git a/src/gpu/graphite/Surface_Graphite.cpp b/src/gpu/graphite/Surface_Graphite.cpp
index 29e4811..696cc4d 100644
--- a/src/gpu/graphite/Surface_Graphite.cpp
+++ b/src/gpu/graphite/Surface_Graphite.cpp
@@ -59,8 +59,8 @@
     return fDevice->readPixels(context, recorder, dst, srcX, srcY);
 }
 
-sk_sp<SkCapabilities> Surface::onCapabilities() {
-    return fDevice->recorder()->priv().caps()->asSkCapabilities();
+sk_sp<const SkCapabilities> Surface::onCapabilities() {
+    return fDevice->recorder()->priv().refCaps();
 }
 
 } // namespace skgpu::graphite
diff --git a/src/gpu/graphite/Surface_Graphite.h b/src/gpu/graphite/Surface_Graphite.h
index ccc87b4..96af04c 100644
--- a/src/gpu/graphite/Surface_Graphite.h
+++ b/src/gpu/graphite/Surface_Graphite.h
@@ -28,7 +28,7 @@
     void onWritePixels(const SkPixmap&, int x, int y) override;
     bool onCopyOnWrite(ContentChangeMode) override;
     bool onReadPixels(Context*, Recorder*, const SkPixmap& dst, int srcX, int srcY);
-    sk_sp<SkCapabilities> onCapabilities() override;
+    sk_sp<const SkCapabilities> onCapabilities() override;
 
 private:
     sk_sp<Device> fDevice;
diff --git a/src/gpu/graphite/mtl/MtlCaps.mm b/src/gpu/graphite/mtl/MtlCaps.mm
index f45227b..3533066 100644
--- a/src/gpu/graphite/mtl/MtlCaps.mm
+++ b/src/gpu/graphite/mtl/MtlCaps.mm
@@ -19,8 +19,6 @@
 
 MtlCaps::MtlCaps(const id<MTLDevice> device)
         : Caps() {
-    fShaderCaps = std::make_unique<SkSL::ShaderCaps>();
-
     this->initGPUFamily(device);
     this->initCaps(device);
     this->initShaderCaps();
@@ -28,6 +26,8 @@
     this->initFormatTable();
 
     // Metal-specific MtlCaps
+
+    this->finishInitialization();
 }
 
 // translates from older MTLFeatureSet interface to MTLGPUFamily interface
diff --git a/src/image/SkSurface.cpp b/src/image/SkSurface.cpp
index dbe1ed0..3ece583 100644
--- a/src/image/SkSurface.cpp
+++ b/src/image/SkSurface.cpp
@@ -160,7 +160,7 @@
     return nextID.fetch_add(1, std::memory_order_relaxed);
 }
 
-sk_sp<SkCapabilities> SkSurface_Base::onCapabilities() {
+sk_sp<const SkCapabilities> SkSurface_Base::onCapabilities() {
     return SkCapabilities::RasterBackend();
 }
 
@@ -210,7 +210,7 @@
     return asSB(this)->getCachedCanvas();
 }
 
-sk_sp<SkCapabilities> SkSurface::capabilities() {
+sk_sp<const SkCapabilities> SkSurface::capabilities() {
     return asSB(this)->onCapabilities();
 }
 
@@ -419,7 +419,7 @@
     void onWritePixels(const SkPixmap&, int x, int y) override {}
     void onDraw(SkCanvas*, SkScalar, SkScalar, const SkSamplingOptions&, const SkPaint*) override {}
     bool onCopyOnWrite(ContentChangeMode) override { return true; }
-    sk_sp<SkCapabilities> onCapabilities() override {
+    sk_sp<const SkCapabilities> onCapabilities() override {
         // Not really, but we have to return *something*
         return SkCapabilities::RasterBackend();
     }
diff --git a/src/image/SkSurface_Base.h b/src/image/SkSurface_Base.h
index c5e4b92..9ccd062 100644
--- a/src/image/SkSurface_Base.h
+++ b/src/image/SkSurface_Base.h
@@ -139,7 +139,7 @@
 
     // TODO: Remove this (make it pure virtual) after updating Android (which has a class derived
     // from SkSurface_Base).
-    virtual sk_sp<SkCapabilities> onCapabilities();
+    virtual sk_sp<const SkCapabilities> onCapabilities();
 
     inline SkCanvas* getCachedCanvas();
     inline sk_sp<SkImage> refCachedImage();
diff --git a/src/image/SkSurface_Gpu.cpp b/src/image/SkSurface_Gpu.cpp
index 4c50ac2..19714bd 100644
--- a/src/image/SkSurface_Gpu.cpp
+++ b/src/image/SkSurface_Gpu.cpp
@@ -392,7 +392,7 @@
     return true;
 }
 
-sk_sp<SkCapabilities> SkSurface_Gpu::onCapabilities() {
+sk_sp<const SkCapabilities> SkSurface_Gpu::onCapabilities() {
     return fDevice->recordingContext()->skCapabilities();
 }
 
diff --git a/src/image/SkSurface_Gpu.h b/src/image/SkSurface_Gpu.h
index ea9d519..b0b9795 100644
--- a/src/image/SkSurface_Gpu.h
+++ b/src/image/SkSurface_Gpu.h
@@ -57,7 +57,7 @@
                 const SkPaint* paint) override;
     bool onDraw(sk_sp<const SkDeferredDisplayList>, SkIPoint offset) override;
 
-    sk_sp<SkCapabilities> onCapabilities() override;
+    sk_sp<const SkCapabilities> onCapabilities() override;
     skgpu::BaseDevice* getDevice();
 
 private:
diff --git a/src/image/SkSurface_Raster.cpp b/src/image/SkSurface_Raster.cpp
index f02fd80..6400ff3 100644
--- a/src/image/SkSurface_Raster.cpp
+++ b/src/image/SkSurface_Raster.cpp
@@ -27,7 +27,7 @@
     void onDraw(SkCanvas*, SkScalar, SkScalar, const SkSamplingOptions&, const SkPaint*) override;
     bool onCopyOnWrite(ContentChangeMode) override;
     void onRestoreBackingMutability() override;
-    sk_sp<SkCapabilities> onCapabilities() override;
+    sk_sp<const SkCapabilities> onCapabilities() override;
 
 private:
     SkBitmap    fBitmap;
@@ -155,7 +155,7 @@
     return true;
 }
 
-sk_sp<SkCapabilities> SkSurface_Raster::onCapabilities() {
+sk_sp<const SkCapabilities> SkSurface_Raster::onCapabilities() {
     return SkCapabilities::RasterBackend();
 }