More conservative reverse mapping bounds for SkDisplacementMapEffect

When reverse mapping bounds through SkDisplacementMapEffect, we need to
consider both the color input and the displacement input because they
could both directly, or indirectly, reference the source.

Bug: chromium:1128962
Change-Id: I03489fd2391f2ea595945961bf7e940a0e200cab
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/319656
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
This commit is contained in:
Fredrik Söderqvist 2020-09-25 15:48:01 +02:00 committed by Skia Commit-Bot
parent f8cafa71c9
commit 0ea0c5e3bd
2 changed files with 24 additions and 0 deletions

View File

@ -417,6 +417,9 @@ SkIRect SkDisplacementMapEffectImpl::onFilterNodeBounds(
SkIRect SkDisplacementMapEffectImpl::onFilterBounds(
const SkIRect& src, const SkMatrix& ctm, MapDirection dir, const SkIRect* inputRect) const {
if (kReverse_MapDirection == dir) {
return INHERITED::onFilterBounds(src, ctm, dir, inputRect);
}
// Recurse only into color input.
if (this->getColorInput()) {
return this->getColorInput()->filterBounds(src, ctm, dir, inputRect);

View File

@ -1934,6 +1934,27 @@ DEF_TEST(ArithmeticImageFilterBounds, reporter) {
test_arithmetic_combinations(reporter, 0.5);
}
// Test SkDisplacementMapEffect::filterBounds.
DEF_TEST(DisplacementMapBounds, reporter) {
SkPaint greenPaint;
greenPaint.setColor(SK_ColorGREEN);
SkIRect floodBounds(SkIRect::MakeXYWH(20, 30, 10, 10));
sk_sp<SkImageFilter> flood(SkImageFilters::Paint(greenPaint, &floodBounds));
SkIRect tilingBounds(SkIRect::MakeXYWH(0, 0, 200, 100));
sk_sp<SkImageFilter> tiling(SkImageFilters::Tile(SkRect::Make(floodBounds),
SkRect::Make(tilingBounds),
flood));
sk_sp<SkImageFilter> displace(SkImageFilters::DisplacementMap(SkColorChannel::kR,
SkColorChannel::kB,
20.0f, nullptr, tiling));
SkIRect input(SkIRect::MakeXYWH(20, 30, 40, 50));
// Expected: union(floodBounds, outset(input, 10))
SkIRect expected(SkIRect::MakeXYWH(10, 20, 60, 70));
REPORTER_ASSERT(reporter,
expected == displace->filterBounds(input, SkMatrix::I(),
SkImageFilter::kReverse_MapDirection));
}
// Test SkImageSource::filterBounds.
DEF_TEST(ImageSourceBounds, reporter) {
sk_sp<SkImage> image(SkImage::MakeFromBitmap(make_gradient_circle(64, 64)));