Cache dst LUTs in SkColorSpaceXform

This is only useful in the rare case that the dst does not
fall into one of our main paths.

But it's a good optimization, since this does happen,
and typically, the dst won't change.

ColorCodecBench z620 --nonstd --xform_only
Without Patch 511us
With Patch    348us

BUG=skia:

GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=3400

Change-Id: Ibf68d9ce7072680465662922f4aa15630545e3d6
Reviewed-on: https://skia-review.googlesource.com/3400
Reviewed-by: Mike Klein <mtklein@chromium.org>
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Matt Sarett <msarett@google.com>
diff --git a/bench/ColorCodecBench.cpp b/bench/ColorCodecBench.cpp
index 9ae5601..6aa46d6 100644
--- a/bench/ColorCodecBench.cpp
+++ b/bench/ColorCodecBench.cpp
@@ -18,6 +18,7 @@
 #endif
 DEFINE_bool(xform_only, false, "Only time the color xform, do not include the decode time");
 DEFINE_bool(srgb,       false, "Convert to srgb dst space");
+DEFINE_bool(nonstd,     false, "Convert to non-standard dst space");
 DEFINE_bool(half,       false, "Convert to half floats");
 
 ColorCodecBench::ColorCodecBench(const char* name, sk_sp<SkData> encoded)
@@ -172,6 +173,13 @@
         fDstSpace = as_CSB(fDstSpace)->makeLinearGamma();
     }
 
+    if (FLAGS_nonstd) {
+        float gammas[3] = { 1.8f, 2.0f, 2.5f, };
+        SkMatrix44 matrix = SkMatrix44(SkMatrix44::kUninitialized_Constructor);
+        matrix.set3x3(0.30f, 0.31f, 0.28f, 0.32f, 0.33f, 0.29f, 0.27f, 0.30f, 0.30f);
+        fDstSpace = SkColorSpace::NewRGB(gammas, matrix);
+    }
+
     fDstInfo = fDstInfo.makeColorSpace(fDstSpace);
 
     fDst.reset(fDstInfo.getSafeSize(fDstInfo.minRowBytes()));
diff --git a/include/core/SkColorSpaceXform.h b/include/core/SkColorSpaceXform.h
index 15b3d49..b1ca92e 100644
--- a/include/core/SkColorSpaceXform.h
+++ b/include/core/SkColorSpaceXform.h
@@ -50,17 +50,11 @@
      *
      */
     bool apply(ColorFormat dstFormat, void* dst, ColorFormat srcFormat, const void* src, int count,
-               SkAlphaType alphaType) const {
-        return this->onApply(dstFormat, dst, srcFormat, src, count, alphaType);
-    }
-
+               SkAlphaType alphaType) const;
 
     virtual ~SkColorSpaceXform() {}
 
 protected:
-    virtual bool onApply(ColorFormat dstFormat, void* dst, ColorFormat srcFormat, const void* src,
-                         int count, SkAlphaType alphaType) const = 0;
-
     SkColorSpaceXform() {}
 };
 
diff --git a/src/core/SkColorSpace.cpp b/src/core/SkColorSpace.cpp
index bdef5b3..b956c7f 100644
--- a/src/core/SkColorSpace.cpp
+++ b/src/core/SkColorSpace.cpp
@@ -8,6 +8,7 @@
 #include "SkColorSpace.h"
 #include "SkColorSpace_Base.h"
 #include "SkColorSpacePriv.h"
+#include "SkColorSpaceXform_Base.h"
 #include "SkOnce.h"
 #include "SkPoint3.h"
 
@@ -319,6 +320,23 @@
     return fFromXYZD50;
 }
 
+void SkColorSpace_Base::toDstGammaTables(const uint8_t* tables[3], sk_sp<SkData>* storage,
+                                         int numTables) const {
+    fToDstGammaOnce([this, numTables] {
+        const bool gammasAreMatching = numTables <= 1;
+        fDstStorage =
+                SkData::MakeUninitialized(numTables * SkColorSpaceXform_Base::kDstGammaTableSize);
+        SkColorSpaceXform_Base::BuildDstGammaTables(fToDstGammaTables,
+                                                    (uint8_t*) fDstStorage->writable_data(), this,
+                                                    gammasAreMatching);
+    });
+
+    *storage = fDstStorage;
+    tables[0] = fToDstGammaTables[0];
+    tables[1] = fToDstGammaTables[1];
+    tables[2] = fToDstGammaTables[2];
+}
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 enum Version {
diff --git a/src/core/SkColorSpaceXform.cpp b/src/core/SkColorSpaceXform.cpp
index 50cd9c1..5e36246 100644
--- a/src/core/SkColorSpaceXform.cpp
+++ b/src/core/SkColorSpaceXform.cpp
@@ -138,9 +138,7 @@
     }
 }
 
