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

#include "gm/gm.h"
#include "include/core/SkBlendMode.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkFont.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPicture.h"
#include "include/core/SkPictureRecorder.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/SkTypes.h"
#include "include/effects/SkGradient.h"
#include "include/private/SkAssert.h"
#include "include/private/SkFloatingPoint.h"
#include "src/core/SkColorPriv.h"
#include "tools/ToolUtils.h"
#include "tools/fonts/FontToolUtils.h"

#include <array>
#include <initializer_list>
#include <math.h>

namespace {

struct GradData {
    SkSpan<const SkColor4f> fColors;
    SkSpan<const float>     fPos;
};

constexpr SkColor4f gColors[] ={
    SkColors::kRed,
    SkColors::kGreen,
    SkColors::kBlue,
    SkColors::kWhite,
    SkColors::kBlack,
};
constexpr SkScalar gPos0[] = { 0, SK_Scalar1 };
constexpr SkScalar gPos1[] = { SK_Scalar1/4, SK_Scalar1*3/4 };
constexpr SkScalar gPos2[] = {
    0, SK_Scalar1/8, SK_Scalar1/2, SK_Scalar1*7/8, SK_Scalar1
};

constexpr SkScalar gPosClamp[]   = {0.0f, 0.0f, 1.0f, 1.0f};
constexpr SkColor4f gColor4fClamp[] = {
    SkColors::kRed,
    SkColors::kGreen,
    SkColors::kGreen,
    SkColors::kBlue,
};
static constexpr auto gGradData = std::to_array<GradData>({
        GradData{ {gColors, 2},        {}},
        GradData{ {gColors, 2},     gPos0},
        GradData{ {gColors, 2},     gPos1},
        GradData{ {gColors, 5},        {}},
        GradData{ {gColors, 5},     gPos2},
        GradData{gColor4fClamp, gPosClamp}
});

static sk_sp<SkShader> MakeLinear(const SkPoint pts[2], const GradData& data,
                                  SkTileMode tm, const SkMatrix& localMatrix) {
    return SkShaders::LinearGradient(pts, {{data.fColors, data.fPos, tm}, {}}, &localMatrix);
}

static sk_sp<SkShader> MakeRadial(const SkPoint pts[2], const GradData& data,
                                  SkTileMode tm, const SkMatrix& localMatrix) {
    SkPoint center;
    center.set(sk_float_midpoint(pts[0].fX, pts[1].fX),
               sk_float_midpoint(pts[0].fY, pts[1].fY));
    return SkShaders::RadialGradient(center, center.fX, {{data.fColors, data.fPos, tm}, {}},
                                     &localMatrix);
}

static sk_sp<SkShader> MakeSweep(const SkPoint pts[2], const GradData& data,
                                 SkTileMode tm, const SkMatrix& localMatrix) {
    SkPoint center;
    center.set(sk_float_midpoint(pts[0].fX, pts[1].fX),
               sk_float_midpoint(pts[0].fY, pts[1].fY));
    return SkShaders::SweepGradient(center, {{data.fColors, data.fPos, tm}, {}}, &localMatrix);
}

static sk_sp<SkShader> Make2Radial(const SkPoint pts[2], const GradData& data,
                                   SkTileMode tm, const SkMatrix& localMatrix) {
    SkPoint center0, center1;
    center0.set(sk_float_midpoint(pts[0].fX, pts[1].fX),
                sk_float_midpoint(pts[0].fY, pts[1].fY));
    center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5),
                SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4));
    return SkShaders::TwoPointConicalGradient(center1, (pts[1].fX - pts[0].fX) / 7,
                                              center0, (pts[1].fX - pts[0].fX) / 2,
                                              {{data.fColors, data.fPos, tm}, {}}, &localMatrix);
}

static sk_sp<SkShader> Make2Conical(const SkPoint pts[2], const GradData& data,
                                    SkTileMode tm, const SkMatrix& localMatrix) {
    SkPoint center0, center1;
    SkScalar radius0 = (pts[1].fX - pts[0].fX) / 10;
    SkScalar radius1 = (pts[1].fX - pts[0].fX) / 3;
    center0.set(pts[0].fX + radius0, pts[0].fY + radius0);
    center1.set(pts[1].fX - radius1, pts[1].fY - radius1);
    return SkShaders::TwoPointConicalGradient(center1, radius1, center0, radius0,
                                              {{data.fColors, data.fPos, tm}, {}}, &localMatrix);
}

typedef sk_sp<SkShader> (*GradMaker)(const SkPoint pts[2], const GradData& data,
                                     SkTileMode tm, const SkMatrix& localMatrix);
static constexpr auto gGradMakers = std::to_array<GradMaker>({
        MakeLinear,
        MakeRadial,
        MakeSweep,
        Make2Radial,
        Make2Conical,
});

///////////////////////////////////////////////////////////////////////////////

class GradientsGM : public skiagm::GM {
public:
    GradientsGM(bool dither) : fDither(dither) {}

protected:
    const bool fDither;

    void onDraw(SkCanvas* canvas) override {
        SkPoint pts[2] = {
            { 0, 0 },
            { SkIntToScalar(100), SkIntToScalar(100) }
        };
        SkTileMode tm = SkTileMode::kClamp;
        SkRect r = { 0, 0, SkIntToScalar(100), SkIntToScalar(100) };
        SkPaint paint;
        paint.setAntiAlias(true);
        paint.setDither(fDither);

        canvas->translate(SkIntToScalar(20), SkIntToScalar(20));
        for (size_t i = 0; i < std::size(gGradData); i++) {
            canvas->save();
            for (size_t j = 0; j < std::size(gGradMakers); j++) {
                SkMatrix scale = SkMatrix::I();

                if (i == 5) { // if the clamp case
                    scale.setScale(0.5f, 0.5f);
                    scale.postTranslate(25.f, 25.f);
                }

                paint.setShader(gGradMakers[j](pts, gGradData[i], tm, scale));
                canvas->drawRect(r, paint);
                canvas->translate(0, SkIntToScalar(120));
            }
            canvas->restore();
            canvas->translate(SkIntToScalar(120), 0);
        }
    }

private:
    void onOnceBeforeDraw() override { this->setBGColor(0xFFDDDDDD); }

    SkString getName() const override {
        return SkString(fDither ? "gradients" : "gradients_nodither");
    }

    SkISize getISize() override { return {840, 815}; }
};
DEF_GM( return new GradientsGM(true); )
DEF_GM( return new GradientsGM(false); )

// Based on the original gradient slide, but with perspective applied to the
// gradient shaders' local matrices
class GradientsLocalPerspectiveGM : public skiagm::GM {
public:
    GradientsLocalPerspectiveGM(bool dither) : fDither(dither) {
        this->setBGColor(0xFFDDDDDD);
    }

private:
    SkString getName() const override {
        return SkString(fDither ? "gradients_local_perspective" :
                                  "gradients_local_perspective_nodither");
    }

    SkISize getISize() override { return {840, 815}; }

