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

// angletypes.h : Defines a variety of structures and enum types that are used throughout libGLESv2

#ifndef LIBANGLE_ANGLETYPES_H_
#define LIBANGLE_ANGLETYPES_H_

#include "common/Color.h"
#include "common/FixedVector.h"
#include "common/PackedEnums.h"
#include "common/bitset_utils.h"
#include "common/vector_utils.h"
#include "libANGLE/Constants.h"
#include "libANGLE/Error.h"
#include "libANGLE/RefCountObject.h"

#include <inttypes.h>
#include <stdint.h>

#include <bitset>
#include <map>
#include <memory>
#include <unordered_map>

namespace gl
{
class Buffer;
class Texture;

enum class Command
{
    Blit,
    Clear,
    CopyImage,
    Dispatch,
    Draw,
    GenerateMipmap,
    Invalidate,
    ReadPixels,
    TexImage,
    Other
};

enum class InitState
{
    MayNeedInit,
    Initialized,
};

template <typename T>
struct RectangleImpl
{
    RectangleImpl() : x(T(0)), y(T(0)), width(T(0)), height(T(0)) {}
    constexpr RectangleImpl(T x_in, T y_in, T width_in, T height_in)
        : x(x_in), y(y_in), width(width_in), height(height_in)
    {}
    explicit constexpr RectangleImpl(const T corners[4])
        : x(corners[0]),
          y(corners[1]),
          width(corners[2] - corners[0]),
          height(corners[3] - corners[1])
    {}
    template <typename S>
    explicit constexpr RectangleImpl(const RectangleImpl<S> rect)
        : x(rect.x), y(rect.y), width(rect.width), height(rect.height)
    {}

    T x0() const { return x; }
    T y0() const { return y; }
    T x1() const { return x + width; }
    T y1() const { return y + height; }

    bool isReversedX() const { return width < T(0); }
    bool isReversedY() const { return height < T(0); }

    // Returns a rectangle with the same area but flipped in X, Y, neither or both.
    RectangleImpl<T> flip(bool flipX, bool flipY) const
    {
        RectangleImpl flipped = *this;
        if (flipX)
        {
            flipped.x     = flipped.x + flipped.width;
            flipped.width = -flipped.width;
        }
        if (flipY)
        {
            flipped.y      = flipped.y + flipped.height;
            flipped.height = -flipped.height;
        }
        return flipped;
    }

    // Returns a rectangle with the same area but with height and width guaranteed to be positive.
    RectangleImpl<T> removeReversal() const { return flip(isReversedX(), isReversedY()); }

    bool encloses(const RectangleImpl<T> &inside) const
    {
        return x0() <= inside.x0() && y0() <= inside.y0() && x1() >= inside.x1() &&
               y1() >= inside.y1();
    }

    bool empty() const;

    T x;
    T y;
    T width;
    T height;
};

template <typename T>
bool operator==(const RectangleImpl<T> &a, const RectangleImpl<T> &b);
template <typename T>
bool operator!=(const RectangleImpl<T> &a, const RectangleImpl<T> &b);

using Rectangle = RectangleImpl<int>;

enum class ClipSpaceOrigin
{
    LowerLeft = 0,
    UpperLeft = 1
};

// Calculate the intersection of two rectangles.  Returns false if the intersection is empty.
ANGLE_NO_DISCARD bool ClipRectangle(const Rectangle &source,
                                    const Rectangle &clip,
                                    Rectangle *intersection);
// Calculate the smallest rectangle that covers both rectangles.  This rectangle may cover areas
// not covered by the two rectangles, for example in this situation:
//
//   +--+        +----+
//   | ++-+  ->  |    |
//   +-++ |      |    |
//     +--+      +----+
//
void GetEnclosingRectangle(const Rectangle &rect1, const Rectangle &rect2, Rectangle *rectUnion);
// Extend the source rectangle to cover parts (or all of) the second rectangle, in such a way that
// no area is covered that isn't covered by both rectangles.  For example:
//
//             +--+        +--+
//  source --> |  |        |  |
//            ++--+-+  ->  |  |
//            |+--+ |      |  |
//            +-----+      +--+
//
void ExtendRectangle(const Rectangle &source, const Rectangle &extend, Rectangle *extended);

struct Offset
{
    constexpr Offset() : x(0), y(0), z(0) {}
    constexpr Offset(int x_in, int y_in, int z_in) : x(x_in), y(y_in), z(z_in) {}

    int x;
    int y;
    int z;
};

constexpr Offset kOffsetZero(0, 0, 0);

bool operator==(const Offset &a, const Offset &b);
bool operator!=(const Offset &a, const Offset &b);

struct Extents
{
    Extents() : width(0), height(0), depth(0) {}
    Extents(int width_, int height_, int depth_) : width(width_), height(height_), depth(depth_) {}

    Extents(const Extents &other)            = default;
    Extents &operator=(const Extents &other) = default;

    bool empty() const { return (width * height * depth) == 0; }

