/*
 * Copyright 2019 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

// This test only works with the GPU backend.

#include "gm/gm.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkBlendMode.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkColorFilter.h"
#include "include/core/SkData.h"
#include "include/core/SkFont.h"
#include "include/core/SkImage.h"
#include "include/core/SkImageFilter.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkMaskFilter.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkScalar.h"
#include "include/core/SkShader.h"
#include "include/core/SkSize.h"
#include "include/core/SkString.h"
#include "include/core/SkTileMode.h"
#include "include/core/SkTypeface.h"
#include "include/core/SkTypes.h"
#include "include/effects/SkColorMatrix.h"
#include "include/effects/SkGradientShader.h"
#include "include/effects/SkImageFilters.h"
#include "include/effects/SkShaderMaskFilter.h"
#include "include/private/SkTArray.h"
#include "src/core/SkLineClipper.h"
#include "tools/Resources.h"
#include "tools/ToolUtils.h"
#include "tools/gpu/YUVUtils.h"

#include <array>
#include <memory>
#include <utility>

class ClipTileRenderer;
using ClipTileRendererArray = SkTArray<sk_sp<ClipTileRenderer>>;

// This GM mimics the draw calls used by complex compositors that focus on drawing rectangles
// and quadrilaterals with per-edge AA, with complex images, effects, and seamless tiling.
// It will be updated to reflect the patterns seen in Chromium's SkiaRenderer. It is currently
// restricted to adding draw ops directly in Ganesh since there is no fully-specified public API.
static constexpr SkScalar kTileWidth = 40;
static constexpr SkScalar kTileHeight = 30;

static constexpr int kRowCount = 4;
static constexpr int kColCount = 3;

// To mimic Chromium's BSP clipping strategy, a set of three lines formed by triangle edges
// of the below points are used to clip against the regular tile grid. The tile grid occupies
// a 120 x 120 rectangle (40px * 3 cols by 30px * 4 rows).
static constexpr SkPoint kClipP1 = {1.75f * kTileWidth, 0.8f * kTileHeight};
static constexpr SkPoint kClipP2 = {0.6f * kTileWidth, 2.f * kTileHeight};
static constexpr SkPoint kClipP3 = {2.9f * kTileWidth, 3.5f * kTileHeight};

///////////////////////////////////////////////////////////////////////////////////////////////
// Utilities for operating on lines and tiles
///////////////////////////////////////////////////////////////////////////////////////////////

// p0 and p1 form a segment contained the tile grid, so extends them by a large enough margin
// that the output points stored in 'line' are outside the tile grid (thus effectively infinite).
static void clipping_line_segment(const SkPoint& p0, const SkPoint& p1, SkPoint line[2]) {
    SkVector v = p1 - p0;
    // 10f was chosen as a balance between large enough to scale the currently set clip
    // points outside of the tile grid, but small enough to preserve precision.
    line[0] = p0 - v * 10.f;
    line[1] = p1 + v * 10.f;
}

// Returns true if line segment (p0-p1) intersects with line segment (l0-l1); if true is returned,
// the intersection point is stored in 'intersect'.
static bool intersect_line_segments(const SkPoint& p0, const SkPoint& p1,
                                    const SkPoint& l0, const SkPoint& l1, SkPoint* intersect) {
    static constexpr SkScalar kHorizontalTolerance = 0.01f; // Pretty conservative

    // Use doubles for accuracy, since the clipping strategy used below can create T
    // junctions, and lower precision could artificially create gaps
    double pY = (double) p1.fY - (double) p0.fY;
    double pX = (double) p1.fX - (double) p0.fX;
    double lY = (double) l1.fY - (double) l0.fY;
    double lX = (double) l1.fX - (double) l0.fX;
    double plY = (double) p0.fY - (double) l0.fY;
    double plX = (double) p0.fX - (double) l0.fX;
    if (SkScalarNearlyZero(pY, kHorizontalTolerance)) {
        if (SkScalarNearlyZero(lY, kHorizontalTolerance)) {
            // Two horizontal lines
            return false;
        } else {
            // Recalculate but swap p and l
            return intersect_line_segments(l0, l1, p0, p1, intersect);
        }
    }

    // Up to now, the line segments do not form an invalid intersection
    double lNumerator = plX * pY - plY * pX;
    double lDenom = lX * pY - lY * pX;
    if (SkScalarNearlyZero(lDenom)) {
        // Parallel or identical
        return false;
    }

    // Calculate alphaL that provides the intersection point along (l0-l1), e.g. l0+alphaL*(l1-l0)
    double alphaL = lNumerator / lDenom;
    if (alphaL < 0.0 || alphaL > 1.0) {
        // Outside of the l segment
        return false;
    }

    // Calculate alphaP from the valid alphaL (since it could be outside p segment)
    // double alphaP = (alphaL * l.fY - pl.fY) / p.fY;
    double alphaP = (alphaL * lY - plY) / pY;
    if (alphaP < 0.0 || alphaP > 1.0) {
        // Outside of p segment
        return false;
    }

    // Is valid, so calculate the actual intersection point
    *intersect = l1 * SkScalar(alphaL) + l0 * SkScalar(1.0 - alphaL);
    return true;
}

// Draw a line through the two points, outset by a fixed length in screen space
static void draw_outset_line(SkCanvas* canvas, const SkMatrix& local, const SkPoint pts[2],
                             const SkPaint& paint) {
    static constexpr SkScalar kLineOutset = 10.f;
    SkPoint mapped[2];
    local.mapPoints(mapped, pts, 2);
    SkVector v = mapped[1] - mapped[0];
    v.setLength(v.length() + kLineOutset);
    canvas->drawLine(mapped[1] - v, mapped[0] + v, paint);
}

// Draw grid of red lines at interior tile boundaries.
static void draw_tile_boundaries(SkCanvas* canvas, const SkMatrix& local) {
    SkPaint paint;
    paint.setAntiAlias(true);
    paint.setColor(SK_ColorRED);
    paint.setStyle(SkPaint::kStroke_Style);
    paint.setStrokeWidth(0.f);
    for (int x = 1; x < kColCount; ++x) {
        SkPoint pts[] = {{x * kTileWidth, 0}, {x * kTileWidth, kRowCount * kTileHeight}};
        draw_outset_line(canvas, local, pts, paint);
    }
    for (int y = 1; y < kRowCount; ++y) {
        SkPoint pts[] = {{0, y * kTileHeight}, {kTileWidth * kColCount, y * kTileHeight}};
        draw_outset_line(canvas, local, pts, paint);
    }
}

// Draw the arbitrary clipping/split boundaries that intersect the tile grid as green lines
static void draw_clipping_boundaries(SkCanvas* canvas, const SkMatrix& local) {
    SkPaint paint;
    paint.setAntiAlias(true);
    paint.setColor(SK_ColorGREEN);
    paint.setStyle(SkPaint::kStroke_Style);
    paint.setStrokeWidth(0.f);

    // Clip the "infinite" line segments to a rectangular region outside the tile grid
    SkRect border = SkRect::MakeWH(kTileWidth * kColCount, kTileHeight * kRowCount);

    // Draw p1 to p2
    SkPoint line[2];
    SkPoint clippedLine[2];
    clipping_line_segment(kClipP1, kClipP2, line);
    SkAssertResult(SkLineClipper::IntersectLine(line, border, clippedLine));
    draw_outset_line(canvas, local, clippedLine, paint);

    // Draw p2 to p3
    clipping_line_segment(kClipP2, kClipP3, line);
    SkAssertResult(SkLineClipper::IntersectLine(line, border, clippedLine));
    draw_outset_line(canvas, local, clippedLine, paint);

    // Draw p3 to p1
    clipping_line_segment(kClipP3, kClipP1, line);
    SkAssertResult(SkLineClipper::IntersectLine(line, border, clippedLine));
    draw_outset_line(canvas, local, clippedLine, paint);
}

static void draw_text(SkCanvas* canvas, const char* text) {
    SkFont font(ToolUtils::create_portable_typeface(), 12);
    canvas->drawString(text, 0, 0, font, SkPaint());
}

/////////////////////////////////////////////////////////////////////////////////////////////////
// Abstraction for rendering a possibly clipped tile, that can apply different effects to mimic
// the Chromium quad types, and a generic GM template to arrange renderers x transforms in a grid
/////////////////////////////////////////////////////////////////////////////////////////////////

class ClipTileRenderer : public SkRefCntBase {
public:
    // Draw the base rect, possibly clipped by 'clip' if that is not null. The edges to antialias
    // are specified in 'edgeAA' (to make manipulation easier than an unsigned bitfield). 'tileID'
    // represents the location of rect within the tile grid, 'quadID' is the unique ID of the clip
    // region within the tile (reset for each tile).
    //
    // The edgeAA order matches that of clip, so it refers to top, right, bottom, left.
    // Return draw count
    virtual int drawTile(SkCanvas* canvas, const SkRect& rect, const SkPoint clip[4],
                          const bool edgeAA[4], int tileID, int quadID) = 0;

    virtual void drawBanner(SkCanvas* canvas) = 0;

    // Return draw count
    virtual int drawTiles(SkCanvas* canvas) {
        // All three lines in a list
        SkPoint lines[6];
        clipping_line_segment(kClipP1, kClipP2, lines);
        clipping_line_segment(kClipP2, kClipP3, lines + 2);
        clipping_line_segment(kClipP3, kClipP1, lines + 4);

        bool edgeAA[4];
        int tileID = 0;
        int drawCount = 0;
        for (int i = 0; i < kRowCount; ++i) {
            for (int j = 0; j < kColCount; ++j) {
                // The unclipped tile geometry
                SkRect tile = SkRect::MakeXYWH(j * kTileWidth, i * kTileHeight,
                                               kTileWidth, kTileHeight);
                // Base edge AA flags if there are no clips; clipped lines will only turn off edges
                edgeAA[0] = i == 0;             // Top
                edgeAA[1] = j == kColCount - 1; // Right
                edgeAA[2] = i == kRowCount - 1; // Bottom
                edgeAA[3] = j == 0;             // Left

                // Now clip against the 3 lines formed by kClipPx and split into general purpose
                // quads as needed.
                int quadCount = 0;
                drawCount += this->clipTile(canvas, tileID, tile, nullptr, edgeAA, lines, 3,
                                            &quadCount);
                tileID++;
            }
        }

        return drawCount;
    }

protected:
    SkCanvas::QuadAAFlags maskToFlags(const bool edgeAA[4]) const {
        unsigned flags = (edgeAA[0] * SkCanvas::kTop_QuadAAFlag) |
                         (edgeAA[1] * SkCanvas::kRight_QuadAAFlag) |
                         (edgeAA[2] * SkCanvas::kBottom_QuadAAFlag) |
                         (edgeAA[3] * SkCanvas::kLeft_QuadAAFlag);
        return static_cast<SkCanvas::QuadAAFlags>(flags);
    }

    // Recursively splits the quadrilateral against the segments stored in 'lines', which must be
    // 2 * lineCount long. Increments 'quadCount' for each split quadrilateral, and invokes the
    // drawTile at leaves.
    int clipTile(SkCanvas* canvas, int tileID, const SkRect& baseRect, const SkPoint quad[4],
                  const bool edgeAA[4], const SkPoint lines[], int lineCount, int* quadCount) {
        if (lineCount == 0) {
            // No lines, so end recursion by drawing the tile. If the tile was never split then
            // 'quad' remains null so that drawTile() can differentiate how it should draw.
            int draws = this->drawTile(canvas, baseRect, quad, edgeAA, tileID, *quadCount);
            *quadCount = *quadCount + 1;
            return draws;
        }

        static constexpr int kTL = 0; // Top-left point index in points array
        static constexpr int kTR = 1; // Top-right point index in points array
        static constexpr int kBR = 2; // Bottom-right point index in points array
        static constexpr int kBL = 3; // Bottom-left point index in points array
        static constexpr int kS0 = 4; // First split point index in points array
        static constexpr int kS1 = 5; // Second split point index in points array

        SkPoint points[6];
        if (quad) {
            // Copy the original 4 points into set of points to consider
            for (int i = 0; i < 4; ++i) {
                points[i] = quad[i];
            }
        } else {
            //  Haven't been split yet, so fill in based on the rect
            baseRect.toQuad(points);
        }

        // Consider the first line against the 4 quad edges in tile, which should have 0,1, or 2
        // intersection points since the tile is convex.
        int splitIndices[2]; // Edge that was intersected
        int intersectionCount = 0;
        for (int i = 0; i < 4; ++i) {
            SkPoint intersect;
            if (intersect_line_segments(points[i], points[i == 3 ? 0 : i + 1],
                                        lines[0], lines[1], &intersect)) {
                // If the intersected point is the same as the last found intersection, the line
                // runs through a vertex, so don't double count it
                bool duplicate = false;
                for (int j = 0; j < intersectionCount; ++j) {
                    if (SkScalarNearlyZero((intersect - points[kS0 + j]).length())) {
                        duplicate = true;
                        break;
                    }
                }
                if (!duplicate) {
                    points[kS0 + intersectionCount] = intersect;
                    splitIndices[intersectionCount] = i;
                    intersectionCount++;
                }
            }
        }

        if (intersectionCount < 2) {
            // Either the first line never intersected the quad (count == 0), or it intersected at a
            // single vertex without going through quad area (count == 1), so check next line
            return this->clipTile(
                    canvas, tileID, baseRect, quad, edgeAA, lines + 2, lineCount - 1, quadCount);
        }

        SkASSERT(intersectionCount == 2);
        // Split the tile points into 2+ sub quads and recurse to the next lines, which may or may
        // not further split the tile. Since the configurations are relatively simple, the possible
        // splits are hardcoded below; subtile quad orderings are such that the sub tiles remain in
        // clockwise order and match expected edges for QuadAAFlags. subtile indices refer to the
        // 6-element 'points' array.
        SkSTArray<3, std::array<int, 4>> subtiles;
        int s2 = -1; // Index of an original vertex chosen for a artificial split
        if (splitIndices[1] - splitIndices[0] == 2) {
            // Opposite edges, so the split trivially forms 2 sub quads
            if (splitIndices[0] == 0) {
                subtiles.push_back({{kTL, kS0, kS1, kBL}});
                subtiles.push_back({{kS0, kTR, kBR, kS1}});
            } else {
                subtiles.push_back({{kTL, kTR, kS0, kS1}});
                subtiles.push_back({{kS1, kS0, kBR, kBL}});
            }
        } else {
            // Adjacent edges, which makes for a more complicated split, since it forms a degenerate
            // quad (triangle) and a pentagon that must be artificially split. The pentagon is split
            // using one of the original vertices (remembered in 's2'), which adds an additional
            // degenerate quad, but ensures there are no T-junctions.
            switch(splitIndices[0]) {
                case 0:
                    // Could be connected to edge 1 or edge 3
                    if (splitIndices[1] == 1) {
                        s2 = kBL;
                        subtiles.push_back({{kS0, kTR, kS1, kS0}}); // degenerate
                        subtiles.push_back({{kTL, kS0, edgeAA[0] ? kS0 : kBL, kBL}}); // degenerate
                        subtiles.push_back({{kS0, kS1, kBR, kBL}});
                    } else {
                        SkASSERT(splitIndices[1] == 3);
                        s2 = kBR;
                        subtiles.push_back({{kTL, kS0, kS1, kS1}}); // degenerate
                        subtiles.push_back({{kS1, edgeAA[3] ? kS1 : kBR, kBR, kBL}}); // degenerate
                        subtiles.push_back({{kS0, kTR, kBR, kS1}});
                    }
                    break;
                case 1:
                    // Edge 0 handled above, should only be connected to edge 2
                    SkASSERT(splitIndices[1] == 2);
                    s2 = kTL;
                    subtiles.push_back({{kS0, kS0, kBR, kS1}}); // degenerate
                    subtiles.push_back({{kTL, kTR, kS0, edgeAA[1] ? kS0 : kTL}}); // degenerate
                    subtiles.push_back({{kTL, kS0, kS1, kBL}});
                    break;
                case 2:
                    // Edge 1 handled above, should only be connected to edge 3
                    SkASSERT(splitIndices[1] == 3);
                    s2 = kTR;
                    subtiles.push_back({{kS1, kS0, kS0, kBL}}); // degenerate
                    subtiles.push_back({{edgeAA[2] ? kS0 : kTR, kTR, kBR, kS0}}); // degenerate
                    subtiles.push_back({{kTL, kTR, kS0, kS1}});
                    break;
                case 3:
                    // Fall through, an adjacent edge split that hits edge 3 should have first found
                    // been found with edge 0 or edge 2 for the other end
                default:
                    SkASSERT(false);
                    return 0;
            }
        }

        SkPoint sub[4];
        bool subAA[4];
        int draws = 0;
        for (int i = 0; i < subtiles.count(); ++i) {
            // Fill in the quad points and update edge AA rules for new interior edges
            for (int j = 0; j < 4; ++j) {
                int p = subtiles[i][j];
                sub[j] = points[p];

                int np = j == 3 ? subtiles[i][0] : subtiles[i][j + 1];
                // The "new" edges are the edges that connect between the two split points or
                // between a split point and the chosen s2 point. Otherwise the edge remains aligned
                // with the original shape, so should preserve the AA setting.
                if ((p >= kS0 && (np == s2 || np >= kS0)) ||
                    ((np >= kS0) && (p == s2 || p >= kS0))) {
                    // New edge
                    subAA[j] = false;
                } else {
                    // The subtiles indices were arranged so that their edge ordering was still top,
                    // right, bottom, left so 'j' can be used to access edgeAA
                    subAA[j] = edgeAA[j];
                }
            }

            // Split the sub quad with the next line
            draws += this->clipTile(canvas, tileID, baseRect, sub, subAA, lines + 2, lineCount - 1,
                                    quadCount);
        }
        return draws;
    }
};

static constexpr int kMatrixCount = 5;

class CompositorGM : public skiagm::GM {
public:
    CompositorGM(const char* name, std::function<ClipTileRendererArray()> makeRendererFn)
            : fMakeRendererFn(std::move(makeRendererFn))
            , fName(name) {}

protected:
    SkISize onISize() override {
        // Initialize the array of renderers.
        this->onceBeforeDraw();

        // The GM draws a grid of renderers (rows) x transforms (col). Within each cell, the
        // renderer draws the transformed tile grid, which is approximately
        // (kColCount*kTileWidth, kRowCount*kTileHeight), although it has additional line
        // visualizations and can be transformed outside of those rectangular bounds (i.e. persp),
        // so pad the cell dimensions to be conservative. Must also account for the banner text.
        static constexpr SkScalar kCellWidth = 1.3f * kColCount * kTileWidth;
        static constexpr SkScalar kCellHeight = 1.3f * kRowCount * kTileHeight;
        return SkISize::Make(SkScalarRoundToInt(kCellWidth * kMatrixCount + 175.f),
                             SkScalarRoundToInt(kCellHeight * fRenderers.count() + 75.f));
    }

    SkString onShortName() override {
        SkString fullName;
        fullName.appendf("compositor_quads_%s", fName.c_str());
        return fullName;
    }

    void onOnceBeforeDraw() override {
        fRenderers = fMakeRendererFn();
        this->configureMatrices();
    }

    void onDraw(SkCanvas* canvas) override {
        static constexpr SkScalar kGap = 40.f;
        static constexpr SkScalar kBannerWidth = 120.f;
        static constexpr SkScalar kOffset = 15.f;

        SkTArray<int> drawCounts(fRenderers.count());
        drawCounts.push_back_n(fRenderers.count(), 0);

        canvas->save();
        canvas->translate(kOffset + kBannerWidth, kOffset);
        for (int i = 0; i < fMatrices.count(); ++i) {
            canvas->save();
            draw_text(canvas, fMatrixNames[i].c_str());

            canvas->translate(0.f, kGap);
            for (int j = 0; j < fRenderers.count(); ++j) {
                canvas->save();
                draw_tile_boundaries(canvas, fMatrices[i]);
                draw_clipping_boundaries(canvas, fMatrices[i]);

                canvas->concat(fMatrices[i]);
                drawCounts[j] += fRenderers[j]->drawTiles(canvas);

                canvas->restore();
                // And advance to the next row
                canvas->translate(0.f, kGap + kRowCount * kTileHeight);
            }
            // Reset back to the left edge
            canvas->restore();
            // And advance to the next column
            canvas->translate(kGap + kColCount * kTileWidth, 0.f);
        }
        canvas->restore();

        // Print a row header, with total draw counts
        canvas->save();
        canvas->translate(kOffset, kGap + 0.5f * kRowCount * kTileHeight);
        for (int j = 0; j < fRenderers.count(); ++j) {
            fRenderers[j]->drawBanner(canvas);
            canvas->translate(0.f, 15.f);
            draw_text(canvas, SkStringPrintf("Draws = %d", drawCounts[j]).c_str());
            canvas->translate(0.f, kGap + kRowCount * kTileHeight);
        }
        canvas->restore();
    }

private:
    std::function<ClipTileRendererArray()> fMakeRendererFn;
    ClipTileRendererArray fRenderers;
    SkTArray<SkMatrix> fMatrices;
    SkTArray<SkString> fMatrixNames;

    SkString fName;

    void configureMatrices() {
        fMatrices.reset();
        fMatrixNames.reset();
        fMatrices.push_back_n(kMatrixCount);

        // Identity
        fMatrices[0].setIdentity();
        fMatrixNames.push_back(SkString("Identity"));

        // Translate/scale
        fMatrices[1].setTranslate(5.5f, 20.25f);
        fMatrices[1].postScale(.9f, .7f);
        fMatrixNames.push_back(SkString("T+S"));

        // Rotation
        fMatrices[2].setRotate(20.0f);
        fMatrices[2].preTranslate(15.f, -20.f);
        fMatrixNames.push_back(SkString("Rotate"));

        // Skew
        fMatrices[3].setSkew(.5f, .25f);
        fMatrices[3].preTranslate(-30.f, 0.f);
        fMatrixNames.push_back(SkString("Skew"));

        // Perspective
        SkPoint src[4];
        SkRect::MakeWH(kColCount * kTileWidth, kRowCount * kTileHeight).toQuad(src);
        SkPoint dst[4] = {{0, 0},
                          {kColCount * kTileWidth + 10.f, 15.f},
                          {kColCount * kTileWidth - 28.f, kRowCount * kTileHeight + 40.f},
                          {25.f, kRowCount * kTileHeight - 15.f}};
        SkAssertResult(fMatrices[4].setPolyToPoly(src, dst, 4));
        fMatrices[4].preTranslate(0.f, 10.f);
        fMatrixNames.push_back(SkString("Perspective"));

        SkASSERT(fMatrices.count() == fMatrixNames.count());
    }

    using INHERITED = skiagm::GM;
};

////////////////////////////////////////////////////////////////////////////////////////////////
// Implementations of TileRenderer that color the clipped tiles in various ways
////////////////////////////////////////////////////////////////////////////////////////////////

class DebugTileRenderer : public ClipTileRenderer {
public:

    static sk_sp<ClipTileRenderer> Make() {
        // Since aa override is disabled, the quad flags arg doesn't matter.
        return sk_sp<ClipTileRenderer>(new DebugTileRenderer(SkCanvas::kAll_QuadAAFlags, false));
    }

    static sk_sp<ClipTileRenderer> MakeAA() {
        return sk_sp<ClipTileRenderer>(new DebugTileRenderer(SkCanvas::kAll_QuadAAFlags, true));
    }

    static sk_sp<ClipTileRenderer> MakeNonAA() {
        return sk_sp<ClipTileRenderer>(new DebugTileRenderer(SkCanvas::kNone_QuadAAFlags, true));
    }

    int drawTile(SkCanvas* canvas, const SkRect& rect, const SkPoint clip[4], const bool edgeAA[4],
                  int tileID, int quadID) override {
        // Colorize the tile based on its grid position and quad ID
        int i = tileID / kColCount;
        int j = tileID % kColCount;

        SkColor4f c = {(i + 1.f) / kRowCount, (j + 1.f) / kColCount, .4f, 1.f};
        float alpha = quadID / 10.f;
        c.fR = c.fR * (1 - alpha) + alpha;
        c.fG = c.fG * (1 - alpha) + alpha;
        c.fB = c.fB * (1 - alpha) + alpha;
        c.fA = c.fA * (1 - alpha) + alpha;

        SkCanvas::QuadAAFlags aaFlags = fEnableAAOverride ? fAAOverride : this->maskToFlags(edgeAA);
        canvas->experimental_DrawEdgeAAQuad(
                rect, clip, aaFlags, c.toSkColor(), SkBlendMode::kSrcOver);
        return 1;
    }

    void drawBanner(SkCanvas* canvas) override {
        draw_text(canvas, "Edge AA");
        canvas->translate(0.f, 15.f);

        SkString config;
        static const char* kFormat = "Ext(%s) - Int(%s)";
        if (fEnableAAOverride) {
            SkASSERT(fAAOverride == SkCanvas::kAll_QuadAAFlags ||
                     fAAOverride == SkCanvas::kNone_QuadAAFlags);
            if (fAAOverride == SkCanvas::kAll_QuadAAFlags) {
                config.appendf(kFormat, "yes", "yes");
            } else {
                config.appendf(kFormat, "no", "no");
            }
        } else {
            config.appendf(kFormat, "yes", "no");
        }
        draw_text(canvas, config.c_str());
    }

private:
    SkCanvas::QuadAAFlags fAAOverride;
    bool fEnableAAOverride;

    DebugTileRenderer(SkCanvas::QuadAAFlags aa, bool enableAAOverrde)
            : fAAOverride(aa)
            , fEnableAAOverride(enableAAOverrde) {}

    using INHERITED = ClipTileRenderer;
};

// Tests tmp_drawEdgeAAQuad
class SolidColorRenderer : public ClipTileRenderer {
public:

    static sk_sp<ClipTileRenderer> Make(const SkColor4f& color) {
        return sk_sp<ClipTileRenderer>(new SolidColorRenderer(color));
    }

    int drawTile(SkCanvas* canvas, const SkRect& rect, const SkPoint clip[4], const bool edgeAA[4],
                  int tileID, int quadID) override {
        canvas->experimental_DrawEdgeAAQuad(rect, clip, this->maskToFlags(edgeAA),
                                            fColor.toSkColor(), SkBlendMode::kSrcOver);
        return 1;
    }

    void drawBanner(SkCanvas* canvas) override {
        draw_text(canvas, "Solid Color");
    }

private:
    SkColor4f fColor;

    SolidColorRenderer(const SkColor4f& color) : fColor(color) {}

    using INHERITED = ClipTileRenderer;
};

// Tests drawEdgeAAImageSet(), but can batch the entries together in different ways
class TextureSetRenderer : public ClipTileRenderer {
public:

    static sk_sp<ClipTileRenderer> MakeUnbatched(sk_sp<SkImage> image) {
        return Make("Texture", "", std::move(image), nullptr, nullptr, nullptr, nullptr,
                    1.f, true, 0);
    }

    static sk_sp<ClipTileRenderer> MakeBatched(sk_sp<SkImage> image, int transformCount) {
        const char* subtitle = transformCount == 0 ? "" : "w/ xforms";
        return Make("Texture Set", subtitle, std::move(image), nullptr, nullptr, nullptr, nullptr,
                    1.f, false, transformCount);
    }

    static sk_sp<ClipTileRenderer> MakeShader(const char* name, sk_sp<SkImage> image,
                                              sk_sp<SkShader> shader, bool local) {
        return Make("Shader", name, std::move(image), std::move(shader),
                    nullptr, nullptr, nullptr, 1.f, local, 0);
    }

    static sk_sp<ClipTileRenderer> MakeColorFilter(const char* name, sk_sp<SkImage> image,
                                                   sk_sp<SkColorFilter> filter) {
        return Make("Color Filter", name, std::move(image), nullptr, std::move(filter), nullptr,
                    nullptr, 1.f, false, 0);
    }

    static sk_sp<ClipTileRenderer> MakeImageFilter(const char* name, sk_sp<SkImage> image,
                                                   sk_sp<SkImageFilter> filter) {
        return Make("Image Filter", name, std::move(image), nullptr, nullptr, std::move(filter),
                    nullptr, 1.f, false, 0);
    }

    static sk_sp<ClipTileRenderer> MakeMaskFilter(const char* name, sk_sp<SkImage> image,
                                                  sk_sp<SkMaskFilter> filter) {
        return Make("Mask Filter", name, std::move(image), nullptr, nullptr, nullptr,
                    std::move(filter), 1.f, false, 0);
    }

    static sk_sp<ClipTileRenderer> MakeAlpha(sk_sp<SkImage> image, SkScalar alpha) {
        return Make("Alpha", SkStringPrintf("a = %.2f", alpha).c_str(), std::move(image), nullptr,
                    nullptr, nullptr, nullptr, alpha, false, 0);
    }

    static sk_sp<ClipTileRenderer> Make(const char* topBanner, const char* bottomBanner,
                                        sk_sp<SkImage> image, sk_sp<SkShader> shader,
                                        sk_sp<SkColorFilter> colorFilter,
                                        sk_sp<SkImageFilter> imageFilter,
                                        sk_sp<SkMaskFilter> maskFilter, SkScalar paintAlpha,
                                        bool resetAfterEachQuad, int transformCount) {
        return sk_sp<ClipTileRenderer>(new TextureSetRenderer(topBanner, bottomBanner,
                std::move(image), std::move(shader), std::move(colorFilter), std::move(imageFilter),
                std::move(maskFilter), paintAlpha, resetAfterEachQuad, transformCount));
    }

    int drawTiles(SkCanvas* canvas) override {
        int draws = this->INHERITED::drawTiles(canvas);
        // Push the last tile set
        draws += this->drawAndReset(canvas);
        return draws;
    }

    int drawTile(SkCanvas* canvas, const SkRect& rect, const SkPoint clip[4], const bool edgeAA[4],
                  int tileID, int quadID) override {
        // Now don't actually draw the tile, accumulate it in the growing entry set
        bool hasClip = false;
        if (clip) {
            // Record the four points into fDstClips
            fDstClips.push_back_n(4, clip);
            hasClip = true;
        }

        int matrixIdx = -1;
        if (!fResetEachQuad && fTransformBatchCount > 0) {
            // Handle transform batching. This works by capturing the CTM of the first tile draw,
            // and then calculate the difference between that and future CTMs for later tiles.
            if (fPreViewMatrices.count() == 0) {
                fBaseCTM = canvas->getTotalMatrix();
                fPreViewMatrices.push_back(SkMatrix::I());
                matrixIdx = 0;
            } else {
                // Calculate matrix s.t. getTotalMatrix() = fBaseCTM * M
                SkMatrix invBase;
                if (!fBaseCTM.invert(&invBase)) {
                    SkDebugf("Cannot invert CTM, transform batching will not be correct.\n");
                } else {
                    SkMatrix preView = SkMatrix::Concat(invBase, canvas->getTotalMatrix());
                    if (preView != fPreViewMatrices[fPreViewMatrices.count() - 1]) {
                        // Add the new matrix
                        fPreViewMatrices.push_back(preView);
                    } // else re-use the last matrix
                    matrixIdx = fPreViewMatrices.count() - 1;
                }
            }
        }

        // This acts like the whole image is rendered over the entire tile grid, so derive local
        // coordinates from 'rect', based on the grid to image transform.
        SkMatrix gridToImage = SkMatrix::RectToRect(SkRect::MakeWH(kColCount * kTileWidth,
                                                                   kRowCount * kTileHeight),
                                                    SkRect::MakeWH(fImage->width(),
                                                                   fImage->height()));
        SkRect localRect = gridToImage.mapRect(rect);

        // drawTextureSet automatically derives appropriate local quad from localRect if clipPtr
        // is not null.
        fSetEntries.push_back(
                {fImage, localRect, rect, matrixIdx, 1.f, this->maskToFlags(edgeAA), hasClip});

        if (fResetEachQuad) {
            // Only ever draw one entry at a time
            return this->drawAndReset(canvas);
        } else {
            return 0;
        }
    }

    void drawBanner(SkCanvas* canvas) override {
        if (fTopBanner.size() > 0) {
            draw_text(canvas, fTopBanner.c_str());
        }
        canvas->translate(0.f, 15.f);
        if (fBottomBanner.size() > 0) {
            draw_text(canvas, fBottomBanner.c_str());
        }
    }

private:
    SkString fTopBanner;
    SkString fBottomBanner;

    sk_sp<SkImage> fImage;
    sk_sp<SkShader> fShader;
    sk_sp<SkColorFilter> fColorFilter;
    sk_sp<SkImageFilter> fImageFilter;
    sk_sp<SkMaskFilter> fMaskFilter;
    SkScalar fPaintAlpha;

    // Batching rules
    bool fResetEachQuad;
    int fTransformBatchCount;

    SkTArray<SkPoint> fDstClips;
    SkTArray<SkMatrix> fPreViewMatrices;
    SkTArray<SkCanvas::ImageSetEntry> fSetEntries;

    SkMatrix fBaseCTM;
    int fBatchCount;

    TextureSetRenderer(const char* topBanner,
                       const char* bottomBanner,
                       sk_sp<SkImage> image,
                       sk_sp<SkShader> shader,
                       sk_sp<SkColorFilter> colorFilter,
                       sk_sp<SkImageFilter> imageFilter,
                       sk_sp<SkMaskFilter> maskFilter,
                       SkScalar paintAlpha,
                       bool resetEachQuad,
                       int transformBatchCount)
            : fTopBanner(topBanner)
            , fBottomBanner(bottomBanner)
            , fImage(std::move(image))
            , fShader(std::move(shader))
            , fColorFilter(std::move(colorFilter))
            , fImageFilter(std::move(imageFilter))
            , fMaskFilter(std::move(maskFilter))
            , fPaintAlpha(paintAlpha)
            , fResetEachQuad(resetEachQuad)
            , fTransformBatchCount(transformBatchCount)
            , fBatchCount(0) {
        SkASSERT(transformBatchCount >= 0 && (!resetEachQuad || transformBatchCount == 0));
    }

    void configureTilePaint(const SkRect& rect, SkPaint* paint) const {
        paint->setAntiAlias(true);
        paint->setBlendMode(SkBlendMode::kSrcOver);

        // Send non-white RGB, that should be ignored
        paint->setColor4f({1.f, 0.4f, 0.25f, fPaintAlpha}, nullptr);


        if (fShader) {
            if (fResetEachQuad) {
                // Apply a local transform in the shader to map from the tile rectangle to (0,0,w,h)
                static const SkRect kTarget = SkRect::MakeWH(kTileWidth, kTileHeight);
                SkMatrix local = SkMatrix::RectToRect(kTarget, rect);
                paint->setShader(fShader->makeWithLocalMatrix(local));
            } else {
                paint->setShader(fShader);
            }
        }

        paint->setColorFilter(fColorFilter);
        paint->setImageFilter(fImageFilter);
        paint->setMaskFilter(fMaskFilter);
    }

    int drawAndReset(SkCanvas* canvas) {
        // Early out if there's nothing to draw
        if (fSetEntries.count() == 0) {
            SkASSERT(fDstClips.count() == 0 && fPreViewMatrices.count() == 0);
            return 0;
        }

        if (!fResetEachQuad && fTransformBatchCount > 0) {
            // A batch is completed
            fBatchCount++;
            if (fBatchCount < fTransformBatchCount) {
                // Haven't hit the point to submit yet, but end the current tile
                return 0;
            }

            // Submitting all tiles back to where fBaseCTM was the canvas' matrix, while the
            // canvas currently has the CTM of the last tile batch, so reset it.
            canvas->setMatrix(fBaseCTM);
        }

#ifdef SK_DEBUG
        int expectedDstClipCount = 0;
        for (int i = 0; i < fSetEntries.count(); ++i) {
            expectedDstClipCount += 4 * fSetEntries[i].fHasClip;
            SkASSERT(fSetEntries[i].fMatrixIndex < 0 ||
                     fSetEntries[i].fMatrixIndex < fPreViewMatrices.count());
        }
        SkASSERT(expectedDstClipCount == fDstClips.count());
#endif

        SkPaint paint;
        SkRect lastTileRect = fSetEntries[fSetEntries.count() - 1].fDstRect;
        this->configureTilePaint(lastTileRect, &paint);

        canvas->experimental_DrawEdgeAAImageSet(
                fSetEntries.begin(), fSetEntries.count(), fDstClips.begin(),
                fPreViewMatrices.begin(), SkSamplingOptions(SkFilterMode::kLinear),
                &paint, SkCanvas::kFast_SrcRectConstraint);

        // Reset for next tile
        fDstClips.reset();
        fPreViewMatrices.reset();
        fSetEntries.reset();
        fBatchCount = 0;

        return 1;
    }

    using INHERITED = ClipTileRenderer;
};

class YUVTextureSetRenderer : public ClipTileRenderer {
public:
    static sk_sp<ClipTileRenderer> MakeFromJPEG(sk_sp<SkData> imageData) {
        return sk_sp<ClipTileRenderer>(new YUVTextureSetRenderer(std::move(imageData)));
    }

    int drawTiles(SkCanvas* canvas) override {
        // Refresh the SkImage at the start, so that it's not attempted for every set entry
        if (fYUVData) {
            fImage = fYUVData->refImage(canvas->recordingContext(),
                                        sk_gpu_test::LazyYUVImage::Type::kFromPixmaps);
            if (!fImage) {
                return 0;
            }
        }

        int draws = this->INHERITED::drawTiles(canvas);
        // Push the last tile set
        draws += this->drawAndReset(canvas);
        return draws;
    }

    int drawTile(SkCanvas* canvas, const SkRect& rect, const SkPoint clip[4], const bool edgeAA[4],
                  int tileID, int quadID) override {
        SkASSERT(fImage);
        // Now don't actually draw the tile, accumulate it in the growing entry set
        bool hasClip = false;
        if (clip) {
            // Record the four points into fDstClips
            fDstClips.push_back_n(4, clip);
            hasClip = true;
        }

        // This acts like the whole image is rendered over the entire tile grid, so derive local
        // coordinates from 'rect', based on the grid to image transform.
        SkMatrix gridToImage = SkMatrix::RectToRect(SkRect::MakeWH(kColCount * kTileWidth,
                                                                   kRowCount * kTileHeight),
                                                    SkRect::MakeWH(fImage->width(),
                                                                   fImage->height()));
        SkRect localRect = gridToImage.mapRect(rect);

        // drawTextureSet automatically derives appropriate local quad from localRect if clipPtr
        // is not null. Also exercise per-entry alpha combined with YUVA images.
        fSetEntries.push_back(
                {fImage, localRect, rect, -1, .5f, this->maskToFlags(edgeAA), hasClip});
        return 0;
    }

    void drawBanner(SkCanvas* canvas) override {
        draw_text(canvas, "Texture");
        canvas->translate(0.f, 15.f);
        draw_text(canvas, "YUV + alpha - GPU Only");
    }

private:
    std::unique_ptr<sk_gpu_test::LazyYUVImage> fYUVData;
    // The last accessed SkImage from fYUVData, held here for easy access by drawTile
    sk_sp<SkImage> fImage;

    SkTArray<SkPoint> fDstClips;
    SkTArray<SkCanvas::ImageSetEntry> fSetEntries;

    YUVTextureSetRenderer(sk_sp<SkData> jpegData)
            : fYUVData(sk_gpu_test::LazyYUVImage::Make(std::move(jpegData)))
            , fImage(nullptr) {}

    int drawAndReset(SkCanvas* canvas) {
        // Early out if there's nothing to draw
        if (fSetEntries.count() == 0) {
            SkASSERT(fDstClips.count() == 0);
            return 0;
        }

#ifdef SK_DEBUG
        int expectedDstClipCount = 0;
        for (int i = 0; i < fSetEntries.count(); ++i) {
            expectedDstClipCount += 4 * fSetEntries[i].fHasClip;
        }
        SkASSERT(expectedDstClipCount == fDstClips.count());
#endif

        SkPaint paint;
        paint.setAntiAlias(true);
        paint.setBlendMode(SkBlendMode::kSrcOver);

        canvas->experimental_DrawEdgeAAImageSet(
                fSetEntries.begin(), fSetEntries.count(), fDstClips.begin(), nullptr,
                SkSamplingOptions(SkFilterMode::kLinear), &paint,
                SkCanvas::kFast_SrcRectConstraint);

        // Reset for next tile
        fDstClips.reset();
        fSetEntries.reset();

        return 1;
    }

    using INHERITED = ClipTileRenderer;
};

static ClipTileRendererArray make_debug_renderers() {
    return ClipTileRendererArray{DebugTileRenderer::Make(),
                                 DebugTileRenderer::MakeAA(),
                                 DebugTileRenderer::MakeNonAA()};
}

static ClipTileRendererArray make_solid_color_renderers() {
    return ClipTileRendererArray{SolidColorRenderer::Make({.2f, .8f, .3f, 1.f})};
}

static ClipTileRendererArray make_shader_renderers() {
    static constexpr SkPoint kPts[] = { {0.f, 0.f}, {0.25f * kTileWidth, 0.25f * kTileHeight} };
    static constexpr SkColor kColors[] = { SK_ColorBLUE, SK_ColorWHITE };
    auto gradient = SkGradientShader::MakeLinear(kPts, kColors, nullptr, 2,
                                                 SkTileMode::kMirror);

    auto info = SkImageInfo::Make(1, 1, kAlpha_8_SkColorType, kOpaque_SkAlphaType);
    SkBitmap bm;
    bm.allocPixels(info);
    bm.eraseColor(SK_ColorWHITE);
    sk_sp<SkImage> image = bm.asImage();

    return ClipTileRendererArray{
               TextureSetRenderer::MakeShader("Gradient", image, gradient, false),
               TextureSetRenderer::MakeShader("Local Gradient", image, gradient, true)};
}

static ClipTileRendererArray make_image_renderers() {
    sk_sp<SkImage> mandrill = GetResourceAsImage("images/mandrill_512.png");
    sk_sp<SkData> mandrillJpeg = GetResourceAsData("images/mandrill_h1v1.jpg");
    return ClipTileRendererArray{TextureSetRenderer::MakeUnbatched(mandrill),
                                 TextureSetRenderer::MakeBatched(mandrill, 0),
                                 TextureSetRenderer::MakeBatched(mandrill, kMatrixCount),
                                 YUVTextureSetRenderer::MakeFromJPEG(mandrillJpeg)};
}

static ClipTileRendererArray make_filtered_renderers() {
    sk_sp<SkImage> mandrill = GetResourceAsImage("images/mandrill_512.png");

    SkColorMatrix cm;
    cm.setSaturation(10);
    sk_sp<SkColorFilter> colorFilter = SkColorFilters::Matrix(cm);
    sk_sp<SkImageFilter> imageFilter = SkImageFilters::Dilate(8, 8, nullptr);

    static constexpr SkColor kAlphas[] = { SK_ColorTRANSPARENT, SK_ColorBLACK };
    auto alphaGradient = SkGradientShader::MakeRadial(
            {0.5f * kTileWidth * kColCount, 0.5f * kTileHeight * kRowCount},
            0.25f * kTileWidth * kColCount, kAlphas, nullptr, 2, SkTileMode::kClamp);
    sk_sp<SkMaskFilter> maskFilter = SkShaderMaskFilter::Make(std::move(alphaGradient));

    return ClipTileRendererArray{
               TextureSetRenderer::MakeAlpha(mandrill, 0.5f),
               TextureSetRenderer::MakeColorFilter("Saturation", mandrill, std::move(colorFilter)),

    // NOTE: won't draw correctly until SkCanvas' AutoLoopers are used to handle image filters
               TextureSetRenderer::MakeImageFilter("Dilate", mandrill, std::move(imageFilter)),

    // NOTE: blur mask filters do work (tested locally), but visually they don't make much
    // sense, since each quad is blurred independently
               TextureSetRenderer::MakeMaskFilter("Shader", mandrill, std::move(maskFilter))};
}

DEF_GM(return new CompositorGM("debug",  make_debug_renderers);)
DEF_GM(return new CompositorGM("color",  make_solid_color_renderers);)
DEF_GM(return new CompositorGM("shader", make_shader_renderers);)
DEF_GM(return new CompositorGM("image",  make_image_renderers);)
DEF_GM(return new CompositorGM("filter", make_filtered_renderers);)