    void onDraw(SkCanvas* canvas) override {
        SkPoint pts[2] = {
            { 0, 0 },
            { SkIntToScalar(100), SkIntToScalar(100) }
        };
        SkTileMode tm = SkTileMode::kClamp;
        SkRect r = { 0, 0, SkIntToScalar(100), SkIntToScalar(100) };
        SkPaint paint;
        paint.setAntiAlias(true);
        paint.setDither(fDither);

        canvas->translate(SkIntToScalar(20), SkIntToScalar(20));
        for (size_t i = 0; i < std::size(gGradData); i++) {
            canvas->save();
            for (size_t j = 0; j < std::size(gGradMakers); j++) {
                // apply an increasing y perspective as we move to the right
                SkMatrix perspective;
                perspective.setIdentity();
                perspective.setPerspY(SkIntToScalar(i+1) / 500);
                perspective.setSkewX(SkIntToScalar(i+1) / 10);

                paint.setShader(gGradMakers[j](pts, gGradData[i], tm, perspective));
                canvas->drawRect(r, paint);
                canvas->translate(0, SkIntToScalar(120));
            }
            canvas->restore();
            canvas->translate(SkIntToScalar(120), 0);
        }
    }

    bool fDither;
};
DEF_GM( return new GradientsLocalPerspectiveGM(true); )
DEF_GM( return new GradientsLocalPerspectiveGM(false); )

// Based on the original gradient slide, but with perspective applied to
// the view matrix
class GradientsViewPerspectiveGM : public GradientsGM {
public:
    GradientsViewPerspectiveGM(bool dither) : INHERITED(dither) { }

private:
    SkString getName() const override {
        return SkString(fDither ? "gradients_view_perspective" :
                                  "gradients_view_perspective_nodither");
    }

    SkISize getISize() override { return {840, 500}; }

    void onDraw(SkCanvas* canvas) override {
        SkMatrix perspective;
        perspective.setIdentity();
        perspective.setPerspY(0.001f);
        perspective.setSkewX(SkIntToScalar(8) / 25);
        canvas->concat(perspective);
        this->INHERITED::onDraw(canvas);
    }

private:
    using INHERITED = GradientsGM;
};
DEF_GM( return new GradientsViewPerspectiveGM(true); )
DEF_GM( return new GradientsViewPerspectiveGM(false); )

/*
 Inspired by this <canvas> javascript, where we need to detect that we are not
 solving a quadratic equation, but must instead solve a linear (since our X^2
 coefficient is 0)

 ctx.fillStyle = '#f00';
 ctx.fillRect(0, 0, 100, 50);

 var g = ctx.createRadialGradient(-80, 25, 70, 0, 25, 150);
 g.addColorStop(0, '#f00');
 g.addColorStop(0.01, '#0f0');
 g.addColorStop(0.99, '#0f0');
 g.addColorStop(1, '#f00');
 ctx.fillStyle = g;
 ctx.fillRect(0, 0, 100, 50);
 */
class GradientsDegenrate2PointGM : public skiagm::GM {
public:
    GradientsDegenrate2PointGM(bool dither) : fDither(dither) {}

private:
    SkString getName() const override {
        return SkString(fDither ? "gradients_degenerate_2pt" : "gradients_degenerate_2pt_nodither");
    }

    SkISize getISize() override { return {320, 320}; }

    void onDraw(SkCanvas* canvas) override {
        canvas->drawColor(SK_ColorBLUE);

        SkColor4f colors[] = { SkColors::kRed, SkColors::kGreen, SkColors::kGreen, SkColors::kRed };
        SkScalar pos[] = { 0, 0.01f, 0.99f, SK_Scalar1 };
        SkPoint c0;
        c0.iset(-80, 25);
        SkScalar r0 = SkIntToScalar(70);
        SkPoint c1;
        c1.iset(0, 25);
        SkScalar r1 = SkIntToScalar(150);
        SkPaint paint;
        paint.setShader(SkShaders::TwoPointConicalGradient(c0, r0, c1, r1,
                                                       {{colors, pos, SkTileMode::kClamp}, {}}));
        paint.setDither(fDither);
        canvas->drawPaint(paint);
    }

    bool fDither;
};
DEF_GM( return new GradientsDegenrate2PointGM(true); )
DEF_GM( return new GradientsDegenrate2PointGM(false); )

/* skbug.com/40031542
<canvas id="canvas"></canvas>
<script>
var c = document.getElementById("canvas");
var ctx = c.getContext("2d");
ctx.fillStyle = '#ff0';
ctx.fillRect(0, 0, 100, 50);

var g = ctx.createRadialGradient(200, 25, 20, 200, 25, 10);
g.addColorStop(0, '#0f0');
g.addColorStop(0.003, '#f00');  // 0.004 makes this work
g.addColorStop(1, '#ff0');
ctx.fillStyle = g;
ctx.fillRect(0, 0, 100, 50);
</script>
*/

// should draw only green
DEF_SIMPLE_GM(small_color_stop, canvas, 100, 150) {
    SkColor4f colors[] = { SkColors::kGreen, SkColors::kRed, SkColors::kYellow };
    SkScalar pos[] = { 0, 0.003f, SK_Scalar1 };  // 0.004f makes this work
    SkPoint c0 = { 200, 25 };
    SkScalar r0 = 20;
    SkPoint c1 = { 200, 25 };
    SkScalar r1 = 10;

    SkPaint paint;
    paint.setColor(SK_ColorYELLOW);
    canvas->drawRect(SkRect::MakeWH(100, 150), paint);
    paint.setShader(SkShaders::TwoPointConicalGradient(c0, r0, c1, r1,
                                                       {{colors, pos, SkTileMode::kClamp}, {}}));
    canvas->drawRect(SkRect::MakeWH(100, 150), paint);
}


/// Tests correctness of *optimized* codepaths in gradients.

class ClampedGradientsGM : public skiagm::GM {
public:
    ClampedGradientsGM(bool dither) : fDither(dither) {}

private:
    SkString getName() const override {
        return SkString(fDither ? "clamped_gradients" : "clamped_gradients_nodither");
    }

    SkISize getISize() override { return {640, 510}; }

    void onDraw(SkCanvas* canvas) override {
        canvas->drawColor(0xFFDDDDDD);

        SkRect r = { 0, 0, SkIntToScalar(100), SkIntToScalar(300) };
        SkPaint paint;
        paint.setDither(fDither);
        paint.setAntiAlias(true);

        SkPoint center;
        center.iset(0, 300);
        canvas->translate(SkIntToScalar(20), SkIntToScalar(20));
        paint.setShader(SkShaders::RadialGradient(
            center, 200, {{gColors, {}, SkTileMode::kClamp}, {}}));
        canvas->drawRect(r, paint);
    }

    bool fDither;
};
DEF_GM( return new ClampedGradientsGM(true); )
DEF_GM( return new ClampedGradientsGM(false); )

/// Checks quality of large radial gradients, which may display
/// some banding.

