//
// Copyright 2013 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.
//
// blocklayout.h:
//   Methods and classes related to uniform layout and packing in GLSL and HLSL.
//

#ifndef COMMON_BLOCKLAYOUT_H_
#define COMMON_BLOCKLAYOUT_H_

#include <cstddef>
#include <map>
#include <vector>

#include <GLSLANG/ShaderLang.h>
#include "angle_gl.h"

namespace sh
{
struct ShaderVariable;
struct InterfaceBlock;

struct BlockMemberInfo
{
    constexpr BlockMemberInfo() = default;

    constexpr BlockMemberInfo(int offset, int arrayStride, int matrixStride, bool isRowMajorMatrix)
        : offset(offset),
          arrayStride(arrayStride),
          matrixStride(matrixStride),
          isRowMajorMatrix(isRowMajorMatrix)
    {}

    constexpr BlockMemberInfo(int offset,
                              int arrayStride,
                              int matrixStride,
                              bool isRowMajorMatrix,
                              int topLevelArrayStride)
        : offset(offset),
          arrayStride(arrayStride),
          matrixStride(matrixStride),
          isRowMajorMatrix(isRowMajorMatrix),
          topLevelArrayStride(topLevelArrayStride)
    {}

    // A single integer identifying the offset of an active variable.
    int offset = -1;

    // A single integer identifying the stride between array elements in an active variable.
    int arrayStride = -1;

    // A single integer identifying the stride between columns of a column-major matrix or rows of a
    // row-major matrix.
    int matrixStride = -1;

    // A single integer identifying whether an active variable is a row-major matrix.
    bool isRowMajorMatrix = false;

    // A single integer identifying the number of active array elements of the top-level shader
    // storage block member containing the active variable.
    int topLevelArrayStride = -1;
};

constexpr size_t ComponentAlignment(size_t numComponents)
{
    return (numComponents == 3u ? 4u : numComponents);
}

constexpr BlockMemberInfo kDefaultBlockMemberInfo;

class BlockLayoutEncoder
{
  public:
    BlockLayoutEncoder();
    virtual ~BlockLayoutEncoder() {}

    BlockMemberInfo encodeType(GLenum type,
                               const std::vector<unsigned int> &arraySizes,
                               bool isRowMajorMatrix);

    size_t getCurrentOffset() const { return mCurrentOffset * kBytesPerComponent; }
    size_t getShaderVariableSize(const ShaderVariable &structVar, bool isRowMajor);

    // Called when entering/exiting a structure variable.
    virtual void enterAggregateType(const ShaderVariable &structVar) = 0;
    virtual void exitAggregateType(const ShaderVariable &structVar)  = 0;

    static constexpr size_t kBytesPerComponent           = 4u;
    static constexpr unsigned int kComponentsPerRegister = 4u;

    static size_t GetBlockRegister(const BlockMemberInfo &info);
    static size_t GetBlockRegisterElement(const BlockMemberInfo &info);

  protected:
    void align(size_t baseAlignment);

    virtual void getBlockLayoutInfo(GLenum type,
                                    const std::vector<unsigned int> &arraySizes,
                                    bool isRowMajorMatrix,
                                    int *arrayStrideOut,
                                    int *matrixStrideOut) = 0;
    virtual void advanceOffset(GLenum type,
                               const std::vector<unsigned int> &arraySizes,
                               bool isRowMajorMatrix,
                               int arrayStride,
                               int matrixStride)          = 0;

    size_t mCurrentOffset;
};

// Will return default values for everything.
class DummyBlockEncoder : public BlockLayoutEncoder
{
  public:
    DummyBlockEncoder() = default;

    void enterAggregateType(const ShaderVariable &structVar) override {}
    void exitAggregateType(const ShaderVariable &structVar) override {}

  protected:
    void getBlockLayoutInfo(GLenum type,
                            const std::vector<unsigned int> &arraySizes,
                            bool isRowMajorMatrix,
                            int *arrayStrideOut,
                            int *matrixStrideOut) override;

    void advanceOffset(GLenum type,
                       const std::vector<unsigned int> &arraySizes,
                       bool isRowMajorMatrix,
                       int arrayStride,
                       int matrixStride) override
    {}
};

// Block layout according to the std140 block layout
// See "Standard Uniform Block Layout" in Section 2.11.6 of the OpenGL ES 3.0 specification

class Std140BlockEncoder : public BlockLayoutEncoder
{
  public:
    Std140BlockEncoder();

    void enterAggregateType(const ShaderVariable &structVar) override;
    void exitAggregateType(const ShaderVariable &structVar) override;

  protected:
    void getBlockLayoutInfo(GLenum type,
                            const std::vector<unsigned int> &arraySizes,
                            bool isRowMajorMatrix,
                            int *arrayStrideOut,
                            int *matrixStrideOut) override;
    void advanceOffset(GLenum type,
                       const std::vector<unsigned int> &arraySizes,
                       bool isRowMajorMatrix,
                       int arrayStride,
                       int matrixStride) override;

    virtual size_t getBaseAlignment(const ShaderVariable &variable) const;
    virtual size_t getTypeBaseAlignment(GLenum type, bool isRowMajorMatrix) const;
};

class Std430BlockEncoder : public Std140BlockEncoder
{
  public:
    Std430BlockEncoder();

