From 5f500920e719b215d5e0e36a6679995ed3c9b4ad Mon Sep 17 00:00:00 2001 From: Brian Osman Date: Thu, 29 Dec 2016 11:50:48 -0500 Subject: [PATCH] Change GaussianBlur logic wrt color spaces 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 Commit-Queue: Brian Osman --- gm/imagefilters.cpp | 2 +- src/core/SkBlurImageFilter.cpp | 18 ++++++++++++------ src/core/SkImageFilter.cpp | 4 +++- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/gm/imagefilters.cpp b/gm/imagefilters.cpp index 27422b5..8855afd 100644 --- a/gm/imagefilters.cpp +++ b/gm/imagefilters.cpp @@ -68,7 +68,7 @@ DEF_SIMPLE_GM(imagefilters_xfermodes, canvas, 480, 480) { } static sk_sp 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); diff --git a/src/core/SkBlurImageFilter.cpp b/src/core/SkBlurImageFilter.cpp index 9ec3303..92a5d0f 100644 --- a/src/core/SkBlurImageFilter.cpp +++ b/src/core/SkBlurImageFilter.cpp @@ -136,6 +136,11 @@ sk_sp 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 inputTexture(input->asTextureRef(context)); if (!inputTexture) { return nullptr; @@ -152,13 +157,14 @@ sk_sp 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 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 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 diff --git a/src/core/SkImageFilter.cpp b/src/core/SkImageFilter.cpp index 7965091..90433fa 100644 --- a/src/core/SkImageFilter.cpp +++ b/src/core/SkImageFilter.cpp @@ -369,7 +369,9 @@ sk_sp 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 -- 2.7.4