Push much of the SkColorSpace_Base interface up to SkColorSpace

Some pieces still remain, but the next step looks less mechanical,
so I wanted to land this piece independently.

Bug: skia:
Change-Id: Ie63afcfa08af2f6e4996911fa2225c43441dbfb2
Reviewed-on: https://skia-review.googlesource.com/84120
Reviewed-by: Mike Klein <mtklein@chromium.org>
Commit-Queue: Brian Osman <brianosman@google.com>
diff --git a/bench/ColorCodecBench.cpp b/bench/ColorCodecBench.cpp
index c38a8a7..37f1a62 100644
--- a/bench/ColorCodecBench.cpp
+++ b/bench/ColorCodecBench.cpp
@@ -83,8 +83,7 @@
 
     if (FLAGS_half) {
         fDstInfo = fDstInfo.makeColorType(kRGBA_F16_SkColorType);
-        SkASSERT(SkColorSpace_Base::Type::kXYZ == as_CSB(fDstSpace)->type());
-        fDstSpace = static_cast<SkColorSpace_XYZ*>(fDstSpace.get())->makeLinearGamma();
+        fDstSpace = fDstSpace->makeLinearGamma();
     }
 
     fDst.reset(fDstInfo.computeMinByteSize());
diff --git a/dm/DM.cpp b/dm/DM.cpp
index ebd2fe4..4deaa2f 100644
--- a/dm/DM.cpp
+++ b/dm/DM.cpp
@@ -919,7 +919,7 @@
 }
 
 static sk_sp<SkColorSpace> rgb_to_gbr() {
-    return as_CSB(SkColorSpace::MakeSRGB())->makeColorSpin();
+    return SkColorSpace::MakeSRGB()->makeColorSpin();
 }
 
 static Sink* create_via(const SkString& tag, Sink* wrapped) {
diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp
index 96817e0..a43f8d1 100644
--- a/dm/DMSrcSink.cpp
+++ b/dm/DMSrcSink.cpp
@@ -385,8 +385,7 @@
             }
 
             if (kRGBA_F16_SkColorType == canvasColorType) {
-                sk_sp<SkColorSpace> linearSpace =
-                        as_CSB(decodeInfo->colorSpace())->makeLinearGamma();
+                sk_sp<SkColorSpace> linearSpace = decodeInfo->colorSpace()->makeLinearGamma();
                 *decodeInfo = decodeInfo->makeColorSpace(std::move(linearSpace));
             }
 
@@ -1083,9 +1082,7 @@
         decodeInfo = decodeInfo.makeAlphaType(kPremul_SkAlphaType);
     }
     if (kRGBA_F16_SkColorType == fColorType) {
-        SkASSERT(SkColorSpace_Base::Type::kXYZ == as_CSB(decodeInfo.colorSpace())->type());
-        SkColorSpace_XYZ* csXYZ = static_cast<SkColorSpace_XYZ*>(decodeInfo.colorSpace());
-        decodeInfo = decodeInfo.makeColorSpace(csXYZ->makeLinearGamma());
+        decodeInfo = decodeInfo.makeColorSpace(decodeInfo.colorSpace()->makeLinearGamma());
     }
 
     SkImageInfo bitmapInfo = decodeInfo;
diff --git a/gm/color4f.cpp b/gm/color4f.cpp
index 36850a1..5f281e9 100644
--- a/gm/color4f.cpp
+++ b/gm/color4f.cpp
@@ -96,7 +96,7 @@
     canvas->translate(10, 10);
 
     auto srgb = SkColorSpace::MakeSRGB();
-    auto spin = as_CSB(srgb)->makeColorSpin(); // RGB -> GBR
+    auto spin = srgb->makeColorSpin(); // RGB -> GBR
 
     const SkColor4f colors[] {
         { 1, 0, 0, 1 },
diff --git a/gm/colorspacexform.cpp b/gm/colorspacexform.cpp
index eb98b01..20e94b1 100644
--- a/gm/colorspacexform.cpp
+++ b/gm/colorspacexform.cpp
@@ -48,7 +48,7 @@
                      kOpaque_SkAlphaType);
 
         // Test F32 input.
-        srcSpace = as_CSB(srcSpace)->makeLinearGamma();
+        srcSpace = srcSpace->makeLinearGamma();
         xform = SkColorSpaceXform::New(srcSpace.get(), dstSpace.get());
         xform->apply(SkColorSpaceXform::kRGBA_F32_ColorFormat, fWideGamutColors1,
                      SkColorSpaceXform::kRGBA_F32_ColorFormat, fSRGBColors, kNumColors,
diff --git a/gm/encode-srgb.cpp b/gm/encode-srgb.cpp
index 527ece9..72f8c84 100644
--- a/gm/encode-srgb.cpp
+++ b/gm/encode-srgb.cpp
@@ -31,7 +31,7 @@
             return SkColorSpace::MakeSRGBLinear();
         }
 
-        return as_CSB(colorSpace)->makeLinearGamma();
+        return colorSpace->makeLinearGamma();
     }
 
     return colorSpace;
diff --git a/gm/makecolorspace.cpp b/gm/makecolorspace.cpp
index 1435c04..5291e3b 100644
--- a/gm/makecolorspace.cpp
+++ b/gm/makecolorspace.cpp
@@ -57,7 +57,7 @@
 
         sk_sp<SkColorSpace> wideGamut = SkColorSpace::MakeRGB(SkColorSpace::kSRGB_RenderTargetGamma,
                                                               SkColorSpace::kAdobeRGB_Gamut);
