Interpolate patch vertices in destination color space

Change-Id: I4e1403eb63370f5e61283ed4a504fb352368adc0
Reviewed-on: https://skia-review.googlesource.com/139862
Reviewed-by: Mike Klein <mtklein@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
diff --git a/src/utils/SkPatchUtils.cpp b/src/utils/SkPatchUtils.cpp
index a28abdf..af91626 100644
--- a/src/utils/SkPatchUtils.cpp
+++ b/src/utils/SkPatchUtils.cpp
@@ -252,38 +252,23 @@
     }
 };
 
-static void skcolor_to_linear(SkRGBAf dst[], const SkColor src[], int count, SkColorSpace* cs,
-                              bool doPremul) {
-    if (cs) {
-        auto srcCS = SkColorSpace::MakeSRGB();
-        auto dstCS = cs->makeLinearGamma();
-        auto op = doPremul ? SkColorSpaceXform::kPremul_AlphaOp
-                           : SkColorSpaceXform::kPreserve_AlphaOp;
-        SkColorSpaceXform::Apply(dstCS.get(), SkColorSpaceXform::kRGBA_F32_ColorFormat,  dst,
-                                 srcCS.get(), SkColorSpaceXform::kBGRA_8888_ColorFormat, src,
-                                 count, op);
-    } else {
-        for (int i = 0; i < count; ++i) {
-            dst[i] = SkRGBAf::FromBGRA32(src[i]);
-            if (doPremul) {
-                dst[i] = dst[i].premul();
-            }
-        }
-    }
+static void skcolor_to_float(SkRGBAf dst[], const SkColor src[], int count, SkColorSpace* dstCS,
+                             bool doPremul) {
+    // Source is always sRGB SkColor (safe because sRGB is a global singleton)
+    auto srcCS = SkColorSpace::MakeSRGB().get();
+
+    auto op = doPremul ? SkColorSpaceXform::kPremul_AlphaOp : SkColorSpaceXform::kPreserve_AlphaOp;
+    SkAssertResult(SkColorSpaceXform::Apply(dstCS, SkColorSpaceXform::kRGBA_F32_ColorFormat,  dst,
+                                            srcCS, SkColorSpaceXform::kBGRA_8888_ColorFormat, src,
+                                            count, op));
 }
 
-static void linear_to_skcolor(SkColor dst[], const SkRGBAf src[], int count, SkColorSpace* cs) {
-    if (cs) {
-        auto srcCS = cs->makeLinearGamma();
-        auto dstCS = SkColorSpace::MakeSRGB();
-        SkColorSpaceXform::Apply(dstCS.get(), SkColorSpaceXform::kBGRA_8888_ColorFormat, dst,
-                                 srcCS.get(), SkColorSpaceXform::kRGBA_F32_ColorFormat,  src,
-                                 count, SkColorSpaceXform::kPreserve_AlphaOp);
-    } else {
-        for (int i = 0; i < count; ++i) {
-            dst[i] = src[i].toBGRA32();
-        }
-    }
+static void float_to_skcolor(SkColor dst[], const SkRGBAf src[], int count, SkColorSpace* srcCS) {
+    // Destination is always sRGB SkColor (safe because sRGB is a global singleton)
+    auto dstCS = SkColorSpace::MakeSRGB().get();
+    SkAssertResult(SkColorSpaceXform::Apply(dstCS, SkColorSpaceXform::kBGRA_8888_ColorFormat, dst,
+                                            srcCS, SkColorSpaceXform::kRGBA_F32_ColorFormat,  src,
+                                            count, SkColorSpaceXform::kPreserve_AlphaOp));
 }
 
 static void unpremul(SkRGBAf array[], int count) {
@@ -294,7 +279,7 @@
 
 sk_sp<SkVertices> SkPatchUtils::MakeVertices(const SkPoint cubics[12], const SkColor srcColors[4],
                                              const SkPoint srcTexCoords[4], int lodX, int lodY,
-                                             bool interpColorsLinearly) {
+                                             SkColorSpace* colorSpace) {
     if (lodX < 1 || lodY < 1 || nullptr == cubics) {
         return nullptr;
     }
@@ -307,6 +292,11 @@
         return nullptr;
     }
 
+    // Treat null interpolation space as sRGB (safe because sRGB is a global singleton)
+    if (!colorSpace) {
+        colorSpace = SkColorSpace::MakeSRGB().get();
+    }
+
     int vertexCount = SkToS32(mult64);
     // it is recommended to generate draw calls of no more than 65536 indices, so we never generate
     // more than 60000 indices. To accomplish that we resize the LOD and vertex count
@@ -333,7 +323,6 @@
     SkSTArenaAlloc<2048> alloc;
     SkRGBAf* cornerColors = srcColors ? alloc.makeArray<SkRGBAf>(4) : nullptr;
     SkRGBAf* tmpColors = srcColors ? alloc.makeArray<SkRGBAf>(vertexCount) : nullptr;
-    auto convertCS = interpColorsLinearly ? SkColorSpace::MakeSRGB() : nullptr;
 
     SkVertices::Builder builder(SkVertices::kTriangles_VertexMode, vertexCount, indexCount, flags);
     SkPoint* pos = builder.positions();
@@ -357,7 +346,7 @@
             doPremul = false;   // no need
         }
 
-        skcolor_to_linear(cornerColors, srcColors, kNumCorners, convertCS.get(), doPremul);
+        skcolor_to_float(cornerColors, srcColors, kNumCorners, colorSpace, doPremul);
     }
 
     SkPoint pts[kNumPtsCubic];
@@ -440,7 +429,7 @@
         if (doPremul) {
             unpremul(tmpColors, vertexCount);
         }
-        linear_to_skcolor(builder.colors(), tmpColors, vertexCount, convertCS.get());
+        float_to_skcolor(builder.colors(), tmpColors, vertexCount, colorSpace);
     }
     return builder.detach();
 }