    int width;
    int height;
    int depth;
};

bool operator==(const Extents &lhs, const Extents &rhs);
bool operator!=(const Extents &lhs, const Extents &rhs);

struct Box
{
    Box() : x(0), y(0), z(0), width(0), height(0), depth(0) {}
    Box(int x_in, int y_in, int z_in, int width_in, int height_in, int depth_in)
        : x(x_in), y(y_in), z(z_in), width(width_in), height(height_in), depth(depth_in)
    {}
    template <typename O, typename E>
    Box(const O &offset, const E &size)
        : x(offset.x),
          y(offset.y),
          z(offset.z),
          width(size.width),
          height(size.height),
          depth(size.depth)
    {}
    bool operator==(const Box &other) const;
    bool operator!=(const Box &other) const;
    Rectangle toRect() const;

    // Whether the Box has offset 0 and the same extents as argument.
    bool coversSameExtent(const Extents &size) const;

    int x;
    int y;
    int z;
    int width;
    int height;
    int depth;
};

struct RasterizerState final
{
    // This will zero-initialize the struct, including padding.
    RasterizerState();
    RasterizerState(const RasterizerState &other);

    bool cullFace;
    CullFaceMode cullMode;
    GLenum frontFace;

    bool polygonOffsetFill;
    GLfloat polygonOffsetFactor;
    GLfloat polygonOffsetUnits;

    // pointDrawMode/multiSample are only used in the D3D back-end right now.
    bool pointDrawMode;
    bool multiSample;

    bool rasterizerDiscard;

    bool dither;
};

bool operator==(const RasterizerState &a, const RasterizerState &b);
bool operator!=(const RasterizerState &a, const RasterizerState &b);

struct BlendState final
{
    // This will zero-initialize the struct, including padding.
    BlendState();
    BlendState(const BlendState &other);

    bool blend;
    GLenum sourceBlendRGB;
    GLenum destBlendRGB;
    GLenum sourceBlendAlpha;
    GLenum destBlendAlpha;
    GLenum blendEquationRGB;
    GLenum blendEquationAlpha;

    bool colorMaskRed;
    bool colorMaskGreen;
    bool colorMaskBlue;
    bool colorMaskAlpha;
};

bool operator==(const BlendState &a, const BlendState &b);
bool operator!=(const BlendState &a, const BlendState &b);

struct DepthStencilState final
{
    // This will zero-initialize the struct, including padding.
    DepthStencilState();
    DepthStencilState(const DepthStencilState &other);

    bool isDepthMaskedOut() const;
    bool isStencilMaskedOut() const;
    bool isStencilNoOp() const;
    bool isStencilBackNoOp() const;

    bool depthTest;
    GLenum depthFunc;
    bool depthMask;

    bool stencilTest;
    GLenum stencilFunc;
    GLuint stencilMask;
    GLenum stencilFail;
    GLenum stencilPassDepthFail;
    GLenum stencilPassDepthPass;
    GLuint stencilWritemask;
    GLenum stencilBackFunc;
    GLuint stencilBackMask;
    GLenum stencilBackFail;
    GLenum stencilBackPassDepthFail;
    GLenum stencilBackPassDepthPass;
    GLuint stencilBackWritemask;
};

bool operator==(const DepthStencilState &a, const DepthStencilState &b);
bool operator!=(const DepthStencilState &a, const DepthStencilState &b);

// Packs a sampler state for completeness checks:
// * minFilter: 5 values (3 bits)
// * magFilter: 2 values (1 bit)
// * wrapS:     3 values (2 bits)
// * wrapT:     3 values (2 bits)
// * compareMode: 1 bit (for == GL_NONE).
// This makes a total of 9 bits. We can pack this easily into 32 bits:
// * minFilter: 8 bits
// * magFilter: 8 bits
// * wrapS:     8 bits
// * wrapT:     4 bits
// * compareMode: 4 bits

struct PackedSamplerCompleteness
{
    uint8_t minFilter;
    uint8_t magFilter;
    uint8_t wrapS;
    uint8_t wrapTCompareMode;
};

static_assert(sizeof(PackedSamplerCompleteness) == sizeof(uint32_t), "Unexpected size");

// State from Table 6.10 (state per sampler object)
class SamplerState final
{
  public:
    // This will zero-initialize the struct, including padding.
    SamplerState();
    SamplerState(const SamplerState &other);

    SamplerState &operator=(const SamplerState &other);

    static SamplerState CreateDefaultForTarget(TextureType type);

    GLenum getMinFilter() const { return mMinFilter; }

    bool setMinFilter(GLenum minFilter);

    GLenum getMagFilter() const { return mMagFilter; }

    bool setMagFilter(GLenum magFilter);

    GLenum getWrapS() const { return mWrapS; }

    bool setWrapS(GLenum wrapS);

    GLenum getWrapT() const { return mWrapT; }

    bool setWrapT(GLenum wrapT);

    GLenum getWrapR() const { return mWrapR; }

    bool setWrapR(GLenum wrapR);

    float getMaxAnisotropy() const { return mMaxAnisotropy; }

    bool setMaxAnisotropy(float maxAnisotropy);

    GLfloat getMinLod() const { return mMinLod; }

    bool setMinLod(GLfloat minLod);

