treat opaque dsts as src alpha type

Ignoring for the moment principled reasons to do this,
this has the following nice properties:

   1) in the absence of a color space transform,
      all sources are transformed to opaque by dropping
      their alpha channel (not part of the steps)

   2) premul sources are not unpremultiplied
      unless we need to transform color spaces

   3) unpremul sources are never premultiplied

This seems like the best generalization of 1) to cases
that require a color space transformation.

The alternative that we have at head treats opaque as
unpremul, so transforming from premul to opaque preserves
the abstract color but not the color composed on black.

Change-Id: Ic7d7ee24012da3d53378c20f5a4e54fa32405613
Reviewed-on: https://skia-review.googlesource.com/148388
Commit-Queue: Mike Klein <mtklein@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
Auto-Submit: Mike Klein <mtklein@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
diff --git a/src/core/SkColorSpaceXformSteps.cpp b/src/core/SkColorSpaceXformSteps.cpp
index 8ef49f3..ef59a2d 100644
--- a/src/core/SkColorSpaceXformSteps.cpp
+++ b/src/core/SkColorSpaceXformSteps.cpp
@@ -12,9 +12,10 @@
 
 SkColorSpaceXformSteps::SkColorSpaceXformSteps(SkColorSpace* src, SkAlphaType srcAT,
                                                SkColorSpace* dst, SkAlphaType dstAT) {
-    // It's mildly interesting to know the output is opaque, but mechanically that's just unpremul.
+    // Opaque outputs are treated as the same alpha type as the source input.
+    // TODO: we'd really like to have a good way of explaining why we think this is useful.
     if (dstAT == kOpaque_SkAlphaType) {
-        dstAT =  kUnpremul_SkAlphaType;
+        dstAT =  srcAT;
     }
 
     // Set all bools to false, all floats to 0.0f.
diff --git a/tests/SkColorSpaceXformStepsTest.cpp b/tests/SkColorSpaceXformStepsTest.cpp
index b1f6994..f0ae414c 100644
--- a/tests/SkColorSpaceXformStepsTest.cpp
+++ b/tests/SkColorSpaceXformStepsTest.cpp
@@ -107,6 +107,26 @@
         { srgb , srgb22, premul, unpremul, true, true,false, true,false },
         { srgb1, adobe , premul, unpremul, true,false, true, true,false },
         { srgb , adobe , premul, unpremul, true, true, true, true,false },
+
+        // Opaque outputs are treated as the same alpha type as the source input.
+        // TODO: we'd really like to have a good way of explaining why we think this is useful.
+        { srgb , srgb  , premul, opaque, false,false,false,false,false },
+        { srgb , srgb1 , premul, opaque,  true, true,false,false, true },
+        { srgb1, adobe1, premul, opaque, false,false, true,false,false },
+        { srgb , adobe1, premul, opaque,  true, true, true,false, true },
+        { srgb1, srgb  , premul, opaque,  true,false,false, true, true },
+        { srgb , srgb22, premul, opaque,  true, true,false, true, true },
+        { srgb1, adobe , premul, opaque,  true,false, true, true, true },
+        { srgb , adobe , premul, opaque,  true, true, true, true, true },
+
+        { srgb , srgb  , unpremul, opaque, false,false,false,false,false },
+        { srgb , srgb1 , unpremul, opaque, false, true,false,false,false },
+        { srgb1, adobe1, unpremul, opaque, false,false, true,false,false },
+        { srgb , adobe1, unpremul, opaque, false, true, true,false,false },
+        { srgb1, srgb  , unpremul, opaque, false,false,false, true,false },
+        { srgb , srgb22, unpremul, opaque, false, true,false, true,false },
+        { srgb1, adobe , unpremul, opaque, false,false, true, true,false },
+        { srgb , adobe , unpremul, opaque, false, true, true, true,false },
     };
 
     uint32_t tested = 0x00000000;