-static const int kDstGammaTableSize =
-        SkColorSpaceXform_Base<kTable_SrcGamma, kTable_DstGamma, kNone_ColorSpaceMatch>
-        ::kDstGammaTableSize;
+static const int kDstGammaTableSize = SkColorSpaceXform_Base::kDstGammaTableSize;
 
 static void build_table_linear_to_gamma(uint8_t* outTable, float exponent) {
     float toGammaExp = 1.0f / exponent;
@@ -256,7 +254,8 @@
 // Build tables to transform src gamma to linear.
 template <typename T>
 static void build_gamma_tables(const T* outGammaTables[3], T* gammaTableStorage, int gammaTableSize,
-                               SkColorSpace* space, const GammaFns<T>& fns, bool gammasAreMatching)
+                               const SkColorSpace* space, const GammaFns<T>& fns,
+                               bool gammasAreMatching)
 {
     switch (as_CSB(space)->gammaNamed()) {
         case kSRGB_SkGammaNamed:
@@ -326,6 +325,13 @@
     }
 }
 
+void SkColorSpaceXform_Base::BuildDstGammaTables(const uint8_t* dstGammaTables[3],
+                                                 uint8_t* dstStorage, const SkColorSpace* space,
+                                                 bool gammasAreMatching) {
+    build_gamma_tables(dstGammaTables, dstStorage, kDstGammaTableSize, space, kFromLinear,
+                       gammasAreMatching);
+}
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 static inline bool is_almost_identity(const SkMatrix44& srcToDst) {
@@ -368,41 +374,41 @@
             switch (as_CSB(dstSpace)->gammaNamed()) {
                 case kSRGB_SkGammaNamed:
                     if (srcSpace->gammaIsLinear()) {
-                        return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base
+                        return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
                                 <kLinear_SrcGamma, kSRGB_DstGamma, kNone_ColorSpaceMatch>
                                 (srcSpace, srcToDst, dstSpace));
                     } else {
-                        return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base
+                        return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
                                 <kTable_SrcGamma, kSRGB_DstGamma, kNone_ColorSpaceMatch>
                                 (srcSpace, srcToDst, dstSpace));
                     }
                 case k2Dot2Curve_SkGammaNamed:
                     if (srcSpace->gammaIsLinear()) {
-                        return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base
+                        return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
                                 <kLinear_SrcGamma, k2Dot2_DstGamma, kNone_ColorSpaceMatch>
                                 (srcSpace, srcToDst, dstSpace));
                     } else {
-                        return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base
+                        return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
                                 <kTable_SrcGamma, k2Dot2_DstGamma, kNone_ColorSpaceMatch>
                                 (srcSpace, srcToDst, dstSpace));
                     }
                 case kLinear_SkGammaNamed:
                     if (srcSpace->gammaIsLinear()) {
-                        return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base
+                        return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
                                 <kLinear_SrcGamma, kLinear_DstGamma, kNone_ColorSpaceMatch>
                                 (srcSpace, srcToDst, dstSpace));
                     } else {
-                        return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base
+                        return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
                                 <kTable_SrcGamma, kLinear_DstGamma, kNone_ColorSpaceMatch>
                                 (srcSpace, srcToDst, dstSpace));
                     }
                 default:
                     if (srcSpace->gammaIsLinear()) {
-                        return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base
+                        return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
                                 <kLinear_SrcGamma, kTable_DstGamma, kNone_ColorSpaceMatch>
                                 (srcSpace, srcToDst, dstSpace));
                     } else {
-                        return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base
+                        return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
                                 <kTable_SrcGamma, kTable_DstGamma, kNone_ColorSpaceMatch>
                                 (srcSpace, srcToDst, dstSpace));
                     }