  protected:
    size_t getBaseAlignment(const ShaderVariable &variable) const override;
    size_t getTypeBaseAlignment(GLenum type, bool isRowMajorMatrix) const override;
};

using BlockLayoutMap = std::map<std::string, BlockMemberInfo>;

void GetInterfaceBlockInfo(const std::vector<ShaderVariable> &fields,
                           const std::string &prefix,
                           BlockLayoutEncoder *encoder,
                           BlockLayoutMap *blockInfoOut);

// Used for laying out the default uniform block on the Vulkan backend.
void GetActiveUniformBlockInfo(const std::vector<ShaderVariable> &uniforms,
                               const std::string &prefix,
                               BlockLayoutEncoder *encoder,
                               BlockLayoutMap *blockInfoOut);

class ShaderVariableVisitor
{
  public:
    virtual ~ShaderVariableVisitor() {}

    virtual void enterStruct(const ShaderVariable &structVar) {}
    virtual void exitStruct(const ShaderVariable &structVar) {}

    virtual void enterStructAccess(const ShaderVariable &structVar, bool isRowMajor) {}
    virtual void exitStructAccess(const ShaderVariable &structVar, bool isRowMajor) {}

    virtual void enterArray(const ShaderVariable &arrayVar) {}
    virtual void exitArray(const ShaderVariable &arrayVar) {}

    virtual void enterArrayElement(const ShaderVariable &arrayVar, unsigned int arrayElement) {}
    virtual void exitArrayElement(const ShaderVariable &arrayVar, unsigned int arrayElement) {}

    virtual void visitSampler(const sh::ShaderVariable &sampler) {}

    virtual void visitVariable(const ShaderVariable &variable, bool isRowMajor) = 0;

  protected:
    ShaderVariableVisitor() {}
};

class VariableNameVisitor : public ShaderVariableVisitor
{
  public:
    VariableNameVisitor(const std::string &namePrefix, const std::string &mappedNamePrefix);
    ~VariableNameVisitor() override;

    void enterStruct(const ShaderVariable &structVar) override;
    void exitStruct(const ShaderVariable &structVar) override;
    void enterStructAccess(const ShaderVariable &structVar, bool isRowMajor) override;
    void exitStructAccess(const ShaderVariable &structVar, bool isRowMajor) override;
    void enterArray(const ShaderVariable &arrayVar) override;
    void exitArray(const ShaderVariable &arrayVar) override;
    void enterArrayElement(const ShaderVariable &arrayVar, unsigned int arrayElement) override;
    void exitArrayElement(const ShaderVariable &arrayVar, unsigned int arrayElement) override;

  protected:
    virtual void visitNamedSampler(const sh::ShaderVariable &sampler,
                                   const std::string &name,
                                   const std::string &mappedName,
                                   const std::vector<unsigned int> &arraySizes)
    {}
    virtual void visitNamedVariable(const ShaderVariable &variable,
                                    bool isRowMajor,
                                    const std::string &name,
                                    const std::string &mappedName,
                                    const std::vector<unsigned int> &arraySizes) = 0;

    std::string collapseNameStack() const;
    std::string collapseMappedNameStack() const;

  private:
    void visitSampler(const sh::ShaderVariable &sampler) final;
    void visitVariable(const ShaderVariable &variable, bool isRowMajor) final;

    std::vector<std::string> mNameStack;
    std::vector<std::string> mMappedNameStack;
    std::vector<unsigned int> mArraySizeStack;
};

class BlockEncoderVisitor : public VariableNameVisitor
{
  public:
    BlockEncoderVisitor(const std::string &namePrefix,
                        const std::string &mappedNamePrefix,
                        BlockLayoutEncoder *encoder);
    ~BlockEncoderVisitor() override;

    void enterStructAccess(const ShaderVariable &structVar, bool isRowMajor) override;
    void exitStructAccess(const ShaderVariable &structVar, bool isRowMajor) override;
    void enterArrayElement(const ShaderVariable &arrayVar, unsigned int arrayElement) override;
    void exitArrayElement(const ShaderVariable &arrayVar, unsigned int arrayElement) override;

    void visitNamedVariable(const ShaderVariable &variable,
                            bool isRowMajor,
                            const std::string &name,
                            const std::string &mappedName,
                            const std::vector<unsigned int> &arraySizes) override;

    virtual void encodeVariable(const ShaderVariable &variable,
                                const BlockMemberInfo &variableInfo,
                                const std::string &name,
                                const std::string &mappedName)
    {}

  protected:
    int mTopLevelArraySize           = 1;
    int mTopLevelArrayStride         = 0;
    bool mIsTopLevelArrayStrideReady = true;
    bool mSkipEnabled                = false;

  private:
    BlockLayoutEncoder *mEncoder;
    unsigned int mStructStackSize = 0;
};

void TraverseShaderVariable(const ShaderVariable &variable,
                            bool isRowMajorLayout,
                            ShaderVariableVisitor *visitor);

template <typename T>
void TraverseShaderVariables(const std::vector<T> &vars,
                             bool isRowMajorLayout,
                             ShaderVariableVisitor *visitor)
{
    for (const T &var : vars)
    {
        TraverseShaderVariable(var, isRowMajorLayout, visitor);
    }
}

template <typename T>
void TraverseActiveShaderVariables(const std::vector<T> &vars,
                                   bool isRowMajorLayout,
                                   ShaderVariableVisitor *visitor)
{
    for (const T &var : vars)
    {
        if (var.active)
        {
            TraverseShaderVariable(var, isRowMajorLayout, visitor);
        }
    }
}
}  // namespace sh

#endif  // COMMON_BLOCKLAYOUT_H_
