diff options
author | Brian Osman <brianosman@google.com> | 2016-12-21 13:36:02 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2016-12-21 19:30:37 +0000 |
commit | 320573f8fc1eddded223eea5b4dbbb6ff0b545ab (patch) | |
tree | d5a9e641679ef41e3bde0c660f249d91f01a3dab /src/effects | |
parent | 20a7ecc49b9fe22b1a44629d717d1a51746773ef (diff) |
Add color space xform fallback to GrMorphologyEffect
99% of the time (or maybe 100%?) morphology will trigger pad_image,
so the input texture will already be in the destimation color space.
If that doesn't happen, then just force the source to be converted,
which keeps the morphology effect and driver code simple.
BUG=skia:
Change-Id: I98876af4f9e9a5da031973213ed76349752ce68f
Reviewed-on: https://skia-review.googlesource.com/6388
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
Diffstat (limited to 'src/effects')
-rw-r--r-- | src/effects/SkMorphologyImageFilter.cpp | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/src/effects/SkMorphologyImageFilter.cpp b/src/effects/SkMorphologyImageFilter.cpp index 130f099d85..42986ce9de 100644 --- a/src/effects/SkMorphologyImageFilter.cpp +++ b/src/effects/SkMorphologyImageFilter.cpp @@ -13,6 +13,7 @@ #include "SkReadBuffer.h" #include "SkRect.h" #include "SkSpecialImage.h" +#include "SkSpecialSurface.h" #include "SkWriteBuffer.h" #if SK_SUPPORT_GPU @@ -492,6 +493,9 @@ static sk_sp<SkSpecialImage> apply_morphology( sk_sp<SkColorSpace> colorSpace = sk_ref_sp(outputProperties.colorSpace()); GrPixelConfig config = GrRenderableConfigForColorSpace(colorSpace.get()); + // We force the inputs to this filter into the destination color space in the calling code. + SkASSERT(input->getColorSpace() == colorSpace.get()); + // setup new clip const GrFixedClip clip(SkIRect::MakeWH(srcTexture->width(), srcTexture->height())); @@ -507,7 +511,7 @@ static sk_sp<SkSpecialImage> apply_morphology( return nullptr; } - apply_morphology_pass(context->textureProvider(), + apply_morphology_pass(context->textureProvider(), dstRTContext.get(), clip, srcTexture.get(), srcRect, dstRect, radius.fWidth, morphType, Gr1DKernelEffect::kX_Direction); @@ -542,6 +546,23 @@ static sk_sp<SkSpecialImage> apply_morphology( std::move(srcTexture), std::move(colorSpace), &input->props()); } + +// Return a copy of 'src' transformed to the output's color space +static sk_sp<SkSpecialImage> image_to_color_space(SkSpecialImage* src, + const SkImageFilter::OutputProperties& outProps) { + sk_sp<SkSpecialSurface> 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<SkSpecialImage> SkMorphologyImageFilter::onFilterImage(SkSpecialImage* source, @@ -582,6 +603,16 @@ sk_sp<SkSpecialImage> SkMorphologyImageFilter::onFilterImage(SkSpecialImage* sou if (source->isTextureBacked()) { 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()); + } + auto type = (kDilate_Op == this->op()) ? GrMorphologyEffect::kDilate_MorphologyType : GrMorphologyEffect::kErode_MorphologyType; sk_sp<SkSpecialImage> result(apply_morphology(context, input.get(), srcBounds, type, |