class RadialGradientGM : public skiagm::GM {
    SkString getName() const override { return SkString("radial_gradient"); }

    SkISize getISize() override { return {1280, 1280}; }

    void onDraw(SkCanvas* canvas) override {
        const SkISize dim = this->getISize();

        canvas->drawColor(0xFF000000);

        SkPaint paint;
        paint.setDither(true);
        SkPoint center;
        center.set(SkIntToScalar(dim.width())/2, SkIntToScalar(dim.height())/2);
        SkScalar radius = SkIntToScalar(dim.width())/2;
        const SkScalar pos[] = { 0.0f,
                             0.35f,
                             1.0f };
        SkColorConverter conv({ 0x7f7f7f7f, 0x7f7f7f7f, 0xb2000000 });
        paint.setShader(SkShaders::RadialGradient(center, radius,
                                              {{conv.colors4f(), pos, SkTileMode::kClamp}, {}}));
        SkRect r = {
            0, 0, SkIntToScalar(dim.width()), SkIntToScalar(dim.height())
        };
        canvas->drawRect(r, paint);
    }
};
DEF_GM( return new RadialGradientGM; )

class RadialGradient2GM : public skiagm::GM {
public:
    RadialGradient2GM(bool dither) : fDither(dither) {}

private:
    SkString getName() const override {
        return SkString(fDither ? "radial_gradient2" : "radial_gradient2_nodither");
    }

    SkISize getISize() override { return {800, 400}; }

    // Reproduces the example given in b/7671058.
    void onDraw(SkCanvas* canvas) override {
        SkPaint paint1, paint2, paint3;
        paint1.setStyle(SkPaint::kFill_Style);
        paint2.setStyle(SkPaint::kFill_Style);
        paint3.setStyle(SkPaint::kFill_Style);

        const SkColor4f sweep_colors[] =
            { {1,0,0,1}, {1,1,0,1}, {0,1,0,1}, {0,1,1,1}, {0,0,1,1}, {1,0,1,1}, {1,0,0,1} };
        const SkColor4f colors1[] = { {1,1,1,1}, {0,0,0,0} };
        const SkColor4f colors2[] = { {0,0,0,1}, {0,0,0,0} };

        const SkScalar cx = 200, cy = 200, radius = 150;
        SkPoint center;
        center.set(cx, cy);

        // We can either interpolate endpoints and premultiply each point (default, more precision),
        // or premultiply the endpoints first, avoiding the need to premultiply each point (cheap).
        static constexpr auto flags = std::to_array<SkGradient::Interpolation::InPremul>({
                SkGradient::Interpolation::InPremul::kNo,
                SkGradient::Interpolation::InPremul::kYes,
        });
        const SkTileMode tm = SkTileMode::kClamp;

        for (size_t i = 0; i < std::size(flags); i++) {
            SkGradient::Interpolation terp{flags[i]};
            paint1.setShader(SkShaders::SweepGradient(center, {{sweep_colors, {}, tm}, terp}));
            paint2.setShader(SkShaders::RadialGradient(center, radius, {{colors1, {}, tm}, terp}));
            paint3.setShader(SkShaders::RadialGradient(center, radius, {{colors2, {}, tm}, terp}));
            paint1.setDither(fDither);
            paint2.setDither(fDither);
            paint3.setDither(fDither);

            canvas->drawCircle(cx, cy, radius, paint1);
            canvas->drawCircle(cx, cy, radius, paint3);
            canvas->drawCircle(cx, cy, radius, paint2);

            canvas->translate(400, 0);
        }
    }

private:
    bool fDither;

    using INHERITED = GM;
};
DEF_GM( return new RadialGradient2GM(true); )
DEF_GM( return new RadialGradient2GM(false); )

// Shallow radial (shows banding on raster)
class RadialGradient3GM : public skiagm::GM {
public:
    RadialGradient3GM(bool dither) : fDither(dither) { }

private:
    SkString getName() const override {
        return SkString(fDither ? "radial_gradient3" : "radial_gradient3_nodither");
    }

    SkISize getISize() override { return {500, 500}; }

    bool runAsBench() const override { return true; }

    void onOnceBeforeDraw() override {
        const SkPoint center = { 0, 0 };
        const SkScalar kRadius = 3000;
        const SkColor4f kColors[] = { {1,1,1,1}, {0,0,0,1} };
        fShader = SkShaders::RadialGradient(center, kRadius,
                                            {{kColors, {}, SkTileMode::kClamp}, {}});
    }

    void onDraw(SkCanvas* canvas) override {
        SkPaint paint;
        paint.setShader(fShader);
        paint.setDither(fDither);
        canvas->drawRect(SkRect::MakeWH(500, 500), paint);
    }

private:
    sk_sp<SkShader> fShader;
    bool fDither;

    using INHERITED = GM;
};
DEF_GM( return new RadialGradient3GM(true); )
DEF_GM( return new RadialGradient3GM(false); )

class RadialGradient4GM : public skiagm::GM {
public:
    RadialGradient4GM(bool dither) : fDither(dither) { }

private:
    SkString getName() const override {
        return SkString(fDither ? "radial_gradient4" : "radial_gradient4_nodither");
    }

    SkISize getISize() override { return {500, 500}; }

    void onOnceBeforeDraw() override {
        const SkPoint center = { 250, 250 };
        const SkScalar kRadius = 250;
        const SkColor4f colors[] = {
            SkColors::kRed, SkColors::kRed, SkColors::kWhite, SkColors::kWhite,SkColors::kRed };
        const SkScalar pos[] = { 0, .4f, .4f, .8f, .8f };
        fShader = SkShaders::RadialGradient(center, kRadius,
                                            {{colors, pos, SkTileMode::kClamp}, {}});
    }

    void onDraw(SkCanvas* canvas) override {
        SkPaint paint;
        paint.setAntiAlias(true);
        paint.setDither(fDither);
        paint.setShader(fShader);
        canvas->drawRect(SkRect::MakeWH(500, 500), paint);
    }

private:
    sk_sp<SkShader> fShader;
    bool fDither;

    using INHERITED = GM;
};
DEF_GM( return new RadialGradient4GM(true); )
DEF_GM( return new RadialGradient4GM(false); )

class LinearGradientGM : public skiagm::GM {
public:
    LinearGradientGM(bool dither) : fDither(dither) { }

private:
    SkString getName() const override {
        return SkString(fDither ? "linear_gradient" : "linear_gradient_nodither");
    }

    const SkScalar kWidthBump = 30.f;
    const SkScalar kHeight = 5.f;
    const SkScalar kMinWidth = 540.f;

    SkISize getISize() override { return {500, 500}; }

