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

#ifndef skgpu_graphite_ShaderCodeDictionary_DEFINED
#define skgpu_graphite_ShaderCodeDictionary_DEFINED

#include "include/core/SkSpan.h"
#include "include/effects/SkRuntimeEffect.h"
#include "include/private/SkEnumBitMask.h"
#include "include/private/SkTo.h"
#include "src/core/SkArenaAlloc.h"
#include "src/core/SkKnownRuntimeEffects.h"
#include "src/core/SkSLTypeShared.h"
#include "src/core/SkSpinlock.h"
#include "src/core/SkTHash.h"
#include "src/gpu/graphite/Attribute.h"
#include "src/gpu/graphite/BuiltInCodeSnippetID.h"
#include "src/gpu/graphite/PaintParamsKey.h"
#include "src/gpu/graphite/ResourceTypes.h"
#include "src/gpu/graphite/Uniform.h"
#include "src/gpu/graphite/UniquePaintParamsID.h"

#include <array>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <string>
#include <string_view>

class SkRuntimeEffect;

namespace skgpu::graphite {

// TODO: How to represent the type (e.g., 2D) of texture being sampled?
class TextureAndSampler {
public:
    constexpr TextureAndSampler(const char* name) : fName(name) {}

    const char* name() const { return fName; }

private:
    const char* fName;
};

enum class SnippetRequirementFlags : uint32_t {
    kNone                   = 0x0,

    // Signature of the ShaderNode
    kLocalCoords            = 0x1,
    kPriorStageOutput       = 0x2,   // AKA the "input" color, or the "src" argument for a blender
    kBlenderDstColor        = 0x4,   // The "dst" argument for a blender

    // Special values and/or behaviors required for the snippet
    kPrimitiveColor         = 0x8,
    kStorageBuffer          = 0x10,
    kStoresSamplerDescData  = 0x20,  // Indicates that the node stores numerical sampler data
    kPassthroughLocalCoords = 0x40,  // Indicates that the node will pass through local coords
                                     // unmodified to its children.
    kLiftExpression         = 0x80,  // Indicates that the liftable expression generated by this
                                     // node will be lifted to the vertex shader and passed to the
                                     // fragment shader as a varying.
    kOmitExpression         = 0x100, // Indicates that the liftable expression generated by this
                                     // node will be used in a compound expression lifted to the
                                     // vertex shader and omitted from the fragment shader entirely.
};
SK_MAKE_BITMASK_OPS(SnippetRequirementFlags)

class ShaderInfo;
class ShaderNode;

// ShaderSnippets define the "ABI" of a SkSL module function and its required uniform data, as
// well as functions for generating the invoking SkSL. Snippets are composed into an effect tree
// using ShaderNodes.
struct ShaderSnippet {
    struct Args {
        std::string fPriorStageOutput;
        std::string fBlenderDstColor;
        std::string fFragCoord;
    };

    using GeneratePreambleForSnippetFn = std::string (*)(const ShaderInfo& shaderInfo,
                                                         const ShaderNode*);
    using GenerateLiftableExpressionFn = std::string (*)(const ShaderInfo& shaderInfo,
                                                         const ShaderNode*,
                                                         const ShaderSnippet::Args& args);
    static const Args kDefaultArgs;

    // If this snippet has an expression that can be lifted from the fragment shader to the vertex
    // shader, the LiftableExpressionType specifies how the resolved expression is used by
    // subsequent shader nodes.
    enum class LiftableExpressionType : uint32_t {
        kNone,
        kLocalCoords,
        kPriorStageOutput,
    };

    ShaderSnippet() = default;

    ShaderSnippet(const char* name,
                  const char* staticFn,
                  SkEnumBitMask<SnippetRequirementFlags> snippetRequirementFlags,
                  SkSpan<const Uniform> uniforms,
                  SkSpan<const TextureAndSampler> texturesAndSamplers = {},
                  GeneratePreambleForSnippetFn preambleGenerator = nullptr,
                  int numChildren = 0,
                  GenerateLiftableExpressionFn liftableExpression = nullptr,
                  LiftableExpressionType liftableExpressionType = LiftableExpressionType::kNone,
                  Interpolation liftableExpressionInterpolation = Interpolation::kPerspective)
            : fName(name)
            , fStaticFunctionName(staticFn)
            , fSnippetRequirementFlags(snippetRequirementFlags)
            , fUniforms(uniforms)
            , fTexturesAndSamplers(texturesAndSamplers)
            , fNumChildren(numChildren)
            , fPreambleGenerator(preambleGenerator)
            , fLiftableExpressionInterpolation(liftableExpressionInterpolation)
            , fLiftableExpressionType(liftableExpressionType)
            , fLiftableExpressionGenerator(liftableExpression) {
        // Must always provide a name; static function is not optional if using the default (null)
        // generation logic.
        SkASSERT(name);
        SkASSERT(staticFn || preambleGenerator);
    }

