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

// formatutils.h: Queries for GL image formats.

#ifndef LIBANGLE_FORMATUTILS_H_
#define LIBANGLE_FORMATUTILS_H_

#include <stdint.h>
#include <cstddef>
#include <ostream>

#include "angle_gl.h"
#include "common/android_util.h"
#include "libANGLE/Caps.h"
#include "libANGLE/Config.h"
#include "libANGLE/Error.h"
#include "libANGLE/Version.h"
#include "libANGLE/VertexAttribute.h"
#include "libANGLE/angletypes.h"

namespace gl
{
struct VertexAttribute;

struct FormatType final
{
    FormatType();
    FormatType(GLenum format_, GLenum type_);
    FormatType(const FormatType &other)            = default;
    FormatType &operator=(const FormatType &other) = default;

    bool operator<(const FormatType &other) const;

    GLenum format;
    GLenum type;
};

struct Type
{
    Type() : bytes(0), bytesShift(0), specialInterpretation(0) {}

    explicit Type(uint32_t packedTypeInfo)
        : bytes(packedTypeInfo & 0xff),
          bytesShift((packedTypeInfo >> 8) & 0xff),
          specialInterpretation((packedTypeInfo >> 16) & 1)
    {}

    GLuint bytes;
    GLuint bytesShift;  // Bit shift by this value to effectively divide/multiply by "bytes" in a
                        // more optimal way
    bool specialInterpretation;
};

uint32_t GetPackedTypeInfo(GLenum type);

ANGLE_INLINE GLenum GetNonLinearFormat(const GLenum format)
{
    switch (format)
    {
        case GL_BGRA8_EXT:
            return GL_BGRA8_SRGB_ANGLEX;
        case GL_RGBA8:
            return GL_SRGB8_ALPHA8;
        case GL_RGB8:
            return GL_SRGB8;
        case GL_BGRX8_ANGLEX:
            return GL_BGRX8_SRGB_ANGLEX;
        case GL_RGBX8_ANGLE:
            return GL_RGBX8_SRGB_ANGLEX;
        case GL_RGBA16F:
            return GL_RGBA16F;
        case GL_RGB10_A2_EXT:
            return GL_RGB10_A2_EXT;
        default:
            return GL_NONE;
    }
}

ANGLE_INLINE bool ColorspaceFormatOverride(const EGLenum colorspace, GLenum *rendertargetformat)
{
    // Override the rendertargetformat based on colorpsace
    switch (colorspace)
    {
        case EGL_GL_COLORSPACE_LINEAR:                 // linear colorspace no translation needed
        case EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT:       // linear colorspace no translation needed
        case EGL_GL_COLORSPACE_BT2020_LINEAR_EXT:      // linear colorspace no translation needed
        case EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT:  // linear colorspace no translation needed
        case EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT:  // App, not the HW, will specify the
                                                            // transfer function
        case EGL_GL_COLORSPACE_SCRGB_EXT:  // App, not the HW, will specify the transfer function
            // No translation
            return true;
        case EGL_GL_COLORSPACE_SRGB_KHR:
        case EGL_GL_COLORSPACE_BT2020_PQ_EXT:
        case EGL_GL_COLORSPACE_BT2020_HLG_EXT:
        case EGL_GL_COLORSPACE_DISPLAY_P3_EXT:
        {
            GLenum nonLinearFormat = GetNonLinearFormat(*rendertargetformat);
            if (nonLinearFormat != GL_NONE)
            {
                *rendertargetformat = nonLinearFormat;
                return true;
            }
            else
            {
                return false;
            }
        }
        break;
        default:
            UNREACHABLE();
            return false;
    }
}

ANGLE_INLINE const Type GetTypeInfo(GLenum type)
{
    return Type(GetPackedTypeInfo(type));
}

// This helpers use tricks based on the assumption that the type has certain values.
static_assert(static_cast<GLuint>(DrawElementsType::UnsignedByte) == 0, "Please update this code.");
static_assert(static_cast<GLuint>(DrawElementsType::UnsignedShort) == 1,
              "Please update this code.");
static_assert(static_cast<GLuint>(DrawElementsType::UnsignedInt) == 2, "Please update this code.");
ANGLE_INLINE GLuint GetDrawElementsTypeSize(DrawElementsType type)
{
    return (1 << static_cast<GLuint>(type));
}

ANGLE_INLINE GLuint GetDrawElementsTypeShift(DrawElementsType type)
{
    return static_cast<GLuint>(type);
}

// Information about an OpenGL internal format.  Can be keyed on the internalFormat and type
// members.
struct InternalFormat
{
    InternalFormat();
    InternalFormat(const InternalFormat &other);
    InternalFormat &operator=(const InternalFormat &other);