-        sk_sp<SkColorSpace> wideGamutLinear = as_CSB(wideGamut)->makeLinearGamma();
+        sk_sp<SkColorSpace> wideGamutLinear = wideGamut->makeLinearGamma();
 
         // Lazy images
         sk_sp<SkImage> opaqueImage = GetResourceAsImage("images/mandrill_128.png");
diff --git a/gm/readpixels.cpp b/gm/readpixels.cpp
index 6e8a51a..9b61f83 100644
--- a/gm/readpixels.cpp
+++ b/gm/readpixels.cpp
@@ -41,7 +41,7 @@
 
 sk_sp<SkColorSpace> fix_for_colortype(SkColorSpace* colorSpace, SkColorType colorType) {
     if (kRGBA_F16_SkColorType == colorType) {
-        return as_CSB(colorSpace)->makeLinearGamma();
+        return colorSpace->makeLinearGamma();
     }
 
     return sk_ref_sp(colorSpace);
diff --git a/include/core/SkColorSpace.h b/include/core/SkColorSpace.h
index 9622532..5642df5 100644
--- a/include/core/SkColorSpace.h
+++ b/include/core/SkColorSpace.h
@@ -13,6 +13,13 @@
 
 class SkData;
 
+enum SkGammaNamed {
+    kLinear_SkGammaNamed,
+    kSRGB_SkGammaNamed,
+    k2Dot2Curve_SkGammaNamed,
+    kNonStandard_SkGammaNamed,
+};
+
 /**
  *  Describes a color gamut with primaries and a white point.
  */
@@ -128,6 +135,8 @@
     };
     Type type() const;
 