    bool needsLocalCoords() const {
        return SkToBool(fSnippetRequirementFlags & SnippetRequirementFlags::kLocalCoords);
    }
    bool needsPriorStageOutput() const {
        return SkToBool(fSnippetRequirementFlags & SnippetRequirementFlags::kPriorStageOutput);
    }
    bool needsBlenderDstColor() const {
        return SkToBool(fSnippetRequirementFlags & SnippetRequirementFlags::kBlenderDstColor);
    }
    bool storesSamplerDescData() const {
        return SkToBool(fSnippetRequirementFlags & SnippetRequirementFlags::kStoresSamplerDescData);
    }

    const char* fName = nullptr;
    const char* fStaticFunctionName = nullptr;

    // The features and args that this shader snippet requires in order to be invoked
    SkEnumBitMask<SnippetRequirementFlags> fSnippetRequirementFlags{SnippetRequirementFlags::kNone};

    // If not null, the list of uniforms in `fUniforms` describes an existing struct type declared
    // in the Graphite modules with the given name. Instead of inlining the each uniform in the
    // top-level interface block or aggregate struct, there will be a single member of this struct's
    // type.
    const char* fUniformStructName = nullptr;
    // If the uniforms are being embedded as a sub-struct, this is the required starting alignment.
    int fRequiredAlignment = -1;

    skia_private::TArray<Uniform> fUniforms;
    skia_private::TArray<TextureAndSampler> fTexturesAndSamplers;

    int fNumChildren = 0;
    GeneratePreambleForSnippetFn fPreambleGenerator = nullptr;

    Interpolation fLiftableExpressionInterpolation = Interpolation::kPerspective;
    LiftableExpressionType fLiftableExpressionType = LiftableExpressionType::kNone;
    GenerateLiftableExpressionFn fLiftableExpressionGenerator = nullptr;
};

// ShaderNodes organize snippets into an effect tree, and provide random access to the dynamically
// bound child snippets. Each node has a fixed number of children defined by its code ID
// (either a BuiltInCodeSnippetID or a runtime effect's assigned ID). All children are non-null.
// A ShaderNode tree represents a decompressed PaintParamsKey.
class ShaderNode {
public:
    // ShaderNodes should be created in conjunction with an SkArenaAlloc that owns all nodes.
    ShaderNode(const ShaderSnippet* snippet,
               SkSpan<ShaderNode*> children,
               int codeID,
               int keyIndex,
               SkSpan<const uint32_t> data)
            : fEntry(snippet)
            , fChildren(children)
            , fCodeID(codeID)
            , fKeyIndex(keyIndex)
            , fRequiredFlags(snippet->fSnippetRequirementFlags)
            , fData(data) {
        SkASSERT(children.size() == (size_t) fEntry->fNumChildren);

        // Propagate requirement flags from children towards root.
        const bool isRuntimeEffect = codeID >= kBuiltInCodeSnippetIDCount;
        const bool isCompose = codeID == (int) BuiltInCodeSnippetID::kCompose ||
                               codeID == (int) BuiltInCodeSnippetID::kBlendCompose;
        for (const ShaderNode* child : children) {
            // Mask off flags to not propagate.
            SkEnumBitMask<SnippetRequirementFlags> mask =
                    SnippetRequirementFlags::kPassthroughLocalCoords |
                    SnippetRequirementFlags::kLiftExpression |
                    SnippetRequirementFlags::kOmitExpression;
            // Runtime effects invoke children with explicit parameters so those requirements never
            // need to propagate to the root. Similarly, compose only needs to propagate the
            // variable parameters for the inner children.
            if (isRuntimeEffect || (isCompose && child == children.back())) {
                mask |= SnippetRequirementFlags::kLocalCoords |
                        SnippetRequirementFlags::kPriorStageOutput |
                        SnippetRequirementFlags::kBlenderDstColor;
            }
            fRequiredFlags |= (child->requiredFlags() & ~mask);
        }

        // Data should only be provided if the snippet has the kStoresSamplerDescData flag.
        SkASSERT(fData.empty() || snippet->storesSamplerDescData());
    }