    GLuint computePixelBytes(GLenum formatType) const;

    [[nodiscard]] bool computeBufferRowLength(uint32_t width, uint32_t *resultOut) const;
    [[nodiscard]] bool computeBufferImageHeight(uint32_t height, uint32_t *resultOut) const;

    [[nodiscard]] bool computeRowPitch(GLenum formatType,
                                       GLsizei width,
                                       GLint alignment,
                                       GLint rowLength,
                                       GLuint *resultOut) const;
    [[nodiscard]] bool computeDepthPitch(GLsizei height,
                                         GLint imageHeight,
                                         GLuint rowPitch,
                                         GLuint *resultOut) const;
    [[nodiscard]] bool computeDepthPitch(GLenum formatType,
                                         GLsizei width,
                                         GLsizei height,
                                         GLint alignment,
                                         GLint rowLength,
                                         GLint imageHeight,
                                         GLuint *resultOut) const;

    [[nodiscard]] bool computePalettedImageRowPitch(GLsizei width, GLuint *resultOut) const;

    [[nodiscard]] bool computeCompressedImageRowPitch(GLsizei width, GLuint *resultOut) const;

    [[nodiscard]] bool computeCompressedImageDepthPitch(GLsizei height,
                                                        GLuint rowPitch,
                                                        GLuint *resultOut) const;

    [[nodiscard]] bool computeCompressedImageSize(const Extents &size, GLuint *resultOut) const;

    [[nodiscard]] std::pair<GLuint, GLuint> getCompressedImageMinBlocks() const;

    [[nodiscard]] bool computeSkipBytes(GLenum formatType,
                                        GLuint rowPitch,
                                        GLuint depthPitch,
                                        const PixelStoreStateBase &state,
                                        bool is3D,
                                        GLuint *resultOut) const;

    [[nodiscard]] bool computePackUnpackEndByte(GLenum formatType,
                                                const Extents &size,
                                                const PixelStoreStateBase &state,
                                                bool is3D,
                                                GLuint *resultOut) const;

    bool isLUMA() const;
    GLenum getReadPixelsFormat(const Extensions &extensions) const;
    GLenum getReadPixelsType(const Version &version) const;

    // Support upload a portion of image?
    bool supportSubImage() const;

    ANGLE_INLINE bool isChannelSizeCompatible(GLuint redSize,
                                              GLuint greenSize,
                                              GLuint blueSize,
                                              GLuint alphaSize) const
    {
        // We only check for equality in all channel sizes
        return ((redSize == redBits) && (greenSize == greenBits) && (blueSize == blueBits) &&
                (alphaSize == alphaBits));
    }

    // Return true if the format is a required renderbuffer format in the given version of the core
    // spec. Note that it isn't always clear whether all the rules that apply to core required
    // renderbuffer formats also apply to additional formats added by extensions. Because of this
    // extension formats are conservatively not included.
    bool isRequiredRenderbufferFormat(const Version &version) const;

    bool isInt() const;
    bool isDepthOrStencil() const;

    GLuint getEGLConfigBufferSize() const;

    bool operator==(const InternalFormat &other) const;
    bool operator!=(const InternalFormat &other) const;

    GLenum internalFormat;

    bool sized;
    GLenum sizedInternalFormat;

