Add GM for failing Image image filter

Tests mirrors (where the src and dst rects are equal, but local coords
have been flipped), and perspective (which is just generally hard).

Bug: skia:11994, skia:12015
Change-Id: Ic57b004d2741e0e713fed17825071c5c9cf63486
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/410000
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
Auto-Submit: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/gm/imagefilterstransformed.cpp b/gm/imagefilterstransformed.cpp
index 3204dde..951e1b7 100644
--- a/gm/imagefilterstransformed.cpp
+++ b/gm/imagefilterstransformed.cpp
@@ -315,3 +315,51 @@
 };
 
 DEF_GM(return new ImageFilterComposedTransform();)
+
+// Tests SkImageFilters::Image under tricky matrices (mirrors and perspective)
+DEF_SIMPLE_GM(imagefilter_transformed_image, canvas, 256, 256) {
+    sk_sp<SkImage> image = GetResourceAsImage("images/color_wheel.png");
+    sk_sp<SkImageFilter> imageFilter = SkImageFilters::Image(image);
+
+    const SkRect imageRect = SkRect::MakeIWH(image->width(), image->height());
+
+    SkM44 m1 = SkM44::Translate(0.9f * image->width(), 0.1f * image->height()) *
+               SkM44::Scale(-.8f, .8f);
+
+    SkM44 m2 = SkM44::RectToRect({-1.f, -1.f, 1.f, 1.f}, imageRect) *
+               SkM44::Perspective(0.01f, 100.f, SK_ScalarPI / 3.f) *
+               SkM44::Translate(0.f, 0.f, -2.f) *
+               SkM44::Rotate({0.f, 1.f, 0.f}, SK_ScalarPI / 6.f) *
+               SkM44::RectToRect(imageRect, {-1.f, -1.f, 1.f, 1.f});
+
+    SkFont font(ToolUtils::create_portable_typeface());
+    canvas->drawString("Columns should match", 5.f, 15.f, font, SkPaint());
+    canvas->translate(0.f, 10.f);
+
+    SkSamplingOptions sampling(SkFilterMode::kLinear);
+    for (auto m : {m1, m2}) {
+        canvas->save();
+        for (bool canvasTransform : {false, true}) {
+            canvas->save();
+            canvas->clipRect(imageRect);
+
+            sk_sp<SkImageFilter> finalFilter;
+            if (canvasTransform) {
+                canvas->concat(m);
+                finalFilter = imageFilter;
+            } else {
+                finalFilter = SkImageFilters::MatrixTransform(m.asM33(), sampling, imageFilter);
+            }
+
+            SkPaint paint;
+            paint.setImageFilter(std::move(finalFilter));
+            canvas->drawPaint(paint);
+
+            canvas->restore();
+            canvas->translate(image->width(), 0.f);
+        }
+        canvas->restore();
+
+        canvas->translate(0.f, image->height());
+    }
+}