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

#include "src/gpu/graphite/ShaderInfo.h"

#include "include/core/SkMesh.h"
#include "src/core/SkMeshPriv.h"
#include "src/gpu/BlendFormula.h"
#include "src/gpu/graphite/ContextUtils.h"
#include "src/gpu/graphite/PaintParamsKey.h"
#include "src/gpu/graphite/RenderPassDesc.h"
#include "src/gpu/graphite/Renderer.h"
#include "src/gpu/graphite/RuntimeEffectDictionary.h"
#include "src/gpu/graphite/ShaderCodeDictionary.h"
#include "src/gpu/graphite/TextureFormat.h"
#include "src/gpu/graphite/UniformManager.h"
#include "src/gpu/graphite/render/MeshRenderStep.h"
#include "src/sksl/SkSLString.h"
#include "src/sksl/SkSLUtil.h"

using namespace skia_private;

namespace skgpu::graphite {

namespace {

struct LiftedExpression {
    // The node who's expression should be lifted.
    const ShaderNode* fNode;
    // The arguments to use as input to the lifted expression.
    ShaderSnippet::Args fArgs;
    // If true, capture the expression's resolved value in a varying.
    // This is false for expressions whose output is only used in other lifted expressions.
    bool fEmitVarying = true;
};

std::string get_uniform_header(int set, int bufferID) {
    std::string result;
    SkSL::String::appendf(
            &result, "layout (set=%d, binding=%d) uniform CombinedUniforms {\n", set, bufferID);
    return result;
}

std::string get_uniforms(UniformOffsetCalculator* offsetter,
                         SkSpan<const Uniform> uniforms,
                         int manglingSuffix,
                         bool* wrotePaintColor) {
    std::string result;
    std::string uniformName;
    for (const Uniform& u : uniforms) {
        uniformName = u.name();

        if (u.isPaintColor() && wrotePaintColor) {
            if (*wrotePaintColor) {
#if defined(SK_DEBUG)
                SkSL::String::appendf(&result, "// deduplicated %s\n", u.name());
#endif
                continue;
            }

            *wrotePaintColor = true;
        } else {
            if (manglingSuffix >= 0) {
                uniformName.append("_");
                uniformName.append(std::to_string(manglingSuffix));
            }
        }

        SkSL::String::appendf(&result,
                              "layout(offset=%d) %s %s",
                              offsetter->advanceOffset(u.type(), u.count()),
                              SkSLTypeString(u.type()),
                              uniformName.c_str());
        if (u.count()) {
            result.append("[");
            result.append(std::to_string(u.count()));
            result.append("]");
        }
        result.append(";\n");
    }

    return result;
}

std::string get_node_uniforms(UniformOffsetCalculator* offsetter,
                              const ShaderNode* node,
                              int* numUniforms,
                              int* numUnliftedUniforms,
                              bool* wrotePaintColor) {
    std::string result;
    SkSpan<const Uniform> uniforms = node->entry()->fUniforms;

    if (!uniforms.empty()) {
        *numUniforms += uniforms.size();
        if (!((node->requiredFlags() & SnippetRequirementFlags::kLiftExpression) ||
              (node->requiredFlags() & SnippetRequirementFlags::kOmitExpression))) {
            *numUnliftedUniforms += uniforms.size();
        }

        if (node->entry()->fUniformStructName) {
            auto substruct = UniformOffsetCalculator::ForStruct(offsetter->layout());
            for (const Uniform& u : uniforms) {
                substruct.advanceOffset(u.type(), u.count());
            }

            const int structOffset = offsetter->advanceStruct(substruct);
            SkSL::String::appendf(&result,
                                  "layout(offset=%d) %s node_%d;",
                                  structOffset,
                                  node->entry()->fUniformStructName,
                                  node->keyIndex());
        } else {
#if defined(SK_DEBUG)
            SkSL::String::appendf(&result, "// %d - %s uniforms\n",
                                  node->keyIndex(), node->entry()->fName);
#endif
            result += get_uniforms(offsetter, uniforms, node->keyIndex(), wrotePaintColor);
        }
    }

    for (const ShaderNode* child : node->children()) {
        result += get_node_uniforms(
                offsetter, child, numUniforms, numUnliftedUniforms, wrotePaintColor);
    }
    return result;
}

std::string get_ssbo_fields(SkSpan<const Uniform> uniforms,
                            int manglingSuffix,
                            bool* wrotePaintColor) {
    std::string result;

    std::string uniformName;
    for (const Uniform& u : uniforms) {
        uniformName = u.name();

        if (u.isPaintColor() && wrotePaintColor) {
            if (*wrotePaintColor) {
#if defined(SK_DEBUG)
                SkSL::String::appendf(&result, "// deduplicated %s\n", u.name());
#endif
                continue;
            }

            *wrotePaintColor = true;
        } else {
            if (manglingSuffix >= 0) {
                uniformName.append("_");
                uniformName.append(std::to_string(manglingSuffix));
            }
        }

        SkSL::String::appendf(&result, "%s %s", SkSLTypeString(u.type()), uniformName.c_str());
        if (u.count()) {
            SkSL::String::appendf(&result, "[%d]", u.count());
        }
        result.append(";\n");
    }

    return result;
}

std::string get_node_ssbo_fields(const ShaderNode* node,
                                 int* numUniforms,
                                 int* numUnliftedUniforms,
                                 bool* wrotePaintColor) {
    std::string result;
    SkSpan<const Uniform> uniforms = node->entry()->fUniforms;

    if (!uniforms.empty()) {
        *numUniforms += uniforms.size();
        if (!((node->requiredFlags() & SnippetRequirementFlags::kLiftExpression) ||
              (node->requiredFlags() & SnippetRequirementFlags::kOmitExpression))) {
            *numUnliftedUniforms += uniforms.size();
        }

        if (node->entry()->fUniformStructName) {
            SkSL::String::appendf(&result, "%s node_%d;",
                                  node->entry()->fUniformStructName, node->keyIndex());
        } else {
#if defined(SK_DEBUG)
            SkSL::String::appendf(&result, "// %d - %s uniforms\n",
                                  node->keyIndex(), node->entry()->fName);
#endif
            result += get_ssbo_fields(uniforms, node->keyIndex(), wrotePaintColor);
        }
    }

    for (const ShaderNode* child : node->children()) {
        result += get_node_ssbo_fields(child, numUniforms, numUnliftedUniforms, wrotePaintColor);
    }
    return result;
}

std::string emit_intrinsic_constants(const ResourceBindingRequirements& bindingReqs) {
    std::string result;
    auto offsetter = UniformOffsetCalculator::ForTopLevel(bindingReqs.fUniformBufferLayout);

    if (bindingReqs.fUsePushConstantsForIntrinsicConstants) {
        SkASSERT(bindingReqs.fBackendApi == BackendApi::kVulkan ||
                 bindingReqs.fBackendApi == BackendApi::kDawn);
        result = SkSL::String::printf(
                "layout (%s, push_constant) uniform IntrinsicUniforms {\n",
                bindingReqs.fBackendApi == BackendApi::kVulkan ? "vulkan" : "webgpu");
    } else {
        std::string header;
        SkSL::String::appendf(&header,
                              "layout (set=%d, binding=%d) uniform IntrinsicUniforms {\n",
                              bindingReqs.fUniformsSetIdx,
                              bindingReqs.fIntrinsicBufferBinding);
        result = std::move(header);
    }
    result += get_uniforms(&offsetter, kIntrinsicUniforms, -1, /* wrotePaintColor= */ nullptr);
    result.append("};\n\n");
    SkASSERTF(bindingReqs.fUsePushConstantsForIntrinsicConstants ||
              result.find('[') == std::string::npos,
              "Arrays are not supported in intrinsic uniforms");
    return result;
}

std::string emit_combined_uniforms(int set,
                                   int bufferID,
                                   const Layout layout,
                                   SkSpan<const ShaderNode*> nodes,
                                   SkSpan<const Uniform> stepUniforms,
                                   int* numPaintUniforms,
                                   int* numUnliftedPaintUniforms,
                                   bool* wrotePaintColor) {
    auto offsetter = UniformOffsetCalculator::ForTopLevel(layout);

    std::string result = get_uniform_header(set, bufferID);
    for (const ShaderNode* n : nodes) {
        result += get_node_uniforms(
                &offsetter, n, numPaintUniforms, numUnliftedPaintUniforms, wrotePaintColor);
    }

    // Paint and RenderStep uniforms share a binding. When RenderSteps are processed in DrawList,
    // the paint uniforms are always processed before the render step ones, so the emitted uniforms
    // must respect that ordering.
    if (!stepUniforms.empty()) {
        result += get_uniforms(&offsetter, stepUniforms, -1, /* wrotePaintColor= */ nullptr);
    }

    result.append("};\n\n");

    if (*numPaintUniforms == 0 && stepUniforms.empty()) {
        // No uniforms were added
        return {};
    }

    return result;
}

std::string emit_combined_storage_buffer(int set,
                                         int bufferID,
                                         SkSpan<const ShaderNode*> nodes,
                                         SkSpan<const Uniform> stepUniforms,
                                         int* numPaintUniforms,
                                         int* numUnliftedPaintUniforms,
                                         bool* wrotePaintColor) {
    std::string fields;
    for (const ShaderNode* n : nodes) {
        fields += get_node_ssbo_fields(
                n, numPaintUniforms, numUnliftedPaintUniforms, wrotePaintColor);
    }

    if (!stepUniforms.empty()) {
        fields += get_ssbo_fields(stepUniforms, -1, /*wrotePaintColor=*/nullptr);
    }

    if (*numPaintUniforms == 0 && stepUniforms.empty()) {
        // No uniforms were added
        return {};
    }

    return SkSL::String::printf(
            "struct CombinedUniformData {%s};\n"
            "layout (set=%d, binding=%d) readonly buffer CombinedUniforms {"
                "CombinedUniformData combinedUniformData[];};\n",
            fields.c_str(),
            set,
            bufferID);
}

std::string emit_uniforms_from_storage_buffer(const char* indexVariableName,
                                              SkSpan<const Uniform> uniforms) {
    std::string result;

    for (const Uniform& u : uniforms) {
        SkSL::String::appendf(&result, "%s %s", SkSLTypeString(u.type()), u.name());
        if (u.count()) {
            SkSL::String::appendf(&result, "[%d]", u.count());
        }
        SkSL::String::appendf(&result,
                              " = combinedUniformData[%s].%s;\n",
                              indexVariableName,
                              u.name());
    }

    return result;
}

std::string emit_step_storage_buffer(const ResourceBindingRequirements& bindingReqs,
                                     const RenderStep* step) {
    // NOTE: currently no renderstep declares fsUsesStorage() = true. Only gradients use fragment
    // shader storage, but they emit their storage buffer declaration directly inside
    // generateFragmentSkSL(). This is redundant and will be fixed in a follow-on patch.
    SkASSERT(!step->fsUsesStorage());

    SkASSERT(step->numStorageUniforms() > 0);
    std::string fields;
    for (auto a : step->storageUniforms()) {
        SkSL::String::appendf(&fields, "%s %s", SkSLTypeString(a.type()), a.name());
        if (a.count()) {
            fields.append("[");
            fields.append(std::to_string(a.count()));
            fields.append("]");
        }
        fields.append(";\n");
    }
    return SkSL::String::printf(
            "struct StepStorageData {\n%s};\n"
            "layout (set=%d, binding=%d) readonly buffer StepStorageBuffer {\n"
            "    StepStorageData stepStorageData[];\n"
            "};\n"
            "inline StepStorageData readStepStorageData(int idx) {\n"
            "    return stepStorageData[idx];\n"
            "}\n"
            "inline StepStorageData readStepStorageData(uint idx) {\n"
            "    return stepStorageData[idx];\n"
            "}\n",
            fields.c_str(),
            bindingReqs.fUniformsSetIdx,
            bindingReqs.fStorageBufferBinding);
}

std::string emit_storage_fallback_texture(const ResourceBindingRequirements& bindingReqs,
                                          const RenderStep* step) {
    if (!step || step->storageUniforms().empty()) {
        return "";
    }

    std::string fields;
    for (auto a : step->storageUniforms()) {
        // Array storage uniforms are not supported by the texture fallback.
        SkASSERT(a.count() == 0);
        SkSL::String::appendf(&fields, "    %s %s;\n", SkSLTypeString(a.type()), a.name());
    }

    static const char* kSwizzles[] = {"x", "y", "z", "w"};
    std::string fieldAssignments;

    // Force Std430 rules to match the struct layout defined by RenderStep.
    UniformOffsetCalculator calculator = UniformOffsetCalculator::ForStruct(Layout::kStd430);

    for (auto a : step->storageUniforms()) {
        const int byteOffset = calculator.advanceOffset(a.type(), a.count());
        const int floatOffset = byteOffset / 4;
        const int startTexel = floatOffset / 4;
        const int startComp = floatOffset % 4;

        const int mat = SkSLTypeMatrixSize(a.type());
        const int vec = SkSLTypeVecLength(a.type());

        std::string expr;
        if (mat == 2) {
            if (startComp == 0) {
                expr = SkSL::String::printf("float2x2(t%d.xy, t%d.zw)", startTexel, startTexel);
            } else {
                expr = SkSL::String::printf(
                        "float2x2(t%d.zw, t%d.xy)", startTexel, startTexel + 1);
            }
        } else if (mat == 3) {
            // std140/std430 dictates 16-byte alignment for 3-component column vectors.
            SkASSERT(startComp == 0);
            expr = SkSL::String::printf("float3x3(t%d.xyz, t%d.xyz, t%d.xyz)",
                                        startTexel,
                                        startTexel + 1,
                                        startTexel + 2);
        } else if (mat == 4) {
            // std140/std430 dictates 16-byte alignment for 4-component column vectors.
            SkASSERT(startComp == 0);
            expr = SkSL::String::printf("float4x4(t%d, t%d, t%d, t%d)",
                                        startTexel,
                                        startTexel + 1,
                                        startTexel + 2,
                                        startTexel + 3);
        } else if (vec == 4) {
            // std140/std430 dictates 16-byte alignment for 4-component vectors.
            SkASSERT(startComp == 0);
            expr = SkSL::String::printf("t%d", startTexel);
        } else if (vec == 3) {
            // std140/std430 dictates 16-byte alignment for vec3; startComp must be 0 to avoid OOB
            // swizzles.
            SkASSERT(startComp == 0);
            expr = SkSL::String::printf(
                    "t%d.%s%s%s",
                    startTexel,
                    kSwizzles[startComp],
                    kSwizzles[startComp + 1],
                    kSwizzles[startComp + 2]);
        } else if (vec == 2) {
            expr = SkSL::String::printf(
                    "t%d.%s%s", startTexel, kSwizzles[startComp], kSwizzles[startComp + 1]);
        } else {
            expr = SkSL::String::printf("t%d.%s", startTexel, kSwizzles[startComp]);
        }

        switch (a.type()) {
            case SkSLType::kInt:
            case SkSLType::kInt2:
            case SkSLType::kInt3:
            case SkSLType::kInt4:
                expr = "floatBitsToInt(" + expr + ")";
                break;
            case SkSLType::kUInt:
            case SkSLType::kUInt2:
            case SkSLType::kUInt3:
            case SkSLType::kUInt4:
                expr = "floatBitsToUint(" + expr + ")";
                break;
            default:
                break;
        }

        SkSL::String::appendf(&fieldAssignments, "    data.%s = %s;\n", a.name(), expr.c_str());
    }

    int nTexels = (calculator.size() + 15) / 16;
    std::string texelLoads = SkSL::String::printf("    const int texWidth = %d;\n",
                                                  bindingReqs.fMaxFallbackTextureSize);
    for (int i = 0; i < nTexels; ++i) {
        SkSL::String::appendf(
                &texelLoads,
                "    int linearIdx%d = index * %d + %d;\n"
                "    int2 coords%d = int2(linearIdx%d %% texWidth, linearIdx%d / texWidth);\n"
                "    float4 t%d = float4(textureRead(storageFallbackTexture, uint2(coords%d)));\n",
                i, nTexels, i, i, i, i, i, i);
    }

    return SkSL::String::printf(
            "layout(set=%d, binding=%d) readonly texture2D storageFallbackTexture;\n"
            "struct StepStorageData {\n%s};\n"
            "StepStorageData readStepStorageData(int index) {\n"
            "%s"
            "    StepStorageData data;\n"
            "%s"
            "    return data;\n"
            "}\n"
            "inline StepStorageData readStepStorageData(uint index) {\n"
            "    return readStepStorageData(int(index));\n"
            "}\n",
            bindingReqs.fUniformsSetIdx,
            bindingReqs.fStorageBufferBinding,
            fields.c_str(),
            texelLoads.c_str(),
            fieldAssignments.c_str());
}

void append_sampler_descs(const SkSpan<const uint32_t> samplerData,
                          skia_private::TArray<SamplerDesc>& outDescs) {
    // Sampler data consists of variable-length SamplerDesc representations which can differ based
    // upon a sampler's immutability and format. For this reason, handle incrementing i in the loop.
    for (size_t i = 0; i < samplerData.size();) {
        // Create a default-initialized SamplerDesc (which only takes up one uint32). If we are
        // using a dynamic sampler, this will be directly inserted into outDescs. Otherwise, it will
        // be populated with actual immutable sampler data and then inserted.
        SamplerDesc desc{};
        size_t samplerDescLength = 1;
        SkASSERT(desc.asSpan().size() == samplerDescLength);

        // Isolate the ImmutableSamplerInfo portion of the SamplerDesc represented by samplerData.
        // If immutableSamplerInfo is non-zero, that means we are using an immutable sampler.
        uint32_t immutableSamplerInfo = samplerData[i] >> SamplerDesc::kImmutableSamplerInfoShift;
        if (immutableSamplerInfo != 0) {
            // Consult the first bit of immutableSamplerInfo which tells us whether the sampler uses
            // a known or external format. With this, update sampler description length.
            bool usesExternalFormat = immutableSamplerInfo & 0b1;
            samplerDescLength = usesExternalFormat ? SamplerDesc::kInt32sNeededExternalFormat
                                                   : SamplerDesc::kInt32sNeededKnownFormat;
            // Populate a SamplerDesc with samplerDescLength quantity of immutable sampler data
            memcpy(&desc, samplerData.data() + i, samplerDescLength * sizeof(uint32_t));
        }
        outDescs.push_back(desc);
        i += samplerDescLength;
    }
}

std::string get_node_texture_samplers(const ResourceBindingRequirements& bindingReqs,
                                      const ShaderNode* node,
                                      int* binding,
                                      skia_private::TArray<SamplerDesc>* outDescs) {
    std::string result;
    SkSpan<const TextureAndSampler> samplers = node->entry()->fTexturesAndSamplers;

    if (!samplers.empty()) {
#if defined(SK_DEBUG)
        SkSL::String::appendf(&result, "// %d - %s samplers\n",
                              node->keyIndex(), node->entry()->fName);
#endif

        // Determine whether we need to analyze & interpret a ShaderNode's data as immutable
        // SamplerDescs based upon whether:
        // 1) A backend passes in a non-nullptr outImmutableSamplers param (may be nullptr in
        //    backends or circumstances where we know immutable sampler data is never stored)
        // 2) Any data is stored on the ShaderNode
        // 3) Whether the ShaderNode snippet's ID matches that of any snippet ID that could store
        //    immutable sampler data.
        int32_t snippetId = node->codeSnippetId();
        if (outDescs) {
            // TODO(b/369846881): Refactor checking snippet ID to instead having a named
            // snippet requirement flag that we can check here to decrease fragility.
            if (!node->data().empty() &&
                (snippetId == static_cast<int32_t>(BuiltInCodeSnippetID::kImageShader) ||
                 snippetId == static_cast<int32_t>(BuiltInCodeSnippetID::kImageShaderClamp) ||
                 snippetId == static_cast<int32_t>(BuiltInCodeSnippetID::kCubicImageShader) ||
                 snippetId == static_cast<int32_t>(BuiltInCodeSnippetID::kHWImageShader))) {
                append_sampler_descs(node->data(), *outDescs);
            } else {
                // Add default SamplerDescs for any dynamic samplers to outDescs.
                outDescs->push_back_n(samplers.size());
            }
        }

        for (const TextureAndSampler& t : samplers) {
            result += EmitSamplerLayout(bindingReqs, binding);
            SkSL::String::appendf(&result, " sampler2D %s_%d;\n", t.name(), node->keyIndex());
        }
    }

    for (const ShaderNode* child : node->children()) {
        result += get_node_texture_samplers(bindingReqs, child, binding, outDescs);
    }
    return result;
}

std::string emit_textures_and_samplers(const ResourceBindingRequirements& bindingReqs,
                                       SkSpan<const ShaderNode*> nodes,
                                       int* binding,
                                       skia_private::TArray<SamplerDesc>* outDescs) {
    std::string result;
    for (const ShaderNode* n : nodes) {
        result += get_node_texture_samplers(bindingReqs, n, binding, outDescs);
    }
    return result;
}

SkSLType sksl_type_for_lifted_expression(
        ShaderSnippet::LiftableExpressionType liftedExpressionType) {
    switch (liftedExpressionType) {
        case ShaderSnippet::LiftableExpressionType::kNone:
            return SkSLType::kVoid;
        case ShaderSnippet::LiftableExpressionType::kLocalCoords:
            return SkSLType::kFloat2;
        case ShaderSnippet::LiftableExpressionType::kPriorStageOutput:
            return SkSLType::kHalf4;
    }
    return SkSLType::kVoid;
}

std::string emit_varyings(const RenderStep* step,
                          const char* direction,
                          const RootNodesInfo& roots,
                          SkSpan<const LiftedExpression> liftedExpressions,
                          bool emitSsboIndexVarying,
                          bool emitLocalCoordsVarying) {
    std::string result;
    int location = 0;

    auto appendVarying = [&](const Varying& v, const char* mangleSuffix = "") {
        const char* interpolation;
        switch (v.interpolation()) {
            case Interpolation::kPerspective: interpolation = ""; break;
            case Interpolation::kLinear:      interpolation = "noperspective "; break;
            case Interpolation::kFlat:        interpolation = "flat "; break;
        }
        SkSL::String::appendf(&result, "layout(location=%d) %s %s%s %s%s;\n",
                              location++,
                              direction,
                              interpolation,
                              SkSLTypeString(v.gpuType()),
                              v.name(),
                              mangleSuffix);
    };

    if (emitSsboIndexVarying) {
        appendVarying({RenderStep::ssboIndexVarying(), SkSLType::kUInt});
    }

    if (emitLocalCoordsVarying) {
        appendVarying({"localCoordsVar", SkSLType::kFloat2});
    }

    for (const LiftedExpression& expr : liftedExpressions) {
        if (expr.fEmitVarying) {
            const ShaderNode* node = expr.fNode;
            const std::string name = node->getExpressionVaryingName();
            appendVarying({name.c_str(),
                           sksl_type_for_lifted_expression(node->entry()->fLiftableExpressionType),
                           node->entry()->fLiftableExpressionInterpolation});
        }
    }

    for (const Varying& v : step->varyings()) {
        appendVarying(v);
    }

    if (roots.fMeshSpec) {
        for (const SkMeshSpecification::Varying& v
                : SkMeshSpecificationPriv::Varyings(*roots.fMeshSpec)) {
            SkSLType type = SkMeshSpecificationPriv::VaryingTypeAsSLType(v.type);
            appendVarying({v.name.c_str(), type}, MeshRenderStep::kMeshVaryingMangleSuffix);
        }
    }

    return result;
}

// Walk the node tree and generate all preambles, accumulating into 'preamble'.
void emit_preambles(const ShaderInfo& shaderInfo,
                    SkSpan<const ShaderNode*> nodes,
                    std::string treeLabel,
                    std::string* preamble) {
    for (int i = 0; i < SkTo<int>(nodes.size()); ++i) {
        const ShaderNode* node = nodes[i];
        std::string nodeLabel = std::to_string(i);
        std::string nextLabel = treeLabel.empty() ? nodeLabel : (treeLabel + "<-" + nodeLabel);

        if (node->numChildren() > 0) {
            emit_preambles(shaderInfo, node->children(), nextLabel, preamble);
        }

        std::string nodePreamble = node->entry()->fPreambleGenerator
                                           ? node->entry()->fPreambleGenerator(shaderInfo, node)
                                           : node->generateDefaultPreamble(shaderInfo);
        if (!nodePreamble.empty()) {
#if defined(SK_DEBUG)
            SkSL::String::appendf(preamble,
                                  "// [%d]   %s: %s\n",
                                  node->keyIndex(),
                                  nextLabel.c_str(),
                                  node->entry()->fName);
#endif
            *preamble += nodePreamble + "\n";
        }
    }
}

std::string emit_color_output(BlendFormula::OutputType outputType,
                              const char* outColor,
                              const char* inColor) {
    switch (outputType) {
        case BlendFormula::kNone_OutputType:
            return SkSL::String::printf("%s = half4(0.0);", outColor);

        case BlendFormula::kCoverage_OutputType:
            return SkSL::String::printf("%s = outputCoverage;", outColor);

        case BlendFormula::kModulate_OutputType:
            return SkSL::String::printf("%s = %s * outputCoverage;", outColor, inColor);

        case BlendFormula::kSAModulate_OutputType:
            return SkSL::String::printf("%s = %s.a * outputCoverage;", outColor, inColor);

        case BlendFormula::kISAModulate_OutputType:
            return SkSL::String::printf("%s = (1.0 - %s.a) * outputCoverage;", outColor, inColor);

        case BlendFormula::kISCModulate_OutputType:
            return SkSL::String::printf(
                    "%s = (half4(1.0) - %s) * outputCoverage;", outColor, inColor);

        default:
            SkUNREACHABLE;
    }
}

std::string emit_advanced_blend_color_output(const char* outColor, const char* inColor) {
    /*
      When using hardware for advanced blend modes, we apply coverage for advanced blend modes by
      multiplying it into the src color before blending. This will "just work" given the following:

      The general SVG blend equation is defined in the spec as follows:

        Dca' = B(Sc, Dc) * Sa * Da + Y * Sca * (1-Da) + Z * Dca * (1-Sa)
        Da'  = X * Sa * Da + Y * Sa * (1-Da) + Z * Da * (1-Sa)

      (Note that Sca, Dca indicate RGB vectors that are premultiplied by alpha,
       and that B(Sc, Dc) is a mode-specific function that accepts non-multiplied
       RGB colors.)

      For every blend mode supported by this class, i.e. the "advanced" blend
      modes, X=Y=Z=1 and this equation reduces to the PDF blend equation.

      It can be shown that when X=Y=Z=1, these equations can modulate alpha for
      coverage.


      == Color ==

      We substitute Y=Z=1 and define a blend() function that calculates Dca' in
      terms of premultiplied alpha only:

        blend(Sca, Dca, Sa, Da) = {
                Dca : if Sa == 0,
                Sca : if Da == 0,
                B(Sca/Sa, Dca/Da) * Sa * Da + Sca * (1-Da) + Dca * (1-Sa) : if Sa,Da != 0}

      And for coverage modulation, we use a post blend src-over model:

        Dca'' = f * blend(Sca, Dca, Sa, Da) + (1-f) * Dca

      (Where f is the fractional coverage.)

      Next we show that we can multiply coverage into the src color by proving the
      following relationship:

        blend(f*Sca, Dca, f*Sa, Da) == f * blend(Sca, Dca, Sa, Da) + (1-f) * Dca

      General case (f,Sa,Da != 0):

        f * blend(Sca, Dca, Sa, Da) + (1-f) * Dca
          = f * (B(Sca/Sa, Dca/Da) * Sa * Da + Sca * (1-Da) + Dca * (1-Sa)) + (1-f) * Dca
            [Sa,Da != 0, definition of blend()]
          = B(Sca/Sa, Dca/Da) * f*Sa * Da + f*Sca * (1-Da) + f*Dca * (1-Sa) + Dca - f*Dca
          = B(Sca/Sa, Dca/Da) * f*Sa * Da + f*Sca - f*Sca * Da + f*Dca - f*Dca * Sa + Dca - f*Dca
          = B(Sca/Sa, Dca/Da) * f*Sa * Da + f*Sca - f*Sca * Da - f*Dca * Sa + Dca
          = B(Sca/Sa, Dca/Da) * f*Sa * Da + f*Sca * (1-Da) - f*Dca * Sa + Dca
          = B(Sca/Sa, Dca/Da) * f*Sa * Da + f*Sca * (1-Da) + Dca * (1 - f*Sa)
          = B(f*Sca/f*Sa, Dca/Da) * f*Sa * Da + f*Sca * (1-Da) + Dca * (1 - f*Sa)  [f!=0]
          = blend(f*Sca, Dca, f*Sa, Da)  [definition of blend()]

      Corner cases (Sa=0, Da=0, and f=0):

        Sa=0: f * blend(Sca, Dca, Sa, Da) + (1-f) * Dca
                = f * Dca + (1-f) * Dca  [Sa=0, definition of blend()]
                = Dca
                = blend(0, Dca, 0, Da)  [definition of blend()]
                = blend(f*Sca, Dca, f*Sa, Da)  [Sa=0]

        Da=0: f * blend(Sca, Dca, Sa, Da) + (1-f) * Dca
                = f * Sca + (1-f) * Dca  [Da=0, definition of blend()]
                = f * Sca  [Da=0]
                = blend(f*Sca, 0, f*Sa, 0)  [definition of blend()]
                = blend(f*Sca, Dca, f*Sa, Da)  [Da=0]

        f=0: f * blend(Sca, Dca, Sa, Da) + (1-f) * Dca
               = Dca  [f=0]
               = blend(0, Dca, 0, Da)  [definition of blend()]
               = blend(f*Sca, Dca, f*Sa, Da)  [f=0]

      == Alpha ==

      We substitute X=Y=Z=1 and define a blend() function that calculates Da':

        blend(Sa, Da) = Sa * Da + Sa * (1-Da) + Da * (1-Sa)
                      = Sa * Da + Sa - Sa * Da + Da - Da * Sa
                      = Sa + Da - Sa * Da

      We use the same model for coverage modulation as we did with color:

        Da'' = f * blend(Sa, Da) + (1-f) * Da

      And show that show that we can multiply coverage into src alpha by proving the following
      relationship:

        blend(f*Sa, Da) == f * blend(Sa, Da) + (1-f) * Da

        f * blend(Sa, Da) + (1-f) * Da
          = f * (Sa + Da - Sa * Da) + (1-f) * Da
          = f*Sa + f*Da - f*Sa * Da + Da - f*Da
          = f*Sa - f*Sa * Da + Da
          = f*Sa + Da - f*Sa * Da
          = blend(f*Sa, Da)
    */
   return emit_color_output(BlendFormula::OutputType::kModulate_OutputType, outColor, inColor);
}

void collect_lifted_expressions(SkSpan<const ShaderNode*> nodes,
                                const ShaderSnippet::Args& args,
                                std::vector<LiftedExpression>& lifted) {
    for (const ShaderNode* node : nodes) {
        const bool emitVaryingInFS =
                static_cast<bool>(node->requiredFlags() & SnippetRequirementFlags::kLiftExpression);
        const bool emitExpressionInVS =
                emitVaryingInFS ||
                (node->requiredFlags() & SnippetRequirementFlags::kOmitExpression);
        SkASSERT(!emitExpressionInVS || node->entry()->fLiftableExpressionGenerator);

        ShaderSnippet::Args childArgs = args;
        if (emitExpressionInVS && node->entry()->fLiftableExpressionGenerator) {
            lifted.push_back({node, args, emitVaryingInFS});
            switch (node->entry()->fLiftableExpressionType) {
                case ShaderSnippet::LiftableExpressionType::kLocalCoords:
                    childArgs.fFragCoord = node->getExpressionVaryingName();
                    break;
                case ShaderSnippet::LiftableExpressionType::kPriorStageOutput:
                    childArgs.fPriorStageOutput = node->getExpressionVaryingName();
                    break;
                default:
                    SkUNREACHABLE;
            }
        }

        collect_lifted_expressions(node->children(), childArgs, lifted);
    }
}

std::vector<LiftedExpression> collect_lifted_expressions(SkSpan<const ShaderNode*> nodes) {
    std::vector<LiftedExpression> lifted;
    ShaderSnippet::Args args = ShaderSnippet::kDefaultArgs;
    args.fFragCoord = "stepLocalCoords";  // Render Steps' stepLocalCoords
    collect_lifted_expressions(nodes, args, lifted);
    return lifted;
}

std::string dst_read_strategy_to_str(DstReadStrategy strategy) {
    switch (strategy) {
        case DstReadStrategy::kNoneRequired:
            return "NoneRequired";
        case DstReadStrategy::kTextureCopy:
            return "TextureCopy";
        case DstReadStrategy::kTextureSample:
            return "TextureSample";
        case DstReadStrategy::kReadFromInput:
            return "ReadFromInput";
        case DstReadStrategy::kFramebufferFetch:
            return "FramebufferFetch";
    }
    SkUNREACHABLE;
}

constexpr skgpu::BlendInfo make_simple_blendInfo(skgpu::BlendCoeff srcCoeff,
                                                 skgpu::BlendCoeff dstCoeff) {
    return { skgpu::BlendEquation::kAdd,
             srcCoeff,
             dstCoeff,
             SK_PMColor4fTRANSPARENT,
             skgpu::BlendModifiesDst(skgpu::BlendEquation::kAdd, srcCoeff, dstCoeff) };
}


constexpr skgpu::BlendEquation get_advanced_blend_equation(SkBlendMode mode) {
    SkASSERT(mode > SkBlendMode::kLastCoeffMode);

    constexpr int kEqOffset = ((int)skgpu::BlendEquation::kOverlay - (int)SkBlendMode::kOverlay);
    static_assert((int)skgpu::BlendEquation::kOverlay ==
                  (int)SkBlendMode::kOverlay + kEqOffset);
    static_assert((int)skgpu::BlendEquation::kDarken ==
                  (int)SkBlendMode::kDarken + kEqOffset);
    static_assert((int)skgpu::BlendEquation::kLighten ==
                  (int)SkBlendMode::kLighten + kEqOffset);
    static_assert((int)skgpu::BlendEquation::kColorDodge ==
                  (int)SkBlendMode::kColorDodge + kEqOffset);
    static_assert((int)skgpu::BlendEquation::kColorBurn ==
                  (int)SkBlendMode::kColorBurn + kEqOffset);
    static_assert((int)skgpu::BlendEquation::kHardLight ==
                  (int)SkBlendMode::kHardLight + kEqOffset);
    static_assert((int)skgpu::BlendEquation::kSoftLight ==
                  (int)SkBlendMode::kSoftLight + kEqOffset);
    static_assert((int)skgpu::BlendEquation::kDifference ==
                  (int)SkBlendMode::kDifference + kEqOffset);
    static_assert((int)skgpu::BlendEquation::kExclusion ==
                  (int)SkBlendMode::kExclusion + kEqOffset);
    static_assert((int)skgpu::BlendEquation::kMultiply ==
                  (int)SkBlendMode::kMultiply + kEqOffset);
    static_assert((int)skgpu::BlendEquation::kHSLHue ==
                  (int)SkBlendMode::kHue + kEqOffset);
    static_assert((int)skgpu::BlendEquation::kHSLSaturation ==
                  (int)SkBlendMode::kSaturation + kEqOffset);
    static_assert((int)skgpu::BlendEquation::kHSLColor ==
                  (int)SkBlendMode::kColor + kEqOffset);
    static_assert((int)skgpu::BlendEquation::kHSLLuminosity ==
                  (int)SkBlendMode::kLuminosity + kEqOffset);
    // There's an illegal BlendEquation that corresponds to no SkBlendMode, hence the extra +1.
    static_assert(skgpu::kBlendEquationCnt == (int)SkBlendMode::kLastMode + 1 + 1 + kEqOffset);

    return static_cast<skgpu::BlendEquation>((int)mode + kEqOffset);
}

constexpr skgpu::BlendInfo make_hardware_advanced_blendInfo(SkBlendMode advancedBlendMode) {
    BlendInfo blendInfo;
    blendInfo.fEquation = get_advanced_blend_equation(advancedBlendMode);
    return blendInfo;
}

static constexpr skgpu::BlendInfo gBlendTable[kSkBlendModeCount] = {
        /* Porter-Duff blend modes */
        /* clear */      make_simple_blendInfo(skgpu::BlendCoeff::kZero, skgpu::BlendCoeff::kZero),
        /* src */        make_simple_blendInfo(skgpu::BlendCoeff::kOne,  skgpu::BlendCoeff::kZero),
        /* dst */        make_simple_blendInfo(skgpu::BlendCoeff::kZero, skgpu::BlendCoeff::kOne),
        /* src-over */   make_simple_blendInfo(skgpu::BlendCoeff::kOne,  skgpu::BlendCoeff::kISA),
        /* dst-over */   make_simple_blendInfo(skgpu::BlendCoeff::kIDA,  skgpu::BlendCoeff::kOne),
        /* src-in */     make_simple_blendInfo(skgpu::BlendCoeff::kDA,   skgpu::BlendCoeff::kZero),
        /* dst-in */     make_simple_blendInfo(skgpu::BlendCoeff::kZero, skgpu::BlendCoeff::kSA),
        /* src-out */    make_simple_blendInfo(skgpu::BlendCoeff::kIDA,  skgpu::BlendCoeff::kZero),
        /* dst-out */    make_simple_blendInfo(skgpu::BlendCoeff::kZero, skgpu::BlendCoeff::kISA),
        /* src-atop */   make_simple_blendInfo(skgpu::BlendCoeff::kDA,   skgpu::BlendCoeff::kISA),
        /* dst-atop */   make_simple_blendInfo(skgpu::BlendCoeff::kIDA,  skgpu::BlendCoeff::kSA),
        /* xor */        make_simple_blendInfo(skgpu::BlendCoeff::kIDA,  skgpu::BlendCoeff::kISA),
        /* plus */       make_simple_blendInfo(skgpu::BlendCoeff::kOne,  skgpu::BlendCoeff::kOne),
        /* modulate */   make_simple_blendInfo(skgpu::BlendCoeff::kZero, skgpu::BlendCoeff::kSC),
        /* screen */     make_simple_blendInfo(skgpu::BlendCoeff::kOne,  skgpu::BlendCoeff::kISC),

        /* BlendInfo for advanced blend modes */
        make_hardware_advanced_blendInfo(SkBlendMode::kOverlay),
        make_hardware_advanced_blendInfo(SkBlendMode::kDarken),
        make_hardware_advanced_blendInfo(SkBlendMode::kLighten),
        make_hardware_advanced_blendInfo(SkBlendMode::kColorDodge),
        make_hardware_advanced_blendInfo(SkBlendMode::kColorBurn),
        make_hardware_advanced_blendInfo(SkBlendMode::kHardLight),
        make_hardware_advanced_blendInfo(SkBlendMode::kSoftLight),
        make_hardware_advanced_blendInfo(SkBlendMode::kDifference),
        make_hardware_advanced_blendInfo(SkBlendMode::kExclusion),
        make_hardware_advanced_blendInfo(SkBlendMode::kMultiply),
        make_hardware_advanced_blendInfo(SkBlendMode::kHue),
        make_hardware_advanced_blendInfo(SkBlendMode::kSaturation),
        make_hardware_advanced_blendInfo(SkBlendMode::kColor),
        make_hardware_advanced_blendInfo(SkBlendMode::kLuminosity)
};

}  // anonymous namespace

struct ShaderInfo::SharedGeneratorData {
    SharedGeneratorData(const Caps* caps,
                        const ShaderCodeDictionary* dict,
                        const RuntimeEffectDictionary* rteDict,
                        SkArenaAlloc* alloc,
                        const RenderStep* step,
                        UniquePaintParamsID paintID,
                        const char* uniformSsboIndex)
            : fHasStepUniforms(step->numUniforms() > 0) {

        // Decompress Root Nodes & Determine Local Coords
        if (paintID.isValid()) {
            PaintParamsKey key = dict->lookup(paintID);
            SkASSERT(key.isValid());

            constexpr int kFixedVaryings = 2;
            const int availableVaryings =
                    caps->maxVaryings() - kFixedVaryings - step->varyings().size();

            bool canLiftCoords = !step->fragmentColorSkSLLocalCoordsVariable();
            fRootsInfo =
                    key.getRootNodes(caps, dict, rteDict, alloc, availableVaryings, canLiftCoords);

            fNeedsLocalCoords = fRootsInfo.fSrcColor &&
                                SkToBool(fRootsInfo.fSrcColor->requiredFlags() &
                                SnippetRequirementFlags::kLocalCoords);
        } else {
            fNeedsLocalCoords = false;
        }

        skia_private::TArray<Uniform> allStepUniforms;
        for (const Uniform& u : step->uniforms()) {
            allStepUniforms.push_back(u);
        }

        // Declare SkMesh uniforms after the render step uniforms are declared so the
        // MeshRenderStep can write the uniforms and have them an the expected location.
        if (fRootsInfo.fMeshSpec) {
            SkASSERT(fHasStepUniforms);
            SkASSERT(fRootsInfo.fMeshShader);
            SkASSERT(step->renderStepID() == RenderStep::RenderStepID::kMesh);
            SkSpan<const Uniform> converted = ShaderCodeDictionary::ConvertRuntimeEffectUniforms(
                                                    fRootsInfo.fMeshSpec->uniforms(), alloc);
            for (const Uniform& u : converted) {
                allStepUniforms.push_back(u);
            }
        }

        // Lift Expressions & Check Uniforms
        bool vsHasLiftedPaintUniforms = false;
        fLiftedExpr = collect_lifted_expressions(fRootsInfo.fRoots);
        for (const auto& expr : fLiftedExpr) {
            if (!expr.fNode->entry()->fUniforms.empty()) {
                vsHasLiftedPaintUniforms = true;
                break;
            }
        }

        bool needsCombinedBufferVS = fHasStepUniforms || vsHasLiftedPaintUniforms;
        fUseUniformStorageBufferVS = caps->storageBufferSupport() && needsCombinedBufferVS;
        fUseUniformStorageBufferFS = caps->storageBufferSupport() && step->performsShading();
        bool useUniformStorageBuffer = fUseUniformStorageBufferVS || fUseUniformStorageBufferFS;

        // Emit Preamble
        int numPaintUniforms = 0;
        int numUnliftedPaintUniforms = 0;
        bool wrotePaintColor = false;
        const ResourceBindingRequirements& bindingReqs = caps->resourceBindingRequirements();

        if (useUniformStorageBuffer) {
            fSharedPreamble = emit_combined_storage_buffer(
                bindingReqs.fUniformsSetIdx,
                bindingReqs.fCombinedUniformBufferBinding,
                fRootsInfo.fRoots,
                allStepUniforms,
                &numPaintUniforms,
                &numUnliftedPaintUniforms,
                &wrotePaintColor);
        } else {
            fSharedPreamble = emit_combined_uniforms(
                bindingReqs.fUniformsSetIdx,
                bindingReqs.fCombinedUniformBufferBinding,
                bindingReqs.fUniformBufferLayout,
                fRootsInfo.fRoots,
                allStepUniforms,
                &numPaintUniforms,
                &numUnliftedPaintUniforms,
                &wrotePaintColor);
        }

        // Calculate Final Flags
        fHasPaintUniforms = numPaintUniforms > 0;
        fHasLiftedPaintUniforms = (numPaintUniforms - numUnliftedPaintUniforms) > 0;
        bool hasUnliftedPaintUniforms = numUnliftedPaintUniforms > 0;

        fHasSsboIndexVarying = useUniformStorageBuffer &&
                              (hasUnliftedPaintUniforms ||
                              (fHasStepUniforms && step->usesUniformsInFragmentSkSL()));

        // Append SSBO Index to preamble if required
        if (useUniformStorageBuffer && uniformSsboIndex) {
            SkSL::String::appendf(&fSharedPreamble, "uint %s;\n", uniformSsboIndex);
        }
    }