+    SkGammaNamed gammaNamed() const;
+
     /**
      *  Returns true if the color space gamma is near enough to be approximated as sRGB.
      *  This includes the canonical sRGB transfer function as well as a 2.2f exponential
@@ -155,6 +164,49 @@
     bool toXYZD50(SkMatrix44* toXYZD50) const;
 
     /**
+     *  Describes color space gamut as a transformation to XYZ D50.
+     *  Returns nullptr if color gamut cannot be described in terms of XYZ D50.
+     */
+    const SkMatrix44* toXYZD50() const;
+
+    /**
+     *  Describes color space gamut as a transformation from XYZ D50
+     *  Returns nullptr if color gamut cannot be described in terms of XYZ D50.
+     */
+    const SkMatrix44* fromXYZD50() const;
+
+    /**
+     *  Returns a hash of the gamut transofmration to XYZ D50. Allows for fast equality checking
+     *  of gamuts, at the (very small) risk of collision.
+     *  Returns 0 if color gamut cannot be described in terms of XYZ D50.
+     */
+    uint32_t toXYZD50Hash() const;
+
+    /**
+     *  Returns a color space with the same gamut as this one, but with a linear gamma.
+     *  For color spaces whose gamut can not be described in terms of XYZ D50, returns
+     *  linear sRGB.
+     */
+    virtual sk_sp<SkColorSpace> makeLinearGamma() const = 0;
+
+    /**
+     *  Returns a color space with the same gamut as this one, with with the sRGB transfer
+     *  function. For color spaces whose gamut can not be described in terms of XYZ D50, returns
+     *  sRGB.
+     */
+    virtual sk_sp<SkColorSpace> makeSRGBGamma() const = 0;
+
+    /**
+     *  Returns a color space with the same transfer function as this one, but with the primary
+     *  colors rotated. For any XYZ space, this produces a new color space that maps RGB to GBR
+     *  (when applied to a source), and maps RGB to BRG (when applied to a destination). For other
+     *  types of color spaces, returns nullptr.
+     *
+     *  This is used for testing, to construct color spaces that have severe and testable behavior.
+     */
+    virtual sk_sp<SkColorSpace> makeColorSpin() const { return nullptr; }
+
+    /**
      *  Returns true if the color space is sRGB.
      *  Returns false otherwise.
      *
@@ -192,6 +244,16 @@
     SkColorSpace() = default;
     friend class SkColorSpace_Base;
 
+    virtual const SkMatrix44* onToXYZD50() const = 0;
+    virtual uint32_t onToXYZD50Hash() const = 0;
+    virtual const SkMatrix44* onFromXYZD50() const = 0;
+
+    virtual SkGammaNamed onGammaNamed() const = 0;
+    virtual bool onGammaCloseToSRGB() const = 0;
+    virtual bool onGammaIsLinear() const = 0;
+    virtual bool onIsNumericalTransferFn(SkColorSpaceTransferFn* coeffs) const = 0;
+    virtual bool onIsCMYK() const { return false; }
+
     using INHERITED = SkRefCnt;
 };
 
diff --git a/src/codec/SkAndroidCodec.cpp b/src/codec/SkAndroidCodec.cpp
index a694b4b..97e07ce 100644
--- a/src/codec/SkAndroidCodec.cpp
+++ b/src/codec/SkAndroidCodec.cpp
@@ -47,7 +47,7 @@
 static bool is_wide_gamut(const SkColorSpace* colorSpace) {
     // Determine if the source image has a gamut that is wider than sRGB.  If so, we
     // will use P3 as the output color space to avoid clipping the gamut.
-    const SkMatrix44* toXYZD50 = as_CSB(colorSpace)->toXYZD50();
+    const SkMatrix44* toXYZD50 = colorSpace->toXYZD50();
     if (toXYZD50) {
         SkPoint rgb[3];
         load_gamut(rgb, *toXYZD50);
diff --git a/src/codec/SkJpegCodec.cpp b/src/codec/SkJpegCodec.cpp
index 8a8b23b..97d71eb 100644
--- a/src/codec/SkJpegCodec.cpp
+++ b/src/codec/SkJpegCodec.cpp
@@ -558,7 +558,7 @@
         return false;
     }
 
-    bool hasCMYKColorSpace = as_CSB(srcInfo.colorSpace())->onIsCMYK();
+    bool hasCMYKColorSpace = SkColorSpace::kCMYK_Type ==  srcInfo.colorSpace()->type();
     return !hasCMYKColorSpace || !hasColorSpaceXform;
 }
 
diff --git a/src/core/SkColorSpace.cpp b/src/core/SkColorSpace.cpp
index 5d22a18..06ec26d 100644
--- a/src/core/SkColorSpace.cpp
+++ b/src/core/SkColorSpace.cpp
@@ -235,27 +235,31 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 SkColorSpace::Type SkColorSpace::type() const {
-    SkMatrix44  m(SkMatrix44::kUninitialized_Constructor);
-    if (this->toXYZD50(&m)) {
-        return m.isScale() ? kGray_Type : kRGB_Type;
+    const SkMatrix44* m = this->toXYZD50();
+    if (m) {
+        return m->isScale() ? kGray_Type : kRGB_Type;
     }
-    return as_CSB(this)->onIsCMYK() ? kCMYK_Type : kRGB_Type;
+    return this->onIsCMYK() ? kCMYK_Type : kRGB_Type;
+}
+
+SkGammaNamed SkColorSpace::gammaNamed() const {
+    return this->onGammaNamed();
 }
 
 bool SkColorSpace::gammaCloseToSRGB() const {
-    return as_CSB(this)->onGammaCloseToSRGB();
+    return this->onGammaCloseToSRGB();
 }
 
 bool SkColorSpace::gammaIsLinear() const {
-    return as_CSB(this)->onGammaIsLinear();
+    return this->onGammaIsLinear();
 }
 
 bool SkColorSpace::isNumericalTransferFn(SkColorSpaceTransferFn* fn) const {
-    return as_CSB(this)->onIsNumericalTransferFn(fn);
+    return this->onIsNumericalTransferFn(fn);
 }
 
 bool SkColorSpace::toXYZD50(SkMatrix44* toXYZD50) const {
-    const SkMatrix44* matrix = as_CSB(this)->toXYZD50();
+    const SkMatrix44* matrix = this->onToXYZD50();
     if (matrix) {
         *toXYZD50 = *matrix;
         return true;
@@ -264,6 +268,18 @@
     return false;
 }
 
+const SkMatrix44* SkColorSpace::toXYZD50() const {
+    return this->onToXYZD50();
+}
+
+const SkMatrix44* SkColorSpace::fromXYZD50() const {
+    return this->onFromXYZD50();
+}
+
+uint32_t SkColorSpace::toXYZD50Hash() const {
+    return this->onToXYZD50Hash();
+}
+
 bool SkColorSpace::isSRGB() const {
     return srgb() == this;
 }
@@ -331,7 +347,7 @@
         SkASSERT(SkColorSpace_Base::Type::kXYZ == as_CSB(this)->type());
         const SkColorSpace_XYZ* thisXYZ = static_cast<const SkColorSpace_XYZ*>(this);
         // If we have a named profile, only write the enum.
-        const SkGammaNamed gammaNamed = thisXYZ->gammaNamed();
+        const SkGammaNamed gammaNamed = this->gammaNamed();
         if (this == srgb()) {
             if (memory) {
                 *((ColorSpaceHeader*) memory) = ColorSpaceHeader::Pack(
@@ -362,7 +378,7 @@
                             ColorSpaceHeader::Pack(k0_Version, 0, gammaNamed,
                                                    ColorSpaceHeader::kMatrix_Flag);
                     memory = SkTAddOffset<void>(memory, sizeof(ColorSpaceHeader));
-                    thisXYZ->toXYZD50()->as3x4RowMajorf((float*) memory);
+                    this->toXYZD50()->as3x4RowMajorf((float*) memory);
                 }
                 return sizeof(ColorSpaceHeader) + 12 * sizeof(float);
             }
@@ -377,7 +393,7 @@
 
                 if (memory) {
                     *((ColorSpaceHeader*) memory) =
-                            ColorSpaceHeader::Pack(k0_Version, 0, thisXYZ->fGammaNamed,
+                            ColorSpaceHeader::Pack(k0_Version, 0, gammaNamed,
                                                    ColorSpaceHeader::kTransferFn_Flag);
                     memory = SkTAddOffset<void>(memory, sizeof(ColorSpaceHeader));
 
@@ -390,7 +406,7 @@
                     *(((float*) memory) + 6) = gammas->params(0).fG;
                     memory = SkTAddOffset<void>(memory, 7 * sizeof(float));
 
-                    thisXYZ->fToXYZD50.as3x4RowMajorf((float*) memory);
+                    this->toXYZD50()->as3x4RowMajorf((float*) memory);
                 }
 
                 return sizeof(ColorSpaceHeader) + 19 * sizeof(float);
@@ -517,21 +533,17 @@
         return false;
     }
 
-    // profiles are mandatory for A2B0 color spaces
-    SkASSERT(as_CSB(src)->type() == SkColorSpace_Base::Type::kXYZ);
-    const SkColorSpace_XYZ* srcXYZ = static_cast<const SkColorSpace_XYZ*>(src);
-    const SkColorSpace_XYZ* dstXYZ = static_cast<const SkColorSpace_XYZ*>(dst);
-
-    if (srcXYZ->gammaNamed() != dstXYZ->gammaNamed()) {
+    // Profiles are mandatory for A2B0 color spaces, so these must be XYZ
+    if (src->gammaNamed() != dst->gammaNamed()) {
         return false;
     }
 
-    switch (srcXYZ->gammaNamed()) {
+    switch (src->gammaNamed()) {
         case kSRGB_SkGammaNamed:
         case k2Dot2Curve_SkGammaNamed:
         case kLinear_SkGammaNamed:
-            if (srcXYZ->toXYZD50Hash() == dstXYZ->toXYZD50Hash()) {
-                SkASSERT(*srcXYZ->toXYZD50() == *dstXYZ->toXYZD50() && "Hash collision");
+            if (src->toXYZD50Hash() == dst->toXYZD50Hash()) {
+                SkASSERT(*src->toXYZD50() == *dst->toXYZD50() && "Hash collision");
                 return true;
             }
             return false;
diff --git a/src/core/SkColorSpace_A2B.h b/src/core/SkColorSpace_A2B.h
index 08784c2..ca78c64 100644
--- a/src/core/SkColorSpace_A2B.h
+++ b/src/core/SkColorSpace_A2B.h
@@ -27,7 +27,7 @@
 // here by the nature of the design.
 class SkColorSpace_A2B : public SkColorSpace_Base {
 public:
-    const SkMatrix44* toXYZD50() const override {
+    const SkMatrix44* onToXYZD50() const override {
         // the matrix specified in A2B0 profiles is not necessarily
         // a to-XYZ matrix, as to-Lab is supported as well so returning
         // that could be misleading. Additionally, B-curves are applied
@@ -36,18 +36,19 @@
         return nullptr;
     }
 
-    uint32_t toXYZD50Hash() const override {
-        // See toXYZD50()'s comment.
+    uint32_t onToXYZD50Hash() const override {
+        // See onToXYZD50()'s comment.
         return 0;
     }
 
-    const SkMatrix44* fromXYZD50() const override {
-        // See toXYZD50()'s comment. Also, A2B0 profiles are not supported
+    const SkMatrix44* onFromXYZD50() const override {
+        // See onToXYZD50()'s comment. Also, A2B0 profiles are not supported
         // as destination color spaces, so an inverse matrix is never wanted.
         return nullptr;
     }
 
     // There is no single gamma curve in an A2B0 profile
+    SkGammaNamed onGammaNamed() const override { return kNonStandard_SkGammaNamed; }
     bool onGammaCloseToSRGB() const override { return false; }
     bool onGammaIsLinear() const override { return false; }
     bool onIsNumericalTransferFn(SkColorSpaceTransferFn* coeffs) const override { return false; }
diff --git a/src/core/SkColorSpace_Base.h b/src/core/SkColorSpace_Base.h
index 083c3eb..c59a827 100644
--- a/src/core/SkColorSpace_Base.h
+++ b/src/core/SkColorSpace_Base.h
@@ -14,13 +14,6 @@
 #include "SkOnce.h"
 #include "SkTemplates.h"
 
-enum SkGammaNamed : uint8_t {
-    kLinear_SkGammaNamed,
-    kSRGB_SkGammaNamed,
-    k2Dot2Curve_SkGammaNamed,
-    kNonStandard_SkGammaNamed,
-};
-
 struct SkGammas : SkRefCnt {
 
     // There are four possible representations for gamma curves.  kNone_Type is used
@@ -139,57 +132,6 @@
 class SkColorSpace_Base : public SkColorSpace {
 public:
 
-    /**
-     *  Describes color space gamut as a transformation to XYZ D50.
-     *  Returns nullptr if color gamut cannot be described in terms of XYZ D50.
-     */
-    virtual const SkMatrix44* toXYZD50() const = 0;
-
-    /**
-     *  Returns a hash of the gamut transofmration to XYZ D50. Allows for fast equality checking
-     *  of gamuts, at the (very small) risk of collision.
-     *  Returns 0 if color gamut cannot be described in terms of XYZ D50.
-     */
-    virtual uint32_t toXYZD50Hash() const = 0;
-
-    /**
-     *  Describes color space gamut as a transformation from XYZ D50
-     *  Returns nullptr if color gamut cannot be described in terms of XYZ D50.
-     */
-    virtual const SkMatrix44* fromXYZD50() const = 0;
-
-    virtual bool onGammaCloseToSRGB() const = 0;
-
-    virtual bool onGammaIsLinear() const = 0;
-
-    virtual bool onIsNumericalTransferFn(SkColorSpaceTransferFn* coeffs) const = 0;
-
-    virtual bool onIsCMYK() const { return false; }
-
-    /**
-     *  Returns a color space with the same gamut as this one, but with a linear gamma.
-     *  For color spaces whose gamut can not be described in terms of XYZ D50, returns
-     *  linear sRGB.
-     */
-    virtual sk_sp<SkColorSpace> makeLinearGamma() const = 0;
-
-    /**
-     *  Returns a color space with the same gamut as this one, with with the sRGB transfer
-     *  function. For color spaces whose gamut can not be described in terms of XYZ D50, returns
-     *  sRGB.
-     */
-    virtual sk_sp<SkColorSpace> makeSRGBGamma() const = 0;
-
-    /**
-     *  Returns a color space with the same transfer function as this one, but with the primary
-     *  colors rotated. For any XYZ space, this produces a new color space that maps RGB to GBR
-     *  (when applied to a source), and maps RGB to BRG (when applied to a destination). For other
-     *  types of color spaces, returns nullptr.
-     *
-     *  This is used for testing, to construct color spaces that have severe and testable behavior.
-     */
-    virtual sk_sp<SkColorSpace> makeColorSpin() const { return nullptr; }
-
     enum class Type : uint8_t {
         kXYZ,
         kA2B
diff --git a/src/core/SkColorSpace_XYZ.cpp b/src/core/SkColorSpace_XYZ.cpp
index ed66a74..34a93f7 100644
--- a/src/core/SkColorSpace_XYZ.cpp
+++ b/src/core/SkColorSpace_XYZ.cpp
@@ -37,7 +37,7 @@
     }
 }
 