    void onOnceBeforeDraw() override {
        SkPoint pts[2] = { {0, 0}, {0, 0} };
        const SkColor4f colors[] = {
            SkColors::kWhite, SkColors::kWhite,
            SkColor4f::FromColor(0xFF008200), SkColor4f::FromColor(0xFF008200),
            SkColors::kWhite, SkColors::kWhite,
        };
        static constexpr auto unitPos = std::to_array<SkScalar>({0, 50, 70, 500, 540});
        std::array<SkScalar, 6> pos;
        pos[5] = 1;
        for (int index = 0; index < (int) std::size(fShader); ++index) {
            pts[1].fX = 500.f + index * kWidthBump;
            for (int inner = 0; inner < (int) std::size(unitPos); ++inner) {
                pos[inner] = unitPos[inner] / (kMinWidth + index * kWidthBump);
            }
            fShader[index] = SkShaders::LinearGradient(pts,
                                                       {{colors, pos, SkTileMode::kClamp}, {}});
        }
    }

    void onDraw(SkCanvas* canvas) override {
        SkPaint paint;
        paint.setAntiAlias(true);
        paint.setDither(fDither);
        for (int index = 0; index < (int) std::size(fShader); ++index) {
            paint.setShader(fShader[index]);
            canvas->drawRect(SkRect::MakeLTRB(0, index * kHeight, kMinWidth + index * kWidthBump,
                    (index + 1) * kHeight), paint);
        }
    }

private:
    std::array<sk_sp<SkShader>, 100> fShader;
    bool fDither;

    using INHERITED = GM;
};
DEF_GM( return new LinearGradientGM(true); )
DEF_GM( return new LinearGradientGM(false); )

class LinearGradientTinyGM : public skiagm::GM {
    SkString getName() const override { return SkString("linear_gradient_tiny"); }

    SkISize getISize() override { return {600, 500}; }

    void onDraw(SkCanvas* canvas) override {
        const SkScalar kRectSize = 100;
        const unsigned kStopCount = 3;
        const SkColor4f colors[kStopCount] = { SkColors::kGreen, SkColors::kRed, SkColors::kGreen };
        struct Configs {
            SkPoint pts[2];
            SkScalar pos[kStopCount];
        };
        static constexpr auto configs = std::to_array<Configs>({
                Configs{       {SkPoint::Make(0, 0), SkPoint::Make(10, 0)},    {0, 0.999999f, 1}},
                Configs{       {SkPoint::Make(0, 0), SkPoint::Make(10, 0)},    {0, 0.000001f, 1}},
                Configs{       {SkPoint::Make(0, 0), SkPoint::Make(10, 0)}, {0, 0.999999999f, 1}},
                Configs{       {SkPoint::Make(0, 0), SkPoint::Make(10, 0)}, {0, 0.000000001f, 1}},

                Configs{       {SkPoint::Make(0, 0), SkPoint::Make(0, 10)},    {0, 0.999999f, 1}},
                Configs{       {SkPoint::Make(0, 0), SkPoint::Make(0, 10)},    {0, 0.000001f, 1}},
                Configs{       {SkPoint::Make(0, 0), SkPoint::Make(0, 10)}, {0, 0.999999999f, 1}},
                Configs{       {SkPoint::Make(0, 0), SkPoint::Make(0, 10)}, {0, 0.000000001f, 1}},

                Configs{ {SkPoint::Make(0, 0), SkPoint::Make(0.00001f, 0)},         {0, 0.5f, 1}},
                Configs{{SkPoint::Make(9.99999f, 0), SkPoint::Make(10, 0)},         {0, 0.5f, 1}},
                Configs{ {SkPoint::Make(0, 0), SkPoint::Make(0, 0.00001f)},         {0, 0.5f, 1}},
                Configs{{SkPoint::Make(0, 9.99999f), SkPoint::Make(0, 10)},         {0, 0.5f, 1}},
        });

        SkPaint paint;
        for (unsigned i = 0; i < std::size(configs); ++i) {
            SkAutoCanvasRestore acr(canvas, true);
            paint.setShader(SkShaders::LinearGradient(configs[i].pts,
                                                      {{colors, configs[i].pos, SkTileMode::kClamp},
                                                       {}}));
            canvas->translate(kRectSize * ((i % 4) * 1.5f + 0.25f),
                              kRectSize * ((i / 4) * 1.5f + 0.25f));

            canvas->drawRect(SkRect::MakeWH(kRectSize, kRectSize), paint);
        }
    }
};

DEF_GM( return new LinearGradientTinyGM; )
}  // namespace

///////////////////////////////////////////////////////////////////////////////////////////////////

struct GradRun {
    SkColor4f fColors[4];
    SkScalar  fPos[4];
    size_t    fCount;

    SkGradient grad(SkTileMode tm) const {
        return {{{fColors, fCount}, {fPos, fCount}, tm}, {}};
    }
};

#define SIZE 121

static sk_sp<SkShader> make_linear(const GradRun& run, SkTileMode mode) {
    const SkPoint pts[] { { 30, 30 }, { SIZE - 30, SIZE - 30 } };
    return SkShaders::LinearGradient(pts, run.grad(mode));
}

static sk_sp<SkShader> make_radial(const GradRun& run, SkTileMode mode) {
    const SkScalar half = SIZE * 0.5f;
    return SkShaders::RadialGradient({half,half}, half - 10, run.grad(mode));
}

static sk_sp<SkShader> make_conical(const GradRun& run, SkTileMode mode) {
    const SkScalar half = SIZE * 0.5f;
    const SkPoint center { half, half };
    return SkShaders::TwoPointConicalGradient(center, 20, center, half - 10, run.grad(mode));
}

static sk_sp<SkShader> make_sweep(const GradRun& run, SkTileMode mode) {
    const SkScalar half = SIZE * 0.5f;
    return SkShaders::SweepGradient({half, half}, run.grad(mode));
}

/*
 *  Exercise duplicate color-stops, at the ends, and in the middle
 *
 *  At the time of this writing, only Linear correctly deals with duplicates at the ends,
 *  and then only correctly on CPU backend.
 */
DEF_SIMPLE_GM(gradients_dup_color_stops, canvas, 704, 564) {
    const SkColor4f preColor  = SkColors::kRed;   // clamp color before start
    const SkColor4f postColor = SkColors::kBlue;  // clamp color after end
    const SkColor4f color0    = SkColors::kBlack;
    const SkColor4f color1    = SkColors::kGreen;
    // should never be seen, fills out fixed-size array
    const SkColor4f badColor  = SkColor4f::FromColor(0xFF3388BB);

    const GradRun runs[] = {
        {   { color0, color1, badColor, badColor },
            { 0, 1, -1, -1 },
            2,
        },
        {   { preColor, color0, color1, badColor },
            { 0, 0, 1, -1 },
            3,
        },
        {   { color0, color1, postColor, badColor },
            { 0, 1, 1, -1 },
            3,
        },
        {   { preColor, color0, color1, postColor },
            { 0, 0, 1, 1 },
            4,
        },
        {   { color0, color0, color1, color1 },
            { 0, 0.5f, 0.5f, 1 },
            4,
        },
    };
    sk_sp<SkShader> (*factories[])(const GradRun&, SkTileMode) {
        make_linear, make_radial, make_conical, make_sweep
    };

    const SkRect rect = SkRect::MakeWH(SIZE, SIZE);
    const SkScalar dx = SIZE + 20;
    const SkScalar dy = SIZE + 20;
    const SkTileMode mode = SkTileMode::kClamp;

    SkPaint paint;
    canvas->translate(10, 10 - dy);
    for (auto factory : factories) {
        canvas->translate(0, dy);
        SkAutoCanvasRestore acr(canvas, true);
        for (const auto& run : runs) {
            paint.setShader(factory(run, mode));
            canvas->drawRect(rect, paint);
            canvas->translate(dx, 0);
        }
    }
}

