Change GaussianBlur logic wrt color spaces
authorBrian Osman <brianosman@google.com>
Thu, 29 Dec 2016 16:50:48 +0000 (11:50 -0500)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Tue, 3 Jan 2017 14:35:06 +0000 (14:35 +0000)
I was using 'source' where I should have said 'input'. Also, to be
consistent with other image filters, ensure that the input is in the
destination gamut before we start blurring.

BUG=skia:

Change-Id: I751961b42a2a5d110ee8ea8916279c8fe0d5248e
Reviewed-on: https://skia-review.googlesource.com/6486
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>

gm/imagefilters.cpp
src/core/SkBlurImageFilter.cpp
src/core/SkImageFilter.cpp

index 27422b5..8855afd 100644 (file)
@@ -68,7 +68,7 @@ DEF_SIMPLE_GM(imagefilters_xfermodes, canvas, 480, 480) {
 }
 
 static sk_sp<SkImage> make_image(SkCanvas* canvas) {
-    const SkImageInfo info = SkImageInfo::MakeN32Premul(100, 100);
+    const SkImageInfo info = SkImageInfo::MakeS32(100, 100, kPremul_SkAlphaType);
     auto surface(canvas->makeSurface(info));
     if (!surface) {
         surface = SkSurface::MakeRaster(info);
index 9ec3303..92a5d0f 100644 (file)
@@ -136,6 +136,11 @@ sk_sp<SkSpecialImage> SkBlurImageFilterImpl::onFilterImage(SkSpecialImage* sourc
 #if SK_SUPPORT_GPU
     if (source->isTextureBacked()) {
         GrContext* context = source->getContext();
+
+        // Ensure the input is in the destination's gamut. This saves us from having to do the
+        // xform during the filter itself.
+        input = ImageToColorSpace(input.get(), ctx.outputProperties());
+
         sk_sp<GrTexture> inputTexture(input->asTextureRef(context));
         if (!inputTexture) {
             return nullptr;
@@ -152,13 +157,14 @@ sk_sp<SkSpecialImage> SkBlurImageFilterImpl::onFilterImage(SkSpecialImage* sourc
         offset->fY = dstBounds.fTop;
         inputBounds.offset(-inputOffset);
         dstBounds.offset(-inputOffset);
-        // We intentionally use the source's color space, not the destination's (from ctx). We
-        // always blur in the source's config, so we need a compatible color space. We also want to
-        // avoid doing gamut conversion on every fetch of the texture.
+        // Typically, we would create the RTC with the output's color space (from ctx), but we
+        // 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.
         sk_sp<GrRenderTargetContext> renderTargetContext(SkGpuBlurUtils::GaussianBlur(
                                                                 context,
                                                                 inputTexture.get(),
-                                                                sk_ref_sp(source->getColorSpace()),
+                                                                sk_ref_sp(input->getColorSpace()),
                                                                 dstBounds,
                                                                 &inputBounds,
                                                                 sigma.x(),
@@ -167,11 +173,11 @@ sk_sp<SkSpecialImage> SkBlurImageFilterImpl::onFilterImage(SkSpecialImage* sourc
             return nullptr;
         }
 
-        // TODO: Get the colorSpace from the renderTargetContext (once it has one)
         return SkSpecialImage::MakeFromGpu(SkIRect::MakeWH(dstBounds.width(), dstBounds.height()),
                                            kNeedNewImageUniqueID_SpecialImage,
                                            renderTargetContext->asTexture(),
-                                           sk_ref_sp(input->getColorSpace()), &source->props());
+                                           sk_ref_sp(renderTargetContext->getColorSpace()),
+                                           &source->props());
     }
 #endif
 
index 7965091..90433fa 100644 (file)
@@ -369,7 +369,9 @@ sk_sp<SkSpecialImage> SkImageFilter::ImageToColorSpace(SkSpecialImage* src,
 
     SkCanvas* canvas = surf->getCanvas();
     SkASSERT(canvas);
-    src->draw(canvas, 0, 0, nullptr);
+    SkPaint p;
+    p.setBlendMode(SkBlendMode::kSrc);
+    src->draw(canvas, 0, 0, &p);
     return surf->makeImageSnapshot();
 }
 #endif