@@ -411,41 +417,41 @@
             switch (as_CSB(dstSpace)->gammaNamed()) {
                 case kSRGB_SkGammaNamed:
                     if (srcSpace->gammaIsLinear()) {
-                        return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base
+                        return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
                                 <kLinear_SrcGamma, kSRGB_DstGamma, kGamut_ColorSpaceMatch>
                                 (srcSpace, srcToDst, dstSpace));
                     } else {
-                        return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base
+                        return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
                                 <kTable_SrcGamma, kSRGB_DstGamma, kGamut_ColorSpaceMatch>
                                 (srcSpace, srcToDst, dstSpace));
                     }
                 case k2Dot2Curve_SkGammaNamed:
                     if (srcSpace->gammaIsLinear()) {
-                        return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base
+                        return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
                                 <kLinear_SrcGamma, k2Dot2_DstGamma, kGamut_ColorSpaceMatch>
                                 (srcSpace, srcToDst, dstSpace));
                     } else {
-                        return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base
+                        return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
                                 <kTable_SrcGamma, k2Dot2_DstGamma, kGamut_ColorSpaceMatch>
                                 (srcSpace, srcToDst, dstSpace));
                     }
                 case kLinear_SkGammaNamed:
                     if (srcSpace->gammaIsLinear()) {
-                        return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base
+                        return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
                                 <kLinear_SrcGamma, kLinear_DstGamma, kGamut_ColorSpaceMatch>
                                 (srcSpace, srcToDst, dstSpace));
                     } else {
-                        return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base
+                        return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
                                 <kTable_SrcGamma, kLinear_DstGamma, kGamut_ColorSpaceMatch>
                                 (srcSpace, srcToDst, dstSpace));
                     }
                 default:
                     if (srcSpace->gammaIsLinear()) {
-                        return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base
+                        return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
                                 <kLinear_SrcGamma, kTable_DstGamma, kGamut_ColorSpaceMatch>
                                 (srcSpace, srcToDst, dstSpace));
                     } else {
-                        return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base
+                        return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
                                 <kTable_SrcGamma, kTable_DstGamma, kGamut_ColorSpaceMatch>
                                 (srcSpace, srcToDst, dstSpace));
                     }
@@ -453,19 +459,19 @@
         case kFull_ColorSpaceMatch:
             switch (as_CSB(dstSpace)->gammaNamed()) {
                 case kSRGB_SkGammaNamed:
-                    return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base
+                    return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
                             <kTable_SrcGamma, kSRGB_DstGamma, kFull_ColorSpaceMatch>
                             (srcSpace, srcToDst, dstSpace));
                 case k2Dot2Curve_SkGammaNamed:
-                    return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base
+                    return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
                             <kTable_SrcGamma, k2Dot2_DstGamma, kFull_ColorSpaceMatch>
                             (srcSpace, srcToDst, dstSpace));
                 case kLinear_SkGammaNamed:
-                    return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base
+                    return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
                             <kLinear_SrcGamma, kLinear_DstGamma, kFull_ColorSpaceMatch>
                             (srcSpace, srcToDst, dstSpace));
                 default:
-                    return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base
+                    return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
                             <kTable_SrcGamma, kTable_DstGamma, kFull_ColorSpaceMatch>
                             (srcSpace, srcToDst, dstSpace));
             }
@@ -1243,25 +1249,21 @@
 }
 
 template <SrcGamma kSrc, DstGamma kDst, ColorSpaceMatch kCSM>
-SkColorSpaceXform_Base<kSrc, kDst, kCSM>
-::SkColorSpaceXform_Base(SkColorSpace* srcSpace, const SkMatrix44& srcToDst, SkColorSpace* dstSpace)
+SkColorSpaceXform_XYZ<kSrc, kDst, kCSM>
+::SkColorSpaceXform_XYZ(SkColorSpace* srcSpace, const SkMatrix44& srcToDst, SkColorSpace* dstSpace)
     : fColorLUT(sk_ref_sp((SkColorLookUpTable*) as_CSB(srcSpace)->colorLUT()))
 {
     srcToDst.asColMajorf(fSrcToDst);
 
     const int numSrcTables = num_tables(srcSpace);
-    const int numDstTables = num_tables(dstSpace);
-    const size_t srcTableBytes = numSrcTables * 256 * sizeof(float);
-    const size_t dstTableBytes = numDstTables * kDstGammaTableSize * sizeof(uint8_t);
-    fStorage.reset(srcTableBytes + dstTableBytes);
-    float* srcStorage = (float*) fStorage.get();
-    uint8_t* dstStorage = SkTAddOffset<uint8_t>(fStorage.get(), srcTableBytes);
-
+    const size_t srcEntries = numSrcTables * 256;
     const bool srcGammasAreMatching = (1 >= numSrcTables);
-    const bool dstGammasAreMatching = (1 >= numDstTables);
-    build_gamma_tables(fSrcGammaTables, srcStorage, 256, srcSpace, kToLinear, srcGammasAreMatching);
-    build_gamma_tables(fDstGammaTables, dstStorage, kDstGammaTableSize, dstSpace, kFromLinear,
-                       dstGammasAreMatching);
+    fSrcStorage.reset(srcEntries);
+    build_gamma_tables(fSrcGammaTables, fSrcStorage.get(), 256, srcSpace, kToLinear,
+                       srcGammasAreMatching);
+
+    const int numDstTables = num_tables(dstSpace);
+    as_CSB(dstSpace)->toDstGammaTables(fDstGammaTables, &fDstStorage, numDstTables);
 }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -1318,7 +1320,7 @@
 }
 
 template <SrcGamma kSrc, DstGamma kDst, ColorSpaceMatch kCSM>
