//
// Copyright 2017 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

// ProgramLinkedResources.h: implements link-time checks for default block uniforms, and generates
// uniform locations. Populates data structures related to uniforms so that they can be stored in
// program state.

#ifndef LIBANGLE_UNIFORMLINKER_H_
#define LIBANGLE_UNIFORMLINKER_H_

#include "angle_gl.h"
#include "common/PackedEnums.h"
#include "common/angleutils.h"
#include "libANGLE/VaryingPacking.h"

#include <functional>

namespace sh
{
class BlockLayoutEncoder;
struct BlockMemberInfo;
struct InterfaceBlock;
struct ShaderVariable;
class BlockEncoderVisitor;
class ShaderVariableVisitor;
struct ShaderVariable;
}  // namespace sh

namespace gl
{
struct BufferVariable;
struct Caps;
class Context;
class InfoLog;
struct InterfaceBlock;
enum class LinkMismatchError;
struct LinkedUniform;
class ProgramState;
class ProgramPipelineState;
class ProgramBindings;
class ProgramAliasedBindings;
class Shader;
struct ShaderVariableBuffer;
struct UnusedUniform;
struct VariableLocation;

using AtomicCounterBuffer = ShaderVariableBuffer;

class UniformLinker final : angle::NonCopyable
{
  public:
    UniformLinker(const ProgramState &state);
    ~UniformLinker();

    bool link(const Caps &caps,
              InfoLog &infoLog,
              const ProgramAliasedBindings &uniformLocationBindings);

    void getResults(std::vector<LinkedUniform> *uniforms,
                    std::vector<UnusedUniform> *unusedUniforms,
                    std::vector<VariableLocation> *uniformLocations);

  private:
    bool validateGraphicsUniforms(InfoLog &infoLog) const;

    bool flattenUniformsAndCheckCapsForShader(Shader *shader,
                                              const Caps &caps,
                                              std::vector<LinkedUniform> &samplerUniforms,
                                              std::vector<LinkedUniform> &imageUniforms,
                                              std::vector<LinkedUniform> &atomicCounterUniforms,
                                              std::vector<LinkedUniform> &inputAttachmentUniforms,
                                              std::vector<UnusedUniform> &unusedUniforms,
                                              InfoLog &infoLog);

    bool flattenUniformsAndCheckCaps(const Caps &caps, InfoLog &infoLog);
    bool checkMaxCombinedAtomicCounters(const Caps &caps, InfoLog &infoLog);

    bool indexUniforms(InfoLog &infoLog, const ProgramAliasedBindings &uniformLocationBindings);
    bool gatherUniformLocationsAndCheckConflicts(
        InfoLog &infoLog,
        const ProgramAliasedBindings &uniformLocationBindings,
        std::set<GLuint> *ignoredLocations,
        int *maxUniformLocation);
    void pruneUnusedUniforms();

    const ProgramState &mState;
    std::vector<LinkedUniform> mUniforms;
    std::vector<UnusedUniform> mUnusedUniforms;
    std::vector<VariableLocation> mUniformLocations;
};

using GetBlockSizeFunc = std::function<
    bool(const std::string &blockName, const std::string &blockMappedName, size_t *sizeOut)>;
using GetBlockMemberInfoFunc = std::function<
    bool(const std::string &name, const std::string &mappedName, sh::BlockMemberInfo *infoOut)>;

// This class is intended to be used during the link step to store interface block information.
// It is called by the Impl class during ProgramImpl::link so that it has access to the
// real block size and layout.
class InterfaceBlockLinker : angle::NonCopyable
{
  public:
    virtual ~InterfaceBlockLinker();

    // This is called once per shader stage. It stores a pointer to the block vector, so it's
    // important that this class does not persist longer than the duration of Program::link.
    void addShaderBlocks(ShaderType shader, const std::vector<sh::InterfaceBlock> *blocks);

    // This is called once during a link operation, after all shader blocks are added.
    void linkBlocks(const GetBlockSizeFunc &getBlockSize,
                    const GetBlockMemberInfoFunc &getMemberInfo) const;