    std::string generateDefaultPreamble(const ShaderInfo& shaderInfo) const;
    std::string invokeAndAssign(const ShaderInfo& shaderInfo,
                                const ShaderSnippet::Args& args,
                                std::string* funcBody) const;

    std::string getExpressionVaryingName() const;

    int32_t codeSnippetId() const { return fCodeID; }
    int32_t keyIndex() const { return fKeyIndex; }
    const ShaderSnippet* entry() const { return fEntry; }

    SkEnumBitMask<SnippetRequirementFlags> requiredFlags() const { return fRequiredFlags; }
    void setLiftExpressionFlag() { fRequiredFlags |= SnippetRequirementFlags::kLiftExpression; }
    void setOmitExpressionFlag() { fRequiredFlags |= SnippetRequirementFlags::kOmitExpression; }
    void unsetLocalCoordsFlag() { fRequiredFlags &= ~SnippetRequirementFlags::kLocalCoords; }

    int numChildren() const { return fEntry->fNumChildren; }
    SkSpan<ShaderNode*> children() { return fChildren; }
    SkSpan<const ShaderNode*> children() const {
        return SkSpan<const ShaderNode*>(const_cast<const ShaderNode**>(fChildren.data()),
                                         fChildren.size());
    }
    const ShaderNode* child(int childIndex) const { return fChildren[childIndex]; }

    SkSpan<const uint32_t> data() const { return fData; }

private:
    const ShaderSnippet* fEntry; // Owned by the ShaderCodeDictionary
    SkSpan<ShaderNode*> fChildren; // Owned by the ShaderInfo's arena

    int32_t fCodeID;
    int32_t fKeyIndex; // index back to PaintParamsKey, unique across nodes within a ShaderInfo

    SkEnumBitMask<SnippetRequirementFlags> fRequiredFlags;
    SkSpan<const uint32_t> fData; // Subspan of PaintParamsKey's fData; shares same owner
};

// ShaderCodeDictionary is a thread-safe dictionary of ShaderSnippets to code IDs for use with
// creating PaintParamKeys, as well as assigning unique IDs to each encountered PaintParamKey.
// It defines ShaderSnippets for every BuiltInCodeSnippetID and maintains records for IDs per
// SkRuntimeEffect, including de-duplicating equivalent SkRuntimeEffect objects.
class ShaderCodeDictionary {
public:
    ShaderCodeDictionary(Layout layout,
                         SkSpan<sk_sp<SkRuntimeEffect>> userDefinedKnownRuntimeEffects);

    UniquePaintParamsID findOrCreate(const PaintParamsKey&);

    UniquePaintParamsID findOrCreate(PaintParamsKeyBuilder*) SK_EXCLUDES(fSpinLock);

    PaintParamsKey lookup(UniquePaintParamsID) const SK_EXCLUDES(fSpinLock);

    SkString idToString(const Caps* caps, UniquePaintParamsID id) const {
        return this->lookup(id).toString(caps, this);
    }

#if defined(SK_DEBUG)
    bool isValidID(int snippetID) const SK_EXCLUDES(fSpinLock);

    void dump(const Caps*, UniquePaintParamsID) const;
#endif

    // This method can return nullptr
    const ShaderSnippet* getEntry(int codeSnippetID) const SK_EXCLUDES(fSpinLock);
    const ShaderSnippet* getEntry(BuiltInCodeSnippetID codeSnippetID) const {
        // Built-in code snippets are initialized once so there is no need to take a lock
        return &fBuiltInCodeSnippets[SkTo<int>(codeSnippetID)];
    }

    // getEntry can be used to retrieve the ShaderSnippet for a user-defined known runtime effect
    // but, since the ShaderCodeDictionary owns those runtime effects, we need another entry
    // point to retrieve the actual effect. For unknown runtime effects this is handled by the
    // RuntimeEffectDictionary which, transiently, holds a ref on the encountered runtime effects.
    const SkRuntimeEffect* getUserDefinedKnownRuntimeEffect(int codeSnippetID) const;

    // Returns -1 on failure
    int findOrCreateRuntimeEffectSnippet(const SkRuntimeEffect* effect) SK_EXCLUDES(fSpinLock);

    bool isUserDefinedKnownRuntimeEffect(int candidate) const;
#if defined(GPU_TEST_UTILS)
    int numUserDefinedRuntimeEffects() const SK_EXCLUDES(fSpinLock);
    int numUserDefinedKnownRuntimeEffects() const;
#endif

    int findOrCreateMeshSnippet(const SkMeshSpecification* spec) SK_EXCLUDES(fSpinLock);