    GLfloat getMaxLod() const { return mMaxLod; }

    bool setMaxLod(GLfloat maxLod);

    GLenum getCompareMode() const { return mCompareMode; }

    bool setCompareMode(GLenum compareMode);

    GLenum getCompareFunc() const { return mCompareFunc; }

    bool setCompareFunc(GLenum compareFunc);

    GLenum getSRGBDecode() const { return mSRGBDecode; }

    bool setSRGBDecode(GLenum sRGBDecode);

    bool setBorderColor(const ColorGeneric &color);

    const ColorGeneric &getBorderColor() const { return mBorderColor; }

    bool sameCompleteness(const SamplerState &samplerState) const
    {
        return mCompleteness.packed == samplerState.mCompleteness.packed;
    }

  private:
    void updateWrapTCompareMode();

    GLenum mMinFilter;
    GLenum mMagFilter;

    GLenum mWrapS;
    GLenum mWrapT;
    GLenum mWrapR;

    // From EXT_texture_filter_anisotropic
    float mMaxAnisotropy;

    GLfloat mMinLod;
    GLfloat mMaxLod;

    GLenum mCompareMode;
    GLenum mCompareFunc;

    GLenum mSRGBDecode;

    ColorGeneric mBorderColor;

    union Completeness
    {
        uint32_t packed;
        PackedSamplerCompleteness typed;
    };

    Completeness mCompleteness;
};

bool operator==(const SamplerState &a, const SamplerState &b);
bool operator!=(const SamplerState &a, const SamplerState &b);

struct DrawArraysIndirectCommand
{
    GLuint count;
    GLuint instanceCount;
    GLuint first;
    GLuint baseInstance;
};
static_assert(sizeof(DrawArraysIndirectCommand) == 16,
              "Unexpected size of DrawArraysIndirectCommand");

struct DrawElementsIndirectCommand
{
    GLuint count;
    GLuint primCount;
    GLuint firstIndex;
    GLint baseVertex;
    GLuint baseInstance;
};
static_assert(sizeof(DrawElementsIndirectCommand) == 20,
              "Unexpected size of DrawElementsIndirectCommand");

struct ImageUnit
{
    ImageUnit();
    ImageUnit(const ImageUnit &other);
    ~ImageUnit();

    BindingPointer<Texture> texture;
    GLint level;
    GLboolean layered;
    GLint layer;
    GLenum access;
    GLenum format;
};

using ImageUnitTextureTypeMap = std::map<unsigned int, gl::TextureType>;

struct PixelStoreStateBase
{
    GLint alignment   = 4;
    GLint rowLength   = 0;
    GLint skipRows    = 0;
    GLint skipPixels  = 0;
    GLint imageHeight = 0;
    GLint skipImages  = 0;
};

struct PixelUnpackState : PixelStoreStateBase
{};

struct PixelPackState : PixelStoreStateBase
{
    bool reverseRowOrder = false;
};

// Used in Program and VertexArray.
using AttributesMask = angle::BitSet<MAX_VERTEX_ATTRIBS>;

// Used in Program
using UniformBlockBindingMask = angle::BitSet<IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS>;

// Used in Framebuffer / Program
using DrawBufferMask = angle::BitSet8<IMPLEMENTATION_MAX_DRAW_BUFFERS>;

class BlendStateExt final
{
    static_assert(IMPLEMENTATION_MAX_DRAW_BUFFERS == 8, "Only up to 8 draw buffers supported.");

  public:
    template <typename ElementType, size_t ElementCount>
    struct StorageType final
    {
        static_assert(ElementCount <= 256, "ElementCount cannot exceed 256.");

#if defined(ANGLE_IS_64_BIT_CPU)
        // Always use uint64_t on 64-bit systems
        static constexpr size_t kBits = 8;
#else
        static constexpr size_t kBits = ElementCount > 16 ? 8 : 4;
#endif

        using Type = typename std::conditional<kBits == 8, uint64_t, uint32_t>::type;

        static constexpr Type kMaxValueMask = (kBits == 8) ? 0xFF : 0xF;

        static constexpr Type GetMask(const size_t drawBuffers)
        {
            ASSERT(drawBuffers > 0);
            ASSERT(drawBuffers <= IMPLEMENTATION_MAX_DRAW_BUFFERS);
            return static_cast<Type>(0xFFFFFFFFFFFFFFFFull >> (64 - drawBuffers * kBits));
        }

        // A multiplier that is used to replicate 4- or 8-bit value 8 times.
        static constexpr Type kReplicator = (kBits == 8) ? 0x0101010101010101ull : 0x11111111;

        // Extract packed `Bits`-bit value of index `index`. `values` variable contains up to 8
        // packed values.
        static constexpr ElementType GetValueIndexed(const size_t index, const Type values)
        {
            ASSERT(index < IMPLEMENTATION_MAX_DRAW_BUFFERS);

            return static_cast<ElementType>((values >> (index * kBits)) & kMaxValueMask);
        }