    // The shader tree decompressed into explicit root nodes.
    RootNodesInfo fRootsInfo;

    // The expressions lifted from the shader tree
    // Changed from const& to value to allow ownership
    std::vector<LiftedExpression> fLiftedExpr;

    // The base SkSL preamble (uniforms, varyings) shared by both stages
    std::string fSharedPreamble;

    // Shared calculated properties
    bool fNeedsLocalCoords;
    bool fHasSsboIndexVarying;
    bool fHasStepUniforms;
    bool fHasPaintUniforms;
    bool fHasLiftedPaintUniforms;

    // Buffer usage flags needed by generators
    bool fUseUniformStorageBufferVS;
    bool fUseUniformStorageBufferFS;
};

std::unique_ptr<ShaderInfo> ShaderInfo::Make(const Caps* caps,
                                             const ShaderCodeDictionary* dict,
                                             const RuntimeEffectDictionary* rteDict,
                                             const RenderPassDesc& rpDesc,
                                             const RenderStep* step,
                                             UniquePaintParamsID paintID,
                                             skia_private::TArray<SamplerDesc>* outDescs) {
    // Determine if an SSBO index is needed at all (by either stage)
    bool needsSsboIndex =
        caps->storageBufferSupport() && (step->performsShading() || step->numUniforms() > 0);
    const char* uniformSsboIndex = needsSsboIndex ? "uniformSsboIndex" : nullptr;

    const bool hasFragShader = paintID.isValid() && step->performsShading();

    // Create the final ShaderInfo object.
    auto result = std::unique_ptr<ShaderInfo>(new ShaderInfo(dict, rteDict, uniformSsboIndex,
                                              hasFragShader ? rpDesc.fDstReadStrategy
                                                            : DstReadStrategy::kNoneRequired));

    // This arena holds all the ShaderNodes and mesh uniform names. It must live for the
    // duration of 'Make' so the rootNodes span is valid when passed to helpers.
    SkArenaAlloc alloc{256};
    SharedGeneratorData sharedData(
            caps, dict, rteDict, &alloc, step, paintID, result->uniformSsboIndex());
    result->fHasCombinedUniforms = sharedData.fHasStepUniforms || sharedData.fHasPaintUniforms;

    result->fAppendAttrs.reserve_exact(
            step->appendAttributes().size() + (sharedData.fRootsInfo.fMeshSpec
                    ? sharedData.fRootsInfo.fMeshSpec->attributes().size()
                    : 0));
    for (const Attribute& renderStepAttr: step->appendAttributes()) {
        result->fAppendAttrs.push_back(renderStepAttr);
    }
    if (sharedData.fRootsInfo.fMeshSpec) {
        for (const SkMeshSpecification::Attribute& specAttr
                : sharedData.fRootsInfo.fMeshSpec->attributes()) {
            result->fAppendAttrs.push_back(Attribute::MakeFromSkMeshAttribute(specAttr));
        }
    }

    SkString paintLabel = dict->idToString(caps, paintID);
    if (hasFragShader) {
        result->generateFragmentSkSL(caps,
                                     dict,
                                     paintLabel.c_str(),
                                     step,
                                     paintID,
                                     rpDesc.fColorAttachment.fFormat,
                                     rpDesc.fWriteSwizzle,
                                     outDescs,
                                     sharedData);
    } else {
        result->fBlendInfo.fWritesColor = false;
    }

    result->fStorageBufferStages |= step->storageBufferStages();

    // TODO(michaelludwig): Modify the depth portion of the DepthStencilSettings depending on
    // whether or not depth is going to be useful (and whether or not the render pass has it).
    result->fDepthStencilSettings = step->depthStencilSettings();

    result->generateVertexSkSL(caps, step, sharedData);
    result->fVSLabel = step->name();
    if (sharedData.fNeedsLocalCoords) {
        result->fVSLabel += " (w/ local coords)";
    }

    result->fFSLabel = step->name();
    result->fFSLabel += " + ";
    result->fFSLabel += paintLabel.c_str();
    if (rpDesc.fWriteSwizzle != Swizzle::RGBA() ||
        result->fDstReadStrategy != DstReadStrategy::kNoneRequired) {
        result->fFSLabel += "(";
        result->fFSLabel += rpDesc.fWriteSwizzle.asString().c_str();
        if (result->fDstReadStrategy != DstReadStrategy::kNoneRequired) {
            result->fFSLabel += ", ";
            result->fFSLabel += dst_read_strategy_to_str(result->fDstReadStrategy);
        }
        result->fFSLabel += ")";
    }

    // KEEP IN SYNC with ContextUtils::GetPipelineLabel()
    result->fPipelineLabel = rpDesc.toPipelineLabel().c_str();
    result->fPipelineLabel += " + ";
    result->fPipelineLabel += step->name();
    result->fPipelineLabel += " + ";
    result->fPipelineLabel += paintLabel.c_str();

    return result;
}

ShaderInfo::ShaderInfo(const ShaderCodeDictionary* shaderCodeDictionary,
                       const RuntimeEffectDictionary* rteDict,
                       const char* uniformSsboIndex,
                       DstReadStrategy dstReadStrategy)
        : fShaderCodeDictionary(shaderCodeDictionary)
        , fRuntimeEffectDictionary(rteDict)
        , fUniformSsboIndex(uniformSsboIndex)
        , fDstReadStrategy(dstReadStrategy) {}

// The current, incomplete, model for shader construction is:
//   - Static code snippets (which can have an arbitrary signature) live in the Graphite
//     pre-compiled module, which is located at `src/sksl/sksl_graphite_frag.sksl`.
//   - Glue code is generated in a `main` method which calls these static code snippets.
//     The glue code is responsible for:
//            1) gathering the correct (mangled) uniforms
//            2) passing the uniforms and any other parameters to the helper method
//   - The result of the final code snippet is then copied into "sk_FragColor".
//   Note: each entry's 'fStaticFunctionName' field is expected to match the name of a function
//   in the Graphite pre-compiled module, or be null if the preamble and expression generators are
//   overridden to not use a static function.
void ShaderInfo::generateFragmentSkSL(const Caps* caps,
                                      const ShaderCodeDictionary* dict,
                                      const char* label,
                                      const RenderStep* step,
                                      UniquePaintParamsID paintID,
                                      TextureFormat targetFormat,
                                      Swizzle writeSwizzle,
                                      skia_private::TArray<SamplerDesc>* outDescs,
                                      const SharedGeneratorData& sharedData) {
#if defined(SK_DEBUG)
    // Validate the root count of the key.
    SkASSERT(sharedData.fRootsInfo.fRoots.size() >= 2 && sharedData.fRootsInfo.fRoots.size() <= 4);
    // With source color node all snippets return a half4, so we just require that its signature
    // takes no extra args or just local coords.
    SkASSERT(sharedData.fRootsInfo.fSrcColor && sharedData.fRootsInfo.fFinalBlend);
    const ShaderSnippet* srcSnippet
            = dict->getEntry(sharedData.fRootsInfo.fSrcColor->codeSnippetId());
    // TODO(b/349997190): Once SkEmptyShader doesn't use the passthrough snippet, we can assert
    // that srcSnippet->needsPriorStageOutput() is false.
    SkASSERT(!srcSnippet->needsBlenderDstColor());
    // Final blender node must take both the src color and dst color, and not any local coordinate.
    const ShaderSnippet* blendSnippet
            = dict->getEntry(sharedData.fRootsInfo.fFinalBlend->codeSnippetId());
    SkASSERT(blendSnippet->needsPriorStageOutput() && blendSnippet->needsBlenderDstColor());
    SkASSERT(!blendSnippet->needsLocalCoords());
    const ShaderSnippet* clipSnippet = sharedData.fRootsInfo.fClip ?
            dict->getEntry(sharedData.fRootsInfo.fClip->codeSnippetId()) : nullptr;
    SkASSERT(!clipSnippet ||
             (!clipSnippet->needsPriorStageOutput() && !clipSnippet->needsBlenderDstColor()));
#endif

    // Check for unexpected corruption / illegal instructions occurring in the wild.
    SkASSERTF_RELEASE((sharedData.fRootsInfo.fRoots.size() >= 2 &&
                       sharedData.fRootsInfo.fRoots.size() <= 4) &&
                      sharedData.fRootsInfo.fSrcColor && sharedData.fRootsInfo.fFinalBlend,
                      "root node size = %zu, label = %s",
                      sharedData.fRootsInfo.fRoots.size(), label);

    // Extract the root nodes for clarity
    const ShaderNode* const srcColorRoot = sharedData.fRootsInfo.fSrcColor;
    const ShaderNode* const finalBlendRoot = sharedData.fRootsInfo.fFinalBlend;
    const int32_t finalBlendRootSnippetId = finalBlendRoot->codeSnippetId();
    const ShaderNode* const clipRoot = sharedData.fRootsInfo.fClip;

    // Determine the algorithm for final blending: direct HW blending, coverage-modified HW
    // blending (w/ or w/o dual-source blending) or via dst-read requirement.
    Coverage finalCoverage = step->coverage();
    if (finalCoverage == Coverage::kNone && SkToBool(clipRoot)) {
        finalCoverage = Coverage::kSingleChannel;
    }

    // Initialize the final blend mode to the final snippet's blend mode. It may be changed based
    // upon whether or not we can use hardware blending.
    std::optional<SkBlendMode> finalBlendMode;
    if (finalBlendRootSnippetId < kBuiltInCodeSnippetIDCount &&
        finalBlendRootSnippetId >= kFixedBlendIDOffset) {
        finalBlendMode = static_cast<SkBlendMode>(finalBlendRootSnippetId - kFixedBlendIDOffset);
    }
    if (finalBlendMode.has_value() &&
        CanUseHardwareBlending(caps, targetFormat, *finalBlendMode, finalCoverage)) {
        // If we can use hardware blending, update the dstReadStrategy to be kNoneRequired to ensure
        // that ShaderInfo properly informs PipelineInfo of the pipeline's dst read requirement.
        fDstReadStrategy = DstReadStrategy::kNoneRequired;
    } else {
        // If we cannot use hardware blending, then we must perform a dst read within the shader.
        // Therefore we should assert that a valid strategy to do so was passed in. Later operations
        // also expect the blend mode to be kSrc, so update that here.
        SkASSERT(fDstReadStrategy != DstReadStrategy::kNoneRequired);
        finalBlendMode = SkBlendMode::kSrc;
    }

    auto allReqFlags = srcColorRoot->requiredFlags() | finalBlendRoot->requiredFlags();
    if (clipRoot) {
        allReqFlags |= clipRoot->requiredFlags();
    }

    std::string fsPreamble;
    const ResourceBindingRequirements& bindingReqs = caps->resourceBindingRequirements();
    fsPreamble += emit_intrinsic_constants(bindingReqs);
    fsPreamble += emit_varyings(step, "in",
                                sharedData.fRootsInfo,
                                sharedData.fLiftedExpr,
                                sharedData.fHasSsboIndexVarying,
                                sharedData.fNeedsLocalCoords);

    if (fDstReadStrategy == DstReadStrategy::kReadFromInput) {
        // If this shader reads the dst texture as an input attachment, assert that a valid set
        // index has been assigned within ResourceBindingRequirements.
        SkASSERT(bindingReqs.fInputAttachmentSetIdx != ResourceBindingRequirements::kUnassigned);
        // TODO: The following SkSL depends upon the fact that Vulkan is currently the only backend
        // that utilizes DstReadStrategy::kReadFromInput. Update accordingly if other backends add
        // support for this DstReadStrategy.
        SkSL::String::appendf(
                &fsPreamble,
                "layout (vulkan, input_attachment_index=%d, set=%d, binding=%d) "
                "subpassInput DstTextureInput;\n",
                /*input attachment idx within set=*/0,
                /*input attachment set idx=*/bindingReqs.fInputAttachmentSetIdx,
                /*binding=*/0);
    }

    bool useStorageBuffer = caps->storageBufferSupport() &&
                            (allReqFlags & SnippetRequirementFlags::kStorageBuffer);
    SkASSERT(caps->storageBufferSupport() ||
             !SkToBool(allReqFlags & SnippetRequirementFlags::kStorageBuffer));
    if (useStorageBuffer) {
        SkSL::String::appendf(&fsPreamble,
                              "layout (set=%d, binding=%d) readonly buffer FSStorageBuffer {\n"
                              "float %s[];\n"
                              "};\n",
                              bindingReqs.fUniformsSetIdx,
                              bindingReqs.fStorageBufferBinding,
                              ShaderInfo::kStorageBufferName);
        fStorageBufferStages |= PipelineStageFlags::kFragmentShader;
    }

    if (step->fsUsesStorage() && step->numStorageUniforms() > 0) {
        if (caps->storageBufferSupport()) {
            fsPreamble += emit_step_storage_buffer(bindingReqs, step);
        } else {
            fsPreamble += emit_storage_fallback_texture(bindingReqs, step);
        }
        fStorageBufferStages |= PipelineStageFlags::kFragmentShader;
    }

    const bool useDstSampler = fDstReadStrategy == DstReadStrategy::kTextureCopy ||
                               fDstReadStrategy == DstReadStrategy::kTextureSample;
    {
        int binding = 0;
        fsPreamble += emit_textures_and_samplers(bindingReqs, sharedData.fRootsInfo.fRoots,
                                                 &binding, outDescs);
        int paintTextureCount = binding;
        if (step->hasTextures()) {
            fsPreamble += step->texturesAndSamplersSkSL(bindingReqs, &binding);
            if (outDescs) {
                // Determine how many render step samplers were used by comparing the binding value
                // against paintTextureCount, taking into account the binding requirements. We
                // assume and do not anticipate the render steps to use immutable samplers.
                int renderStepSamplerCount = bindingReqs.fSeparateTextureAndSamplerBinding
                                                     ? (binding - paintTextureCount) / 2
                                                     : binding - paintTextureCount;
                // Add default SamplerDescs for all the dynamic samplers used by the render step so
                // the size of outDescs will be equivalent to the total number of samplers.
                outDescs->push_back_n(renderStepSamplerCount);
            }
        }
        if (useDstSampler) {
            fsPreamble += EmitSamplerLayout(bindingReqs, &binding);
            fsPreamble += " sampler2D dstSampler;";
            // Add default SamplerDesc for the intrinsic dstSampler to stay consistent with
            // `fNumFragmentTexturesAndSamplers`.
            if (outDescs) {
                outDescs->push_back({});
            }
        }

        // Record how many textures and samplers are used.
        fNumFragmentTexturesAndSamplers = binding;
    }

    // Emit preamble declarations and helper functions required for snippets. In the default case
    // this adds functions that bind a node's specific mangled uniforms to the snippet's
    // implementation in the SkSL modules.
    emit_preambles(*this, sharedData.fRootsInfo.fRoots, /*treeLabel=*/"", &fsPreamble);
    if (sharedData.fRootsInfo.fMeshShader) {
        fsPreamble += ShaderCodeDictionary::GenerateMeshFSPreamble(
                            *this, sharedData.fRootsInfo.fMeshShader);
    }

    std::string mainBody = "void main() {";

    if (sharedData.fHasSsboIndexVarying) {
        SkSL::String::appendf(&mainBody,
                              "%s = %s;\n",
                              this->uniformSsboIndex(),
                              RenderStep::ssboIndexVarying());
    }

    if (srcColorRoot->requiredFlags() & SnippetRequirementFlags::kPrimitiveColor) {
        SkASSERT(step->emitsPrimitiveColor());
        mainBody += "half4 primitiveColor;";
        mainBody += step->fragmentColorSkSL(sharedData.fRootsInfo);
    } else if (step->fragmentColorSkSLLocalCoordsVariable()) {
        mainBody += step->fragmentColorSkSL(sharedData.fRootsInfo);
    }
    // else the RenderStep may be producing a primitive color but the paint is not consuming it
    // so just skip injecting that SkSL entirely.

    // Using kDefaultArgs as the initial value means it will refer to undefined variables, but the
    // root nodes should--at most--be depending on the coordinate when "needsLocalCoords" is true.
    // If the PaintParamsKey violates that structure, this will produce SkSL compile errors.
    ShaderSnippet::Args args = ShaderSnippet::kDefaultArgs;
    args.fFragCoord = step->fragmentColorSkSLLocalCoordsVariable()
                            ? step->fragmentColorSkSLLocalCoordsVariable()
                            : "localCoordsVar";  // the varying added in emit_varyings()
    // TODO(b/349997190): The paint root node should not depend on any prior stage's output, but
    // it can happen with how SkEmptyShader is currently mapped to `sk_passthrough`. In this case
    // it requires that prior stage color to be transparent black. When SkEmptyShader can instead
    // cause the draw to be skipped, this can go away.
    args.fPriorStageOutput = "half4(0)";

    // Calculate the src color and stash its output variable in `args`
    args.fPriorStageOutput = srcColorRoot->invokeAndAssign(*this, args, &mainBody);

    // If not using hardware blending, we perform a dst read in the shader and must add SkSL
    // accordingly.
    if (fDstReadStrategy != DstReadStrategy::kNoneRequired) {
        // Get the current dst color into a local variable, it may be used later on for coverage
        // blending as well as the final blend.
        mainBody += "half4 dstColor;";
        if (useDstSampler) {
            // dstReadBounds is in frag coords and already includes the replay translation. The
            // reciprocol of the dstCopy dimensions are in ZW.
            mainBody += "dstColor = sample(dstSampler,"
                                          "dstReadBounds.zw*(sk_FragCoord.xy - dstReadBounds.xy));";
        } else if (fDstReadStrategy == DstReadStrategy::kReadFromInput) {
            // The dst texture should have been written to with the appropriate write swizzle, so we
            // do not need to worry about the read swizzle when accessing that value for blending.
#if defined(SK_DEBUG)
            mainBody += "// Read color from input attachment\n";
#endif
            mainBody += "dstColor = subpassLoad(DstTextureInput);\n";
        } else {
            SkASSERT(fDstReadStrategy == DstReadStrategy::kFramebufferFetch);
            mainBody += "dstColor = sk_LastFragColor;";
        }

        args.fBlenderDstColor = "dstColor";
        args.fPriorStageOutput = finalBlendRoot->invokeAndAssign(*this, args, &mainBody);
    }

    if (writeSwizzle != Swizzle::RGBA()) {
        SkSL::String::appendf(&mainBody, "%s = %s.%s;", args.fPriorStageOutput.c_str(),
                                                        args.fPriorStageOutput.c_str(),
                                                        writeSwizzle.asString().c_str());
    }

    if (finalCoverage == Coverage::kNone) {
        // Either direct HW blending or a dst-read w/o any extra coverage. In both cases we just
        // need to assign directly to sk_FragCoord and update the HW blend info to finalBlendMode.
        SkASSERT(finalBlendMode.has_value());
        fBlendInfo = gBlendTable[static_cast<int>(*finalBlendMode)];
        SkSL::String::appendf(&mainBody, "sk_FragColor = %s;", args.fPriorStageOutput.c_str());
    } else {
        // Accumulate the output coverage. This will either modify the src color and secondary
        // outputs for dual-source blending, or be combined directly with the in-shader blended
        // final color if a dst-readback was required.

        if (sharedData.fUseUniformStorageBufferFS && sharedData.fHasStepUniforms) {
            mainBody +=
                    emit_uniforms_from_storage_buffer(this->uniformSsboIndex(), step->uniforms());
        }

        mainBody += "half4 outputCoverage = half4(1);";
        if (step->coverage() != Coverage::kNone) {
            mainBody += step->fragmentCoverageSkSL();
        }

        if (clipRoot) {
            // The clip block node is invoked with device coords, not local coords like the main
            // shading root node. However sk_FragCoord includes any replay translation and we
            // need to recover the original device coordinate.
            mainBody += "float2 devCoord = sk_FragCoord.xy - viewport.xy;";
            args.fFragCoord = "devCoord";
            std::string clipBlockOutput = clipRoot->invokeAndAssign(*this, args, &mainBody);
            SkSL::String::appendf(&mainBody, "outputCoverage *= %s.a;", clipBlockOutput.c_str());
        }

        const char* outColor = args.fPriorStageOutput.c_str();
        if (fDstReadStrategy != DstReadStrategy::kNoneRequired) {
            // If this draw uses a non-coherent dst read, we want to keep the existing dst color (or
            // whatever has been previously drawn) when there's no coverage. This helps for batching
            // text draws that need to read from a dst copy for blends. However, this only helps the
            // case where the outer bounding boxes of each letter overlap and not two actual parts
            // of the text.
            if (useDstSampler) {
                // We don't think any shaders actually output negative coverage, but just as a
                // safety check for floating point precision errors, we compare with <= here. We
                // just check the RGB values of the coverage, since the alpha may not have been set
                // when using LCD. If we are using single-channel coverage, alpha will be equal to
                // RGB anyway.
                mainBody +=
                    "if (all(lessThanEqual(outputCoverage.rgb, half3(0)))) {"
                        "discard;"
                    "}";
            }

            // Use kSrc HW BlendInfo and do the coverage blend with dst in the shader.
            SkASSERT(finalBlendMode.has_value() && finalBlendMode.value() == SkBlendMode::kSrc);
            fBlendInfo = gBlendTable[static_cast<int>(*finalBlendMode)];
            SkSL::String::appendf(
                    &mainBody,
                    "sk_FragColor = %s * outputCoverage + dstColor * (1.0 - outputCoverage);",
                    outColor);
            if (finalCoverage == Coverage::kLCD) {
                SkSL::String::appendf(
                        &mainBody,
                        "half3 lerpRGB = mix(dstColor.aaa, %s.aaa, outputCoverage.rgb);"
                        "sk_FragColor.a = max(max(lerpRGB.r, lerpRGB.g), lerpRGB.b);",
                        outColor);
            }
        } else {
            // Adjust the shader output(s) to incorporate the coverage so that HW blending produces
            // the correct output.
            if (finalBlendMode > SkBlendMode::kLastCoeffMode) {
                SkASSERT(finalCoverage == Coverage::kSingleChannel);
                fBlendInfo = gBlendTable[static_cast<int>(*finalBlendMode)];
                mainBody += emit_advanced_blend_color_output("sk_FragColor", outColor);
            } else {
                // Porter-Duff blend modes can utilize BlendFormula.
                // TODO: Determine whether draw is opaque and pass that to GetBlendFormula.
                BlendFormula coverageBlendFormula =
                        finalCoverage == Coverage::kLCD
                                ? skgpu::GetLCDBlendFormula(*finalBlendMode)
                                : skgpu::GetBlendFormula(
                                        /*isOpaque=*/false, /*hasCoverage=*/true, *finalBlendMode);
                fBlendInfo = {coverageBlendFormula.equation(),
                              coverageBlendFormula.srcCoeff(),
                              coverageBlendFormula.dstCoeff(),
                              SK_PMColor4fTRANSPARENT,
                              coverageBlendFormula.modifiesDst()};

                if (finalCoverage == Coverage::kLCD) {
                    mainBody += "outputCoverage.a = max(max(outputCoverage.r, "
                                                           "outputCoverage.g), "
                                                   "outputCoverage.b);";
                }

                mainBody += emit_color_output(coverageBlendFormula.primaryOutput(),
                                              "sk_FragColor",
                                              outColor);
                if (coverageBlendFormula.hasSecondaryOutput()) {
                    SkASSERT(caps->shaderCaps()->fDualSourceBlendingSupport);
                    mainBody += emit_color_output(coverageBlendFormula.secondaryOutput(),
                                                  "sk_SecondaryFragColor",
                                                  outColor);
                }
            }
        }
    }
    mainBody += "}\n";

    SkASSERT(fFragmentSkSL.empty());
    fFragmentSkSL.reserve(
            sharedData.fSharedPreamble.size() + fsPreamble.size() + mainBody.size() +2);
    fFragmentSkSL  = sharedData.fSharedPreamble;
    fFragmentSkSL += "\n";
    fFragmentSkSL += fsPreamble;
    fFragmentSkSL += "\n";
    fFragmentSkSL += mainBody;
}

void ShaderInfo::generateVertexSkSL(const Caps* caps,
                                    const RenderStep* step,
                                    const SharedGeneratorData& sharedData) {
    std::string vsPreamble;
    // Fixed program header (intrinsics are always declared as an uniform interface block)
    const ResourceBindingRequirements& bindingReqs = caps->resourceBindingRequirements();
    vsPreamble = emit_intrinsic_constants(bindingReqs);
    // Varyings needed by RenderStep and potentially lifted expressions
    vsPreamble += emit_varyings(step, "out",
                                sharedData.fRootsInfo,
                                sharedData.fLiftedExpr,
                                sharedData.fHasSsboIndexVarying,
                                sharedData.fNeedsLocalCoords);

    // Declare vertex storage buffer (or fallback texture) if the RenderStep has storage uniforms
    if (step->vsUsesStorage() && step->numStorageUniforms() > 0) {
        if (caps->storageBufferSupport()) {
            vsPreamble += emit_step_storage_buffer(bindingReqs, step);
        } else {
            vsPreamble += emit_storage_fallback_texture(bindingReqs, step);
        }
        fStorageBufferStages |= PipelineStageFlags::kVertexShader;
    }

    // Add vertex attributes
    SkSpan<const Attribute> staticAttrs = step->staticAttributes();
    SkSpan<const Attribute> appendAttrs = this->appendAttributes().empty()
                                                ? step->appendAttributes()
                                                : this->appendAttributes();
    if (!staticAttrs.empty() || !appendAttrs.empty()) {
        int attr = 0;
        auto add_attrs = [&vsPreamble, &attr](SkSpan<const Attribute> attrs) {
            for (auto a : attrs) {
                SkSL::String::appendf(&vsPreamble, "layout(location=%d) in ", attr++);
                vsPreamble.append(SkSLTypeString(a.gpuType()));
                SkSL::String::appendf(&vsPreamble, " %s;\n", a.name());
            }
        };
        if (!staticAttrs.empty()) {
#if defined(SK_DEBUG)
            vsPreamble.append("// static attrs\n");
#endif
            add_attrs(staticAttrs);
        }
        if (!appendAttrs.empty()) {
#if defined(SK_DEBUG)
            vsPreamble.append("// append attrs\n");
#endif
            add_attrs(appendAttrs);
        }
    }

    if (sharedData.fRootsInfo.fMeshShader) {
        vsPreamble += ShaderCodeDictionary::GenerateMeshVSPreamble(
                            *this, sharedData.fRootsInfo.fMeshShader);
    }

    // Vertex shader function declaration
    std::string mainBody = "void main() {";
    // Create stepLocalCoords which render steps can write to.
    mainBody += "float2 stepLocalCoords = float2(0);";

    // We define the SSBO index variable immediately if the VS is using storage buffers. This covers
    // both the "Step Uniforms" case and the "Lifted Uniforms Only" case.
    if (sharedData.fUseUniformStorageBufferVS) {
        SkSL::String::appendf(&mainBody, "%s = %s;\n", this->uniformSsboIndex(),
                                  RenderStep::ssboIndexAttribute());
        if (sharedData.fHasStepUniforms) {
            mainBody +=
                    emit_uniforms_from_storage_buffer(this->uniformSsboIndex(), step->uniforms());
        }
    }

    // Inject RenderStep's main vertex logic
    mainBody += step->vertexSkSL(sharedData.fRootsInfo);

    // Calculate sk_Position
    mainBody +=
            "sk_Position = float4(viewport.zw*devPosition.xy - sign(viewport.zw)*devPosition.ww,"
            "devPosition.zw);";

    // Assign local coords to varying if needed
    if (sharedData.fNeedsLocalCoords) {
        mainBody += "localCoordsVar = stepLocalCoords;";
    }

    // Generate lifted expressions
    if (!sharedData.fLiftedExpr.empty()) {
        for (const LiftedExpression& expr : sharedData.fLiftedExpr) {
            const ShaderNode* node = expr.fNode;
            // Determine the SkSL type string if not emitting directly to a varying
            const char* typeStr = expr.fEmitVarying
                                          ? ""
                                          : SkSLTypeString(sksl_type_for_lifted_expression(
                                                    node->entry()->fLiftableExpressionType));
            const std::string varName = node->getExpressionVaryingName();

            // Generate the expression code, potentially extracting uniforms from SSBO if needed
            std::string expression;
            expression = node->entry()->fLiftableExpressionGenerator(*this, node, expr.fArgs);

            // Assign the expression result to the varying or a temporary variable
            SkSL::String::appendf(
                    &mainBody, "%s %s = %s;", typeStr, varName.c_str(), expression.c_str());
        }
    }

    // Assign SSBO index to varying if needed
    if (sharedData.fHasSsboIndexVarying) {
        if (sharedData.fUseUniformStorageBufferVS) {
            // Use the local variable we already defined
            SkSL::String::appendf(&mainBody,
                                  "%s = %s;",
                                  RenderStep::ssboIndexVarying(),
                                  this->uniformSsboIndex());
        } else {
            // No local variable, read directly from attribute
            SkSL::String::appendf(&mainBody,
                                  "%s = %s;",
                                  RenderStep::ssboIndexVarying(),
                                  RenderStep::ssboIndexAttribute());
        }
    }

    mainBody += "}"; // End main()

    SkASSERT(fVertexSkSL.empty());
    fVertexSkSL.reserve(
            sharedData.fSharedPreamble.size() + vsPreamble.size() + mainBody.size() + 2);
    fVertexSkSL = sharedData.fSharedPreamble;
    fVertexSkSL += "\n";
    fVertexSkSL += vsPreamble;
    fVertexSkSL += "\n";
    fVertexSkSL += mainBody;
}


#if defined(GPU_TEST_UTILS)
std::string ShaderInfo::EmitStorageFallbackTexture(const ResourceBindingRequirements& bindingReqs,
                                                   const RenderStep* step) {
    return emit_storage_fallback_texture(bindingReqs, step);
}
#endif

}  // namespace skgpu::graphite