static void draw_many_stops(SkCanvas* canvas) {
    const unsigned kStopCount = 200;
    const SkPoint pts[] = { {50, 50}, {450, 450}};

    std::array<SkColor4f, kStopCount> colors;
    for (unsigned i = 0; i < kStopCount; i++) {
        switch (i % 5) {
        case 0: colors[i] = SkColors::kRed;   break;
        case 1: colors[i] = SkColors::kGreen; break;
        case 2: colors[i] = SkColors::kGreen; break;
        case 3: colors[i] = SkColors::kBlue;  break;
        case 4: colors[i] = SkColors::kRed;   break;
        }
    }

    SkPaint p;
    p.setShader(SkShaders::LinearGradient(pts, {{colors, {}, SkTileMode::kClamp}, {}}));

    canvas->drawRect(SkRect::MakeXYWH(0, 0, 500, 500), p);
}

DEF_SIMPLE_GM(gradient_many_stops, canvas, 500, 500) {
    draw_many_stops(canvas);
}

static void draw_many_hard_stops(SkCanvas* canvas) {
    const unsigned kStopCount = 300;
    const SkPoint pts[] = {{50, 50}, {450, 450}};

    std::array<SkColor4f, kStopCount> colors;
    std::array<SkScalar, kStopCount> pos;
    for (unsigned i = 0; i < kStopCount; i++) {
        switch (i % 6) {
            case 0: colors[i] = SkColors::kRed;   break;
            case 1: colors[i] = SkColors::kGreen; break;
            case 2: colors[i] = SkColors::kGreen; break;
            case 3: colors[i] = SkColors::kBlue;  break;
            case 4: colors[i] = SkColors::kBlue;  break;
            case 5: colors[i] = SkColors::kRed;   break;
        }
        pos[i] = (2.0f * (i / 2)) / kStopCount;
    }

    SkPaint p;
    p.setShader(SkShaders::LinearGradient(pts, {{colors, pos, SkTileMode::kClamp}, {}}));

    canvas->drawRect(SkRect::MakeXYWH(0, 0, 500, 500), p);
}

DEF_SIMPLE_GM(gradient_many_hard_stops, canvas, 500, 500) {
    draw_many_hard_stops(canvas);
}

static void draw_circle_shader(SkCanvas* canvas, SkScalar cx, SkScalar cy, SkScalar r,
                               sk_sp<SkShader> (*shaderFunc)()) {
    SkPaint p;
    p.setAntiAlias(true);
    p.setShader(shaderFunc());
    canvas->drawCircle(cx, cy, r, p);

    p.setShader(nullptr);
    p.setColor(SK_ColorGRAY);
    p.setStyle(SkPaint::kStroke_Style);
    p.setStrokeWidth(2);
    canvas->drawCircle(cx, cy, r, p);
}

DEF_SIMPLE_GM(fancy_gradients, canvas, 800, 300) {
    draw_circle_shader(canvas, 150, 150, 100, []() -> sk_sp<SkShader> {
        // Checkerboard using two linear gradients + picture shader.
        SkScalar kTileSize = 80 / sqrtf(2);
        SkColor4f colors1[] = { {0,0,0,1}, {0,0,0,1},
                                {1,1,1,1}, {1,1,1,1},
                                {0,0,0,1}, {0,0,0,1} };
        SkColor4f colors2[] = { {0,0,0,1}, {0,0,0,1},
                                {0,0,0,0}, {0,0,0,0},
                                {0,0,0,1}, {0,0,0,1} };
        SkScalar pos[] = { 0, .25f, .25f, .75f, .75f, 1 };
        static_assert(std::size(colors1) == std::size(pos), "color/pos size mismatch");
        static_assert(std::size(colors2) == std::size(pos), "color/pos size mismatch");

        SkPictureRecorder recorder;
        recorder.beginRecording(SkRect::MakeWH(kTileSize, kTileSize));

        SkPaint p;

        SkPoint pts1[] = { { 0, 0 }, { kTileSize, kTileSize }};
        p.setShader(SkShaders::LinearGradient(pts1, {{colors1, pos, SkTileMode::kClamp}, {}}));
        recorder.getRecordingCanvas()->drawPaint(p);

        SkPoint pts2[] = { { 0, kTileSize }, { kTileSize, 0 }};
        p.setShader(SkShaders::LinearGradient(pts2, {{colors2, pos, SkTileMode::kClamp}, {}}));
        recorder.getRecordingCanvas()->drawPaint(p);

        SkMatrix m = SkMatrix::I();
        m.preRotate(45);
        return recorder.finishRecordingAsPicture()->makeShader(
                                           SkTileMode::kRepeat, SkTileMode::kRepeat,
                                           SkFilterMode::kNearest, &m, nullptr);
    });

    draw_circle_shader(canvas, 400, 150, 100, []() -> sk_sp<SkShader> {
        // Checkerboard using a sweep gradient + picture shader.
        SkScalar kTileSize = 80;
        SkColor4f colors[] = { {0,0,0,1}, {0,0,0,1},
                               {1,1,1,1}, {1,1,1,1},
                               {0,0,0,1}, {0,0,0,1},
                               {1,1,1,1}, {1,1,1,1} };
        SkScalar pos[] = { 0, .25f, .25f, .5f, .5f, .75f, .75f, 1 };
        static_assert(std::size(colors) == std::size(pos), "color/pos size mismatch");

        SkPaint p;
        p.setShader(SkShaders::SweepGradient({kTileSize / 2, kTileSize / 2},
                                             {{colors, pos, SkTileMode::kClamp}, {}}));
        SkPictureRecorder recorder;
        recorder.beginRecording(SkRect::MakeWH(kTileSize, kTileSize))->drawPaint(p);

        return recorder.finishRecordingAsPicture()->makeShader(
                                           SkTileMode::kRepeat,
                                           SkTileMode::kRepeat, SkFilterMode::kNearest);
    });

    draw_circle_shader(canvas, 650, 150, 100, []() -> sk_sp<SkShader> {
        // Dartboard using sweep + radial.
        const SkColor4f a = {1,1,1,1};
        const SkColor4f b = {0,0,0,1};
        SkColor4f colors[] = { a, a, b, b, a, a, b, b, a, a, b, b, a, a, b, b};
        SkScalar pos[] = { 0, .125f, .125f, .25f, .25f, .375f, .375f, .5f, .5f,
                           .625f, .625f, .75f, .75f, .875f, .875f, 1};
        static_assert(std::size(colors) == std::size(pos), "color/pos size mismatch");

        SkPoint center = { 650, 150 };
        sk_sp<SkShader> sweep1 = SkShaders::SweepGradient(center,
                                                          {{colors, pos, SkTileMode::kClamp}, {}});
        SkMatrix m = SkMatrix::I();
        m.preRotate(22.5f, center.x(), center.y());
        sk_sp<SkShader> sweep2 = SkShaders::SweepGradient(center,
                                                    {{colors, pos, SkTileMode::kClamp}, {}}, &m);

        sk_sp<SkShader> sweep(SkShaders::Blend(SkBlendMode::kExclusion, sweep1, sweep2));

        SkScalar radialPos[] = { 0, .02f, .02f, .04f, .04f, .08f, .08f, .16f, .16f, .31f, .31f,
                                 .62f, .62f, 1, 1, 1 };
        static_assert(std::size(colors) == std::size(radialPos),
                      "color/pos size mismatch");

        return SkShaders::Blend(SkBlendMode::kExclusion, sweep,
                                SkShaders::RadialGradient(center, 100,
                                                    {{colors, radialPos, SkTileMode::kClamp}, {}}));
    });
}