-bool SkColorSpaceXform_Base<kSrc, kDst, kCSM>
+bool SkColorSpaceXform_XYZ<kSrc, kDst, kCSM>
 ::onApply(ColorFormat dstColorFormat, void* dst, ColorFormat srcColorFormat, const void* src,
           int len, SkAlphaType alphaType) const
 {
@@ -1421,10 +1423,16 @@
     }
 }
 
+bool SkColorSpaceXform::apply(ColorFormat dstColorFormat, void* dst, ColorFormat srcColorFormat,
+                              const void* src, int len, SkAlphaType alphaType) const {
+    return ((SkColorSpaceXform_Base*) this)->onApply(dstColorFormat, dst, srcColorFormat, src, len,
+                                                     alphaType);
+}
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 std::unique_ptr<SkColorSpaceXform> SlowIdentityXform(SkColorSpace* space) {
-        return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_Base
+        return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
                 <kTable_SrcGamma, kTable_DstGamma, kNone_ColorSpaceMatch>
                 (space, SkMatrix::I(), space));
 }
diff --git a/src/core/SkColorSpaceXform_Base.h b/src/core/SkColorSpaceXform_Base.h
index 02714ad..c1b9785 100644
--- a/src/core/SkColorSpaceXform_Base.h
+++ b/src/core/SkColorSpaceXform_Base.h
@@ -11,6 +11,23 @@
 #include "SkColorSpace.h"
 #include "SkColorSpace_Base.h"
 #include "SkColorSpaceXform.h"
+#include "SkResourceCache.h"
+
+class SkColorSpaceXform_Base : public SkColorSpaceXform {
+public:
+    static constexpr int kDstGammaTableSize = 1024;
+
+protected:
+    virtual bool onApply(ColorFormat dstFormat, void* dst, ColorFormat srcFormat, const void* src,
+                         int count, SkAlphaType alphaType) const = 0;
+
+private:
+    static void BuildDstGammaTables(const uint8_t* outGammaTables[3], uint8_t* gammaTableStorage,
+                                    const SkColorSpace* space, bool gammasAreMatching);
+
+    friend class SkColorSpaceXform;
+    friend class SkColorSpace_Base;
+};
 
 enum SrcGamma {
     kLinear_SrcGamma,
@@ -31,24 +48,22 @@
 };
 
 template <SrcGamma kSrc, DstGamma kDst, ColorSpaceMatch kCSM>