-const SkMatrix44* SkColorSpace_XYZ::fromXYZD50() const {
+const SkMatrix44* SkColorSpace_XYZ::onFromXYZD50() const {
     fFromXYZOnce([this] {
         if (!fToXYZD50.invert(&fFromXYZD50)) {
             // If a client gives us a dst gamut with a transform that we can't invert, we will
diff --git a/src/core/SkColorSpace_XYZ.h b/src/core/SkColorSpace_XYZ.h
index 3ea2665..4e12a5a 100644
--- a/src/core/SkColorSpace_XYZ.h
+++ b/src/core/SkColorSpace_XYZ.h
@@ -14,10 +14,10 @@
 
 class SkColorSpace_XYZ : public SkColorSpace_Base {
 public:
-    const SkMatrix44* toXYZD50() const override { return &fToXYZD50; }
-    uint32_t toXYZD50Hash() const override { return fToXYZD50Hash; }
+    const SkMatrix44* onToXYZD50() const override { return &fToXYZD50; }
+    uint32_t onToXYZD50Hash() const override { return fToXYZD50Hash; }
 
-    const SkMatrix44* fromXYZD50() const override;
+    const SkMatrix44* onFromXYZD50() const override;
 
     bool onGammaCloseToSRGB() const override;
 
@@ -31,7 +31,7 @@
     sk_sp<SkColorSpace> makeSRGBGamma() const override;
     sk_sp<SkColorSpace> makeColorSpin() const override;
 
-    SkGammaNamed gammaNamed() const { return fGammaNamed; }
+    SkGammaNamed onGammaNamed() const override { return fGammaNamed; }
 
     const SkGammas* gammas() const { return fGammas.get(); }
 
diff --git a/src/core/SkDraw_vertices.cpp b/src/core/SkDraw_vertices.cpp
index 004575e..52d2a6c 100644
--- a/src/core/SkDraw_vertices.cpp
+++ b/src/core/SkDraw_vertices.cpp
@@ -163,7 +163,7 @@
         }
     } else {
         auto srcCS = SkColorSpace::MakeSRGB();
-        auto dstCS = as_CSB(deviceCS)->makeLinearGamma();
+        auto dstCS = deviceCS->makeLinearGamma();
         SkColorSpaceXform::Apply(dstCS.get(), SkColorSpaceXform::kRGBA_F32_ColorFormat, dst,
                                  srcCS.get(), SkColorSpaceXform::kBGRA_8888_ColorFormat, src,
                                  count, SkColorSpaceXform::kPremul_AlphaOp);
diff --git a/src/core/SkICC.cpp b/src/core/SkICC.cpp
index 109c40a..128bce3 100644
--- a/src/core/SkICC.cpp
+++ b/src/core/SkICC.cpp
@@ -32,17 +32,11 @@
 }
 
 bool SkICC::toXYZD50(SkMatrix44* toXYZD50) const {
-    const SkMatrix44* m = as_CSB(fColorSpace)->toXYZD50();
-    if (!m) {
-        return false;
-    }
-
-    *toXYZD50 = *m;
-    return true;
+    return fColorSpace->toXYZD50(toXYZD50);
 }
 
 bool SkICC::isNumericalTransferFn(SkColorSpaceTransferFn* coeffs) const {
-    return as_CSB(fColorSpace)->onIsNumericalTransferFn(coeffs);
+    return fColorSpace->isNumericalTransferFn(coeffs);
 }
 
 static const int kDefaultTableSize = 512; // Arbitrary
diff --git a/src/core/SkPM4fPriv.h b/src/core/SkPM4fPriv.h
index ff4e644..28780d6 100644
--- a/src/core/SkPM4fPriv.h
+++ b/src/core/SkPM4fPriv.h
@@ -109,15 +109,15 @@
         return false;
     }
 
-    const SkMatrix44 *fromSrc = as_CSB(src)->  toXYZD50(),
-                       *toDst = as_CSB(dst)->fromXYZD50();
+    const SkMatrix44 *fromSrc = src->  toXYZD50(),
+                       *toDst = dst->fromXYZD50();
     if (!fromSrc || !toDst) {
         SkDEBUGFAIL("We can't handle non-XYZ color spaces in append_gamut_transform().");
         return false;
     }
 
     // Slightly more sophisticated version of if (src == dst)
-    if (as_CSB(src)->toXYZD50Hash() == as_CSB(dst)->toXYZD50Hash()) {
+    if (src->toXYZD50Hash() == dst->toXYZD50Hash()) {
         return false;
     }
 
diff --git a/src/gpu/GrColorSpaceXform.cpp b/src/gpu/GrColorSpaceXform.cpp
index f0dc279..ac93fb4 100644
--- a/src/gpu/GrColorSpaceXform.cpp
+++ b/src/gpu/GrColorSpaceXform.cpp
@@ -119,20 +119,20 @@
         return nullptr;
     }
 
-    const SkMatrix44* toXYZD50   = as_CSB(src)->toXYZD50();
-    const SkMatrix44* fromXYZD50 = as_CSB(dst)->fromXYZD50();
+    const SkMatrix44* toXYZD50   = src->toXYZD50();
+    const SkMatrix44* fromXYZD50 = dst->fromXYZD50();
     if (!toXYZD50 || !fromXYZD50) {
         // Unsupported colour spaces -- cannot specify gamut as a matrix
         return nullptr;
     }
 
     // Determine if a gamut xform is needed
-    uint32_t srcHash = as_CSB(src)->toXYZD50Hash();
-    uint32_t dstHash = as_CSB(dst)->toXYZD50Hash();
+    uint32_t srcHash = src->toXYZD50Hash();
+    uint32_t dstHash = dst->toXYZD50Hash();
     if (srcHash != dstHash) {
         flags |= kApplyGamutXform_Flag;
     } else {
-        SkASSERT(*toXYZD50 == *as_CSB(dst)->toXYZD50() && "Hash collision");
+        SkASSERT(*toXYZD50 == *dst->toXYZD50() && "Hash collision");
     }
 
     if (0 == flags) {
diff --git a/src/image/SkImage_Lazy.cpp b/src/image/SkImage_Lazy.cpp
index b18b17a..c5a2b8d 100644
--- a/src/image/SkImage_Lazy.cpp
+++ b/src/image/SkImage_Lazy.cpp
@@ -390,7 +390,7 @@
             return fInfo.makeColorSpace(nullptr);
         case kLinearF16_CachedFormat:
             return fInfo.makeColorType(kRGBA_F16_SkColorType)
-                        .makeColorSpace(as_CSB(fInfo.colorSpace())->makeLinearGamma());
+                        .makeColorSpace(fInfo.colorSpace()->makeLinearGamma());
         case kSRGB8888_CachedFormat:
             // If the transfer function is nearly (but not exactly) sRGB, we don't want the codec
             // to bother trans-coding. It would be slow, and do more harm than good visually,
@@ -399,7 +399,7 @@
                 return fInfo.makeColorType(kRGBA_8888_SkColorType);
             } else {
                 return fInfo.makeColorType(kRGBA_8888_SkColorType)
-                            .makeColorSpace(as_CSB(fInfo.colorSpace())->makeSRGBGamma());
+                            .makeColorSpace(fInfo.colorSpace()->makeSRGBGamma());
             }
         case kSBGR8888_CachedFormat:
             // See note above about not-quite-sRGB transfer functions.
@@ -407,7 +407,7 @@
                 return fInfo.makeColorType(kBGRA_8888_SkColorType);
             } else {
                 return fInfo.makeColorType(kBGRA_8888_SkColorType)
-                            .makeColorSpace(as_CSB(fInfo.colorSpace())->makeSRGBGamma());
+                            .makeColorSpace(fInfo.colorSpace()->makeSRGBGamma());
             }
         default:
             SkDEBUGFAIL("Invalid cached format");
diff --git a/src/images/SkImageEncoderFns.h b/src/images/SkImageEncoderFns.h
index dd02ebf..8e44ff2 100644
--- a/src/images/SkImageEncoderFns.h
+++ b/src/images/SkImageEncoderFns.h
@@ -361,7 +361,7 @@
 
     sk_sp<SkColorSpace> owned;
     if (kRGBA_F16_SkColorType == info.colorType()) {
-        owned = as_CSB(cs)->makeSRGBGamma();
+        owned = cs->makeSRGBGamma();
         cs = owned.get();
     }
 
diff --git a/src/shaders/gradients/SkGradientShader.cpp b/src/shaders/gradients/SkGradientShader.cpp
index 1ff42e7..1a3e749 100644
--- a/src/shaders/gradients/SkGradientShader.cpp
+++ b/src/shaders/gradients/SkGradientShader.cpp
@@ -1385,8 +1385,7 @@
     if (fUseColors4f) {
         fColorSpace = GrTest::TestColorSpace(random);
         if (fColorSpace) {
-            SkASSERT(SkColorSpace_Base::Type::kXYZ == as_CSB(fColorSpace)->type());
-            fColorSpace = static_cast<SkColorSpace_XYZ*>(fColorSpace.get())->makeLinearGamma();
+            fColorSpace = fColorSpace->makeLinearGamma();
         }
     }
 
diff --git a/src/utils/SkPatchUtils.cpp b/src/utils/SkPatchUtils.cpp
index 512e8cc..c42957c 100644
--- a/src/utils/SkPatchUtils.cpp
+++ b/src/utils/SkPatchUtils.cpp
@@ -253,7 +253,7 @@
                               bool doPremul) {
     if (cs) {
         auto srcCS = SkColorSpace::MakeSRGB();
-        auto dstCS = as_CSB(cs)->makeLinearGamma();
+        auto dstCS = cs->makeLinearGamma();
         auto op = doPremul ? SkColorSpaceXform::kPremul_AlphaOp
                            : SkColorSpaceXform::kPreserve_AlphaOp;
         SkColorSpaceXform::Apply(dstCS.get(), SkColorSpaceXform::kRGBA_F32_ColorFormat,  dst,
@@ -271,7 +271,7 @@
 
 static void linear_to_skcolor(SkColor dst[], const SkRGBAf src[], int count, SkColorSpace* cs) {
     if (cs) {
-        auto srcCS = as_CSB(cs)->makeLinearGamma();
+        auto srcCS = cs->makeLinearGamma();
         auto dstCS = SkColorSpace::MakeSRGB();
         SkColorSpaceXform::Apply(dstCS.get(), SkColorSpaceXform::kBGRA_8888_ColorFormat, dst,
                                  srcCS.get(), SkColorSpaceXform::kRGBA_F32_ColorFormat,  src,
diff --git a/tests/CodecTest.cpp b/tests/CodecTest.cpp
index 787e854..7eddbb7 100644
--- a/tests/CodecTest.cpp
+++ b/tests/CodecTest.cpp
@@ -1143,9 +1143,7 @@
                         || SkCodec::kInvalidConversion == result);
     }
 
-    SkASSERT(SkColorSpace_Base::Type::kXYZ == as_CSB(infoF16.colorSpace())->type());
-    SkColorSpace_XYZ* csXYZ = static_cast<SkColorSpace_XYZ*>(infoF16.colorSpace());
-    infoF16 = infoF16.makeColorSpace(csXYZ->makeLinearGamma());
+    infoF16 = infoF16.makeColorSpace(infoF16.colorSpace()->makeLinearGamma());
     result = codec->getPixels(infoF16, bm.getPixels(), bm.rowBytes());
     REPORTER_ASSERT(r, SkCodec::kSuccess == result);
     result = codec->startScanlineDecode(infoF16);
diff --git a/tests/ColorSpaceTest.cpp b/tests/ColorSpaceTest.cpp
index d180cda..5aa9f17 100644
--- a/tests/ColorSpaceTest.cpp
+++ b/tests/ColorSpaceTest.cpp
@@ -24,11 +24,9 @@
                        const SkGammaNamed expectedGamma) {
 
     REPORTER_ASSERT(r, nullptr != space);
-    SkASSERT(SkColorSpace_Base::Type::kXYZ == as_CSB(space)->type());
-    SkColorSpace_XYZ* csXYZ = static_cast<SkColorSpace_XYZ*>(space);
-    REPORTER_ASSERT(r, expectedGamma == csXYZ->gammaNamed());
+    REPORTER_ASSERT(r, expectedGamma == space->gammaNamed());
 
-    const SkMatrix44& mat = *csXYZ->toXYZD50();
+    const SkMatrix44& mat = *space->toXYZD50();
     const float src[] = {
         1, 0, 0, 1,
         0, 1, 0, 1,
@@ -211,9 +209,7 @@
         auto cs = SkColorSpace_Base::MakeNamed(rec.fNamed);
         REPORTER_ASSERT(r, cs);
         if (cs) {
-            SkASSERT(SkColorSpace_Base::Type::kXYZ == as_CSB(cs)->type());
-            SkColorSpace_XYZ* csXYZ = static_cast<SkColorSpace_XYZ*>(cs.get());
-            REPORTER_ASSERT(r, rec.fExpectedGamma == csXYZ->gammaNamed());
+            REPORTER_ASSERT(r, rec.fExpectedGamma == cs->gammaNamed());
         }
     }
 
@@ -477,8 +473,8 @@
     srgbMat.set3x3RowMajorf(gSRGB_toXYZD50);
     sk_sp<SkColorSpace> strange = SkColorSpace::MakeRGB(fn, srgbMat);
 
-    REPORTER_ASSERT(r, *as_CSB(srgb)->toXYZD50() == *as_CSB(strange)->toXYZD50());
-    REPORTER_ASSERT(r, as_CSB(srgb)->toXYZD50Hash() == as_CSB(strange)->toXYZD50Hash());
+    REPORTER_ASSERT(r, *srgb->toXYZD50() == *strange->toXYZD50());
+    REPORTER_ASSERT(r, srgb->toXYZD50Hash() == strange->toXYZD50Hash());
 }
 
 DEF_TEST(ColorSpace_IsSRGB, r) {
diff --git a/tests/ReadPixelsTest.cpp b/tests/ReadPixelsTest.cpp
index a296c46..9dda8e8 100644
--- a/tests/ReadPixelsTest.cpp
+++ b/tests/ReadPixelsTest.cpp
@@ -595,11 +595,11 @@
                     for (SkAlphaType srcAT: kAlphaTypes) {
                         for (sk_sp<SkColorSpace> srcCS : kColorSpaces) {
                             if (kRGBA_F16_SkColorType == dstCT && dstCS) {
-                                dstCS = as_CSB(dstCS)->makeLinearGamma();
+                                dstCS = dstCS->makeLinearGamma();
                             }
 
                             if (kRGBA_F16_SkColorType == srcCT && srcCS) {
-                                srcCS = as_CSB(srcCS)->makeLinearGamma();
+                                srcCS = srcCS->makeLinearGamma();
                             }
 
                             test_conversion(reporter,
diff --git a/tests/SurfaceTest.cpp b/tests/SurfaceTest.cpp
index ac1acec..942cd8f 100644
--- a/tests/SurfaceTest.cpp
+++ b/tests/SurfaceTest.cpp
@@ -812,7 +812,7 @@
 
     auto srgbColorSpace = SkColorSpace::MakeSRGB();
     auto adobeColorSpace = SkColorSpace_Base::MakeNamed(SkColorSpace_Base::kAdobeRGB_Named);
-    const SkMatrix44* srgbMatrix = as_CSB(srgbColorSpace)->toXYZD50();
+    const SkMatrix44* srgbMatrix = srgbColorSpace->toXYZD50();
     SkASSERT(srgbMatrix);
     SkColorSpaceTransferFn oddGamma;
     oddGamma.fA = 1.0f;
diff --git a/tests/TestConfigParsing.cpp b/tests/TestConfigParsing.cpp
index be149d6..747ad10 100644
--- a/tests/TestConfigParsing.cpp
+++ b/tests/TestConfigParsing.cpp
@@ -158,10 +158,9 @@
     REPORTER_ASSERT(reporter, configs[24]->asConfigGpu()->getColorType() == kRGBA_F16_SkColorType);
     REPORTER_ASSERT(reporter, configs[24]->asConfigGpu()->getColorSpace());
     REPORTER_ASSERT(reporter, configs[24]->asConfigGpu()->getColorSpace()->gammaIsLinear());
-    const SkMatrix44* srgbXYZ = as_CSB(srgbColorSpace)->toXYZD50();
+    const SkMatrix44* srgbXYZ = srgbColorSpace->toXYZD50();
     SkASSERT(srgbXYZ);
-    const SkMatrix44* config25XYZ =
-            as_CSB(configs[24]->asConfigGpu()->getColorSpace())->toXYZD50();
+    const SkMatrix44* config25XYZ = configs[24]->asConfigGpu()->getColorSpace()->toXYZD50();
     SkASSERT(config25XYZ);
     REPORTER_ASSERT(reporter, *config25XYZ == *srgbXYZ);
     REPORTER_ASSERT(reporter, configs[25]->asConfigGpu()->getColorType() == kRGBA_8888_SkColorType);
@@ -169,15 +168,14 @@
     REPORTER_ASSERT(reporter, configs[32]->asConfigGpu()->getColorType() == kRGBA_F16_SkColorType);
     REPORTER_ASSERT(reporter, configs[32]->asConfigGpu()->getColorSpace());
     REPORTER_ASSERT(reporter, configs[32]->asConfigGpu()->getColorSpace()->gammaIsLinear());
-    const SkMatrix44* config41XYZ =
-            as_CSB(configs[32]->asConfigGpu()->getColorSpace())->toXYZD50();
+    const SkMatrix44* config41XYZ = configs[32]->asConfigGpu()->getColorSpace()->toXYZD50();
     SkASSERT(config41XYZ);
     REPORTER_ASSERT(reporter, *config41XYZ != *srgbXYZ);
     REPORTER_ASSERT(reporter, configs[33]->asConfigGpu()->getColorType() == kRGBA_F16_SkColorType);
     REPORTER_ASSERT(reporter, configs[33]->asConfigGpu()->getColorSpace());
     REPORTER_ASSERT(reporter, configs[33]->asConfigGpu()->getColorSpace()->gammaIsLinear());
-    REPORTER_ASSERT(reporter, *as_CSB(configs[33]->asConfigGpu()->getColorSpace())->toXYZD50() !=
-                    *as_CSB(srgbColorSpace)->toXYZD50());
+    REPORTER_ASSERT(reporter, *configs[33]->asConfigGpu()->getColorSpace()->toXYZD50() !=
+                    *srgbColorSpace->toXYZD50());
     REPORTER_ASSERT(reporter, configs[34]->asConfigGpu()->getContextType() ==
                               GrContextFactory::kGL_ContextType);
     REPORTER_ASSERT(reporter, SkToBool(configs[34]->asConfigGpu()->getContextOverrides() &
diff --git a/tools/colorspaceinfo.cpp b/tools/colorspaceinfo.cpp
index be23f8d..390f7cc 100644
--- a/tools/colorspaceinfo.cpp
+++ b/tools/colorspaceinfo.cpp
@@ -531,7 +531,7 @@
         // Draw the sRGB gamut if requested.
         if (FLAGS_sRGB_gamut) {
             sk_sp<SkColorSpace> sRGBSpace = SkColorSpace::MakeSRGB();
-            const SkMatrix44* mat = as_CSB(sRGBSpace)->toXYZD50();
+            const SkMatrix44* mat = sRGBSpace->toXYZD50();
             SkASSERT(mat);
             draw_gamut(gamutCanvas.canvas(), *mat, "sRGB", 0xFFFF9394, false);
         }
@@ -540,11 +540,11 @@
         if (FLAGS_adobeRGB) {
             sk_sp<SkColorSpace> adobeRGBSpace = SkColorSpace::MakeRGB(
                     SkColorSpace::kSRGB_RenderTargetGamma, SkColorSpace::kAdobeRGB_Gamut);
-            const SkMatrix44* mat = as_CSB(adobeRGBSpace)->toXYZD50();
+            const SkMatrix44* mat = adobeRGBSpace->toXYZD50();
             SkASSERT(mat);
             draw_gamut(gamutCanvas.canvas(), *mat, "Adobe RGB", 0xFF31a9e1, false);
         }
-        const SkMatrix44* mat = as_CSB(colorSpace)->toXYZD50();
+        const SkMatrix44* mat = colorSpace->toXYZD50();
         SkASSERT(mat);
         auto xyz = static_cast<SkColorSpace_XYZ*>(colorSpace.get());
         draw_gamut(gamutCanvas.canvas(), *mat, input, 0xFF000000, true);
@@ -556,7 +556,7 @@
         if (FLAGS_sRGB_gamma) {
             draw_transfer_fn(gammaCanvas.canvas(), kSRGB_SkGammaNamed, nullptr, 0xFFFF9394);
         }
-        draw_transfer_fn(gammaCanvas.canvas(), xyz->gammaNamed(), xyz->gammas(), 0xFF000000);
+        draw_transfer_fn(gammaCanvas.canvas(), colorSpace->gammaNamed(), xyz->gammas(), 0xFF000000);
         if (!gammaCanvas.save(&outputFilenames, createOutputFilename("gamma", 0))) {
             return -1;
         }
diff --git a/tools/create_flutter_test_images.cpp b/tools/create_flutter_test_images.cpp
index dbcd25e..683c2fe 100644
--- a/tools/create_flutter_test_images.cpp
+++ b/tools/create_flutter_test_images.cpp
@@ -15,7 +15,7 @@
  *  Create a color space that swaps the red, green, and blue channels.
  */
 static sk_sp<SkColorSpace> gbr_color_space() {
-    return as_CSB(SkColorSpace::MakeSRGB())->makeColorSpin();
+    return SkColorSpace::MakeSRGB()->makeColorSpin();
 }
 
 /**