        // Replicate `Bits`-bit value 8 times and mask the result.
        static constexpr Type GetReplicatedValue(const ElementType value, const Type mask)
        {
            ASSERT(static_cast<size_t>(value) <= kMaxValueMask);
            return (static_cast<size_t>(value) * kReplicator) & mask;
        }

        // Replace `Bits`-bit value of index `index` in `target` with `value`.
        static constexpr void SetValueIndexed(const size_t index,
                                              const ElementType value,
                                              Type *target)
        {
            ASSERT(static_cast<size_t>(value) <= kMaxValueMask);
            ASSERT(index < IMPLEMENTATION_MAX_DRAW_BUFFERS);

            // Bitmask with set bits that contain the value of index `index`.
            const Type selector = kMaxValueMask << (index * kBits);

            // Shift the new `value` to its position in the packed value.
            const Type builtValue = static_cast<Type>(value) << (index * kBits);

            // Mark differing bits of `target` and `builtValue`, then flip the bits on those
            // positions in `target`.
            // Taken from https://graphics.stanford.edu/~seander/bithacks.html#MaskedMerge
            *target = *target ^ ((*target ^ builtValue) & selector);
        }

        // Compare two packed sets of eight 4-bit values and return an 8-bit diff mask.
        static constexpr DrawBufferMask GetDiffMask(const uint32_t packedValue1,
                                                    const uint32_t packedValue2)
        {
            uint32_t diff = packedValue1 ^ packedValue2;

            // For each 4-bit value that is different between inputs, set the msb to 1 and other
            // bits to 0.
            diff = (diff | ((diff & 0x77777777) + 0x77777777)) & 0x88888888;

            // By this point, `diff` looks like a...b...c...d...e...f...g...h... (dots mean zeros).
            // To get DrawBufferMask, we need to compress this 32-bit value to 8 bits, i.e. abcdefgh

            // Multiplying the lower half of `diff` by 0x249 (0x200 + 0x40 + 0x8 + 0x1) produces:
            // ................e...f...g...h... +
            // .............e...f...g...h...... +
            // ..........e...f...g...h......... +
            // .......e...f...g...h............
            // ________________________________ =
            // .......e..ef.efgefghfgh.gh..h...
            //                 ^^^^
            // Similar operation is applied to the upper word.
            // This calculation could be replaced with a single PEXT instruction from BMI2 set.
            diff = ((((diff & 0xFFFF0000) * 0x249) >> 24) & 0xF0) | (((diff * 0x249) >> 12) & 0xF);

            return DrawBufferMask(static_cast<uint8_t>(diff));
        }

        // Compare two packed sets of eight 8-bit values and return an 8-bit diff mask.
        static constexpr DrawBufferMask GetDiffMask(const uint64_t packedValue1,
                                                    const uint64_t packedValue2)
        {
            uint64_t diff = packedValue1 ^ packedValue2;

            // For each 8-bit value that is different between inputs, set the msb to 1 and other
            // bits to 0.
            diff = (diff | ((diff & 0x7F7F7F7F7F7F7F7F) + 0x7F7F7F7F7F7F7F7F)) & 0x8080808080808080;

            // By this point, `diff` looks like (dots mean zeros):
            // a.......b.......c.......d.......e.......f.......g.......h.......
            // To get DrawBufferMask, we need to compress this 64-bit value to 8 bits, i.e. abcdefgh

            // Multiplying `diff` by 0x0002040810204081 produces:
            // a.......b.......c.......d.......e.......f.......g.......h....... +
            // .b.......c.......d.......e.......f.......g.......h.............. +
            // ..c.......d.......e.......f.......g.......h..................... +
            // ...d.......e.......f.......g.......h............................ +
            // ....e.......f.......g.......h................................... +
            // .....f.......g.......h.......................................... +
            // ......g.......h................................................. +
            // .......h........................................................
            // ________________________________________________________________ =
            // abcdefghbcdefgh.cdefgh..defgh...efgh....fgh.....gh......h.......
            // ^^^^^^^^
            // This operation could be replaced with a single PEXT instruction from BMI2 set.
            diff = 0x0002040810204081 * diff >> 56;

            return DrawBufferMask(static_cast<uint8_t>(diff));
        }
    };

    using FactorStorage    = StorageType<BlendFactorType, angle::EnumSize<BlendFactorType>()>;
    using EquationStorage  = StorageType<BlendEquationType, angle::EnumSize<BlendEquationType>()>;
    using ColorMaskStorage = StorageType<uint8_t, 16>;
    static_assert(std::is_same<FactorStorage::Type, uint64_t>::value &&
                      std::is_same<EquationStorage::Type, uint64_t>::value,
                  "Factor and Equation storage must be 64-bit.");

    BlendStateExt(const size_t drawBuffers = 1);

    BlendStateExt(const BlendStateExt &other);
    BlendStateExt &operator=(const BlendStateExt &other);

    ///////// Blending Toggle /////////

    void setEnabled(const bool enabled);
    void setEnabledIndexed(const size_t index, const bool enabled);

    ///////// Color Write Mask /////////

    static constexpr size_t PackColorMask(const bool red,
                                          const bool green,
                                          const bool blue,
                                          const bool alpha)
    {
        return (red ? 1 : 0) | (green ? 2 : 0) | (blue ? 4 : 0) | (alpha ? 8 : 0);
    }

