From 29437eb5c782ff49b9c2a23ef5dd4a54e9e45c44 Mon Sep 17 00:00:00 2001 From: Brian Osman Date: Tue, 27 Dec 2016 12:50:37 -0500 Subject: [PATCH] Add color space fallback for matrix convolution filter GrMatrixConvolutionFilter is used in two places right now. The GaussianBlur code ensures that we blur in the space of the source image, so no conversion is needed. This changes SkMatrixConvolutionImageFilter to give the same guarantee. BUG=skia: Change-Id: I1a6199d4893f2e579dc6fa809c59cd195bd62f90 Reviewed-on: https://skia-review.googlesource.com/6467 Reviewed-by: Brian Osman Commit-Queue: Brian Osman --- src/effects/SkMatrixConvolutionImageFilter.cpp | 27 +++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/effects/SkMatrixConvolutionImageFilter.cpp b/src/effects/SkMatrixConvolutionImageFilter.cpp index fe6d8ac..40d09d6 100644 --- a/src/effects/SkMatrixConvolutionImageFilter.cpp +++ b/src/effects/SkMatrixConvolutionImageFilter.cpp @@ -283,6 +283,22 @@ static GrTextureDomain::Mode convert_tilemodes(SkMatrixConvolutionImageFilter::T return GrTextureDomain::kIgnore_Mode; } +// Return a copy of 'src' transformed to the output's color space +static sk_sp image_to_color_space(SkSpecialImage* src, + const SkImageFilter::OutputProperties& outProps) { + sk_sp surf(src->makeSurface( + outProps, SkISize::Make(src->width(), src->height()))); + if (!surf) { + return sk_ref_sp(src); + } + + SkCanvas* canvas = surf->getCanvas(); + SkASSERT(canvas); + + src->draw(canvas, 0, 0, nullptr); + + return surf->makeImageSnapshot(); +} #endif sk_sp SkMatrixConvolutionImageFilter::onFilterImage(SkSpecialImage* source, @@ -306,6 +322,16 @@ sk_sp SkMatrixConvolutionImageFilter::onFilterImage(SkSpecialIma fKernelSize.width() * fKernelSize.height() <= MAX_KERNEL_SIZE) { GrContext* context = source->getContext(); + // If the input is not yet already in the destination color space, do an explicit up-front + // conversion. This is extremely unlikely (maybe even impossible). Typically, applyCropRect + // will have called pad_image to account for our dilation of bounds, so the result will + // already be moved to the destination color space. If someone makes a filter DAG that + // avoids that, then we use this fall-back, which saves us from having to do the xform + // during the filter itself. + if (input->getColorSpace() != ctx.outputProperties().colorSpace()) { + input = image_to_color_space(input.get(), ctx.outputProperties()); + } + sk_sp inputTexture(input->asTextureRef(context)); SkASSERT(inputTexture); @@ -313,7 +339,6 @@ sk_sp SkMatrixConvolutionImageFilter::onFilterImage(SkSpecialIma offset->fY = bounds.top(); bounds.offset(-inputOffset); - // SRGBTODO: handle sRGB here sk_sp fp(GrMatrixConvolutionEffect::Make(inputTexture.get(), bounds, fKernelSize, -- 2.7.4