//
// Copyright 2010 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.
//

#ifndef LIBANGLE_UNIFORM_H_
#define LIBANGLE_UNIFORM_H_

#include <string>
#include <vector>
#include "common/unsafe_buffers.h"

#include "angle_gl.h"
#include "common/MemoryBuffer.h"
#include "common/debug.h"
#include "common/uniform_type_info_autogen.h"
#include "common/utilities.h"
#include "compiler/translator/blocklayout.h"
#include "libANGLE/angletypes.h"

namespace gl
{
class BinaryInputStream;
class BinaryOutputStream;
struct UniformTypeInfo;
struct UsedUniform;
struct LinkedUniform;

#define ACTIVE_VARIABLE_COMMON_INTERFACES                         \
    void setActive(ShaderType shaderType, bool used, uint32_t id) \
    {                                                             \
        ASSERT(shaderType != ShaderType::InvalidEnum);            \
        pod.activeUseBits.set(shaderType, used);                  \
        pod.ids[shaderType] = id;                                 \
    }                                                             \
    ShaderType getFirstActiveShaderType() const                   \
    {                                                             \
        return pod.activeUseBits.first();                         \
    }                                                             \
    bool isActive(ShaderType shaderType) const                    \
    {                                                             \
        return pod.activeUseBits[shaderType];                     \
    }                                                             \
    const ShaderMap<uint32_t> &getIds() const                     \
    {                                                             \
        return pod.ids;                                           \
    }                                                             \
    uint32_t getId(ShaderType shaderType) const                   \
    {                                                             \
        return pod.ids[shaderType];                               \
    }                                                             \
    ShaderBitSet activeShaders() const                            \
    {                                                             \
        return pod.activeUseBits;                                 \
    }                                                             \
    uint32_t activeShaderCount() const                            \
    {                                                             \
        return static_cast<uint32_t>(pod.activeUseBits.count());  \
    }

struct ActiveVariable
{
    ActiveVariable() { ANGLE_UNSAFE_TODO(memset(&pod, 0, sizeof(pod))); }

    ACTIVE_VARIABLE_COMMON_INTERFACES

    struct PODStruct
    {
        ShaderBitSet activeUseBits;
        // The id of a linked variable in each shader stage.  This id originates from
        // sh::ShaderVariable::id or sh::InterfaceBlock::id
        ShaderMap<uint32_t> ids;
    } pod;
};

inline const UniformTypeInfo &GetUniformTypeInfoFromIndex(UniformTypeIndex index)
{
    ASSERT(index.value >= 0 && index.value < kUniformInfoTable.size());
    return kUniformInfoTable[index.value];
}

// Important: This struct must have basic data types only, so that we can initialize with memcpy. Do
// not put any std::vector or objects with virtual functions in it.
// Helper struct representing a single shader uniform. Most of this structure's data member and
// access functions mirrors ShaderVariable; See ShaderVars.h for more info.
ANGLE_ENABLE_STRUCT_PADDING_WARNINGS
struct LinkedUniform
{
    LinkedUniform() = default;
    LinkedUniform(GLenum typeIn,
                  GLenum precisionIn,
                  const std::vector<unsigned int> &arraySizesIn,
                  const int bindingIn,
                  const int offsetIn,
                  const int locationIn,
                  const int bufferIndexIn,
                  const sh::BlockMemberInfo &blockInfoIn);
    LinkedUniform(const UsedUniform &usedUniform);

    const UniformTypeInfo &getUniformTypeInfo() const
    {
        return GetUniformTypeInfoFromIndex(pod.typeIndex);
    }

    bool isSampler() const { return getUniformTypeInfo().isSampler; }
    bool isImage() const { return getUniformTypeInfo().isImageType; }
    bool isAtomicCounter() const { return IsAtomicCounterType(getType()); }
    bool isInDefaultBlock() const { return pod.bufferIndex == -1; }
    size_t getElementSize() const { return getUniformTypeInfo().externalSize; }
    GLint getElementComponents() const { return GetUniformElementComponents(pod.typeIndex); }

    bool isTexelFetchStaticUse() const { return pod.flagBits.texelFetchStaticUse; }
    bool isFragmentInOut() const { return pod.flagBits.isFragmentInOut; }

    bool isArray() const { return pod.flagBits.isArray; }
    uint16_t getBasicTypeElementCount() const
    {
        ASSERT(pod.flagBits.isArray || pod.arraySize == 1u);
        return pod.arraySize;
    }

    GLenum getType() const { return getUniformTypeInfo().type; }
    uint16_t getOuterArrayOffset() const { return pod.outerArrayOffset; }
    uint16_t getOuterArraySizeProduct() const { return pod.outerArraySizeProduct; }
    uint16_t getBlockOffset() const { return pod.blockOffset; }
    int16_t getBinding() const { return pod.binding; }
    int16_t getOffset() const { return pod.offset; }
    int getBufferIndex() const { return pod.bufferIndex; }
    int getLocation() const { return pod.location; }
    GLenum getImageUnitFormat() const { return pod.imageUnitFormat; }
    bool isFloat16() const { return pod.flagBits.isFloat16; }

    ACTIVE_VARIABLE_COMMON_INTERFACES

    struct PODStruct
    {
        UniformTypeIndex typeIndex;
        uint16_t precision;

        int32_t location;

        // These are from sh::struct BlockMemberInfo struct. See locklayout.h for detail.
        uint16_t blockOffset;
        uint16_t blockArrayStride;