    static constexpr void UnpackColorMask(const size_t value,
                                          bool *red,
                                          bool *green,
                                          bool *blue,
                                          bool *alpha)
    {
        *red   = static_cast<bool>(value & 1);
        *green = static_cast<bool>(value & 2);
        *blue  = static_cast<bool>(value & 4);
        *alpha = static_cast<bool>(value & 8);
    }

    ColorMaskStorage::Type expandColorMaskValue(const bool red,
                                                const bool green,
                                                const bool blue,
                                                const bool alpha) const;
    ColorMaskStorage::Type expandColorMaskIndexed(const size_t index) const;
    void setColorMask(const bool red, const bool green, const bool blue, const bool alpha);
    void setColorMaskIndexed(const size_t index, const uint8_t value);
    void setColorMaskIndexed(const size_t index,
                             const bool red,
                             const bool green,
                             const bool blue,
                             const bool alpha);
    uint8_t getColorMaskIndexed(const size_t index) const;
    void getColorMaskIndexed(const size_t index,
                             bool *red,
                             bool *green,
                             bool *blue,
                             bool *alpha) const;
    DrawBufferMask compareColorMask(ColorMaskStorage::Type other) const;

    ///////// Blend Equation /////////

    EquationStorage::Type expandEquationValue(const GLenum mode) const;
    EquationStorage::Type expandEquationValue(const gl::BlendEquationType equation) const;
    EquationStorage::Type expandEquationColorIndexed(const size_t index) const;
    EquationStorage::Type expandEquationAlphaIndexed(const size_t index) const;
    void setEquations(const GLenum modeColor, const GLenum modeAlpha);
    void setEquationsIndexed(const size_t index, const GLenum modeColor, const GLenum modeAlpha);
    void setEquationsIndexed(const size_t index,
                             const size_t otherIndex,
                             const BlendStateExt &other);
    GLenum getEquationColorIndexed(size_t index) const;
    GLenum getEquationAlphaIndexed(size_t index) const;
    DrawBufferMask compareEquations(const EquationStorage::Type color,
                                    const EquationStorage::Type alpha) const;
    DrawBufferMask compareEquations(const BlendStateExt &other) const
    {
        return compareEquations(other.mEquationColor, other.mEquationAlpha);
    }

    ///////// Blend Factors /////////

    FactorStorage::Type expandFactorValue(const GLenum func) const;
    FactorStorage::Type expandSrcColorIndexed(const size_t index) const;
    FactorStorage::Type expandDstColorIndexed(const size_t index) const;
    FactorStorage::Type expandSrcAlphaIndexed(const size_t index) const;
    FactorStorage::Type expandDstAlphaIndexed(const size_t index) const;
    void setFactors(const GLenum srcColor,
                    const GLenum dstColor,
                    const GLenum srcAlpha,
                    const GLenum dstAlpha);
    void setFactorsIndexed(const size_t index,
                           const GLenum srcColor,
                           const GLenum dstColor,
                           const GLenum srcAlpha,
                           const GLenum dstAlpha);
    void setFactorsIndexed(const size_t index, const size_t otherIndex, const BlendStateExt &other);
    GLenum getSrcColorIndexed(size_t index) const;
    GLenum getDstColorIndexed(size_t index) const;
    GLenum getSrcAlphaIndexed(size_t index) const;
    GLenum getDstAlphaIndexed(size_t index) const;
    DrawBufferMask compareFactors(const FactorStorage::Type srcColor,
                                  const FactorStorage::Type dstColor,
                                  const FactorStorage::Type srcAlpha,
                                  const FactorStorage::Type dstAlpha) const;
    DrawBufferMask compareFactors(const BlendStateExt &other) const
    {
        return compareFactors(other.mSrcColor, other.mDstColor, other.mSrcAlpha, other.mDstAlpha);
    }

    constexpr FactorStorage::Type getSrcColorBits() const { return mSrcColor; }
    constexpr FactorStorage::Type getSrcAlphaBits() const { return mSrcAlpha; }
    constexpr FactorStorage::Type getDstColorBits() const { return mDstColor; }
    constexpr FactorStorage::Type getDstAlphaBits() const { return mDstAlpha; }

    constexpr EquationStorage::Type getEquationColorBits() const { return mEquationColor; }
    constexpr EquationStorage::Type getEquationAlphaBits() const { return mEquationAlpha; }

    constexpr ColorMaskStorage::Type getAllColorMaskBits() const { return mAllColorMask; }
    constexpr ColorMaskStorage::Type getColorMaskBits() const { return mColorMask; }

    constexpr DrawBufferMask getAllEnabledMask() const { return mAllEnabledMask; }
    constexpr DrawBufferMask getEnabledMask() const { return mEnabledMask; }

    constexpr DrawBufferMask getUsesAdvancedBlendEquationMask() const
    {
        return mUsesAdvancedBlendEquationMask;
    }

    constexpr uint8_t getDrawBufferCount() const { return mDrawBufferCount; }