DEF_SIMPLE_GM(sweep_tiling, canvas, 690, 512) {
    static constexpr SkScalar size = 160;
    static constexpr SkColor4f colors[] = { SkColors::kBlue, SkColors::kYellow, SkColors::kGreen };
    static constexpr SkScalar   pos[] = { 0, .25f, .50f };
    static_assert(std::size(colors) == std::size(pos), "size mismatch");

    static constexpr SkTileMode modes[] = { SkTileMode::kClamp,
                                            SkTileMode::kRepeat,
                                            SkTileMode::kMirror };

    static const struct {
        SkScalar start, end;
    } angles[] = {
        { -330, -270 },
        {   30,   90 },
        {  390,  450 },
        {  -30,  800 },
    };

    SkPaint p;
    const SkRect r = SkRect::MakeWH(size, size);

    for (auto mode : modes) {
        {
            SkAutoCanvasRestore acr(canvas, true);

            for (auto angle : angles) {
                p.setShader(SkShaders::SweepGradient({size / 2, size / 2}, angle.start, angle.end,
                                                     {{colors, pos, mode}, {}}));

                canvas->drawRect(r, p);
                canvas->translate(size * 1.1f, 0);
            }
        }
        canvas->translate(0, size * 1.1f);
    }
}

DEF_SIMPLE_GM(rgbw_sweep_gradient, canvas, 100, 100) {
    static constexpr SkScalar size = 100;
    static constexpr SkColor4f colors[] = {SkColors::kWhite, SkColors::kWhite,
                                           SkColors::kBlue, SkColors::kBlue,
                                           SkColors::kRed, SkColors::kRed,
                                           SkColors::kGreen, SkColors::kGreen};
    static constexpr SkScalar   pos[] = { 0, .25f, .25f, .50f, .50f, .75, .75, 1 };
    static_assert(std::size(colors) == std::size(pos), "size mismatch");

    SkPaint p;
    p.setShader(SkShaders::SweepGradient({size / 2, size / 2},
                                         {{colors, pos, SkTileMode::kClamp}, {}}));
    canvas->drawRect(SkRect::MakeWH(size, size), p);
}

// Exercises the special-case Ganesh gradient effects.
DEF_SIMPLE_GM(gradients_interesting, canvas, 640, 1300) {
    static const SkColor4f colors2[] = { SkColors::kRed, SkColors::kBlue };
    static const SkColor4f colors3[] = { SkColors::kRed, SkColors::kYellow, SkColors::kBlue };
    static const SkColor4f colors4[] = {
                      SkColors::kRed, SkColors::kYellow, SkColors::kYellow, SkColors::kBlue };

    static const SkScalar softRight[]  = { 0, .999f,   1 }; // Based on Android launcher "clipping"
    static const SkScalar hardLeft[]   = { 0,     0,   1 };
    static const SkScalar hardRight[]  = { 0,     1,   1 };
    static const SkScalar hardCenter[] = { 0,   .5f, .5f, 1 };

    static const struct {
        SkSpan<const SkColor4f> colors;
        SkSpan<const float> pos;
    } configs[] = {
        { colors2, {} }, // kTwo_ColorType
        { colors3, {} }, // kThree_ColorType (simple)
        { colors3, softRight }, // kThree_ColorType (tricky)
        { colors3, hardLeft }, // kHardStopLeftEdged_ColorType
        { colors3, hardRight }, // kHardStopRightEdged_ColorType
        { colors4, hardCenter }, // kSingleHardStop_ColorType
    };

    static const SkTileMode modes[] = {
        SkTileMode::kClamp,
        SkTileMode::kRepeat,
        SkTileMode::kMirror,
    };

    static constexpr SkScalar size = 200;
    static const SkPoint pts[] = { { size / 3, size / 3 }, { size * 2 / 3, size * 2 / 3} };

    SkPaint p;
    for (const auto& cfg : configs) {
        {
            SkAutoCanvasRestore acr(canvas, true);
            for (auto mode : modes) {
                SkGradient grad = {{cfg.colors, cfg.pos, mode}, {}};
                p.setShader(SkShaders::LinearGradient(pts, grad));
                canvas->drawRect(SkRect::MakeWH(size, size), p);
                canvas->translate(size * 1.1f, 0);
            }
        }
        canvas->translate(0, size * 1.1f);
    }
}

// TODO(skbug.com/40044214): Still need to test degenerate gradients in strange color spaces
DEF_SIMPLE_GM_BG(gradients_color_space, canvas, 265, 355, SK_ColorGRAY) {
    using CS = SkGradient::Interpolation::ColorSpace;

    struct Config {
        CS fColorSpace;
        const char* fLabel;
    };
    static const Config kConfigs[] = {
            {CS::kSRGB, "sRGB"},
            {CS::kSRGBLinear, "Linear"},
            {CS::kLab, "Lab"},
            {CS::kOKLab, "OKLab"},
            {CS::kOKLabGamutMap, "OKLabGamutMap"},
            {CS::kLCH, "LCH"},
            {CS::kOKLCH, "OKLCH"},
            {CS::kOKLCHGamutMap, "OKLCHGamutMap"},
            {CS::kHSL, "HSL"},
            {CS::kHWB, "HWB"},
            {CS::kA98RGB, "a98RGB"},
            {CS::kProphotoRGB, "ProPhotoRGB"},
            {CS::kDisplayP3, "DisplayP3"},
            {CS::kRec2020, "Rec2020"},
    };

    SkPoint pts[] = {{0, 0}, {200, 0}};
    SkColor4f colors[] = {SkColors::kBlue, SkColors::kYellow};

    SkPaint labelPaint;
    SkPaint p;
    SkGradient::Interpolation interpolation;
    canvas->translate(5, 5);
    SkFont font = ToolUtils::DefaultPortableFont();

    for (const Config& config : kConfigs) {
        interpolation.fColorSpace = config.fColorSpace;
        SkGradient g = {{colors, {}, SkTileMode::kClamp, SkColorSpace::MakeSRGB()}, interpolation};
        p.setShader(SkShaders::LinearGradient(pts, g));
        canvas->drawRect({0, 0, 200, 20}, p);
        canvas->drawSimpleText(config.fLabel, strlen(config.fLabel), SkTextEncoding::kUTF8, 210, 15,
                               font, labelPaint);
        canvas->translate(0, 25);
    }
}