    static SkSLType UniformTypeToSkSLType(const SkRuntimeEffect::Uniform& u);

    static SkSpan<const Uniform> ConvertRuntimeEffectUniforms(
            SkSpan<const SkRuntimeEffect::Uniform> uniforms,
            SkArenaAlloc* arena);

    static std::string GenerateMeshVSPreamble(const ShaderInfo& shaderInfo, const ShaderNode* node);
    static std::string GenerateMeshFSPreamble(const ShaderInfo& shaderInfo, const ShaderNode* node);

private:
    SkSpan<const Uniform> convertUniforms(const SkRuntimeEffect* effect);
    ShaderSnippet convertRuntimeEffect(const SkRuntimeEffect* effect, const char* name);
    ShaderSnippet convertMeshShader(const SkMeshSpecification* spec);

    void registerUserDefinedKnownRuntimeEffects(SkSpan<sk_sp<SkRuntimeEffect>>);

    const Layout fLayout;

    std::array<ShaderSnippet, kBuiltInCodeSnippetIDCount> fBuiltInCodeSnippets;

    using KnownRuntimeEffectArray = std::array<ShaderSnippet, SkKnownRuntimeEffects::kStableKeyCnt>;
    KnownRuntimeEffectArray fKnownRuntimeEffectCodeSnippets SK_GUARDED_BY(fSpinLock);

    using ShaderSnippetArray = skia_private::TArray<ShaderSnippet>;
    using RuntimeEffectArray = skia_private::TArray<sk_sp<SkRuntimeEffect>>;

    // These two arrays are not guarded by a lock since they are only initialized in the ctor
    ShaderSnippetArray fUserDefinedKnownCodeSnippets;
    RuntimeEffectArray fUserDefinedKnownRuntimeEffects;

    // The value returned from 'getEntry' must be stable so, hold the user-defined code snippet
    // entries as pointers.
    ShaderSnippetArray fUserDefinedCodeSnippets SK_GUARDED_BY(fSpinLock);

    // TODO: can we do something better given this should have write-seldom/read-often behavior?
    mutable SkSpinlock fSpinLock;

    using PaintIDMap = skia_private::THashMap<PaintParamsKey,
                                              UniquePaintParamsID,
                                              PaintParamsKey::Hash>;

    PaintIDMap fPaintKeyToID SK_GUARDED_BY(fSpinLock);
    skia_private::TArray<PaintParamsKey> fIDToPaintKey SK_GUARDED_BY(fSpinLock);

    SK_BEGIN_REQUIRE_DENSE
    struct RuntimeEffectKey {
        uint32_t fHash;
        uint32_t fUniformSize;

        bool operator==(RuntimeEffectKey rhs) const {
            return fHash == rhs.fHash && fUniformSize == rhs.fUniformSize;
        }
    };
    struct MeshSpecKey {
        uint32_t fHash;
        uint32_t fAttributeStride;
        uint32_t fUniformSize;

        bool operator==(MeshSpecKey rhs) const {
            return fHash == rhs.fHash && fAttributeStride == rhs.fAttributeStride &&
                   fUniformSize == rhs.fUniformSize;
        }
    };
    SK_END_REQUIRE_DENSE

    // A map from RuntimeEffectKeys (hash plus uniforms) to code-snippet IDs. RuntimeEffectKeys
    // don't track the lifetime of a runtime effect at all; they live forever, and a newly-
    // instantiated runtime effect with the same program as a previously-discarded effect will reuse
    // an existing ID. Entries in the runtime-effect map are never removed; they only disappear when
    // the context is discarded, which takes the ShaderCodeDictionary along with it. However, they
    // are extremely small (< 20 bytes) so the memory footprint should be unnoticeable.
    using RuntimeEffectMap = skia_private::THashMap<RuntimeEffectKey, int32_t>;
    RuntimeEffectMap fRuntimeEffectMap SK_GUARDED_BY(fSpinLock);

    using MeshSpecMap = skia_private::THashMap<MeshSpecKey, int32_t>;
    MeshSpecMap fMeshMap SK_GUARDED_BY(fSpinLock);

    // This arena holds:
    //   - the backing data for PaintParamsKeys in `fPaintKeyToID` and `fIDToPaintKey`
    //   - Uniform data created by `findOrCreateRuntimeEffectSnippet`
    // and in all cases is guarded by `fSpinLock`
    SkArenaAlloc fArena{256};
};

} // namespace skgpu::graphite

#endif // skgpu_graphite_ShaderCodeDictionary_DEFINED