    constexpr void setSrcColorBits(const FactorStorage::Type srcColor) { mSrcColor = srcColor; }
    constexpr void setSrcAlphaBits(const FactorStorage::Type srcAlpha) { mSrcAlpha = srcAlpha; }
    constexpr void setDstColorBits(const FactorStorage::Type dstColor) { mDstColor = dstColor; }
    constexpr void setDstAlphaBits(const FactorStorage::Type dstAlpha) { mDstAlpha = dstAlpha; }

    constexpr void setEquationColorBits(const EquationStorage::Type equationColor)
    {
        mEquationColor = equationColor;
    }
    constexpr void setEquationAlphaBits(const EquationStorage::Type equationAlpha)
    {
        mEquationAlpha = equationAlpha;
    }

    constexpr void setColorMaskBits(const ColorMaskStorage::Type colorMask)
    {
        mColorMask = colorMask;
    }

    constexpr void setEnabledMask(const DrawBufferMask enabledMask) { mEnabledMask = enabledMask; }

    ///////// Data Members /////////
  private:
    uint64_t mParameterMask;

    FactorStorage::Type mSrcColor;
    FactorStorage::Type mDstColor;
    FactorStorage::Type mSrcAlpha;
    FactorStorage::Type mDstAlpha;

    EquationStorage::Type mEquationColor;
    EquationStorage::Type mEquationAlpha;

    ColorMaskStorage::Type mAllColorMask;
    ColorMaskStorage::Type mColorMask;

    DrawBufferMask mAllEnabledMask;
    DrawBufferMask mEnabledMask;

    // Cache of whether the blend equation for each index is from KHR_blend_equation_advanced.
    DrawBufferMask mUsesAdvancedBlendEquationMask;

    uint8_t mDrawBufferCount;

    ANGLE_MAYBE_UNUSED uint32_t kUnused = 0;
};

static_assert(sizeof(BlendStateExt) == sizeof(uint64_t) +
                                           (sizeof(BlendStateExt::FactorStorage::Type) * 4 +
                                            sizeof(BlendStateExt::EquationStorage::Type) * 2 +
                                            sizeof(BlendStateExt::ColorMaskStorage::Type) * 2 +
                                            sizeof(DrawBufferMask) * 3 + sizeof(uint8_t)) +
                                           sizeof(uint32_t),
              "The BlendStateExt class must not contain gaps.");

// Used in StateCache
using StorageBuffersMask = angle::BitSet<IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS>;

template <typename T>
using SampleMaskArray = std::array<T, IMPLEMENTATION_MAX_SAMPLE_MASK_WORDS>;

template <typename T>
using TexLevelArray = std::array<T, IMPLEMENTATION_MAX_TEXTURE_LEVELS>;

using TexLevelMask = angle::BitSet<IMPLEMENTATION_MAX_TEXTURE_LEVELS>;

enum class ComponentType
{
    Float       = 0,
    Int         = 1,
    UnsignedInt = 2,
    NoType      = 3,
    EnumCount   = 4,
    InvalidEnum = 4,
};

constexpr ComponentType GLenumToComponentType(GLenum componentType)
{
    switch (componentType)
    {
        case GL_FLOAT:
            return ComponentType::Float;
        case GL_INT:
            return ComponentType::Int;
        case GL_UNSIGNED_INT:
            return ComponentType::UnsignedInt;
        case GL_NONE:
            return ComponentType::NoType;
        default:
            return ComponentType::InvalidEnum;
    }
}

constexpr angle::PackedEnumMap<ComponentType, uint32_t> kComponentMasks = {{
    {ComponentType::Float, 0x10001},
    {ComponentType::Int, 0x00001},
    {ComponentType::UnsignedInt, 0x10000},
}};

constexpr size_t kMaxComponentTypeMaskIndex = 16;
using ComponentTypeMask                     = angle::BitSet<kMaxComponentTypeMaskIndex * 2>;

ANGLE_INLINE void SetComponentTypeMask(ComponentType type, size_t index, ComponentTypeMask *mask)
{
    ASSERT(index <= kMaxComponentTypeMaskIndex);
    *mask &= ~(0x10001 << index);
    *mask |= kComponentMasks[type] << index;
}

ANGLE_INLINE ComponentType GetComponentTypeMask(const ComponentTypeMask &mask, size_t index)
{
    ASSERT(index <= kMaxComponentTypeMaskIndex);
    uint32_t mask_bits = static_cast<uint32_t>((mask.to_ulong() >> index) & 0x10001);
    switch (mask_bits)
    {
        case 0x10001:
            return ComponentType::Float;
        case 0x00001:
            return ComponentType::Int;
        case 0x10000:
            return ComponentType::UnsignedInt;
        default:
            return ComponentType::InvalidEnum;
    }
}

bool ValidateComponentTypeMasks(unsigned long outputTypes,
                                unsigned long inputTypes,
                                unsigned long outputMask,
                                unsigned long inputMask);

enum class RenderToTextureImageIndex
{
    // The default image of the texture, where data is expected to be.
    Default = 0,