DEF_SIMPLE_GM_BG(gradients_hue_method, canvas, 285, 155, SK_ColorGRAY) {
    using HM = SkGradient::Interpolation::HueMethod;

    struct Config {
        HM fHueMethod;
        const char* fLabel;
    };
    static const Config kConfigs[] = {
        { HM::kShorter,    "Shorter" },
        { HM::kLonger,     "Longer" },
        { HM::kIncreasing, "Increasing" },
        { HM::kDecreasing, "Decreasing" },
    };

    SkPoint pts[] = {{0, 0}, {200, 0}};
    SkColor4f colors[] = {SkColors::kRed, SkColors::kGreen, SkColors::kRed, SkColors::kRed };

    SkPaint labelPaint;
    SkPaint p;
    SkGradient::Interpolation interpolation;
    interpolation.fColorSpace = SkGradient::Interpolation::ColorSpace::kHSL;
    canvas->translate(5, 5);
    SkFont font = ToolUtils::DefaultPortableFont();

    for (const Config& config : kConfigs) {
        interpolation.fHueMethod = config.fHueMethod;
        SkGradient g = {{colors, {}, SkTileMode::kClamp, SkColorSpace::MakeSRGB()}, interpolation};
        p.setShader(SkShaders::LinearGradient(pts, g));
        canvas->drawRect({0, 0, 200, 20}, p);
        canvas->drawSimpleText(config.fLabel, strlen(config.fLabel), SkTextEncoding::kUTF8, 210, 15,
                               font, labelPaint);
        canvas->translate(0, 25);
    }

    // Test a bug (skbug.com/40044215) with how gradient shaders handle explicit positions.
    // If there are no explicit positions at 0 or 1, those are automatically added, with copies of
    // the first/last color. When using kLonger, this can produce extra gradient that should
    // actually be solid. This gradient *should* be:
    //   |- solid red -|- red to green, the long way -|- solid green -|
    interpolation.fHueMethod = HM::kLonger;
    SkScalar middlePos[] = { 0.3f, 0.7f };
    SkGradient g = {{{colors, 2}, middlePos, SkTileMode::kClamp, SkColorSpace::MakeSRGB()},
                    interpolation};
    p.setShader(SkShaders::LinearGradient(pts, g));
    canvas->drawRect({0, 0, 200, 20}, p);
    canvas->translate(0, 25);

    // However... if the user explicitly includes those duplicate color stops in kLonger mode,
    // we expect the gradient to do a full rotation in those regions:
    //  |- full circle, red to red -|- red to green -|- full circle, green to green -|
    colors[0] = colors[1] = SkColors::kRed;
    colors[2] = colors[3] = SkColors::kGreen;
    SkScalar allPos[] = { 0.0f, 0.3f, 0.7f, 1.0f };
    g = {{colors, allPos, SkTileMode::kClamp, SkColorSpace::MakeSRGB()}, interpolation};
    p.setShader(SkShaders::LinearGradient(pts, g));
    canvas->drawRect({0, 0, 200, 20}, p);
    canvas->translate(0, 25);
}

DEF_SIMPLE_GM_BG(gradients_color_space_tilemode, canvas, 360, 105, SK_ColorGRAY) {
    // Test exotic (CSS) gradient color spaces in conjunction with tile modes. Rather than test
    // every combination, we pick one color space that has a sufficiently strange interpolated
    // representation (OKLCH) and just use that. We're mostly interested in making sure that things
    // like decal mode are implemented at the correct time in the pipeline, relative to hue
    // conversion, re-premultiplication, etc.
    SkPoint pts[] = {{20, 0}, {120, 0}};
    SkColor4f colors[] = {SkColors::kBlue, SkColors::kYellow};

    SkPaint p;
    SkGradient::Interpolation interpolation;
    interpolation.fColorSpace = SkGradient::Interpolation::ColorSpace::kOKLCH;

    canvas->translate(5, 5);

    for (int tm = 0; tm < kSkTileModeCount; ++tm) {
        SkGradient g = {{colors, {}, static_cast<SkTileMode>(tm)}, interpolation};
        p.setShader(SkShaders::LinearGradient(pts, g));
        canvas->drawRect({0, 0, 350, 20}, p);
        canvas->translate(0, 25);
    }
}

DEF_SIMPLE_GM_BG(gradients_color_space_many_stops, canvas, 500, 500, SK_ColorGRAY) {
    // Test exotic (CSS) gradient color spaces with many stops. Rather than test every combination,
    // we pick one color space that has a sufficiently strange interpolated representation (OKLCH)
    // and just use that. We're mostly interested in making sure that the texture fallback on GPU
    // works correctly.
    const SkPoint pts[] = { {50, 50}, {450, 465}};

    const unsigned kStopCount = 200;
    std::array<SkColor4f, kStopCount> colors;
    for (unsigned i = 0; i < kStopCount; i++) {
        switch (i % 5) {
            case 0: colors[i] = SkColors::kRed; break;
            case 1: colors[i] = SkColors::kGreen; break;
            case 2: colors[i] = SkColors::kGreen; break;
            case 3: colors[i] = SkColors::kBlue; break;
            case 4: colors[i] = SkColors::kRed; break;
        }
    }

    SkPaint p;

    SkGradient::Interpolation interpolation;
    interpolation.fColorSpace = SkGradient::Interpolation::ColorSpace::kOKLCH;
    p.setShader(SkShaders::LinearGradient(pts,
                    {{colors, {}, SkTileMode::kClamp, SkColorSpace::MakeSRGB()}, interpolation}));

    canvas->drawRect(SkRect::MakeXYWH(0, 0, 500, 500), p);
}

