/*
 * Copyright 2019 Google LLC
 *
 * 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/SkGradient.h"
#include "include/effects/SkImageFilters.h"
#include "include/effects/SkShaderMaskFilter.h"
#include "include/private/SkTArray.h"
#include "src/core/SkLineClipper.h"
#include "tools/DecodeUtils.h"
#include "tools/Resources.h"
#include "tools/ToolUtils.h"
#include "tools/fonts/FontToolUtils.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, 2}, {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::DefaultPortableTypeface(), 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

        std::array<SkPoint, 6> points;
        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.copyToQuad(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.
        std::array<int, 2> splitIndices;  // 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];
        std::array<bool, 4> subAA;
        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.data(),
                                    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 getISize() 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 getName() const 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
        const std::array<SkPoint, 4> src = SkRect::MakeWH(kColCount * kTileWidth,
                                                          kRowCount * kTileHeight).toQuad();
        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));
        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::RectToRectOrIdentity(
                                    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::RectToRectOrIdentity(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) {
#if defined(SK_GANESH)
            fImage = fYUVData->refImage(canvas->recordingContext(),
                                        sk_gpu_test::LazyYUVImage::Type::kFromPixmaps);

#endif
            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::RectToRectOrIdentity(
                                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 SkColor4f kColors[] = { SkColors::kBlue, SkColors::kWhite };
    auto gradient = SkShaders::LinearGradient(kPts, {{kColors, {}, 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 = ToolUtils::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 = ToolUtils::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 SkColor4f kAlphas[] = { SkColors::kTransparent, SkColors::kBlack };
    auto alphaGradient = SkShaders::RadialGradient(
            {0.5f * kTileWidth * kColCount, 0.5f * kTileHeight * kRowCount},
            0.25f * kTileWidth * kColCount, {{kAlphas, {}, 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);)