    // Intermediate multisampled images for EXT_multisampled_render_to_texture.
    // These values must match log2(SampleCount).
    IntermediateImage2xMultisampled  = 1,
    IntermediateImage4xMultisampled  = 2,
    IntermediateImage8xMultisampled  = 3,
    IntermediateImage16xMultisampled = 4,

    // We currently only support up to 16xMSAA in backends that use this enum.
    InvalidEnum = 5,
    EnumCount   = 5,
};

template <typename T>
using RenderToTextureImageMap = angle::PackedEnumMap<RenderToTextureImageIndex, T>;

struct ContextID
{
    uint32_t value;
};

inline bool operator==(ContextID lhs, ContextID rhs)
{
    return lhs.value == rhs.value;
}

inline bool operator!=(ContextID lhs, ContextID rhs)
{
    return lhs.value != rhs.value;
}

inline bool operator<(ContextID lhs, ContextID rhs)
{
    return lhs.value < rhs.value;
}

constexpr size_t kCubeFaceCount = 6;

template <typename T>
using TextureTypeMap = angle::PackedEnumMap<TextureType, T>;
using TextureMap     = TextureTypeMap<BindingPointer<Texture>>;

// ShaderVector can contain one item per shader.  It differs from ShaderMap in that the values are
// not indexed by ShaderType.
template <typename T>
using ShaderVector = angle::FixedVector<T, static_cast<size_t>(ShaderType::EnumCount)>;

template <typename T>
using AttachmentArray = std::array<T, IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS>;

template <typename T>
using AttachmentVector = angle::FixedVector<T, IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS>;

using AttachmentsMask = angle::BitSet<IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS>;

template <typename T>
using DrawBuffersArray = std::array<T, IMPLEMENTATION_MAX_DRAW_BUFFERS>;

template <typename T>
using DrawBuffersVector = angle::FixedVector<T, IMPLEMENTATION_MAX_DRAW_BUFFERS>;

template <typename T>
using AttribArray = std::array<T, MAX_VERTEX_ATTRIBS>;

using ActiveTextureMask = angle::BitSet<IMPLEMENTATION_MAX_ACTIVE_TEXTURES>;

template <typename T>
using ActiveTextureArray = std::array<T, IMPLEMENTATION_MAX_ACTIVE_TEXTURES>;

using ActiveTextureTypeArray = ActiveTextureArray<TextureType>;

template <typename T>
using UniformBuffersArray = std::array<T, IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS>;
template <typename T>
using StorageBuffersArray = std::array<T, IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS>;
template <typename T>
using AtomicCounterBuffersArray = std::array<T, IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS>;
using AtomicCounterBufferMask   = angle::BitSet<IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS>;
template <typename T>
using ImagesArray = std::array<T, IMPLEMENTATION_MAX_IMAGE_UNITS>;

using ImageUnitMask = angle::BitSet<IMPLEMENTATION_MAX_IMAGE_UNITS>;

using SupportedSampleSet = std::set<GLuint>;

template <typename T>
using TransformFeedbackBuffersArray =
    std::array<T, gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS>;

template <typename T>
using QueryTypeMap = angle::PackedEnumMap<QueryType, T>;

constexpr size_t kBarrierVectorDefaultSize = 16;

template <typename T>
using BarrierVector = angle::FastVector<T, kBarrierVectorDefaultSize>;

using BufferBarrierVector = BarrierVector<Buffer *>;

using SamplerBindingVector = std::vector<BindingPointer<Sampler>>;
using BufferVector         = std::vector<OffsetBindingPointer<Buffer>>;

struct TextureAndLayout
{
    Texture *texture;
    GLenum layout;
};
using TextureBarrierVector = BarrierVector<TextureAndLayout>;

// OffsetBindingPointer.getSize() returns the size specified by the user, which may be larger than
// the size of the bound buffer. This function reduces the returned size to fit the bound buffer if
// necessary. Returns 0 if no buffer is bound or if integer overflow occurs.
GLsizeiptr GetBoundBufferAvailableSize(const OffsetBindingPointer<Buffer> &binding);

// A texture level index.
template <typename T>
class LevelIndexWrapper
{
  public:
    LevelIndexWrapper() = default;
    explicit constexpr LevelIndexWrapper(T levelIndex) : mLevelIndex(levelIndex) {}
    constexpr LevelIndexWrapper(const LevelIndexWrapper &other)            = default;
    constexpr LevelIndexWrapper &operator=(const LevelIndexWrapper &other) = default;

    constexpr T get() const { return mLevelIndex; }

