/*
 * 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/base/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>

using namespace skia_private;

class ClipTileRenderer;
using ClipTileRendererArray = TArray<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.
        STArray<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.size(); ++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.size() + 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;

        TArray<int> drawCounts(fRenderers.size());
        drawCounts.push_back_n(fRenderers.size(), 0);

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

            canvas->translate(0.f, kGap);
            for (int j = 0; j < fRenderers.size(); ++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.size(); ++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;
    TArray<SkMatrix> fMatrices;
    TArray<SkString> fMatrixNames;

    SkString fName;

    void configureMatrices() {
        fMatrices.clear();
        fMatrixNames.clear();
        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.size() == fMatrixNames.size());
    }

    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;
        constexpr 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.size() == 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.size() - 1]) {
                        // Add the new matrix
                        fPreViewMatrices.push_back(preView);
                    } // else re-use the last matrix
                    matrixIdx = fPreViewMatrices.size() - 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;

    TArray<SkPoint> fDstClips;
    TArray<SkMatrix> fPreViewMatrices;
    TArray<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.size() == 0) {
            SkASSERT(fDstClips.size() == 0 && fPreViewMatrices.size() == 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.size(); ++i) {
            expectedDstClipCount += 4 * fSetEntries[i].fHasClip;
            SkASSERT(fSetEntries[i].fMatrixIndex < 0 ||
                     fSetEntries[i].fMatrixIndex < fPreViewMatrices.size());
        }
        SkASSERT(expectedDstClipCount == fDstClips.size());
#endif

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

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

        // Reset for next tile
        fDstClips.clear();
        fPreViewMatrices.clear();
        fSetEntries.clear();
        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;

    TArray<SkPoint> fDstClips;
    TArray<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.size() == 0) {
            SkASSERT(fDstClips.size() == 0);
            return 0;
        }

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

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

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

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

        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);)
