Add perspective support to GrTextureOp.

Bug: skia:
Change-Id: Idea4ffae37dc2c2f339af60a2b74ded476091758
Reviewed-on: https://skia-review.googlesource.com/127600
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
diff --git a/gm/perspimages.cpp b/gm/perspimages.cpp
new file mode 100644
index 0000000..a4242cf
--- /dev/null
+++ b/gm/perspimages.cpp
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "gm.h"
+#include "Resources.h"
+#include "SkGradientShader.h"
+#include "SkImage.h"
+#include "SkPath.h"
+#include "SkSurface.h"
+#include "sk_tool_utils.h"
+
+static sk_sp<SkImage> make_image1() { return GetResourceAsImage("images/mandrill_128.png"); }
+
+static sk_sp<SkImage> make_image2() {
+    return GetResourceAsImage("images/brickwork-texture.jpg")->makeSubset({0, 0, 128, 128});
+}
+
+namespace skiagm {
+
+class PerspImages : public GM {
+public:
+    PerspImages() = default;
+
+protected:
+    SkString onShortName() override { return SkString("persp_images"); }
+
+    SkISize onISize() override { return SkISize::Make(1150, 880); }
+
+    void onOnceBeforeDraw() override {
+        fImages.push_back(make_image1());
+        fImages.push_back(make_image2());
+    }
+
+    void onDraw(SkCanvas* canvas) override {
+        SkTDArray<SkMatrix> matrices;
+        matrices.push()->setAll(1.f, 0.f,    0.f,
+                                0.f, 1.f,    0.f,
+                                0.f, 0.005f, 1.f);
+        matrices.push()->setAll(1.f,     0.f,    0.f,
+                                0.f,     1.f,    0.f,
+                                0.007f, -0.005f, 1.f);
+        matrices[1].preSkew(0.2f, -0.1f);
+        matrices[1].preRotate(-65.f);
+        matrices[1].preScale(1.2f, .8f);
+        matrices[1].postTranslate(0.f, 60.f);
+        SkPaint paint;
+        int n = 0;
+        SkRect bounds = SkRect::MakeEmpty();
+        for (const auto& img : fImages) {
+            SkRect imgB = SkRect::MakeWH(img->width(), img->height());
+            for (const auto& m : matrices) {
+                SkRect temp;
+                m.mapRect(&temp, imgB);
+                bounds.join(temp);
+            }
+        }
+        canvas->translate(-bounds.fLeft + 10.f, -bounds.fTop + 10.f);
+        canvas->save();
+        for (auto subrect : {false, true}) {
+            for (const auto& m : matrices) {
+                for (auto aa : {false, true}) {
+                    paint.setAntiAlias(aa);
+                    for (auto filter : {kNone_SkFilterQuality, kLow_SkFilterQuality,
+                                        kMedium_SkFilterQuality, kHigh_SkFilterQuality}) {
+                        for (const auto& img : fImages) {
+                            paint.setFilterQuality(filter);
+                            canvas->save();
+                            canvas->concat(m);
+                            if (subrect) {
+                                SkRect src = {img->width() / 4.f, img->height() / 4.f,
+                                              3.f * img->width() / 4.f, 3.f * img->height() / 4};
+                                SkRect dst = {0, 0,
+                                              3.f / 4.f * img->width(), 3.f / 4.f * img->height()};
+                                canvas->drawImageRect(img, src, dst, &paint);
+                            } else {
+                                canvas->drawImage(img, 0, 0, &paint);
+                            }
+                            canvas->restore();
+                            ++n;
+                            if (n < 8) {
+                                canvas->translate(bounds.width() + 10.f, 0);
+                            } else {
+                                canvas->restore();
+                                canvas->translate(0, bounds.height() + 10.f);
+                                canvas->save();
+                                n = 0;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        canvas->restore();
+    }
+
+private:
+    static constexpr int kNumImages = 4;
+    SkTArray<sk_sp<SkImage>> fImages;
+
+    typedef GM INHERITED;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+DEF_GM(return new PerspImages();)
+
+}  // namespace skiagm