    LevelIndexWrapper &operator++()
    {
        ++mLevelIndex;
        return *this;
    }
    constexpr bool operator<(const LevelIndexWrapper &other) const
    {
        return mLevelIndex < other.mLevelIndex;
    }
    constexpr bool operator<=(const LevelIndexWrapper &other) const
    {
        return mLevelIndex <= other.mLevelIndex;
    }
    constexpr bool operator>(const LevelIndexWrapper &other) const
    {
        return mLevelIndex > other.mLevelIndex;
    }
    constexpr bool operator>=(const LevelIndexWrapper &other) const
    {
        return mLevelIndex >= other.mLevelIndex;
    }
    constexpr bool operator==(const LevelIndexWrapper &other) const
    {
        return mLevelIndex == other.mLevelIndex;
    }
    constexpr bool operator!=(const LevelIndexWrapper &other) const
    {
        return mLevelIndex != other.mLevelIndex;
    }
    constexpr LevelIndexWrapper operator+(T other) const
    {
        return LevelIndexWrapper(mLevelIndex + other);
    }
    constexpr LevelIndexWrapper operator-(T other) const
    {
        return LevelIndexWrapper(mLevelIndex - other);
    }
    constexpr T operator-(LevelIndexWrapper other) const { return mLevelIndex - other.mLevelIndex; }

  private:
    T mLevelIndex;
};

// A GL texture level index.
using LevelIndex = LevelIndexWrapper<GLint>;

enum class MultisamplingMode
{
    // Regular multisampling
    Regular = 0,
    // GL_EXT_multisampled_render_to_texture renderbuffer/texture attachments which perform implicit
    // resolve of multisampled data.
    MultisampledRenderToTexture,
};
}  // namespace gl

namespace rx
{
// A macro that determines whether an object has a given runtime type.
#if defined(__clang__)
#    if __has_feature(cxx_rtti)
#        define ANGLE_HAS_DYNAMIC_CAST 1
#    endif
#elif !defined(NDEBUG) && (!defined(_MSC_VER) || defined(_CPPRTTI)) &&              \
    (!defined(__GNUC__) || __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 3) || \
     defined(__GXX_RTTI))
#    define ANGLE_HAS_DYNAMIC_CAST 1
#endif

#ifdef ANGLE_HAS_DYNAMIC_CAST
#    define ANGLE_HAS_DYNAMIC_TYPE(type, obj) (dynamic_cast<type>(obj) != nullptr)
#    undef ANGLE_HAS_DYNAMIC_CAST
#else
#    define ANGLE_HAS_DYNAMIC_TYPE(type, obj) (obj != nullptr)
#endif

// Downcast a base implementation object (EG TextureImpl to TextureD3D)
template <typename DestT, typename SrcT>
inline DestT *GetAs(SrcT *src)
{
    ASSERT(ANGLE_HAS_DYNAMIC_TYPE(DestT *, src));
    return static_cast<DestT *>(src);
}

template <typename DestT, typename SrcT>
inline const DestT *GetAs(const SrcT *src)
{
    ASSERT(ANGLE_HAS_DYNAMIC_TYPE(const DestT *, src));
    return static_cast<const DestT *>(src);
}

#undef ANGLE_HAS_DYNAMIC_TYPE

// Downcast a GL object to an Impl (EG gl::Texture to rx::TextureD3D)
template <typename DestT, typename SrcT>
inline DestT *GetImplAs(SrcT *src)
{
    return GetAs<DestT>(src->getImplementation());
}

template <typename DestT, typename SrcT>
inline DestT *SafeGetImplAs(SrcT *src)
{
    return src != nullptr ? GetAs<DestT>(src->getImplementation()) : nullptr;
}

}  // namespace rx

#include "angletypes.inc"

namespace angle
{
// Zero-based for better array indexing
enum FramebufferBinding
{
    FramebufferBindingRead = 0,
    FramebufferBindingDraw,
    FramebufferBindingSingletonMax,
    FramebufferBindingBoth = FramebufferBindingSingletonMax,
    FramebufferBindingMax,
    FramebufferBindingUnknown = FramebufferBindingMax,
};

inline FramebufferBinding EnumToFramebufferBinding(GLenum enumValue)
{
    switch (enumValue)
    {
        case GL_READ_FRAMEBUFFER:
            return FramebufferBindingRead;
        case GL_DRAW_FRAMEBUFFER:
            return FramebufferBindingDraw;
        case GL_FRAMEBUFFER:
            return FramebufferBindingBoth;
        default:
            UNREACHABLE();
            return FramebufferBindingUnknown;
    }
}

inline GLenum FramebufferBindingToEnum(FramebufferBinding binding)
{
    switch (binding)
    {
        case FramebufferBindingRead:
            return GL_READ_FRAMEBUFFER;
        case FramebufferBindingDraw:
            return GL_DRAW_FRAMEBUFFER;
        case FramebufferBindingBoth:
            return GL_FRAMEBUFFER;
        default:
            UNREACHABLE();
            return GL_NONE;
    }
}

template <typename ObjT, typename ContextT>
class DestroyThenDelete
{
  public:
    DestroyThenDelete() = default;
    DestroyThenDelete(const ContextT *context) : mContext(context) {}

    void operator()(ObjT *obj)
    {
        (void)(obj->onDestroy(mContext));
        delete obj;
    }

  private:
    const ContextT *mContext = nullptr;
};

template <typename ObjT, typename ContextT>
using UniqueObjectPointer = std::unique_ptr<ObjT, DestroyThenDelete<ObjT, ContextT>>;

}  // namespace angle

namespace gl
{
class State;
}  // namespace gl

#endif  // LIBANGLE_ANGLETYPES_H_