DEF_SIMPLE_GM(gradients_alpha_many_stops, canvas, 100, 100) {
    static const SkPoint kPts[] = {{0.f, 0.f}, {0.f, 100.f}};

    // From https://issues.chromium.org/issues/401546700, this encounters Graphite's
    // storage buffer option for storing gradient buffers AND uses colors that emphasize
    // premul vs. unpremul handling of the color data.
    static const float kPos[] = {0.f, 0.19f, 0.34f, 0.47f, 0.565f, 0.65f,
                                 0.73f, 0.802f, 0.861f, 0.91f, 0.952f, 0.982f, 1.f};

    static constexpr float kG = 34 / 255.f;
    static const SkColor4f kColors[] = {{kG, kG, kG, 1.f},
                                        {kG, kG, kG, 0.738f},
                                        {kG, kG, kG, 0.541f},
                                        {kG, kG, kG, 0.382f},
                                        {kG, kG, kG, 0.278f},
                                        {kG, kG, kG, 0.194f},
                                        {kG, kG, kG, 0.126f},
                                        {kG, kG, kG, 0.075f},
                                        {kG, kG, kG, 0.042f},
                                        {kG, kG, kG, 0.021f},
                                        {kG, kG, kG, 0.008f},
                                        {kG, kG, kG, 0.002f},
                                        {kG, kG, kG, 0.f}};

    canvas->clear(SkColor4f{0.5f, 0.5f, 0.5f, 1.f});

    SkPaint paint;
    paint.setShader(SkShaders::LinearGradient(kPts, {{kColors, kPos, SkTileMode::kClamp}, {}}));
    canvas->drawPaint(paint);
}

static void draw_powerless_hue_gradients(SkCanvas* canvas,
                                         SkGradient::Interpolation::ColorSpace colorSpace) {
    ToolUtils::draw_checkerboard(canvas);

    auto nextRow = [=]() {
        canvas->restore();
        canvas->translate(0, 25);
        canvas->save();
    };

    auto gradient = [&](std::initializer_list<SkColor4f> colors,
                        std::initializer_list<float> pos,
                        bool inPremul = false) {
        using Interpolation = SkGradient::Interpolation;
        SkASSERT(pos.size() == 0 || pos.size() == colors.size());
        SkPaint paint;
        SkPoint pts[] = {{0, 0}, {200, 0}};
        Interpolation interpolation;
        interpolation.fColorSpace = colorSpace;
        interpolation.fInPremul = static_cast<Interpolation::InPremul>(inPremul);
        paint.setShader(SkShaders::LinearGradient(pts, {{colors, pos, SkTileMode::kClamp},
                                                        interpolation}));
        canvas->drawRect({0, 0, 200, 20}, paint);
        canvas->translate(205, 0); // next column
    };

    canvas->translate(5, 5);
    canvas->save();

    // For each test case, the first gradient (first column) has an under-specified result due to a
    // powerless component after conversion to LCH. The second gradient (second column) "hints" the
    // correct result, by slightly tinting the otherwise powerless color.

    gradient({SkColors::kWhite,            SkColors::kBlue}, {});
    gradient({{0.99f, 0.99f, 1.00f, 1.0f}, SkColors::kBlue}, {}); // white, with blue hue
    nextRow();

    gradient({SkColors::kBlack,            SkColors::kBlue}, {});
    gradient({{0.00f, 0.00f, 0.01f, 1.0f}, SkColors::kBlue}, {}); // black, with blue hue
    nextRow();

    // Transparent cases are done in both premul and unpremul interpolation:

    gradient({SkColors::kTransparent,      SkColors::kBlue}, {}, /*inPremul=*/false);
    gradient({{0.00f, 0.00f, 0.01f, 0.0f}, SkColors::kBlue}, {}, /*inPremul=*/false);
    nextRow();

    gradient({SkColors::kTransparent,      SkColors::kBlue}, {}, /*inPremul=*/true);
    gradient({{0.00f, 0.00f, 0.01f, 0.0f}, SkColors::kBlue}, {}, /*inPremul=*/true);
    nextRow();

    gradient({{1.00f, 1.00f, 1.00f, 0.0f}, SkColors::kBlue}, {}, /*inPremul=*/false);
    gradient({{0.99f, 0.99f, 1.00f, 0.0f}, SkColors::kBlue}, {}, /*inPremul=*/false);
    nextRow();

    gradient({{1.00f, 1.00f, 1.00f, 0.0f}, SkColors::kBlue}, {}, /*inPremul=*/true);
    gradient({{0.99f, 0.99f, 1.00f, 0.0f}, SkColors::kBlue}, {}, /*inPremul=*/true);
    nextRow();

    // Now we test three-stop gradients, where the middle stop needs to be "split" to handle the
    // different hues on either side. Again, the second column explicitly injects those to produce
    // a reference result. See: https://github.com/w3c/csswg-drafts/issues/9295

    gradient({SkColors::kRed, SkColors::kWhite, SkColors::kBlue}, {});
    gradient({SkColors::kRed,
              {1.00f, 0.99f, 0.99f, 1.0f},
              {0.99f, 0.99f, 1.00f, 1.0f},
              SkColors::kBlue},
             {0.0f, 0.5f, 0.5f, 1.0f});
    nextRow();

    gradient({SkColors::kRed, SkColors::kBlack, SkColors::kBlue}, {});
    gradient({SkColors::kRed,
              {0.01f, 0.00f, 0.00f, 1.0f},
              {0.00f, 0.00f, 0.01f, 1.0f},
              SkColors::kBlue},
             {0.0f, 0.5f, 0.5f, 1.0f});
    nextRow();

    gradient({SkColors::kRed, SkColors::kTransparent, SkColors::kBlue}, {});
    gradient({SkColors::kRed,
              {0.01f, 0.00f, 0.00f, 0.0f},
              {0.00f, 0.00f, 0.01f, 0.0f},
              SkColors::kBlue},
             {0.0f, 0.5f, 0.5f, 1.0f});
    nextRow();

    // Now do a few black-white tests, to ensure that the hue propagation works correctly, even
    // when there isn't any hue in the adjacent stops.
    using HueMethod = SkGradient::Interpolation::HueMethod;
    auto blackWhiteGradient = [&](HueMethod hm) {
        using Interpolation = SkGradient::Interpolation;
        SkPaint paint;
        SkPoint pts[] = {{0, 0}, {405, 0}};
        Interpolation interpolation;
        interpolation.fColorSpace = colorSpace;
        interpolation.fHueMethod = hm;
        const SkColor4f colors[] = {SkColors::kWhite, SkColors::kGray,
                                    SkColors::kWhite, SkColors::kDkGray,
                                    SkColors::kWhite, SkColors::kBlack};
        paint.setShader(SkShaders::LinearGradient(pts, {{colors, {}, SkTileMode::kClamp},
                                                        interpolation}));
        canvas->drawRect({0, 0, 405, 20}, paint);
        nextRow();
    };

    blackWhiteGradient(HueMethod::kShorter);
    blackWhiteGradient(HueMethod::kIncreasing);
    blackWhiteGradient(HueMethod::kDecreasing);
    blackWhiteGradient(HueMethod::kLonger);
}

#define DEF_POWERLESS_HUE_GM(colorSpace)                                                    \
    DEF_SIMPLE_GM(gradients_powerless_hue_##colorSpace, canvas, 415, 330) {                 \
        draw_powerless_hue_gradients(canvas,                                                \
                                     SkGradient::Interpolation::ColorSpace::k##colorSpace); \
    }

DEF_POWERLESS_HUE_GM(LCH)
DEF_POWERLESS_HUE_GM(OKLCH)
DEF_POWERLESS_HUE_GM(HSL)
DEF_POWERLESS_HUE_GM(HWB)
