aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/effects/SkMorphologyImageFilter.cpp
diff options
context:
space:
mode:
authorGravatar Brian Osman <brianosman@google.com>2016-12-21 13:36:02 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2016-12-21 19:30:37 +0000
commit320573f8fc1eddded223eea5b4dbbb6ff0b545ab (patch)
treed5a9e641679ef41e3bde0c660f249d91f01a3dab /src/effects/SkMorphologyImageFilter.cpp
parent20a7ecc49b9fe22b1a44629d717d1a51746773ef (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/SkMorphologyImageFilter.cpp')
-rw-r--r--src/effects/SkMorphologyImageFilter.cpp33
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,