    GLuint redBits;
    GLuint greenBits;
    GLuint blueBits;

    GLuint luminanceBits;

    GLuint alphaBits;
    GLuint sharedBits;

    GLuint depthBits;
    GLuint stencilBits;

    GLuint pixelBytes;

    GLuint componentCount;

    bool compressed;
    GLuint compressedBlockWidth;
    GLuint compressedBlockHeight;
    GLuint compressedBlockDepth;

    bool paletted;
    GLuint paletteBits;

    GLenum format;
    GLenum type;

    GLenum componentType;
    GLenum colorEncoding;

    typedef bool (*SupportCheckFunction)(const Version &, const Extensions &);
    SupportCheckFunction textureSupport;
    SupportCheckFunction filterSupport;
    SupportCheckFunction textureAttachmentSupport;  // glFramebufferTexture2D
    SupportCheckFunction renderbufferSupport;       // glFramebufferRenderbuffer
    SupportCheckFunction blendSupport;
};

// A "Format" wraps an InternalFormat struct, querying it from either a sized internal format or
// unsized internal format and type.
// TODO(geofflang): Remove this, it doesn't add any more information than the InternalFormat object.
struct Format
{
    // Sized types only.
    explicit Format(GLenum internalFormat);

    // Sized or unsized types.
    explicit Format(const InternalFormat &internalFormat);
    Format(GLenum internalFormat, GLenum type);

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

    bool valid() const;

    static Format Invalid();
    static bool SameSized(const Format &a, const Format &b);
    static bool EquivalentForBlit(const Format &a, const Format &b);

    friend std::ostream &operator<<(std::ostream &os, const Format &fmt);

    // This is the sized info.
    const InternalFormat *info;
};

const InternalFormat &GetSizedInternalFormatInfo(GLenum internalFormat);
const InternalFormat &GetInternalFormatInfo(GLenum internalFormat, GLenum type);

// Strip sizing information from an internal format.  Doesn't necessarily validate that the internal
// format is valid.
GLenum GetUnsizedFormat(GLenum internalFormat);

// Return whether the compressed format requires whole image/mip level to be uploaded to texture.
bool CompressedFormatRequiresWholeImage(GLenum internalFormat);

// In support of GetImage, check for LUMA formats and override with real format
void MaybeOverrideLuminance(GLenum &format, GLenum &type, GLenum actualFormat, GLenum actualType);

typedef std::set<GLenum> FormatSet;
const FormatSet &GetAllSizedInternalFormats();

typedef angle::HashMap<GLenum, angle::HashMap<GLenum, InternalFormat>> InternalFormatInfoMap;
const InternalFormatInfoMap &GetInternalFormatMap();

int GetAndroidHardwareBufferFormatFromChannelSizes(const egl::AttributeMap &attribMap);

GLenum GetConfigColorBufferFormat(const egl::Config *config);
GLenum GetConfigDepthStencilBufferFormat(const egl::Config *config);

ANGLE_INLINE int GetNativeVisualID(const InternalFormat &internalFormat)
{
    int nativeVisualId = 0;
#if defined(ANGLE_PLATFORM_ANDROID)
    nativeVisualId =
        angle::android::GLInternalFormatToNativePixelFormat(internalFormat.internalFormat);
#endif
#if defined(ANGLE_PLATFORM_LINUX) && defined(ANGLE_USES_GBM)
    nativeVisualId = angle::GLInternalFormatToGbmFourCCFormat(internalFormat.internalFormat);
#endif

    return nativeVisualId;
}

// From the ESSL 3.00.4 spec:
// Vertex shader inputs can only be float, floating-point vectors, matrices, signed and unsigned
// integers and integer vectors. Vertex shader inputs cannot be arrays or structures.

enum AttributeType
{
    ATTRIBUTE_FLOAT,
    ATTRIBUTE_VEC2,
    ATTRIBUTE_VEC3,
    ATTRIBUTE_VEC4,
    ATTRIBUTE_INT,
    ATTRIBUTE_IVEC2,
    ATTRIBUTE_IVEC3,
    ATTRIBUTE_IVEC4,
    ATTRIBUTE_UINT,
    ATTRIBUTE_UVEC2,
    ATTRIBUTE_UVEC3,
    ATTRIBUTE_UVEC4,
    ATTRIBUTE_MAT2,
    ATTRIBUTE_MAT3,
    ATTRIBUTE_MAT4,
    ATTRIBUTE_MAT2x3,
    ATTRIBUTE_MAT2x4,
    ATTRIBUTE_MAT3x2,
    ATTRIBUTE_MAT3x4,
    ATTRIBUTE_MAT4x2,
    ATTRIBUTE_MAT4x3,
};

AttributeType GetAttributeType(GLenum enumValue);

typedef std::vector<angle::FormatID> InputLayout;

struct VertexFormat : private angle::NonCopyable
{
    VertexFormat(GLenum typeIn, GLboolean normalizedIn, GLuint componentsIn, bool pureIntegerIn);

