More color space improvements to DM

Added P3 configs (tagged surface and SkColorSpaceXformCanvas)

Added logic to tag the output PNGs when using a xform canvas,
so the images look correct in Chrome (and work correctly with
skdiff).

We don't use the gamma_correct tag for much in gold, but only
set it for outputs with a linear transfer function.

Change-Id: Iee713682e5010b0bd3212538a6dcb201ae4e8592
Reviewed-on: https://skia-review.googlesource.com/142170
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
diff --git a/dm/DM.cpp b/dm/DM.cpp
index 5e21e89..83a9f17 100644
--- a/dm/DM.cpp
+++ b/dm/DM.cpp
@@ -946,6 +946,9 @@
 static Sink* create_via(const SkString& tag, Sink* wrapped) {
 #define VIA(t, via, ...) if (tag.equals(t)) { return new via(__VA_ARGS__); }
     VIA("gbr",       ViaCSXform,           wrapped, rgb_to_gbr(), true);
+    VIA("p3",        ViaCSXform,           wrapped,
+                     SkColorSpace::MakeRGB(SkColorSpace::kSRGB_RenderTargetGamma,
+                                           SkColorSpace::kDCIP3_D65_Gamut), false);
     VIA("lite",      ViaLite,              wrapped);
     VIA("pipe",      ViaPipe,              wrapped);
 #ifdef TEST_VIA_SVG
@@ -1182,10 +1185,9 @@
                             const char* ext,
                             SkStream* data, size_t len,
                             const SkBitmap* bitmap) {
-        bool gammaCorrect = false;
-        if (bitmap) {
-            gammaCorrect = SkToBool(bitmap->info().colorSpace());
-        }
+        bool gammaCorrect = bitmap &&
+                            bitmap->info().colorSpace() &&
+                            bitmap->info().colorSpace()->gammaIsLinear();
 
         JsonWriter::BitmapResult result;
         result.name          = task.src->name();
diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp
index 4f139eb..d3f7ab6 100644
--- a/dm/DMSrcSink.cpp
+++ b/dm/DMSrcSink.cpp
@@ -18,6 +18,7 @@
 #include "Resources.h"
 #include "SkAndroidCodec.h"
 #include "SkAutoMalloc.h"
+#include "SkAutoPixmapStorage.h"
 #include "SkBase64.h"
 #include "SkCodec.h"
 #include "SkCodecImageGenerator.h"
@@ -2192,8 +2193,7 @@
     , fColorSpin(colorSpin) {}
 
 Error ViaCSXform::draw(const Src& src, SkBitmap* bitmap, SkWStream* stream, SkString* log) const {
-    return draw_to_canvas(fSink.get(), bitmap, stream, log, src.size(),
-                          [&](SkCanvas* canvas) -> Error {
+    Error err = draw_to_canvas(fSink.get(), bitmap, stream, log, src.size(), [&](SkCanvas* canvas) {
         {
             SkAutoCanvasRestore acr(canvas, true);
             auto proxy = SkCreateColorSpaceXformCanvas(canvas, fCS);
@@ -2219,8 +2219,25 @@
             canvas->drawBitmap(pixels, 0, 0, &rotateColors);
         }
 
-        return "";
+        return Error("");
     });
+
+    if (!err.isEmpty()) {
+        return err;
+    }
+
+    if (bitmap && !fColorSpin) {
+        // It should be possible to do this without all the copies, but that (I think) requires
+        // adding API to SkBitmap.
+        SkAutoPixmapStorage pmap;
+        pmap.alloc(bitmap->info());
+        bitmap->readPixels(pmap);
+        pmap.setColorSpace(fCS);
+        bitmap->allocPixels(pmap.info());
+        bitmap->writePixels(pmap);
+    }
+
+    return "";
 }
 
 }  // namespace DM
diff --git a/tools/flags/SkCommonFlagsConfig.cpp b/tools/flags/SkCommonFlagsConfig.cpp
index ffe3502..7eacb3f 100644
--- a/tools/flags/SkCommonFlagsConfig.cpp
+++ b/tools/flags/SkCommonFlagsConfig.cpp
@@ -55,6 +55,7 @@
     { "gl1010102",             "gpu", "api=gl,color=1010102" },
     { "gles1010102",           "gpu", "api=gles,color=1010102" },
     { "glsrgb",                "gpu", "api=gl,color=srgb" },
+    { "glp3",                  "gpu", "api=gl,color=p3" },
     { "glesrgb",               "gpu", "api=gl,color=esrgb" },
     { "glnarrow",              "gpu", "api=gl,color=narrow" },
     { "glenarrow",             "gpu", "api=gl,color=enarrow" },
@@ -305,6 +306,10 @@
     } else if (value.equals("srgb")) {
         *outColorType = kRGBA_8888_SkColorType;
         *outColorSpace = SkColorSpace::MakeSRGB();
+    } else if (value.equals("p3")) {
+        *outColorType = kRGBA_8888_SkColorType;
+        *outColorSpace = SkColorSpace::MakeRGB(SkColorSpace::kSRGB_RenderTargetGamma,
+                                               SkColorSpace::kDCIP3_D65_Gamut);
     } else if (value.equals("esrgb")) {
         *outColorType = kRGBA_F16_SkColorType;
         *outColorSpace = SkColorSpace::MakeSRGB();