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

#include "include/core/SkAlphaType.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkBlendMode.h"
#include "include/core/SkBlender.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkCapabilities.h"
#include "include/core/SkColor.h"
#include "include/core/SkColorFilter.h"
#include "include/core/SkColorType.h"
#include "include/core/SkData.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPixmap.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkScalar.h"
#include "include/core/SkShader.h"
#include "include/core/SkSize.h"
#include "include/core/SkSpan.h"
#include "include/core/SkStream.h"
#include "include/core/SkString.h"
#include "include/core/SkSurface.h"
#include "include/core/SkTypes.h"
#include "include/effects/SkBlenders.h"
#include "include/effects/SkGradient.h"
#include "include/effects/SkRuntimeEffect.h"
#include "include/gpu/GpuTypes.h"
#include "include/private/SkSLSampleUsage.h"
#include "include/private/SkTArray.h"
#include "include/sksl/SkSLDebugTrace.h"
#include "include/sksl/SkSLVersion.h"
#include "src/core/SkColorData.h"
#include "src/core/SkColorSpacePriv.h"
#include "src/core/SkRuntimeEffectPriv.h"
#include "src/core/SkStringView.h"
#include "src/gpu/KeyBuilder.h"
#include "src/gpu/SkBackingFit.h"
#include "src/sksl/SkSLString.h"
#include "tests/CtsEnforcement.h"
#include "tests/Test.h"
#include "tools/GpuToolUtils.h"

#if defined(SK_GANESH)
#include "include/gpu/ganesh/GrDirectContext.h"
#include "include/gpu/ganesh/SkSurfaceGanesh.h"
#include "src/gpu/ganesh/GrCaps.h"
#include "src/gpu/ganesh/GrColor.h"
#include "src/gpu/ganesh/GrDirectContextPriv.h"
#include "src/gpu/ganesh/GrFragmentProcessor.h"
#include "src/gpu/ganesh/GrImageInfo.h"
#include "src/gpu/ganesh/GrPixmap.h"
#include "src/gpu/ganesh/SurfaceFillContext.h"
#include "src/gpu/ganesh/effects/GrSkSLFP.h"
#endif

#include <array>
#include <cstdint>
#include <functional>
#include <initializer_list>
#include <memory>
#include <string>
#include <thread>
#include <utility>

using namespace skia_private;

class GrRecordingContext;
struct GrContextOptions;
struct SkIPoint;

#if defined(SK_GRAPHITE)
#include "include/gpu/graphite/Context.h"
#include "include/gpu/graphite/Recorder.h"
#include "include/gpu/graphite/Recording.h"
#include "include/gpu/graphite/Surface.h"
#include "src/gpu/graphite/Surface_Graphite.h"

struct GraphiteInfo {
    skgpu::graphite::Context* context = nullptr;
    skgpu::graphite::Recorder* recorder = nullptr;
};
#else
struct GraphiteInfo {
    void* context = nullptr;
    void* recorder = nullptr;
};
#endif

void test_invalid_effect(skiatest::Reporter* r, const char* src, const char* expected) {
    auto [effect, errorText] = SkRuntimeEffect::MakeForShader(SkString(src));
    REPORTER_ASSERT(r, !effect);
    REPORTER_ASSERT(r, errorText.contains(expected),
                    "Expected error message to contain \"%s\". Actual message: \"%s\"",
                    expected, errorText.c_str());
}

#define EMPTY_MAIN "half4 main(float2 p) { return half4(0); }"

DEF_TEST(SkRuntimeEffectInvalid_NoInVariables, r) {
    // 'in' variables aren't allowed at all:
    test_invalid_effect(r, "in bool b;"    EMPTY_MAIN, "'in'");
    test_invalid_effect(r, "in float f;"   EMPTY_MAIN, "'in'");
    test_invalid_effect(r, "in float2 v;"  EMPTY_MAIN, "'in'");
    test_invalid_effect(r, "in half3x3 m;" EMPTY_MAIN, "'in'");
}

DEF_TEST(SkRuntimeEffectInvalid_UndefinedFunction, r) {
    test_invalid_effect(r, "half4 missing(); half4 main(float2 p) { return missing(); }",
                           "function 'half4 missing()' is not defined");
}

DEF_TEST(SkRuntimeEffectInvalid_UndefinedMain, r) {
    // Shouldn't be possible to create an SkRuntimeEffect without "main"
    test_invalid_effect(r, "", "main");
}

DEF_TEST(SkRuntimeEffectInvalid_SkCapsDisallowed, r) {
    // sk_Caps is an internal system. It should not be visible to runtime effects
    test_invalid_effect(
            r,
            "half4 main(float2 p) { return sk_Caps.floatIs32Bits ? half4(1) : half4(0); }",
            "name 'sk_Caps' is reserved");
}