        uint16_t blockMatrixStride;
        uint16_t imageUnitFormat;

        // maxUniformVectorsCount is 4K due to we clamp maxUniformBlockSize to 64KB. All of these
        // variable should be enough to pack into 16 bits to reduce the size of mUniforms.
        static_assert(IMPLEMENTATION_MAX_UNIFORM_BLOCK_SIZE <=
                      std::numeric_limits<uint16_t>::max() + 1);
        int16_t binding;
        int16_t bufferIndex;

        int16_t offset;
        uint16_t arraySize;

        uint16_t outerArraySizeProduct;
        uint16_t outerArrayOffset;

        uint16_t parentArrayIndex;
        union
        {
            struct
            {
                uint8_t isFragmentInOut : 1;
                uint8_t texelFetchStaticUse : 1;
                uint8_t isArray : 1;
                uint8_t blockIsRowMajorMatrix : 1;
                uint8_t isBlock : 1;
                uint8_t isFloat16 : 1;
                uint8_t padding : 2;
            } flagBits;
            uint8_t flagBitsAsUByte;
        };
        ShaderBitSet activeUseBits;

        uint32_t id;
        // The id of a linked variable in each shader stage.  This id originates from
        // sh::ShaderVariable::id or sh::InterfaceBlock::id
        ShaderMap<uint32_t> ids;
    } pod;
};
ANGLE_DISABLE_STRUCT_PADDING_WARNINGS

struct BufferVariable
{
    BufferVariable();
    BufferVariable(GLenum type,
                   GLenum precision,
                   const std::string &name,
                   const std::vector<unsigned int> &arraySizes,
                   const int bufferIndex,
                   int topLevelArraySize,
                   const sh::BlockMemberInfo &blockInfo);
    ~BufferVariable() {}

    bool isArray() const { return pod.isArray; }
    uint32_t getBasicTypeElementCount() const { return pod.basicTypeElementCount; }

    ACTIVE_VARIABLE_COMMON_INTERFACES

    std::string name;
    std::string mappedName;

    ANGLE_ENABLE_STRUCT_PADDING_WARNINGS
    struct PODStruct
    {
        uint16_t type;
        uint16_t precision;

        // 1 byte each
        ShaderBitSet activeUseBits;
        bool isArray;

        int16_t bufferIndex;

        // The id of a linked variable in each shader stage.  This id originates from
        // sh::ShaderVariable::id or sh::InterfaceBlock::id
        ShaderMap<uint32_t> ids;

        sh::BlockMemberInfo blockInfo;

        int32_t topLevelArraySize;
        uint32_t basicTypeElementCount;
    } pod;
    ANGLE_DISABLE_STRUCT_PADDING_WARNINGS
};

// Represents a single atomic counter buffer
struct AtomicCounterBuffer
{
    AtomicCounterBuffer();
    ~AtomicCounterBuffer() {}

    ACTIVE_VARIABLE_COMMON_INTERFACES
    int numActiveVariables() const { return static_cast<int>(memberIndexes.size()); }
    void unionReferencesWith(const LinkedUniform &otherUniform);

    std::vector<unsigned int> memberIndexes;

    ANGLE_ENABLE_STRUCT_PADDING_WARNINGS
    struct PODStruct
    {
        // The id of a linked variable in each shader stage.  This id originates from
        // sh::ShaderVariable::id or sh::InterfaceBlock::id
        ShaderMap<uint32_t> ids;
        // The binding as specified by the shader.
        int inShaderBinding;
        unsigned int dataSize;
        ShaderBitSet activeUseBits;
        uint8_t pads[3];
    } pod;
    ANGLE_DISABLE_STRUCT_PADDING_WARNINGS
};

// Helper struct representing a single shader interface block
struct InterfaceBlock
{
    InterfaceBlock();
    InterfaceBlock(const std::string &nameIn,
                   const std::string &mappedNameIn,
                   bool isArrayIn,
                   bool isReadOnlyIn,
                   unsigned int arrayElementIn,
                   unsigned int firstFieldArraySizeIn,
                   int bindingIn);

    std::string nameWithArrayIndex() const;
    std::string mappedNameWithArrayIndex() const;

    ACTIVE_VARIABLE_COMMON_INTERFACES

    int numActiveVariables() const { return static_cast<int>(memberIndexes.size()); }

    std::string name;
    std::string mappedName;
    std::vector<unsigned int> memberIndexes;

    ANGLE_ENABLE_STRUCT_PADDING_WARNINGS
    struct PODStruct
    {
        uint32_t arrayElement;
        uint32_t firstFieldArraySize;

        ShaderBitSet activeUseBits;
        uint8_t isArray : 1;
        // Only valid for SSBOs, specifies whether it has the readonly qualifier.
        uint8_t isReadOnly : 1;
        uint8_t padings : 6;
        // The binding as specified by the shader (0 if unspecified, per spec)
        int16_t inShaderBinding;

        unsigned int dataSize;
        // The id of a linked variable in each shader stage.  This id originates from
        // sh::ShaderVariable::id or sh::InterfaceBlock::id
        ShaderMap<uint32_t> ids;
    } pod;
    ANGLE_DISABLE_STRUCT_PADDING_WARNINGS
};

#undef ACTIVE_VARIABLE_COMMON_INTERFACES
}  // namespace gl

#endif  // LIBANGLE_UNIFORM_H_