-class SkColorSpaceXform_Base : public SkColorSpaceXform {
-public:
-    static constexpr int kDstGammaTableSize = 1024;
-
+class SkColorSpaceXform_XYZ : public SkColorSpaceXform_Base {
 protected:
     bool onApply(ColorFormat dstFormat, void* dst, ColorFormat srcFormat, const void* src,
                  int count, SkAlphaType alphaType) const override;
 
 private:
-    SkColorSpaceXform_Base(SkColorSpace* srcSpace, const SkMatrix44& srcToDst,
-                           SkColorSpace* dstSpace);
+    SkColorSpaceXform_XYZ(SkColorSpace* srcSpace, const SkMatrix44& srcToDst,
+                          SkColorSpace* dstSpace);
 
     sk_sp<SkColorLookUpTable> fColorLUT;
 
     // Contain pointers into storage or pointers into precomputed tables.
     const float*              fSrcGammaTables[3];
+    SkAutoTMalloc<float>      fSrcStorage;
     const uint8_t*            fDstGammaTables[3];
-    SkAutoMalloc              fStorage;
+    sk_sp<SkData>             fDstStorage;
 
     float                     fSrcToDst[16];
 
diff --git a/src/core/SkColorSpace_Base.h b/src/core/SkColorSpace_Base.h
index 36cc477..a188a11 100644
--- a/src/core/SkColorSpace_Base.h
+++ b/src/core/SkColorSpace_Base.h
@@ -177,6 +177,8 @@
     const SkMatrix44& toXYZD50() const { return fToXYZD50; }
     const SkMatrix44& fromXYZD50() const;
     
+    void toDstGammaTables(const uint8_t* tables[3], sk_sp<SkData>* storage, int numTables) const;
+
     /**
      *  Create an SkColorSpace with the same gamut as this color space, but with linear gamma.
      */
@@ -200,14 +202,18 @@
     SkColorSpace_Base(sk_sp<SkColorLookUpTable> colorLUT, SkGammaNamed gammaNamed,
                       sk_sp<SkGammas> gammas, const SkMatrix44& toXYZ, sk_sp<SkData> profileData);
 
-    sk_sp<SkColorLookUpTable> fColorLUT;
-    const SkGammaNamed        fGammaNamed;
-    sk_sp<SkGammas>           fGammas;
-    sk_sp<SkData>             fProfileData;
+    sk_sp<SkColorLookUpTable>      fColorLUT;
+    const SkGammaNamed             fGammaNamed;
+    sk_sp<SkGammas>                fGammas;
+    sk_sp<SkData>                  fProfileData;
 
-    const SkMatrix44          fToXYZD50;
-    mutable SkMatrix44        fFromXYZD50;
-    mutable SkOnce            fFromXYZOnce;
+    const SkMatrix44               fToXYZD50;
+    mutable SkMatrix44             fFromXYZD50;
+    mutable SkOnce                 fFromXYZOnce;
+
+    mutable sk_sp<SkData>          fDstStorage;
+    mutable const uint8_t*         fToDstGammaTables[3];
+    mutable SkOnce                 fToDstGammaOnce;
 
     friend class SkColorSpace;
     friend class ColorSpaceXformTest;
diff --git a/tests/ColorSpaceXformTest.cpp b/tests/ColorSpaceXformTest.cpp
index 0885d58..6cf0dbe 100644
--- a/tests/ColorSpaceXformTest.cpp
+++ b/tests/ColorSpaceXformTest.cpp
@@ -30,7 +30,8 @@
     return SkTAbs(x - y) <= 1;
 }
 
-static void test_identity_xform(skiatest::Reporter* r, const sk_sp<SkGammas>& gammas) {
+static void test_identity_xform(skiatest::Reporter* r, const sk_sp<SkGammas>& gammas,
+                                bool repeat) {
     // Arbitrary set of 10 pixels
     constexpr int width = 10;
     constexpr uint32_t srcPixels[width] = {
@@ -57,6 +58,12 @@
         REPORTER_ASSERT(r, almost_equal(((srcPixels[i] >> 24) & 0xFF),
                                         SkGetPackedA32(dstPixels[i])));
     }
+
+    if (repeat) {
+        // We should cache part of the transform after the run.  So it is interesting
+        // to make sure it still runs correctly the second time.
+        test_identity_xform(r, gammas, false);
+    }
 }
 
 DEF_TEST(ColorSpaceXform_TableGamma, r) {
@@ -81,7 +88,7 @@
     table[7] = 0.60f;
     table[8] = 0.75f;
     table[9] = 1.00f;
-    test_identity_xform(r, gammas);
+    test_identity_xform(r, gammas, true);
 }
 
 DEF_TEST(ColorSpaceXform_ParametricGamma, r) {
@@ -107,7 +114,7 @@
     params->fB = 0.055f / 1.055f;
     params->fC = 0.0f;
     params->fG = 2.4f;
-    test_identity_xform(r, gammas);
+    test_identity_xform(r, gammas, true);
 }
 
 DEF_TEST(ColorSpaceXform_ExponentialGamma, r) {
@@ -115,7 +122,7 @@
     sk_sp<SkGammas> gammas = sk_sp<SkGammas>(new SkGammas());
     gammas->fRedType = gammas->fGreenType = gammas->fBlueType = SkGammas::Type::kValue_Type;
     gammas->fRedData.fValue = gammas->fGreenData.fValue = gammas->fBlueData.fValue = 1.4f;
-    test_identity_xform(r, gammas);
+    test_identity_xform(r, gammas, true);
 }
 
 DEF_TEST(ColorSpaceXform_NamedGamma, r) {
@@ -124,7 +131,7 @@
     gammas->fRedData.fNamed = kSRGB_SkGammaNamed;
     gammas->fGreenData.fNamed = k2Dot2Curve_SkGammaNamed;
     gammas->fBlueData.fNamed = kLinear_SkGammaNamed;
-    test_identity_xform(r, gammas);
+    test_identity_xform(r, gammas, true);
 }
 
 DEF_TEST(ColorSpaceXform_NonMatchingGamma, r) {
@@ -165,7 +172,7 @@
     gammas->fBlueType = SkGammas::Type::kParam_Type;
     gammas->fBlueData.fParamOffset = sizeof(float) * tableSize;
 
-    test_identity_xform(r, gammas);
+    test_identity_xform(r, gammas, true);
 }
 
 DEF_TEST(ColorSpaceXform_applyCLUTMemoryAccess, r) {