  protected:
    InterfaceBlockLinker();
    void init(std::vector<InterfaceBlock> *blocksOut,
              std::vector<std::string> *unusedInterfaceBlocksOut);
    void defineInterfaceBlock(const GetBlockSizeFunc &getBlockSize,
                              const GetBlockMemberInfoFunc &getMemberInfo,
                              const sh::InterfaceBlock &interfaceBlock,
                              ShaderType shaderType) const;

    virtual size_t getCurrentBlockMemberIndex() const = 0;

    virtual sh::ShaderVariableVisitor *getVisitor(const GetBlockMemberInfoFunc &getMemberInfo,
                                                  const std::string &namePrefix,
                                                  const std::string &mappedNamePrefix,
                                                  ShaderType shaderType,
                                                  int blockIndex) const = 0;

    ShaderMap<const std::vector<sh::InterfaceBlock> *> mShaderBlocks = {};

    std::vector<InterfaceBlock> *mBlocksOut             = nullptr;
    std::vector<std::string> *mUnusedInterfaceBlocksOut = nullptr;
};

class UniformBlockLinker final : public InterfaceBlockLinker
{
  public:
    UniformBlockLinker();
    ~UniformBlockLinker() override;

    void init(std::vector<InterfaceBlock> *blocksOut,
              std::vector<LinkedUniform> *uniformsOut,
              std::vector<std::string> *unusedInterfaceBlocksOut);

  private:
    size_t getCurrentBlockMemberIndex() const override;

    sh::ShaderVariableVisitor *getVisitor(const GetBlockMemberInfoFunc &getMemberInfo,
                                          const std::string &namePrefix,
                                          const std::string &mappedNamePrefix,
                                          ShaderType shaderType,
                                          int blockIndex) const override;

    std::vector<LinkedUniform> *mUniformsOut = nullptr;
};

class ShaderStorageBlockLinker final : public InterfaceBlockLinker
{
  public:
    ShaderStorageBlockLinker();
    ~ShaderStorageBlockLinker() override;

    void init(std::vector<InterfaceBlock> *blocksOut,
              std::vector<BufferVariable> *bufferVariablesOut,
              std::vector<std::string> *unusedInterfaceBlocksOut);

  private:
    size_t getCurrentBlockMemberIndex() const override;

    sh::ShaderVariableVisitor *getVisitor(const GetBlockMemberInfoFunc &getMemberInfo,
                                          const std::string &namePrefix,
                                          const std::string &mappedNamePrefix,
                                          ShaderType shaderType,
                                          int blockIndex) const override;

    std::vector<BufferVariable> *mBufferVariablesOut = nullptr;
};

class AtomicCounterBufferLinker final : angle::NonCopyable
{
  public:
    AtomicCounterBufferLinker();
    ~AtomicCounterBufferLinker();

    void init(std::vector<AtomicCounterBuffer> *atomicCounterBuffersOut);
    void link(const std::map<int, unsigned int> &sizeMap) const;

  private:
    std::vector<AtomicCounterBuffer> *mAtomicCounterBuffersOut = nullptr;
};

// The link operation is responsible for finishing the link of uniform and interface blocks.
// This way it can filter out unreferenced resources and still have access to the info.
// TODO(jmadill): Integrate uniform linking/filtering as well as interface blocks.
struct UnusedUniform
{
    UnusedUniform(std::string name,
                  bool isSampler,
                  bool isImage,
                  bool isAtomicCounter,
                  bool isFragmentInOut)
    {
        this->name            = name;
        this->isSampler       = isSampler;
        this->isImage         = isImage;
        this->isAtomicCounter = isAtomicCounter;
        this->isFragmentInOut = isFragmentInOut;
    }

    std::string name;
    bool isSampler;
    bool isImage;
    bool isAtomicCounter;
    bool isFragmentInOut;
};

struct ProgramLinkedResources
{
    ProgramLinkedResources();
    ~ProgramLinkedResources();

