Fix GPU blurring when using SkColorSpaceXformCanvas

Several GMs didn't draw at all (and asserted in debug builds). This fixes
all of that, so that the xform canvas (or even just pure-legaacy canvas)
doesn't accidentally blur in linear space by creating sRGB render target
contexts for sRGB-tagged inputs.

Bug: skia:
Change-Id: I37c567a1c5b0e004dc301e5c272c7b470ac5f4c8
Reviewed-on: https://skia-review.googlesource.com/66884
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
diff --git a/src/core/SkBlurImageFilter.cpp b/src/core/SkBlurImageFilter.cpp
index 55be271..4bfba17 100644
--- a/src/core/SkBlurImageFilter.cpp
+++ b/src/core/SkBlurImageFilter.cpp
@@ -61,7 +61,7 @@
     sk_sp<SkSpecialImage> gpuFilter(
             SkSpecialImage *source,
             SkVector sigma, const sk_sp<SkSpecialImage> &input,
-            SkIRect inputBounds, SkIRect dstBounds) const;
+            SkIRect inputBounds, SkIRect dstBounds, const OutputProperties& outProps) const;
     #endif
 
     sk_sp<SkSpecialImage> cpuFilter(
@@ -574,7 +574,8 @@
         // xform during the filter itself.
         input = ImageToColorSpace(input.get(), ctx.outputProperties());
 
-        result = this->gpuFilter(source, sigma, input, inputBounds, dstBounds);
+        result = this->gpuFilter(source, sigma, input, inputBounds, dstBounds,
+                                 ctx.outputProperties());
     } else
     #endif
     {
@@ -601,7 +602,7 @@
 sk_sp<SkSpecialImage> SkBlurImageFilterImpl::gpuFilter(
         SkSpecialImage *source,
         SkVector sigma, const sk_sp<SkSpecialImage> &input,
-        SkIRect inputBounds, SkIRect dstBounds) const
+        SkIRect inputBounds, SkIRect dstBounds, const OutputProperties& outProps) const
 {
     // If both sigmas produce arms of the cross that are less than 1/2048, then they
     // do not contribute to the sum of the filter in a way to change a gamma corrected result.
@@ -626,10 +627,17 @@
     // always blur in the PixelConfig of the *input*. Those might not be compatible (if they
     // have different transfer functions). We've already guaranteed that those color spaces
     // have the same gamut, so in this case, we do everything in the input's color space.
+    // ...
+    // Unless the output is legacy. In that case, the input could be almost anything (if we're
+    // using SkColorSpaceXformCanvas), but we can't make a corresponding RTC. We don't care to,
+    // either, we want to do our blending (and blurring) without any color correction, so pass
+    // nullptr here, causing us to operate entirely in the input's color space, with no decoding.
+    // Then, when we create the output image later, we tag it with the input's color space, so
+    // it will be tagged correctly, regardless of how we created the intermediate RTCs.
     sk_sp<GrRenderTargetContext> renderTargetContext(SkGpuBlurUtils::GaussianBlur(
         context,
         std::move(inputTexture),
-        sk_ref_sp(input->getColorSpace()),
+        outProps.colorSpace() ? sk_ref_sp(input->getColorSpace()) : nullptr,
         dstBounds,
         inputBounds,
         sigma.x(),
@@ -644,7 +652,7 @@
             SkIRect::MakeWH(dstBounds.width(), dstBounds.height()),
             kNeedNewImageUniqueID_SpecialImage,
             renderTargetContext->asTextureProxyRef(),
-            renderTargetContext->colorSpaceInfo().refColorSpace(),
+            sk_ref_sp(input->getColorSpace()),
             &source->props());
 }
 #endif