aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/effects
diff options
context:
space:
mode:
Diffstat (limited to 'src/effects')
-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,