    GLenum type;
    GLboolean normalized;
    GLuint components;
    bool pureInteger;
};

angle::FormatID GetVertexFormatID(VertexAttribType type,
                                  GLboolean normalized,
                                  GLuint components,
                                  bool pureInteger);

angle::FormatID GetVertexFormatID(const VertexAttribute &attrib, VertexAttribType currentValueType);
angle::FormatID GetCurrentValueFormatID(VertexAttribType currentValueType);
const VertexFormat &GetVertexFormatFromID(angle::FormatID vertexFormatID);
size_t GetVertexFormatSize(angle::FormatID vertexFormatID);
angle::FormatID ConvertFormatSignedness(const angle::Format &format);

ANGLE_INLINE bool IsS3TCFormat(const GLenum format)
{
    switch (format)
    {
        case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
        case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
        case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
        case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
        case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
        case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
        case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
        case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
            return true;

        default:
            return false;
    }
}

ANGLE_INLINE bool IsRGTCFormat(const GLenum format)
{
    switch (format)
    {
        case GL_COMPRESSED_RED_RGTC1_EXT:
        case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT:
        case GL_COMPRESSED_RED_GREEN_RGTC2_EXT:
        case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT:
            return true;

        default:
            return false;
    }
}

ANGLE_INLINE bool IsBPTCFormat(const GLenum format)
{
    switch (format)
    {
        case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
        case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT:
        case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT:
        case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT:
            return true;

        default:
            return false;
    }
}

ANGLE_INLINE bool IsASTC2DFormat(const GLenum format)
{
    if ((format >= GL_COMPRESSED_RGBA_ASTC_4x4_KHR &&
         format <= GL_COMPRESSED_RGBA_ASTC_12x12_KHR) ||
        (format >= GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR &&
         format <= GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR))
    {
        return true;
    }
    return false;
}

ANGLE_INLINE bool IsETC1Format(const GLenum format)
{
    switch (format)
    {
        case GL_ETC1_RGB8_OES:
            return true;

        default:
            return false;
    }
}

ANGLE_INLINE bool IsETC2EACFormat(const GLenum format)
{
    // ES 3.1, Table 8.19
    switch (format)
    {
        case GL_COMPRESSED_R11_EAC:
        case GL_COMPRESSED_SIGNED_R11_EAC:
        case GL_COMPRESSED_RG11_EAC:
        case GL_COMPRESSED_SIGNED_RG11_EAC:
        case GL_COMPRESSED_RGB8_ETC2:
        case GL_COMPRESSED_SRGB8_ETC2:
        case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
        case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
        case GL_COMPRESSED_RGBA8_ETC2_EAC:
        case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
            return true;

        default:
            return false;
    }
}

ANGLE_INLINE constexpr bool IsPVRTC1Format(const GLenum format)
{
    // This function is called for all compressed texture uploads. The expression below generates
    // fewer instructions than a regular switch statement. Two groups of four consecutive values,
    // each group starts with two least significant bits unset.
    return ((format & ~3) == GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG) ||
           ((format & ~3) == GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT);
}
static_assert(IsPVRTC1Format(GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG), "0x8C00");
static_assert(IsPVRTC1Format(GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG), "0x8C01");
static_assert(IsPVRTC1Format(GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG), "0x8C02");
static_assert(IsPVRTC1Format(GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG), "0x8C03");
static_assert(IsPVRTC1Format(GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT), "0x8A54");
static_assert(IsPVRTC1Format(GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT), "0x8A55");
static_assert(IsPVRTC1Format(GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT), "0x8A56");
static_assert(IsPVRTC1Format(GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT), "0x8A57");
static_assert(!IsPVRTC1Format(0x8BFF) && !IsPVRTC1Format(0x8C04), "invalid");
static_assert(!IsPVRTC1Format(0x8A53) && !IsPVRTC1Format(0x8A58), "invalid");

ANGLE_INLINE bool IsBGRAFormat(const GLenum internalFormat)
{
    switch (internalFormat)
    {
        case GL_BGRA8_EXT:
        case GL_BGRA4_ANGLEX:
        case GL_BGR5_A1_ANGLEX:
        case GL_BGRA8_SRGB_ANGLEX:
        case GL_BGRX8_ANGLEX:
        case GL_BGR565_ANGLEX:
        case GL_BGR10_A2_ANGLEX:
            return true;

        default:
            return false;
    }
}

// Check if an internal format is ever valid in ES3.  Makes no checks about support for a specific
// context.
bool ValidES3InternalFormat(GLenum internalFormat);

// Implemented in format_map_autogen.cpp
bool ValidES3Format(GLenum format);
bool ValidES3Type(GLenum type);
bool ValidES3FormatCombination(GLenum format, GLenum type, GLenum internalFormat);

// Implemented in format_map_desktop.cpp
bool ValidDesktopFormat(GLenum format);
bool ValidDesktopType(GLenum type);
bool ValidDesktopFormatCombination(GLenum format, GLenum type, GLenum internalFormat);

// Implemented in es3_copy_conversion_table_autogen.cpp
bool ValidES3CopyConversion(GLenum textureFormat, GLenum framebufferFormat);

ANGLE_INLINE ComponentType GetVertexAttributeComponentType(bool pureInteger, VertexAttribType type)
{
    if (pureInteger)
    {
        switch (type)
        {
            case VertexAttribType::Byte:
            case VertexAttribType::Short:
            case VertexAttribType::Int:
                return ComponentType::Int;

            case VertexAttribType::UnsignedByte:
            case VertexAttribType::UnsignedShort:
            case VertexAttribType::UnsignedInt:
                return ComponentType::UnsignedInt;

            default:
                UNREACHABLE();
                return ComponentType::NoType;
        }
    }
    else
    {
        return ComponentType::Float;
    }
}

constexpr std::size_t kMaxYuvPlaneCount = 3;
template <typename T>
using YuvPlaneArray = std::array<T, kMaxYuvPlaneCount>;

struct YuvFormatInfo
{
    // Sized types only.
    YuvFormatInfo(GLenum internalFormat, const Extents &yPlaneExtent);

    GLenum glInternalFormat;
    uint32_t planeCount;
    YuvPlaneArray<uint32_t> planeBpp;
    YuvPlaneArray<Extents> planeExtent;
    YuvPlaneArray<uint32_t> planePitch;
    YuvPlaneArray<uint32_t> planeSize;
    YuvPlaneArray<uint32_t> planeOffset;
};

bool IsYuvFormat(GLenum format);
uint32_t GetPlaneCount(GLenum format);
uint32_t GetYPlaneBpp(GLenum format);
uint32_t GetChromaPlaneBpp(GLenum format);
void GetSubSampleFactor(GLenum format,
                        int *horizontalSubsampleFactor,
                        int *verticalSubsampleFactor);
}  // namespace gl

#endif  // LIBANGLE_FORMATUTILS_H_