    void init(std::vector<InterfaceBlock> *uniformBlocksOut,
              std::vector<LinkedUniform> *uniformsOut,
              std::vector<InterfaceBlock> *shaderStorageBlocksOut,
              std::vector<BufferVariable> *bufferVariablesOut,
              std::vector<AtomicCounterBuffer> *atomicCounterBuffersOut);

    ProgramVaryingPacking varyingPacking;
    UniformBlockLinker uniformBlockLinker;
    ShaderStorageBlockLinker shaderStorageBlockLinker;
    AtomicCounterBufferLinker atomicCounterBufferLinker;
    std::vector<UnusedUniform> unusedUniforms;
    std::vector<std::string> unusedInterfaceBlocks;
};

struct LinkingVariables final : private angle::NonCopyable
{
    LinkingVariables(const ProgramState &state);
    LinkingVariables(const ProgramPipelineState &state);
    ~LinkingVariables();

    ShaderMap<std::vector<sh::ShaderVariable>> outputVaryings;
    ShaderMap<std::vector<sh::ShaderVariable>> inputVaryings;
    ShaderMap<std::vector<sh::ShaderVariable>> uniforms;
    ShaderMap<std::vector<sh::InterfaceBlock>> uniformBlocks;
    ShaderBitSet isShaderStageUsedBitset;
};

class CustomBlockLayoutEncoderFactory : angle::NonCopyable
{
  public:
    virtual ~CustomBlockLayoutEncoderFactory() {}

    virtual sh::BlockLayoutEncoder *makeEncoder() = 0;
};

// Used by the backends in Program*::linkResources to parse interface blocks and provide
// information to ProgramLinkedResources' linkers.
class ProgramLinkedResourcesLinker final : angle::NonCopyable
{
  public:
    ProgramLinkedResourcesLinker(CustomBlockLayoutEncoderFactory *customEncoderFactory)
        : mCustomEncoderFactory(customEncoderFactory)
    {}

    void linkResources(const ProgramState &programState,
                       const ProgramLinkedResources &resources) const;

  private:
    void getAtomicCounterBufferSizeMap(const ProgramState &programState,
                                       std::map<int, unsigned int> &sizeMapOut) const;

    CustomBlockLayoutEncoderFactory *mCustomEncoderFactory;
};

bool LinkValidateProgramGlobalNames(InfoLog &infoLog,
                                    const ProgramExecutable &executable,
                                    const LinkingVariables &linkingVariables);
bool LinkValidateShaderInterfaceMatching(const std::vector<sh::ShaderVariable> &outputVaryings,
                                         const std::vector<sh::ShaderVariable> &inputVaryings,
                                         ShaderType frontShaderType,
                                         ShaderType backShaderType,
                                         int frontShaderVersion,
                                         int backShaderVersion,
                                         bool isSeparable,
                                         InfoLog &infoLog);
bool LinkValidateBuiltInVaryingsInvariant(const std::vector<sh::ShaderVariable> &vertexVaryings,
                                          const std::vector<sh::ShaderVariable> &fragmentVaryings,
                                          int vertexShaderVersion,
                                          InfoLog &infoLog);
bool LinkValidateBuiltInVaryings(const std::vector<sh::ShaderVariable> &inputVaryings,
                                 const std::vector<sh::ShaderVariable> &outputVaryings,
                                 ShaderType inputShaderType,
                                 ShaderType outputShaderType,
                                 int inputShaderVersion,
                                 int outputShaderVersion,
                                 InfoLog &infoLog);
LinkMismatchError LinkValidateProgramVariables(const sh::ShaderVariable &variable1,
                                               const sh::ShaderVariable &variable2,
                                               bool validatePrecision,
                                               bool treatVariable1AsNonArray,
                                               bool treatVariable2AsNonArray,
                                               std::string *mismatchedStructOrBlockMemberName);
void AddProgramVariableParentPrefix(const std::string &parentName,
                                    std::string *mismatchedFieldName);
}  // namespace gl

#endif  // LIBANGLE_UNIFORMLINKER_H_