DEF_TEST(SkRuntimeEffect_DeadCodeEliminationStackOverflow, r) {
    // Verify that a deeply-nested loop does not cause stack overflow during dead-code elimination.
    auto [effect, errorText] = SkRuntimeEffect::MakeForColorFilter(SkString(R"(
        half4 main(half4 color) {
            half value = color.r;

            for (int a=0; a<10; ++a) { // 10
            for (int b=0; b<10; ++b) { // 100
            for (int c=0; c<10; ++c) { // 1000
            for (int d=0; d<10; ++d) { // 10000
                ++value;
            }}}}

            return value.xxxx;
        }
    )"));
    REPORTER_ASSERT(r, effect, "%s", errorText.c_str());
}

DEF_TEST(SkRuntimeEffectCanDisableES2Restrictions, r) {
    auto test_valid_es3 = [](skiatest::Reporter* r, const char* sksl) {
        SkRuntimeEffect::Options opt = SkRuntimeEffectPriv::ES3Options();
        auto [effect, errorText] = SkRuntimeEffect::MakeForShader(SkString(sksl), opt);
        REPORTER_ASSERT(r, effect, "%s", errorText.c_str());
    };

    test_invalid_effect(r, "float f[2] = float[2](0, 1);" EMPTY_MAIN, "construction of array type");
    test_valid_es3     (r, "float f[2] = float[2](0, 1);" EMPTY_MAIN);
}

DEF_TEST(SkRuntimeEffectCanEnableVersion300, r) {
    auto test_valid = [](skiatest::Reporter* r, const char* sksl) {
        auto [effect, errorText] = SkRuntimeEffect::MakeForShader(SkString(sksl));
        REPORTER_ASSERT(r, effect, "%s", errorText.c_str());
    };

    test_invalid_effect(r, "#version 100\nfloat f[2] = float[2](0, 1);" EMPTY_MAIN,
                           "construction of array type");
    test_valid         (r, "#version 300\nfloat f[2] = float[2](0, 1);" EMPTY_MAIN);
}

DEF_TEST(SkRuntimeEffectUniformFlags, r) {
    auto [effect, errorText] = SkRuntimeEffect::MakeForShader(SkString(R"(
        uniform int simple;                      // should have no flags
        uniform float arrayOfOne[1];             // should have kArray_Flag
        uniform float arrayOfMultiple[2];        // should have kArray_Flag
        layout(color) uniform float4 color;      // should have kColor_Flag
        uniform half3 halfPrecisionFloat;        // should have kHalfPrecision_Flag
        layout(color) uniform half4 allFlags[2]; // should have Array | Color | HalfPrecision
    )"  EMPTY_MAIN));
    REPORTER_ASSERT(r, effect, "%s", errorText.c_str());

    SkSpan<const SkRuntimeEffect::Uniform> uniforms = effect->uniforms();
    REPORTER_ASSERT(r, uniforms.size() == 6);

    REPORTER_ASSERT(r, uniforms[0].flags == 0);
    REPORTER_ASSERT(r, uniforms[1].flags == SkRuntimeEffect::Uniform::kArray_Flag);
    REPORTER_ASSERT(r, uniforms[2].flags == SkRuntimeEffect::Uniform::kArray_Flag);
    REPORTER_ASSERT(r, uniforms[3].flags == SkRuntimeEffect::Uniform::kColor_Flag);
    REPORTER_ASSERT(r, uniforms[4].flags == SkRuntimeEffect::Uniform::kHalfPrecision_Flag);
    REPORTER_ASSERT(r, uniforms[5].flags == (SkRuntimeEffect::Uniform::kArray_Flag |
                                             SkRuntimeEffect::Uniform::kColor_Flag |
                                             SkRuntimeEffect::Uniform::kHalfPrecision_Flag));
}

DEF_TEST(SkRuntimeEffectValidation, r) {
    auto es2Effect = SkRuntimeEffect::MakeForShader(SkString("#version 100\n" EMPTY_MAIN)).effect;
    auto es3Effect = SkRuntimeEffect::MakeForShader(SkString("#version 300\n" EMPTY_MAIN)).effect;
    REPORTER_ASSERT(r, es2Effect && es3Effect);

    auto es2Caps = SkCapabilities::RasterBackend();
    REPORTER_ASSERT(r, es2Caps->skslVersion() == SkSL::Version::k100);

    REPORTER_ASSERT(r, SkRuntimeEffectPriv::CanDraw(es2Caps.get(), es2Effect.get()));
    REPORTER_ASSERT(r, !SkRuntimeEffectPriv::CanDraw(es2Caps.get(), es3Effect.get()));
}

DEF_TEST(SkRuntimeEffectForColorFilter, r) {
    // Tests that the color filter factory rejects or accepts certain SkSL constructs
    auto test_valid = [r](const char* sksl) {
        auto [effect, errorText] = SkRuntimeEffect::MakeForColorFilter(SkString(sksl));
        REPORTER_ASSERT(r, effect, "%s", errorText.c_str());
    };

    auto test_invalid = [r](const char* sksl, const char* expected) {
        auto [effect, errorText] = SkRuntimeEffect::MakeForColorFilter(SkString(sksl));
        REPORTER_ASSERT(r, !effect);
        REPORTER_ASSERT(r,
                        errorText.contains(expected),
                        "Expected error message to contain \"%s\". Actual message: \"%s\"",
                        expected,
                        errorText.c_str());
    };

    // Color filters must use the 'half4 main(half4)' signature. Either color can be float4/vec4
    test_valid("half4  main(half4  c) { return c; }");
    test_valid("float4 main(half4  c) { return c; }");
    test_valid("half4  main(float4 c) { return c; }");
    test_valid("float4 main(float4 c) { return c; }");
    test_valid("vec4   main(half4  c) { return c; }");
    test_valid("half4  main(vec4   c) { return c; }");
    test_valid("vec4   main(vec4   c) { return c; }");

    // Invalid return types
    test_invalid("void  main(half4 c) {}",                "'main' must return");
    test_invalid("half3 main(half4 c) { return c.rgb; }", "'main' must return");

    // Invalid argument types (some are valid as shaders, but not color filters)
    test_invalid("half4 main() { return half4(1); }",           "'main' parameter");
    test_invalid("half4 main(float2 p) { return half4(1); }",   "'main' parameter");
    test_invalid("half4 main(float2 p, half4 c) { return c; }", "'main' parameter");

    // sk_FragCoord should not be available
    test_invalid("half4 main(half4 c) { return sk_FragCoord.xy01; }", "unknown identifier");

    // Sampling a child shader requires that we pass explicit coords
    test_valid("uniform shader child;"
               "half4 main(half4 c) { return child.eval(c.rg); }");

    // Sampling a colorFilter requires a color
    test_valid("uniform colorFilter child;"
               "half4 main(half4 c) { return child.eval(c); }");

    // Sampling a blender requires two colors
    test_valid("uniform blender child;"
               "half4 main(half4 c) { return child.eval(c, c); }");
}

DEF_TEST(SkRuntimeEffectForBlender, r) {
    // Tests that the blender factory rejects or accepts certain SkSL constructs
    auto test_valid = [r](const char* sksl) {
        auto [effect, errorText] = SkRuntimeEffect::MakeForBlender(SkString(sksl));
        REPORTER_ASSERT(r, effect, "%s", errorText.c_str());
    };

    auto test_invalid = [r](const char* sksl, const char* expected) {
        auto [effect, errorText] = SkRuntimeEffect::MakeForBlender(SkString(sksl));
        REPORTER_ASSERT(r, !effect);
        REPORTER_ASSERT(r,
                        errorText.contains(expected),
                        "Expected error message to contain \"%s\". Actual message: \"%s\"",
                        expected,
                        errorText.c_str());
    };

    // Blenders must use the 'half4 main(half4, half4)' signature. Any mixture of float4/vec4/half4
    // is allowed.
    test_valid("half4  main(half4  s, half4  d) { return s; }");
    test_valid("float4 main(float4 s, float4 d) { return d; }");
    test_valid("float4 main(half4  s, float4 d) { return s; }");
    test_valid("half4  main(float4 s, half4  d) { return d; }");
    test_valid("vec4   main(half4  s, half4  d) { return s; }");
    test_valid("half4  main(vec4   s, vec4   d) { return d; }");
    test_valid("vec4   main(vec4   s, vec4   d) { return s; }");

    // Invalid return types
    test_invalid("void  main(half4 s, half4 d) {}",                "'main' must return");
    test_invalid("half3 main(half4 s, half4 d) { return s.rgb; }", "'main' must return");

    // Invalid argument types (some are valid as shaders/color filters)
    test_invalid("half4 main() { return half4(1); }",                    "'main' parameter");
    test_invalid("half4 main(half4 c) { return c; }",                    "'main' parameter");
    test_invalid("half4 main(float2 p) { return half4(1); }",            "'main' parameter");
    test_invalid("half4 main(float2 p, half4 c) { return c; }",          "'main' parameter");
    test_invalid("half4 main(float2 p, half4 a, half4 b) { return a; }", "'main' parameter");
    test_invalid("half4 main(half4 a, half4 b, half4 c) { return a; }",  "'main' parameter");

    // sk_FragCoord should not be available
    test_invalid("half4 main(half4 s, half4 d) { return sk_FragCoord.xy01; }",
                 "unknown identifier");

    // Sampling a child shader requires that we pass explicit coords
    test_valid("uniform shader child;"
               "half4 main(half4 s, half4 d) { return child.eval(s.rg); }");

    // Sampling a colorFilter requires a color
    test_valid("uniform colorFilter child;"
               "half4 main(half4 s, half4 d) { return child.eval(d); }");

    // Sampling a blender requires two colors
    test_valid("uniform blender child;"
               "half4 main(half4 s, half4 d) { return child.eval(s, d); }");
}

DEF_TEST(SkRuntimeEffectForShader, r) {
    // Tests that the shader factory rejects or accepts certain SkSL constructs
    auto test_valid = [r](const char* sksl, SkRuntimeEffect::Options options = {}) {
        auto [effect, errorText] = SkRuntimeEffect::MakeForShader(SkString(sksl), options);
        REPORTER_ASSERT(r, effect, "%s", errorText.c_str());
    };

    auto test_invalid = [r](const char* sksl,
                            const char* expected,
                            SkRuntimeEffect::Options options = {}) {
        auto [effect, errorText] = SkRuntimeEffect::MakeForShader(SkString(sksl));
        REPORTER_ASSERT(r, !effect);
        REPORTER_ASSERT(r,
                        errorText.contains(expected),
                        "Expected error message to contain \"%s\". Actual message: \"%s\"",
                        expected,
                        errorText.c_str());
    };

    // Shaders must use the 'half4 main(float2)' signature
    // Either color can be half4/float4/vec4, but the coords must be float2/vec2
    test_valid("half4  main(float2 p) { return p.xyxy; }");
    test_valid("float4 main(float2 p) { return p.xyxy; }");
    test_valid("vec4   main(float2 p) { return p.xyxy; }");
    test_valid("half4  main(vec2   p) { return p.xyxy; }");
    test_valid("vec4   main(vec2   p) { return p.xyxy; }");

    // The 'half4 main(float2, half4|float4)' signature is disallowed on both public and private
    // runtime effects.
    SkRuntimeEffect::Options options;
    SkRuntimeEffectPriv::AllowPrivateAccess(&options);
    test_invalid("half4  main(float2 p, half4  c) { return c; }", "'main' parameter");
    test_invalid("half4  main(float2 p, half4  c) { return c; }", "'main' parameter", options);

    test_invalid("half4  main(float2 p, float4 c) { return c; }", "'main' parameter");
    test_invalid("half4  main(float2 p, float4 c) { return c; }", "'main' parameter", options);

    test_invalid("half4  main(float2 p, vec4   c) { return c; }", "'main' parameter");
    test_invalid("half4  main(float2 p, vec4   c) { return c; }", "'main' parameter", options);

    test_invalid("float4 main(float2 p, half4  c) { return c; }", "'main' parameter");
    test_invalid("float4 main(float2 p, half4  c) { return c; }", "'main' parameter", options);

    test_invalid("vec4   main(float2 p, half4  c) { return c; }", "'main' parameter");
    test_invalid("vec4   main(float2 p, half4  c) { return c; }", "'main' parameter", options);

    test_invalid("vec4   main(vec2   p, vec4   c) { return c; }", "'main' parameter");
    test_invalid("vec4   main(vec2   p, vec4   c) { return c; }", "'main' parameter", options);

    // Invalid return types
    test_invalid("void  main(float2 p) {}",                "'main' must return");
    test_invalid("half3 main(float2 p) { return p.xy1; }", "'main' must return");

    // Invalid argument types (some are valid as color filters, but not shaders)
    test_invalid("half4 main() { return half4(1); }", "'main' parameter");
    test_invalid("half4 main(half4 c) { return c; }", "'main' parameter");

    // sk_FragCoord should be available, but only if we've enabled it via Options
    test_invalid("half4 main(float2 p) { return sk_FragCoord.xy01; }",
                 "unknown identifier 'sk_FragCoord'");

    test_valid("half4 main(float2 p) { return sk_FragCoord.xy01; }", options);

    // Sampling a child shader requires that we pass explicit coords
    test_valid("uniform shader child;"
               "half4 main(float2 p) { return child.eval(p); }");

    // Sampling a colorFilter requires a color
    test_valid("uniform colorFilter child;"
               "half4 main(float2 p) { return child.eval(half4(1)); }");

    // Sampling a blender requires two colors
    test_valid("uniform blender child;"
               "half4 main(float2 p) { return child.eval(half4(0.5), half4(0.6)); }");
}

using PreTestFn = std::function<void(SkCanvas*, SkPaint*)>;

void paint_canvas(SkCanvas* canvas, SkPaint* paint, const PreTestFn& preTestCallback) {
    canvas->save();
    if (preTestCallback) {
        preTestCallback(canvas, paint);
    }
    canvas->drawPaint(*paint);
    canvas->restore();
}

static bool read_pixels(SkSurface* surface,
                        uint32_t* pixels) {
    SkImageInfo info = surface->imageInfo();
    SkPixmap dest{info, pixels, info.minRowBytes()};
    return surface->readPixels(dest, /*srcX=*/0, /*srcY=*/0);
}

static void verify_2x2_surface_results(skiatest::Reporter* r,
                                       const SkRuntimeEffect* effect,
                                       SkSurface* surface,
                                       std::array<uint32_t, 4> expected) {
    std::array<uint32_t, 4> actual;
    SkImageInfo info = surface->imageInfo();
    if (!read_pixels(surface, actual.data())) {
        REPORT_FAILURE(r, "readPixels", SkString("readPixels failed"));
        return;
    }

    if (actual != expected) {
        REPORT_FAILURE(r, "Runtime effect didn't match expectations",
                       SkStringPrintf("\n"
                                      "Expected: [ %08x %08x %08x %08x ]\n"
                                      "Got     : [ %08x %08x %08x %08x ]\n"
                                      "SkSL:\n%s\n",
                                      expected[0], expected[1], expected[2], expected[3],
                                      actual[0],   actual[1],   actual[2],   actual[3],
                                      effect->source().c_str()));
    }
}

static sk_sp<SkSurface> make_surface(GrRecordingContext* grContext,
                                     const GraphiteInfo* graphite,
                                     SkISize size) {
    const SkImageInfo info = SkImageInfo::Make(size, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
    sk_sp<SkSurface> surface;
    if (graphite) {
#if defined(SK_GRAPHITE)
        surface = SkSurfaces::RenderTarget(graphite->recorder, info);
#endif
    } else if (grContext) {
#if defined(SK_GANESH)
        surface = SkSurfaces::RenderTarget(grContext, skgpu::Budgeted::kNo, info);
#endif
    } else {
        surface = SkSurfaces::Raster(info);
    }
    SkASSERT(surface);
    return surface;
}

class TestEffect {
public:
    TestEffect(skiatest::Reporter* r,
               GrRecordingContext* grContext,
               const GraphiteInfo* graphite,
               SkISize size = {2, 2})
            : fReporter(r), fGrContext(grContext), fGraphite(graphite), fSize(size) {
        fSurface = make_surface(fGrContext, fGraphite, fSize);
    }

    void build(const char* src) {
        SkRuntimeEffect::Options options;
        SkRuntimeEffectPriv::AllowPrivateAccess(&options);
        auto [effect, errorText] = SkRuntimeEffect::MakeForShader(SkString(src), options);
        if (!effect) {
            ERRORF(fReporter, "Effect didn't compile: %s", errorText.c_str());
            return;
        }
        fBuilder.emplace(std::move(effect));
    }

    SkRuntimeShaderBuilder::BuilderUniform uniform(const char* name) {
        return fBuilder->uniform(name);
    }

    SkRuntimeShaderBuilder::BuilderChild child(const char* name) {
        return fBuilder->child(name);
    }

    void test(std::array<uint32_t, 4> expected, PreTestFn preTestCallback = nullptr) {
        auto shader = fBuilder->makeShader();
        if (!shader) {
            ERRORF(fReporter, "Effect didn't produce a shader");
            return;
        }

        SkCanvas* canvas = fSurface->getCanvas();

        // We shouldn't need to clear the canvas, because we are about to paint over the whole thing
        // with a `source` blend mode. However, there are a few devices where the background can
        // leak through when we paint with MSAA on. (This seems to be a driver/hardware bug.)
        // Graphite, at present, uses MSAA to do `drawPaint`. To avoid flakiness in this test on
        // those devices, we explicitly clear the canvas here. (skbug.com/40044848)
        canvas->clear(SK_ColorBLACK);

        SkPaint paint;
        paint.setShader(std::move(shader));
        paint.setBlendMode(SkBlendMode::kSrc);

        paint_canvas(canvas, &paint, preTestCallback);

        verify_2x2_surface_results(fReporter, fBuilder->effect(), fSurface.get(), expected);
    }

    std::string trace(const SkIPoint& traceCoord) {
        sk_sp<SkShader> shader = fBuilder->makeShader();
        if (!shader) {
            ERRORF(fReporter, "Effect didn't produce a shader");
            return {};
        }

        auto [debugShader, debugTrace] = SkRuntimeEffect::MakeTraced(std::move(shader), traceCoord);

        SkCanvas* canvas = fSurface->getCanvas();
        SkPaint paint;
        paint.setShader(std::move(debugShader));
        paint.setBlendMode(SkBlendMode::kSrc);

        paint_canvas(canvas, &paint, /*preTestCallback=*/nullptr);

        SkDynamicMemoryWStream wstream;
        debugTrace->dump(&wstream);
        sk_sp<SkData> streamData = wstream.detachAsData();
        return std::string(static_cast<const char*>(streamData->data()), streamData->size());
    }

    void test(uint32_t expected, PreTestFn preTestCallback = nullptr) {
        this->test({expected, expected, expected, expected}, preTestCallback);
    }

private:
    skiatest::Reporter*             fReporter;
    sk_sp<SkSurface>                fSurface;
    GrRecordingContext*             fGrContext;
    const GraphiteInfo*             fGraphite;
    SkISize                         fSize;
    std::optional<SkRuntimeShaderBuilder> fBuilder;
};

class TestBlend {
public:
    TestBlend(skiatest::Reporter* r, GrRecordingContext* grContext, const GraphiteInfo* graphite)
            : fReporter(r), fGrContext(grContext), fGraphite(graphite) {
        fSurface = make_surface(fGrContext, fGraphite, /*size=*/{2, 2});
    }

    void build(const char* src, bool allowPrivateAccess = false) {
        SkRuntimeEffect::Options options;
        if (allowPrivateAccess) {
            SkRuntimeEffectPriv::AllowPrivateAccess(&options);
        }
        auto [effect, errorText] = SkRuntimeEffect::MakeForBlender(SkString(src), options);
        if (!effect) {
            ERRORF(fReporter, "Effect didn't compile: %s", errorText.c_str());
            return;
        }
        fBuilder.emplace(std::move(effect));
    }

    SkSurface* surface() {
        return fSurface.get();
    }

    SkRuntimeBlendBuilder::BuilderUniform uniform(const char* name) {
        return fBuilder->uniform(name);
    }

    SkRuntimeBlendBuilder::BuilderChild child(const char* name) {
        return fBuilder->child(name);
    }

    void test(std::array<uint32_t, 4> expected, PreTestFn preTestCallback = nullptr) {
        auto blender = fBuilder->makeBlender();
        if (!blender) {
            ERRORF(fReporter, "Effect didn't produce a blender");
            return;
        }

        SkCanvas* canvas = fSurface->getCanvas();
        SkPaint paint;
        paint.setBlender(std::move(blender));
        paint.setColor(SK_ColorGRAY);

        paint_canvas(canvas, &paint, preTestCallback);

        verify_2x2_surface_results(fReporter, fBuilder->effect(), fSurface.get(), expected);
    }

    void test(uint32_t expected, PreTestFn preTestCallback = nullptr) {
        this->test({expected, expected, expected, expected}, preTestCallback);
    }

private:
    skiatest::Reporter*            fReporter;
    sk_sp<SkSurface>               fSurface;
    GrRecordingContext*            fGrContext;
    const GraphiteInfo*            fGraphite;
    std::optional<SkRuntimeBlendBuilder> fBuilder;
};

// Produces a shader which will paint these opaque colors in a 2x2 rectangle:
// [  Red, Green ]
// [ Blue, White ]
static sk_sp<SkShader> make_RGBW_shader() {
    static constexpr SkColor4f colors[] = {SkColors::kWhite, SkColors::kWhite,
                                           SkColors::kBlue, SkColors::kBlue,
                                           SkColors::kRed, SkColors::kRed,
                                           SkColors::kGreen, SkColors::kGreen};
    static constexpr float pos[] = { 0, .25f, .25f, .50f, .50f, .75, .75, 1 };
    static_assert(std::size(colors) == std::size(pos), "size mismatch");
    return SkShaders::SweepGradient({1, 1}, {{colors, pos, SkTileMode::kClamp}, {}});
}

static void test_RuntimeEffect_Shaders(skiatest::Reporter* r,
                                       GrRecordingContext* grContext,
                                       const GraphiteInfo* graphite) {
    TestEffect effect(r, grContext, graphite);
    using float4 = std::array<float, 4>;
    using int4 = std::array<int, 4>;

    // Local coords
    effect.build("half4 main(float2 p) { return half4(half2(p - 0.5), 0, 1); }");
    effect.test({0xFF000000, 0xFF0000FF, 0xFF00FF00, 0xFF00FFFF});

    // Use of a simple uniform. (Draw twice with two values to ensure it's updated).
    effect.build("uniform float4 gColor; half4 main(float2 p) { return half4(gColor); }");
    effect.uniform("gColor") = float4{ 0.0f, 0.25f, 0.75f, 1.0f };
    effect.test(0xFFBF4000);
    effect.uniform("gColor") = float4{ 1.0f, 0.0f, 0.0f, 0.498f };
    effect.test(0x7F0000FF);  // Tests that we don't clamp to valid premul

    // Same, with integer uniforms
    effect.build("uniform int4 gColor; half4 main(float2 p) { return half4(gColor) / 255.0; }");
    effect.uniform("gColor") = int4{ 0x00, 0x40, 0xBF, 0xFF };
    effect.test(0xFFBF4000);
    effect.uniform("gColor") = int4{ 0xFF, 0x00, 0x00, 0x7F };
    effect.test(0x7F0000FF);  // Tests that we don't clamp to valid premul

    // Test sk_FragCoord (device coords). Rotate the canvas to be sure we're seeing device coords.
    // Since the surface is 2x2, we should see (0,0), (1,0), (0,1), (1,1). Multiply by 0.498 to
    // make sure we're not saturating unexpectedly.
    effect.build(
            "half4 main(float2 p) { return half4(0.498 * (half2(sk_FragCoord.xy) - 0.5), 0, 1); }");
    effect.test({0xFF000000, 0xFF00007F, 0xFF007F00, 0xFF007F7F},
                [](SkCanvas* canvas, SkPaint*) { canvas->rotate(45.0f); });

    // Runtime effects should use relaxed precision rules by default
    effect.build("half4 main(float2 p) { return float4(p - 0.5, 0, 1); }");
    effect.test({0xFF000000, 0xFF0000FF, 0xFF00FF00, 0xFF00FFFF});

    // ... and support *returning* float4 (aka vec4), not just half4
    effect.build("float4 main(float2 p) { return float4(p - 0.5, 0, 1); }");
    effect.test({0xFF000000, 0xFF0000FF, 0xFF00FF00, 0xFF00FFFF});
    effect.build("vec4 main(float2 p) { return float4(p - 0.5, 0, 1); }");
    effect.test({0xFF000000, 0xFF0000FF, 0xFF00FF00, 0xFF00FFFF});

    // Mutating coords should work. (skbug.com/40042292)
    effect.build("vec4 main(vec2 p) { p -= 0.5; return vec4(p, 0, 1); }");
    effect.test({0xFF000000, 0xFF0000FF, 0xFF00FF00, 0xFF00FFFF});
    effect.build("void moveCoords(inout vec2 p) { p -= 0.5; }"
                 "vec4 main(vec2 p) { moveCoords(p); return vec4(p, 0, 1); }");
    effect.test({0xFF000000, 0xFF0000FF, 0xFF00FF00, 0xFF00FFFF});

    //
    // Sampling children
    //

    // Sampling a null shader should return transparent black
    if (!graphite) {
        // TODO: Graphite does not yet pass this test.
        effect.build("uniform shader child;"
                     "half4 main(float2 p) { return child.eval(p); }");
        effect.child("child") = nullptr;
        effect.test(0x00000000,
                    [](SkCanvas*, SkPaint* paint) { paint->setColor4f({1.0f, 1.0f, 0.0f, 1.0f}); });
    }

    // Sampling a null color-filter should return the passed-in color
    effect.build("uniform colorFilter child;"
                 "half4 main(float2 p) { return child.eval(half4(1, 1, 0, 1)); }");
    effect.child("child") = nullptr;
    effect.test(0xFF00FFFF);

    // Sampling a null blender should return blend_src_over(src, dest).
    effect.build("uniform blender child;"
                 "half4 main(float2 p) {"
                 "    float4 src = float4(p - 0.5, 0, 1) * 0.498;"
                 "    return child.eval(src, half4(0, 0, 0, 1));"
                 "}");
    effect.child("child") = nullptr;
    effect.test({0xFF000000, 0xFF00007F, 0xFF007F00, 0xFF007F7F});

    // Sampling a simple child at our coordinates
    sk_sp<SkShader> rgbwShader = make_RGBW_shader();

    effect.build("uniform shader child;"
                 "half4 main(float2 p) { return child.eval(p); }");
    effect.child("child") = rgbwShader;
    effect.test({0xFF0000FF, 0xFF00FF00, 0xFFFF0000, 0xFFFFFFFF});

    // Sampling with explicit coordinates (reflecting about the diagonal)
    effect.build("uniform shader child;"
                 "half4 main(float2 p) { return child.eval(p.yx); }");
    effect.child("child") = rgbwShader;
    effect.test({0xFF0000FF, 0xFFFF0000, 0xFF00FF00, 0xFFFFFFFF});

    // Bind an image shader, but don't use it - ensure that we don't assert or generate bad shaders.
    // (skbug.com/40043510)
    effect.build("uniform shader child;"
                 "half4 main(float2 p) { return half4(0, 1, 0, 1); }");
    effect.child("child") = rgbwShader;
    effect.test(0xFF00FF00);

    //
    // Helper functions
    //

    // Test case for inlining in the pipeline-stage and fragment-shader passes (skbug.com/40041860):
    effect.build("float2 helper(float2 x) { return x + 1; }"
                 "half4 main(float2 p) { float2 v = helper(p); return half4(half2(v), 0, 1); }");
    effect.test(0xFF00FFFF);

    // Passing a shader to a helper function
    effect.build("uniform shader child; float2 position;"
                 "noinline half4 my_eval(shader s) { return s.eval(position); }"
                 "half4 main(float2 p) { position = p; return my_eval(child); }");
    effect.child("child") = rgbwShader;
    effect.test({0xFF0000FF, 0xFF00FF00, 0xFFFF0000, 0xFFFFFFFF});
}

DEF_TEST(SkRuntimeEffectSimple, r) {
    test_RuntimeEffect_Shaders(r, /*grContext=*/nullptr, /*graphite=*/nullptr);
}

#if defined(SK_GRAPHITE)
DEF_GRAPHITE_TEST_FOR_RENDERING_CONTEXTS(SkRuntimeEffectSimple_Graphite, r, context,
                                         CtsEnforcement::kApiLevel_202404) {
    std::unique_ptr<skgpu::graphite::Recorder> recorder = context->makeRecorder();
    GraphiteInfo graphite = {context, recorder.get()};
    test_RuntimeEffect_Shaders(r, /*grContext=*/nullptr, &graphite);
}
#endif

#if defined(SK_GANESH)
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(SkRuntimeEffectSimple_GPU,
                                       r,
                                       ctxInfo,
                                       CtsEnforcement::kApiLevel_T) {
    test_RuntimeEffect_Shaders(r, ctxInfo.directContext(), /*graphite=*/nullptr);
}
#endif

static void verify_draw_obeys_capabilities(skiatest::Reporter* r,
                                           const SkRuntimeEffect* effect,
                                           SkSurface* surface,
                                           const SkPaint& paint) {
    // We expect the draw to do something if-and-only-if expectSuccess is true:
    const bool expectSuccess = surface->capabilities()->skslVersion() >= SkSL::Version::k300;

    constexpr uint32_t kGreen = 0xFF00FF00;
    constexpr uint32_t kRed   = 0xFF0000FF;
    const uint32_t kExpected = expectSuccess ? kGreen : kRed;

    surface->getCanvas()->clear(SK_ColorRED);
    surface->getCanvas()->drawPaint(paint);
    verify_2x2_surface_results(r, effect, surface, {kExpected, kExpected, kExpected, kExpected});
}

static void test_RuntimeEffectObeysCapabilities(skiatest::Reporter* r, SkSurface* surface) {
    // This test creates shaders and blenders that target `#version 300`. If a user validates an
    // effect like this against a particular device, and later draws that effect to a device with
    // insufficient capabilities -- we want to fail gracefully (drop the draw entirely).
    // If the capabilities indicate that the effect is supported, we expect it to work.
    //
    // We test two different scenarios here:
    // 1) An effect flagged as #version 300, but actually compatible with #version 100.
    // 2) An effect flagged as #version 300, and using features not available in ES2.
    //
    // We expect both cases to fail cleanly on ES2-only devices -- nothing should be drawn, and
    // there should be no asserts or driver shader-compilation errors.
    //
    // In all tests, we first clear the canvas to RED, then draw an effect that (if it renders)
    // will fill the canvas with GREEN. We check that the final colors match our expectations,
    // based on the device capabilities.

    // Effect that would actually work on CPU/ES2, but should still fail on those devices:
    {
        auto effect = SkRuntimeEffect::MakeForShader(SkString(R"(
            #version 300
            half4 main(float2 xy) { return half4(0, 1, 0, 1); }
        )")).effect;
        REPORTER_ASSERT(r, effect);
        SkPaint paint;
        paint.setShader(effect->makeShader(/*uniforms=*/nullptr, /*children=*/{}));
        REPORTER_ASSERT(r, paint.getShader());
        verify_draw_obeys_capabilities(r, effect.get(), surface, paint);
    }

    // Effect that won't work on CPU/ES2 at all, and should fail gracefully on those devices.
    // We choose to use bit-pun intrinsics because SkSL doesn't automatically inject an extension
    // to enable them (like it does for derivatives). We pass a non-literal value so that SkSL's
    // constant folding doesn't elide them entirely before the driver sees the shader.
    {
        auto effect = SkRuntimeEffect::MakeForShader(SkString(R"(
            #version 300
            half4 main(float2 xy) {
                half4 result = half4(0, 1, 0, 1);
                result.g = intBitsToFloat(floatBitsToInt(result.g));
                return result;
            }
        )")).effect;
        REPORTER_ASSERT(r, effect);
        SkPaint paint;
        paint.setShader(effect->makeShader(/*uniforms=*/nullptr, /*children=*/{}));
        REPORTER_ASSERT(r, paint.getShader());
        verify_draw_obeys_capabilities(r, effect.get(), surface, paint);
    }

    //
    // As above, but with a blender
    //

    {
        auto effect = SkRuntimeEffect::MakeForBlender(SkString(R"(
            #version 300
            half4 main(half4 src, half4 dst) { return half4(0, 1, 0, 1); }
        )")).effect;
        REPORTER_ASSERT(r, effect);
        SkPaint paint;
        paint.setBlender(effect->makeBlender(/*uniforms=*/nullptr, /*children=*/{}));
        REPORTER_ASSERT(r, paint.getBlender());
        verify_draw_obeys_capabilities(r, effect.get(), surface, paint);
    }

    {
        auto effect = SkRuntimeEffect::MakeForBlender(SkString(R"(
            #version 300
            half4 main(half4 src, half4 dst) {
                half4 result = half4(0, 1, 0, 1);
                result.g = intBitsToFloat(floatBitsToInt(result.g));
                return result;
            }
        )")).effect;
        REPORTER_ASSERT(r, effect);
        SkPaint paint;
        paint.setBlender(effect->makeBlender(/*uniforms=*/nullptr, /*children=*/{}));
        REPORTER_ASSERT(r, paint.getBlender());
        verify_draw_obeys_capabilities(r, effect.get(), surface, paint);
    }
}

DEF_TEST(SkRuntimeEffectObeysCapabilities_CPU, r) {
    SkImageInfo info = SkImageInfo::Make(2, 2, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
    sk_sp<SkSurface> surface = SkSurfaces::Raster(info);
    REPORTER_ASSERT(r, surface);
    test_RuntimeEffectObeysCapabilities(r, surface.get());
}

#if defined(SK_GANESH)
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(SkRuntimeEffectObeysCapabilities_GPU,
                                       r,
                                       ctxInfo,
                                       CtsEnforcement::kApiLevel_U) {
    SkImageInfo info = SkImageInfo::Make(2, 2, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
    sk_sp<SkSurface> surface =
            SkSurfaces::RenderTarget(ctxInfo.directContext(), skgpu::Budgeted::kNo, info);
    REPORTER_ASSERT(r, surface);
    test_RuntimeEffectObeysCapabilities(r, surface.get());
}

DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(SkRuntimeColorFilterReturningInvalidAlpha_GPU,
                                       r,
                                       ctxInfo,
                                       CtsEnforcement::kNever) {
    SkImageInfo info = SkImageInfo::Make(2, 2, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
    sk_sp<SkSurface> surface =
            SkSurfaces::RenderTarget(ctxInfo.directContext(), skgpu::Budgeted::kNo, info);
    REPORTER_ASSERT(r, surface);

    auto effect = SkRuntimeEffect::MakeForColorFilter(SkString(R"(
        half4 main(half4 color) { return half4(2); }
    )")).effect;
    REPORTER_ASSERT(r, effect);
    SkPaint paint;
    paint.setColorFilter(effect->makeColorFilter(/*uniforms=*/nullptr));
    REPORTER_ASSERT(r, paint.getColorFilter());
    surface->getCanvas()->drawPaint(paint);
}
#endif

DEF_TEST(SkRuntimeColorFilterLimitedToES2, r) {
    // Verify that SkSL requesting #version 300 can't be used to create a color-filter effect.
    // This restriction could be removed if we can find a way to implement filterColor4f for these
    // color filters.
    {
        auto effect = SkRuntimeEffect::MakeForColorFilter(SkString(R"(
            #version 300
            half4 main(half4 inColor) { return half4(1, 0, 0, 1); }
        )")).effect;
        REPORTER_ASSERT(r, !effect);
    }

    {
        auto effect = SkRuntimeEffect::MakeForColorFilter(SkString(R"(
            #version 300
            uniform int loops;
            half4 main(half4 inColor) {
                half4 result = half4(1, 0, 0, 1);
                for (int i = 0; i < loops; i++) {
                    result = result.argb;
                }
                return result;
            }
        )")).effect;
        REPORTER_ASSERT(r, !effect);
    }
}

DEF_TEST(SkRuntimeEffectTraceShader, r) {
    for (int imageSize : {2, 80}) {
        TestEffect effect(r, /*grContext=*/nullptr, /*graphite=*/nullptr,
                          SkISize{imageSize, imageSize});
        effect.build(R"(
            half4 main(float2 p) {
                float2 val = p - 0.5;
                return val.0y01;
            }
        )");
        int center = imageSize / 2;
        std::string dump = effect.trace({center, 1});
        static constexpr char kSkRPSlotDump[] =
R"($0 = p (float2 : slot 1/2, L0)
$1 = p (float2 : slot 2/2, L0)
$2 = [main].result (float4 : slot 1/4, L0)
$3 = [main].result (float4 : slot 2/4, L0)
$4 = [main].result (float4 : slot 3/4, L0)
$5 = [main].result (float4 : slot 4/4, L0)
$6 = val (float2 : slot 1/2, L0)
$7 = val (float2 : slot 2/2, L0)
F0 = half4 main(float2 p)
)";
        auto expectedTrace = SkSL::String::printf(R"(
enter half4 main(float2 p)
  p.x = %d.5
  p.y = 1.5
  scope +1
   line 3
   val.x = %d
   val.y = 1
   line 4
   [main].result.x = 0
   [main].result.y = 1
   [main].result.z = 0
   [main].result.w = 1
  scope -1
exit half4 main(float2 p)
)", center, center);
        REPORTER_ASSERT(
                r,
                skstd::starts_with(dump, kSkRPSlotDump) && skstd::ends_with(dump, expectedTrace),
                "Trace does not match expectation for %dx%d:\n%.*s\n",
                imageSize, imageSize, (int)dump.size(), dump.data());
    }
}

DEF_TEST(SkRuntimeEffectTracesAreUnoptimized, r) {
    TestEffect effect(r, /*grContext=*/nullptr, /*graphite=*/nullptr);

    effect.build(R"(
        int globalUnreferencedVar = 7;
        half inlinableFunction() {
            return 1;
        }
        half4 main(float2 p) {
            if (true) {
                int localUnreferencedVar = 7;
            }
            return inlinableFunction().xxxx;
        }
    )");
    std::string dump = effect.trace({1, 1});
    static constexpr char kSkRPSlotDump[] =
R"($0 = p (float2 : slot 1/2, L0)
$1 = p (float2 : slot 2/2, L0)
$2 = globalUnreferencedVar (int, L0)
$3 = [main].result (float4 : slot 1/4, L0)
$4 = [main].result (float4 : slot 2/4, L0)
$5 = [main].result (float4 : slot 3/4, L0)
$6 = [main].result (float4 : slot 4/4, L0)
$7 = localUnreferencedVar (int, L0)
$8 = [inlinableFunction].result (float, L0)
F0 = half4 main(float2 p)
F1 = half inlinableFunction()
)";
    static constexpr char kExpectedTrace[] = R"(
globalUnreferencedVar = 7
enter half4 main(float2 p)
  p.x = 1.5
  p.y = 1.5
  scope +1
   line 7
   scope +1
    line 8
    localUnreferencedVar = 7
   scope -1
   line 10
   enter half inlinableFunction()
     scope +1
      line 4
      [inlinableFunction].result = 1
     scope -1
   exit half inlinableFunction()
   [main].result.x = 1
   [main].result.y = 1
   [main].result.z = 1
   [main].result.w = 1
  scope -1
exit half4 main(float2 p)
)";
    REPORTER_ASSERT(
            r,
            skstd::starts_with(dump, kSkRPSlotDump) && skstd::ends_with(dump, kExpectedTrace),
            "Trace output does not match expectation:\n%.*s\n", (int)dump.size(), dump.data());
}

DEF_TEST(SkRuntimeEffectTraceCodeThatCannotBeUnoptimized, r) {
    TestEffect effect(r, /*grContext=*/nullptr, /*graphite=*/nullptr);

    effect.build(R"(
        half4 main(float2 p) {
            int variableThatGetsOptimizedAway = 7;
            if (true) {
                return half4(1);
            }
            // This (unreachable) path doesn't return a value.
            // Without optimization, SkSL thinks this code doesn't return a value on every path.
        }
    )");
    std::string dump = effect.trace({1, 1});
    static constexpr char kSkRPSlotDump[] =
R"($0 = p (float2 : slot 1/2, L0)
$1 = p (float2 : slot 2/2, L0)
$2 = [main].result (float4 : slot 1/4, L0)
$3 = [main].result (float4 : slot 2/4, L0)
$4 = [main].result (float4 : slot 3/4, L0)
$5 = [main].result (float4 : slot 4/4, L0)
F0 = half4 main(float2 p)
)";
    static constexpr char kExpectedTrace[] = R"(
enter half4 main(float2 p)
  p.x = 1.5
  p.y = 1.5
  scope +1
   scope +1
    line 5
    [main].result.x = 1
    [main].result.y = 1
    [main].result.z = 1
    [main].result.w = 1
   scope -1
  scope -1
exit half4 main(float2 p)
)";
    REPORTER_ASSERT(
            r,
            skstd::starts_with(dump, kSkRPSlotDump) && skstd::ends_with(dump, kExpectedTrace),
            "Trace output does not match expectation:\n%.*s\n", (int)dump.size(), dump.data());
}

static void test_RuntimeEffect_Blenders(skiatest::Reporter* r,
                                        GrRecordingContext* grContext,
                                        const GraphiteInfo* graphite) {
    TestBlend effect(r, grContext, graphite);

    using float2 = std::array<float, 2>;
    using float4 = std::array<float, 4>;
    using int4 = std::array<int, 4>;

    SkPaint rgbwPaint;
    rgbwPaint.setShader(make_RGBW_shader());
    rgbwPaint.setBlendMode(SkBlendMode::kSrc);

    // Use of a simple uniform. (Draw twice with two values to ensure it's updated).
    effect.build("uniform float4 gColor; half4 main(half4 s, half4 d) { return half4(gColor); }");
    effect.uniform("gColor") = float4{ 0.0f, 0.25f, 0.75f, 1.0f };
    effect.test(0xFFBF4000);
    effect.uniform("gColor") = float4{ 1.0f, 0.0f, 0.0f, 0.498f };
    effect.test(0x7F0000FF);  // We don't clamp here either

    // Same, with integer uniforms
    effect.build("uniform int4 gColor;"
                 "half4 main(half4 s, half4 d) { return half4(gColor) / 255.0; }");
    effect.uniform("gColor") = int4{ 0x00, 0x40, 0xBF, 0xFF };
    effect.test(0xFFBF4000);
    effect.uniform("gColor") = int4{ 0xFF, 0x00, 0x00, 0x7F };
    effect.test(0x7F0000FF);  // We don't clamp here either

    // Verify that mutating the source and destination colors is allowed
    effect.build("half4 main(half4 s, half4 d) { s += d; d += s; return half4(1); }");
    effect.test(0xFFFFFFFF);

    // Verify that we can write out the source color (ignoring the dest color)
    // This is equivalent to the kSrc blend mode.
    effect.build("half4 main(half4 s, half4 d) { return s; }");
    effect.test(0xFF888888);

    // Fill the destination with a variety of colors (using the RGBW shader)
    effect.surface()->getCanvas()->drawPaint(rgbwPaint);

    // Verify that we can read back the dest color exactly as-is (ignoring the source color)
    // This is equivalent to the kDst blend mode.
    effect.build("half4 main(half4 s, half4 d) { return d; }");
    effect.test({0xFF0000FF, 0xFF00FF00, 0xFFFF0000, 0xFFFFFFFF});

    // Verify that we can invert the destination color (including the alpha channel).
    // The expected outputs are the exact inverse of the previous test.
    effect.build("half4 main(half4 s, half4 d) { return half4(1) - d; }");
    effect.test({0x00FFFF00, 0x00FF00FF, 0x0000FFFF, 0x00000000});

    // Verify that color values are clamped to 0 and 1.
    effect.build("half4 main(half4 s, half4 d) { return half4(-1); }");
    effect.test(0x00000000);
    effect.build("half4 main(half4 s, half4 d) { return half4(2); }");
    effect.test(0xFFFFFFFF);

    //
    // Sampling children
    //

    // Sampling a null shader should return transparent black.
    effect.build("uniform shader child;"
                 "half4 main(half4 s, half4 d) { return child.eval(s.rg); }");
    effect.child("child") = nullptr;
    effect.test(0x00000000,
                [](SkCanvas*, SkPaint* paint) { paint->setColor4f({1.0f, 1.0f, 0.0f, 1.0f}); });

    effect.build("uniform colorFilter child;"
                 "half4 main(half4 s, half4 d) { return child.eval(s); }");
    effect.child("child") = nullptr;
    effect.test(0xFF00FFFF,
                [](SkCanvas*, SkPaint* paint) { paint->setColor4f({1.0f, 1.0f, 0.0f, 1.0f}); });

    // Sampling a null blender should do a src-over blend. Draw 50% black over RGBW to verify this.
    effect.surface()->getCanvas()->drawPaint(rgbwPaint);
    effect.build("uniform blender child;"
                 "half4 main(half4 s, half4 d) { return child.eval(s, d); }");
    effect.child("child") = nullptr;
    effect.test({0xFF000080, 0xFF008000, 0xFF800000, 0xFF808080},
                [](SkCanvas*, SkPaint* paint) { paint->setColor4f({0.0f, 0.0f, 0.0f, 0.497f}); });

    // Sampling a shader at various coordinates
    effect.build("uniform shader child;"
                 "uniform half2 pos;"
                 "half4 main(half4 s, half4 d) { return child.eval(pos); }");
    effect.child("child") = make_RGBW_shader();
    effect.uniform("pos") = float2{0.5, 0.5};
    effect.test(0xFF0000FF);

    effect.uniform("pos") = float2{1.5, 0.5};
    effect.test(0xFF00FF00);

    effect.uniform("pos") = float2{0.5, 1.5};
    effect.test(0xFFFF0000);

    effect.uniform("pos") = float2{1.5, 1.5};
    effect.test(0xFFFFFFFF);

    // Sampling a shader as above, but via a helper function
    effect.build("uniform shader child;"
                 "uniform half2 pos;"
                 "half4 eval_at_pos(shader x) { return x.eval(pos); }"
                 "half4 main(half4 s, half4 d) { return eval_at_pos(child); }",
                 /*allowPrivateAccess=*/true);
    effect.child("child") = make_RGBW_shader();
    effect.uniform("pos") = float2{0.5, 0.5};
    effect.test(0xFF0000FF);

    effect.uniform("pos") = float2{1.5, 0.5};
    effect.test(0xFF00FF00);

    effect.uniform("pos") = float2{0.5, 1.5};
    effect.test(0xFFFF0000);

    effect.uniform("pos") = float2{1.5, 1.5};
    effect.test(0xFFFFFFFF);

    // Sampling a color filter
    effect.build("uniform colorFilter child;"
                 "half4 main(half4 s, half4 d) { return child.eval(half4(1)); }");
    effect.child("child") = SkColorFilters::Blend(0xFF012345, SkBlendMode::kSrc);
    effect.test(0xFF452301);

    // Sampling a built-in blender
    effect.surface()->getCanvas()->drawPaint(rgbwPaint);
    effect.build("uniform blender child;"
                 "half4 main(half4 s, half4 d) { return child.eval(s, d); }");
    effect.child("child") = SkBlender::Mode(SkBlendMode::kPlus);
    effect.test({0xFF4523FF, 0xFF45FF01, 0xFFFF2301, 0xFFFFFFFF},
                [](SkCanvas*, SkPaint* paint) { paint->setColor(0xFF012345); });

    // Sampling a runtime-effect blender
    effect.surface()->getCanvas()->drawPaint(rgbwPaint);
    effect.build("uniform blender child;"
                 "half4 main(half4 s, half4 d) { return child.eval(s, d); }");
    effect.child("child") = SkBlenders::Arithmetic(0, 1, 1, 0, /*enforcePremul=*/false);
    effect.test({0xFF4523FF, 0xFF45FF01, 0xFFFF2301, 0xFFFFFFFF},
                [](SkCanvas*, SkPaint* paint) { paint->setColor(0xFF012345); });
}

DEF_TEST(SkRuntimeEffect_Blender_CPU, r) {
    test_RuntimeEffect_Blenders(r, /*grContext=*/nullptr, /*graphite=*/nullptr);
}

#if defined(SK_GANESH)
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(SkRuntimeEffect_Blender_GPU,
                                       r,
                                       ctxInfo,
                                       CtsEnforcement::kApiLevel_T) {
    test_RuntimeEffect_Blenders(r, ctxInfo.directContext(), /*graphite=*/nullptr);
}
#endif

DEF_TEST(SkRuntimeShaderBuilderReuse, r) {
    const char* kSource = R"(
        uniform half x;
        half4 main(float2 p) { return half4(x); }
    )";

    sk_sp<SkRuntimeEffect> effect = SkRuntimeEffect::MakeForShader(SkString(kSource)).effect;
    REPORTER_ASSERT(r, effect);

    // Test passes if this sequence doesn't assert.  skbug.com/40042013
    SkRuntimeShaderBuilder b(std::move(effect));
    b.uniform("x") = 0.0f;
    auto shader_0 = b.makeShader();

    b.uniform("x") = 1.0f;
    auto shader_1 = b.makeShader();
}

DEF_TEST(SkRuntimeBlendBuilderReuse, r) {
    const char* kSource = R"(
        uniform half x;
        half4 main(half4 s, half4 d) { return half4(x); }
    )";

    sk_sp<SkRuntimeEffect> effect = SkRuntimeEffect::MakeForBlender(SkString(kSource)).effect;
    REPORTER_ASSERT(r, effect);

    // We should be able to construct multiple SkBlenders in a row without asserting.
    SkRuntimeBlendBuilder b(std::move(effect));
    for (float x = 0.0f; x <= 2.0f; x += 2.0f) {
        b.uniform("x") = x;
        sk_sp<SkBlender> blender = b.makeBlender();
    }
}

DEF_TEST(SkRuntimeShaderBuilderSetUniforms, r) {
    const char* kSource = R"(
        uniform half x;
        uniform vec2 offset;
        half4 main(float2 p) { return half4(x); }
    )";

    sk_sp<SkRuntimeEffect> effect = SkRuntimeEffect::MakeForShader(SkString(kSource)).effect;
    REPORTER_ASSERT(r, effect);

    SkRuntimeShaderBuilder b(std::move(effect));

    // Test passes if this sequence doesn't assert.
    float x = 1.0f;
    REPORTER_ASSERT(r, b.uniform("x").set(&x, 1));

    // add extra value to ensure that set doesn't try to use sizeof(array)
    float origin[] = { 2.0f, 3.0f, 4.0f };
    REPORTER_ASSERT(r, b.uniform("offset").set<float>(origin, 2));

#ifndef SK_DEBUG
    REPORTER_ASSERT(r, !b.uniform("offset").set<float>(origin, 1));
    REPORTER_ASSERT(r, !b.uniform("offset").set<float>(origin, 3));
#endif

    auto shader = b.makeShader();
}

DEF_TEST(SkRuntimeEffectThreaded, r) {
    // This tests that we can safely use SkRuntimeEffect::MakeForShader from more than one thread,
    // and also that programs don't refer to shared structures owned by the compiler.
    // skbug.com/40041933
    static constexpr char kSource[] = "half4 main(float2 p) { return sk_FragCoord.xyxy; }";

    std::thread threads[16];
    for (auto& thread : threads) {
        thread = std::thread([r]() {
            SkRuntimeEffect::Options options;
            SkRuntimeEffectPriv::AllowPrivateAccess(&options);
            auto [effect, error] = SkRuntimeEffect::MakeForShader(SkString(kSource), options);
            REPORTER_ASSERT(r, effect);
        });
    }

    for (auto& thread : threads) {
        thread.join();
    }
}

DEF_TEST(SkRuntimeEffectAllowsPrivateAccess, r) {
    SkRuntimeEffect::Options defaultOptions;
    SkRuntimeEffect::Options optionsWithAccess;
    SkRuntimeEffectPriv::AllowPrivateAccess(&optionsWithAccess);

    // Confirm that shaders can only access $private_functions when private access is allowed.
    {
        static constexpr char kShader[] =
                "half4 main(float2 p) { return $hsl_to_rgb(p.xxx, p.y); }";
        SkRuntimeEffect::Result normal =
                SkRuntimeEffect::MakeForShader(SkString(kShader), defaultOptions);
        REPORTER_ASSERT(r, !normal.effect);
        SkRuntimeEffect::Result privileged =
                SkRuntimeEffect::MakeForShader(SkString(kShader), optionsWithAccess);
        REPORTER_ASSERT(r, privileged.effect, "%s", privileged.errorText.c_str());
    }

    // Confirm that color filters can only access $private_functions when private access is allowed.
    {
        static constexpr char kColorFilter[] =
                "half4 main(half4 c)  { return $hsl_to_rgb(c.rgb, c.a); }";
        SkRuntimeEffect::Result normal =
                SkRuntimeEffect::MakeForColorFilter(SkString(kColorFilter), defaultOptions);
        REPORTER_ASSERT(r, !normal.effect);
        SkRuntimeEffect::Result privileged =
                SkRuntimeEffect::MakeForColorFilter(SkString(kColorFilter), optionsWithAccess);
        REPORTER_ASSERT(r, privileged.effect, "%s", privileged.errorText.c_str());
    }

    // Confirm that blenders can only access $private_functions when private access is allowed.
    {
        static constexpr char kBlender[] =
                "half4 main(half4 s, half4 d) { return $hsl_to_rgb(s.rgb, d.a); }";
        SkRuntimeEffect::Result normal =
                SkRuntimeEffect::MakeForBlender(SkString(kBlender), defaultOptions);
        REPORTER_ASSERT(r, !normal.effect);
        SkRuntimeEffect::Result privileged =
                SkRuntimeEffect::MakeForBlender(SkString(kBlender), optionsWithAccess);
        REPORTER_ASSERT(r, privileged.effect, "%s", privileged.errorText.c_str());
    }
}

DEF_TEST(SkRuntimeColorFilterSingleColor, r) {
    // Test runtime colorfilters support filterColor4f().
    auto [effect, err] =
            SkRuntimeEffect::MakeForColorFilter(SkString{"half4 main(half4 c) { return c*c; }"});
    REPORTER_ASSERT(r, effect);
    REPORTER_ASSERT(r, err.isEmpty());

    sk_sp<SkColorFilter> cf = effect->makeColorFilter(SkData::MakeEmpty());
    REPORTER_ASSERT(r, cf);

    SkColor4f c = cf->filterColor4f({0.25, 0.5, 0.75, 1.0},
                                    sk_srgb_singleton(), sk_srgb_singleton());
    REPORTER_ASSERT(r, c.fR == 0.0625f);
    REPORTER_ASSERT(r, c.fG == 0.25f);
    REPORTER_ASSERT(r, c.fB == 0.5625f);
    REPORTER_ASSERT(r, c.fA == 1.0f);
}

static void test_RuntimeEffectStructNameReuse(skiatest::Reporter* r, GrRecordingContext* rContext) {
    // Test that two different runtime effects can reuse struct names in a single paint operation
    auto [childEffect, err] = SkRuntimeEffect::MakeForShader(SkString(
        "uniform shader paint;"
        "struct S { half4 rgba; };"
        "void process(inout S s) { s.rgba.rgb *= 0.5; }"
        "half4 main(float2 p) { S s; s.rgba = paint.eval(p); process(s); return s.rgba; }"
    ));
    REPORTER_ASSERT(r, childEffect, "%s\n", err.c_str());
    sk_sp<SkShader> sourceColor = SkShaders::Color({0.99608f, 0.50196f, 0.0f, 1.0f}, nullptr);
    const uint32_t kExpected = 0xFF00407F;
    sk_sp<SkShader> child = childEffect->makeShader(/*uniforms=*/nullptr,
                                                    &sourceColor,
                                                    /*childCount=*/1);

    TestEffect effect(r, /*grContext=*/nullptr, /*graphite=*/nullptr);
    effect.build(
            "uniform shader child;"
            "struct S { float2 coord; };"
            "void process(inout S s) { s.coord = s.coord.yx; }"
            "half4 main(float2 p) { S s; s.coord = p; process(s); return child.eval(s.coord); "
            "}");
    effect.child("child") = child;
    effect.test(kExpected, [](SkCanvas*, SkPaint* paint) {});
}

DEF_TEST(SkRuntimeStructNameReuse, r) {
    test_RuntimeEffectStructNameReuse(r, nullptr);
}

#if defined(SK_GANESH)
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(SkRuntimeStructNameReuse_GPU,
                                       r,
                                       ctxInfo,
                                       CtsEnforcement::kApiLevel_T) {
    test_RuntimeEffectStructNameReuse(r, ctxInfo.directContext());
}
#endif

DEF_TEST(SkRuntimeColorFilterFlags, r) {
    auto expectAlphaUnchanged = [&](const char* shader) {
        auto [effect, err] = SkRuntimeEffect::MakeForColorFilter(SkString{shader});
        REPORTER_ASSERT(r, effect && err.isEmpty(), "%s", shader);
        sk_sp<SkColorFilter> filter = effect->makeColorFilter(SkData::MakeEmpty());
        REPORTER_ASSERT(r, filter && filter->isAlphaUnchanged(), "%s", shader);
    };

    auto expectAlphaChanged = [&](const char* shader) {
        auto [effect, err] = SkRuntimeEffect::MakeForColorFilter(SkString{shader});
        REPORTER_ASSERT(r, effect && err.isEmpty(), "%s", shader);
        sk_sp<SkColorFilter> filter = effect->makeColorFilter(SkData::MakeEmpty());
        REPORTER_ASSERT(r, filter && !filter->isAlphaUnchanged(), "%s", shader);
    };

    // We expect these patterns to be detected as alpha-unchanged.
    expectAlphaUnchanged("half4 main(half4 color) { return color; }");
    expectAlphaUnchanged("half4 main(half4 color) { return color.aaaa; }");
    expectAlphaUnchanged("half4 main(half4 color) { return color.bgra; }");
    expectAlphaUnchanged("half4 main(half4 color) { return color.rraa; }");
    expectAlphaUnchanged("half4 main(half4 color) { return color.010a; }");
    expectAlphaUnchanged("half4 main(half4 color) { return half4(0, 0, 0, color.a); }");
    expectAlphaUnchanged("half4 main(half4 color) { return half4(half2(1), color.ba); }");
    expectAlphaUnchanged("half4 main(half4 color) { return half4(half2(1), half2(color.a)); }");
    expectAlphaUnchanged("half4 main(half4 color) { return half4(color.a); }");
    expectAlphaUnchanged("half4 main(half4 color) { return half4(float4(color.baba)); }");
    expectAlphaUnchanged("half4 main(half4 color) { return color.r != color.g ? color :"
                                                                              " color.000a; }");
    expectAlphaUnchanged("half4 main(half4 color) { return color.a == color.r ? color.rrra : "
                                                          "color.g == color.b ? color.ggga : "
                                                                            "   color.bbba; }");
    // Modifying the input color invalidates the check.
    expectAlphaChanged("half4 main(half4 color) { color.a = 0; return color; }");

    // These swizzles don't end in alpha.
    expectAlphaChanged("half4 main(half4 color) { return color.argb; }");
    expectAlphaChanged("half4 main(half4 color) { return color.rrrr; }");

    // This compound constructor doesn't end in alpha.
    expectAlphaChanged("half4 main(half4 color) { return half4(1, 1, 1, color.r); }");

    // This splat constructor doesn't use alpha.
    expectAlphaChanged("half4 main(half4 color) { return half4(color.r); }");

    // These ternaries don't return alpha on both sides
    expectAlphaChanged("half4 main(half4 color) { return color.a > 0 ? half4(0) : color; }");
    expectAlphaChanged("half4 main(half4 color) { return color.g < 1 ? color.bgra : color.abgr; }");
    expectAlphaChanged("half4 main(half4 color) { return color.b > 0.5 ? half4(0) : half4(1); }");

    // Performing arithmetic on the input causes it to report as "alpha changed" even if the
    // arithmetic is a no-op; we aren't smart enough to see through it.
    expectAlphaChanged("half4 main(half4 color) { return color + half4(1,1,1,0); }");
    expectAlphaChanged("half4 main(half4 color) { return color + half4(0,0,0,4); }");

    // All exit paths are checked.
    expectAlphaChanged("half4 main(half4 color) { "
                       "    if (color.r > 0.5) { return color; }"
                       "    return half4(0);"
                       "}");
    expectAlphaChanged("half4 main(half4 color) { "
                       "    if (color.r > 0.5) { return half4(0); }"
                       "    return color;"
                       "}");
}

#if defined(SK_GANESH)
DEF_TEST(SkRuntimeShaderSampleCoords, r) {
    // This test verifies that we detect calls to sample where the coords are the same as those
    // passed to main. In those cases, it's safe to turn the "explicit" sampling into "passthrough"
    // sampling. This optimization is implemented very conservatively.
    //
    // It also checks that we correctly set the "referencesSampleCoords" bit on the runtime effect
    // FP, depending on how the coords parameter to main is used.

    auto test = [&](const char* src, bool expectExplicit, bool expectReferencesSampleCoords) {
        auto [effect, err] =
                SkRuntimeEffect::MakeForShader(SkStringPrintf("uniform shader child; %s", src));
        REPORTER_ASSERT(r, effect);

        auto child = GrFragmentProcessor::MakeColor({ 1, 1, 1, 1 });
        auto fp = GrSkSLFP::Make(effect.get(), "test_fp", /*inputFP=*/nullptr,
                                 GrSkSLFP::OptFlags::kNone, "child", std::move(child));
        REPORTER_ASSERT(r, fp);

        REPORTER_ASSERT(r, fp->childProcessor(0)->sampleUsage().isExplicit() == expectExplicit);
        REPORTER_ASSERT(r, fp->usesSampleCoords() == expectReferencesSampleCoords);
    };

    // Cases where our optimization is valid, and works:

    // Direct use of passed-in coords. Here, the only use of sample coords is for a sample call
    // converted to passthrough, so referenceSampleCoords is *false*, despite appearing in main.
    test("half4 main(float2 xy) { return child.eval(xy); }", false, false);
    // Sample with passed-in coords, read (but don't write) sample coords elsewhere
    test("half4 main(float2 xy) { return child.eval(xy) + sin(xy.x); }", false, true);

    // Cases where our optimization is not valid, and does not happen:

    // Sampling with values completely unrelated to passed-in coords
    test("half4 main(float2 xy) { return child.eval(float2(0, 0)); }", true, false);
    // Use of expression involving passed in coords
    test("half4 main(float2 xy) { return child.eval(xy * 0.5); }", true, true);
    // Use of coords after modification
    test("half4 main(float2 xy) { xy *= 2; return child.eval(xy); }", true, true);
    // Use of coords after modification via out-param call
    test("void adjust(inout float2 xy) { xy *= 2; }"
         "half4 main(float2 xy) { adjust(xy); return child.eval(xy); }", true, true);

    // There should (must) not be any false-positive cases. There are false-negatives.
    // In all of these cases, our optimization would be valid, but does not happen:

    // Direct use of passed-in coords, modified after use
    test("half4 main(float2 xy) { half4 c = child.eval(xy); xy *= 2; return c; }", true, true);
    // Passed-in coords copied to a temp variable
    test("half4 main(float2 xy) { float2 p = xy; return child.eval(p); }", true, true);
    // Use of coords passed to helper function
    test("half4 helper(float2 xy) { return child.eval(xy); }"
         "half4 main(float2 xy) { return helper(xy); }", true, true);
}
#endif

DEF_TEST(SkRuntimeShaderIsOpaque, r) {
    // This test verifies that we detect certain simple patterns in runtime shaders, and can deduce
    // (via code in SkSL::Analysis::ReturnsOpaqueColor) that the resulting shader is always opaque.
    // That logic is conservative, and the tests below reflect this.

    auto test = [&](const char* body, bool expectOpaque) {
        auto [effect, err] = SkRuntimeEffect::MakeForShader(SkStringPrintf(R"(
            uniform shader cOnes;
            uniform shader cZeros;
            uniform float4 uOnes;
            uniform float4 uZeros;
            half4 main(float2 xy) {
                %s
            })", body));
        REPORTER_ASSERT(r, effect);

        auto cOnes = SkShaders::Color(SK_ColorWHITE);
        auto cZeros = SkShaders::Color(SK_ColorTRANSPARENT);
        SkASSERT(cOnes->isOpaque());
        SkASSERT(!cZeros->isOpaque());

        SkRuntimeShaderBuilder builder(effect);
        builder.child("cOnes") = std::move(cOnes);
        builder.child("cZeros") = std::move(cZeros);
        builder.uniform("uOnes") = SkColors::kWhite;
        builder.uniform("uZeros") = SkColors::kTransparent;

        auto shader = builder.makeShader();
        REPORTER_ASSERT(r, shader->isOpaque() == expectOpaque);
    };

    // Cases where our optimization is valid, and works:

    // Returning opaque literals
    test("return half4(1);",          true);
    test("return half4(0, 1, 0, 1);", true);
    test("return half4(0, 0, 0, 1);", true);

    // Simple expressions involving uniforms
    test("return uZeros.rgb1;",          true);
    test("return uZeros.bgra.rgb1;",     true);
    test("return half4(uZeros.rgb, 1);", true);

    // Simple expressions involving child.eval
    test("return cZeros.eval(xy).rgb1;",          true);
    test("return cZeros.eval(xy).bgra.rgb1;",     true);
    test("return half4(cZeros.eval(xy).rgb, 1);", true);

    // Multiple returns
    test("if (xy.x < 100) { return uZeros.rgb1; } else { return cZeros.eval(xy).rgb1; }", true);

    // More expression cases:
    test("return (cZeros.eval(xy) * uZeros).rgb1;", true);
    test("return half4(1, 1, 1, 0.5 + 0.5);",       true);

    // Constant variable propagation
    test("const half4 kWhite = half4(1); return kWhite;", true);

    // Cases where our optimization is not valid, and does not happen:

    // Returning non-opaque literals
    test("return half4(0);",          false);
    test("return half4(1, 1, 1, 0);", false);

    // Returning non-opaque uniforms or children
    test("return uZeros;",          false);
    test("return cZeros.eval(xy);", false);

    // Multiple returns
    test("if (xy.x < 100) { return uZeros; } else { return cZeros.eval(xy).rgb1; }", false);
    test("if (xy.x < 100) { return uZeros.rgb1; } else { return cZeros.eval(xy); }", false);

    // There should (must) not be any false-positive cases. There are false-negatives.
    // In these cases, our optimization would be valid, but does not happen:

    // More complex expressions that can't be simplified
    test("return xy.x < 100 ? uZeros.rgb1 : cZeros.eval(xy).rgb1;", false);

    // Finally, there are cases that are conditional on the uniforms and children. These *could*
    // determine dynamically if the uniform and/or child being referenced is opaque, and use that
    // information. Today, we don't do this, so we pessimistically assume they're transparent:
    test("return uOnes;",          false);
    test("return cOnes.eval(xy);", false);
}

// This test verifies that when a runtime shader's input coordinates are previously transformed
// by a local matrix (which may be lifted to the vertex shader on GPU backends), the coordinates
// resolve correctly for the runtime shader and any child shaders.
void test_using_transformed_coords(skiatest::Reporter* reporter,
                                   GrDirectContext* ganeshContext,
                                   GraphiteInfo* graphiteInfo) {
    const SkImageInfo surfaceImageInfo = SkImageInfo::Make(SkISize::Make(12, 1),
                                                           SkColorType::kRGBA_8888_SkColorType,
                                                           SkAlphaType::kPremul_SkAlphaType);
    sk_sp<SkSurface> surface;
    if (ganeshContext) {
#if defined(SK_GANESH)
        surface = SkSurfaces::RenderTarget(ganeshContext, skgpu::Budgeted::kNo, surfaceImageInfo);
#endif
    } else if (graphiteInfo) {
#if defined(SK_GRAPHITE)
        surface = SkSurfaces::RenderTarget(graphiteInfo->recorder, surfaceImageInfo);
#endif
    }
    REPORTER_ASSERT(reporter, surface);
    if (!surface) {
        return;
    }

    SkCanvas* canvas = surface->getCanvas();

    // Make a 1x12 pixel image with left 1/4 red and right 3/4 green.
    SkBitmap bitmap;
    bitmap.allocN32Pixels(12, 1, true);
    SkCanvas bitmapCanvas(bitmap);
    bitmapCanvas.drawIRect(SkIRect::MakeXYWH(0, 0, 3, 1), SkPaint(SkColors::kRed));
    bitmapCanvas.drawIRect(SkIRect::MakeXYWH(3, 0, 9, 1), SkPaint(SkColors::kGreen));

    sk_sp<SkShader> imageShader = ToolUtils::MakeTextureImage(canvas, bitmap.asImage())
                                          ->makeShader(SkFilterMode::kNearest);

    // Runtime effect that sets the blue channel to 1 in the right half of its child.
    SkString src(
            "uniform shader s;"
            "half4 main(float2 p) {"
                // round() doesn't seem to be legal in runtime shaders for some reason.
                "return half4(s.eval(p).rg, max(0.0, sign(p.x / 12.0 - 0.5)), 1.0);"
            "}");
    SkRuntimeEffect::Result runtimeEffectResult = SkRuntimeEffect::MakeForShader(src);
    auto [effect, errorText] = SkRuntimeEffect::MakeForShader(SkString(src));
    REPORTER_ASSERT(reporter, effect);
    if (!effect) {
        return;
    }

    // Nest the image shader under the runtime shader, all under a local matrix transformation that
    // translates the draw right 1/4 of the way.
    SkPaint paint;
    paint.setShader(runtimeEffectResult.effect->makeShader(nullptr, &imageShader, 1)
                            ->makeWithLocalMatrix(SkMatrix::Translate(3.0f, 0.0f)));

    canvas->drawPaint(paint);

    // Read pixels.
    SkBitmap readBitmap;
    SkPixmap pixmap;
    readBitmap.allocPixels(surfaceImageInfo);
    SkAssertResult(readBitmap.peekPixels(&pixmap));
    if (!surface->readPixels(pixmap, 0, 0)) {
        ERRORF(reporter, "readPixels failed");
        return;
    }

    // The first half of the canvas should be red, since the image was drawn shifted to the right
    // with clamp tiling.
    REPORTER_ASSERT(reporter, pixmap.getColor4f(1, 0) == SkColors::kRed);
    REPORTER_ASSERT(reporter, pixmap.getColor4f(4, 0) == SkColors::kRed);

    // The third quarter of the canvas should be green. This is the second quarter of the image,
    // translated right, and not affected by the runtime shader which should only touch the right
    // half of the image.
    REPORTER_ASSERT(reporter, pixmap.getColor4f(7, 0) == SkColors::kGreen);

    // The last quarter of the canvas should be cyan, since the green in the image has its blue
    // channel set to 1 by the runtime shader.
    REPORTER_ASSERT(reporter, pixmap.getColor4f(10, 0) == SkColors::kCyan);
}

#if defined(SK_GRAPHITE)
DEF_GRAPHITE_TEST_FOR_RENDERING_CONTEXTS(SkRuntimeShader_TransformedCoords_Graphite,
                                         reporter,
                                         context,
                                         CtsEnforcement::kApiLevel_202604) {
    std::unique_ptr<skgpu::graphite::Recorder> recorder = context->makeRecorder();
    GraphiteInfo graphiteInfo = {context, recorder.get()};
    test_using_transformed_coords(reporter, /*ganeshContext=*/nullptr, &graphiteInfo);
}
#endif

#if defined(SK_GANESH)
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(SkRuntimeShader_TransformedCoords_Ganesh,
                                       reporter,
                                       contextInfo,
                                       CtsEnforcement::kApiLevel_202604) {
    test_using_transformed_coords(reporter, contextInfo.directContext(), /*graphiteInfo=*/nullptr);
}

DEF_GANESH_TEST_FOR_ALL_CONTEXTS(GrSkSLFP_Specialized, r, ctxInfo, CtsEnforcement::kApiLevel_T) {
    struct FpAndKey {
        std::unique_ptr<GrFragmentProcessor> fp;
        TArray<uint32_t, true>             key;
    };

    // Constant color, but with an 'specialize' option that decides if the color is inserted in the
    // SkSL as a literal, or left as a uniform
    auto make_color_fp = [&](SkPMColor4f color, bool specialize) {
        static const SkRuntimeEffect* effect = SkMakeRuntimeEffect(SkRuntimeEffect::MakeForShader,
            "uniform half4 color;"
            "half4 main(float2 xy) { return color; }"
        );
        FpAndKey result;
        result.fp = GrSkSLFP::Make(effect, "color_fp", /*inputFP=*/nullptr,
                                   GrSkSLFP::OptFlags::kNone,
                                   "color", GrSkSLFP::SpecializeIf(specialize, color));
        skgpu::KeyBuilder builder(&result.key);
        result.fp->addToKey(*ctxInfo.directContext()->priv().caps()->shaderCaps(), &builder);
        builder.flush();
        return result;
    };

    FpAndKey uRed   = make_color_fp({1, 0, 0, 1}, false),
             uGreen = make_color_fp({0, 1, 0, 1}, false),
             sRed   = make_color_fp({1, 0, 0, 1}, true),
             sGreen = make_color_fp({0, 1, 0, 1}, true);

    // uRed and uGreen should have the same key - they just have different uniforms
    SkASSERT(uRed.key == uGreen.key);
    // sRed and sGreen should have keys that are different from the uniform case, and each other
    SkASSERT(sRed.key != uRed.key);
    SkASSERT(sGreen.key != uRed.key);
    SkASSERT(sRed.key != sGreen.key);
}

DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrSkSLFP_UniformArray,
                                       r,
                                       ctxInfo,
                                       CtsEnforcement::kApiLevel_T) {
    // Make a fill-context to draw into.
    GrDirectContext* directContext = ctxInfo.directContext();
    SkImageInfo info = SkImageInfo::Make(1, 1, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
    std::unique_ptr<skgpu::ganesh::SurfaceFillContext> testCtx =
            directContext->priv().makeSFC(info, /*label=*/{}, SkBackingFit::kExact);

    // Make an effect that takes a uniform array as input.
    static constexpr std::array<float, 4> kRed  {1.0f, 0.0f, 0.0f, 1.0f};
    static constexpr std::array<float, 4> kGreen{0.0f, 1.0f, 0.0f, 1.0f};
    static constexpr std::array<float, 4> kBlue {0.0f, 0.0f, 1.0f, 1.0f};
    static constexpr std::array<float, 4> kGray {0.499f, 0.499f, 0.499f, 1.0f};

    for (const auto& colorArray : {kRed, kGreen, kBlue, kGray}) {
        // Compile our runtime effect.
        static const SkRuntimeEffect* effect = SkMakeRuntimeEffect(SkRuntimeEffect::MakeForShader,
            "uniform half color[4];"
            "half4 main(float2 xy) { return half4(color[0], color[1], color[2], color[3]); }"
        );
        // Render our shader into the fill-context with our various input colors.
        testCtx->fillWithFP(GrSkSLFP::Make(effect, "test_fp", /*inputFP=*/nullptr,
                                           GrSkSLFP::OptFlags::kNone,
                                           "color", SkSpan(colorArray)));
        // Read our color back and ensure it matches.
        GrColor actual;
        GrPixmap pixmap(info, &actual, sizeof(GrColor));
        if (!testCtx->readPixels(directContext, pixmap, /*srcPt=*/{0, 0})) {
            REPORT_FAILURE(r, "readPixels", SkString("readPixels failed"));
            break;
        }
        if (actual != GrColorPackRGBA(255 * colorArray[0], 255 * colorArray[1],
                                      255 * colorArray[2], 255 * colorArray[3])) {
            REPORT_FAILURE(r, "Uniform array didn't match expectations",
                           SkStringPrintf("\n"
                                          "Expected: [ %g %g %g %g ]\n"
                                          "Got     : [ %08x ]\n",
                                          colorArray[0], colorArray[1],
                                          colorArray[2], colorArray[3],
                                          actual));
            break;
        }
    }
}
#endif

DEF_TEST(SkRuntimeShader_b500080194, r) {
    constexpr const char* kSkSL =
        "half4 main(float2 xy) {"
          "float4 v;"
          "v.x += xy.x;"
          "(v = abs(v)).xyz;"
          "(v = abs(v)).xyz;"
          "(v = abs(v)).xyz;"
          "(v = abs(v)).xyz;"
          "(v = abs(v)).xyz;"
          "(v = abs(v)).xyz;"
          "(v = abs(v)).xyz;"
          "(v = abs(v)).xyz;"
          "(v = abs(v)).xyz;"
          "(v = abs(v)).xyz;"
          "(v = abs(v)).xyz;"
          "(v = abs(v)).xyz;"
          "(v = abs(v)).xyz;"
          "(v = abs(v)).xyz;"
          "(v = abs(v)).xyz;"
          "(v = abs(v)).xyz;"
          "(v = abs(v)).xyz;"
          "(v = abs(v)).xyz;"
          "(v = abs(v)).xyz;"
          "(v = abs(v)).xyz;"
          "return half4(v);"
        "}";

    auto [effect, err] = SkRuntimeEffect::MakeForShader(SkString(kSkSL));

    if (!effect) {
        REPORT_FAILURE(r, "SkSL compile failed", SkString("SkSL compile failed"));
    } else {
        sk_sp<SkShader> shader = effect->makeShader(/*uniforms=*/nullptr, {});
        SkPaint paint;
        paint.setShader(std::move(shader));
        sk_sp<SkSurface> surface = SkSurfaces::Raster(SkImageInfo::MakeN32Premul(64, 64));
        // This caused a crash before the patch.
        surface->getCanvas()->drawPaint(paint);
    }
}

DEF_TEST(SkRuntimeShader_b507643404, r) {
    constexpr const char* kSkSL =
        "half4 blend_src_over(half4,half4 dst){"
          "float a;return(a)/dst;"
        "}"
        "half4 main(half4 src,half4){"
          "return blend_src_over(src,half4(0));"
        "}";

    // This effect compiles when we aren't optimizing/inlining, but fails when we are.
    SkRuntimeEffect::Options options;
    options.forceUnoptimized = false;
    auto [effect, err] = SkRuntimeEffect::MakeForBlender(SkString(kSkSL));
    if (!effect) {
        SkDebugf("Error: %s\n", err.c_str());
        REPORT_FAILURE(r, "SkSL compile failed", SkString("SkSL compile failed"));
    } else {
        sk_sp<SkBlender> blender = effect->makeBlender(nullptr);
        REPORTER_ASSERT(r, blender);
        if (!blender) {
            return;
        }
        SkPaint paint;
        paint.setColor(SK_ColorRED);
        paint.setBlender(std::move(blender));

        sk_sp<SkSurface> s = SkSurfaces::Raster(SkImageInfo::MakeN32Premul(4, 4));
        REPORTER_ASSERT(r, s);
        // We should make sure this doesn't crash
        s->getCanvas()->drawPaint(paint);
    }
}
