//
// 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:
        case GL_BGRX8_ANGLEX:
        case GL_RGBX8_ANGLE:
            return GL_SRGB8;
        case GL_RGBA16F:
            return GL_RGBA16F;
        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_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_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;

    ANGLE_NO_DISCARD bool computeBufferRowLength(uint32_t width, uint32_t *resultOut) const;
    ANGLE_NO_DISCARD bool computeBufferImageHeight(uint32_t height, uint32_t *resultOut) const;

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

    ANGLE_NO_DISCARD bool computeCompressedImageSize(const Extents &size, GLuint *resultOut) const;

    ANGLE_NO_DISCARD std::pair<GLuint, GLuint> getCompressedImageMinBlocks() const;

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

    ANGLE_NO_DISCARD 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;

    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;

    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
    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:
        case GL_ETC1_SRGB8_NV:
            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 bool IsPVRTC1Format(const GLenum format)
{
    switch (format)
    {
        case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
        case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
        case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
        case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
        case GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT:
        case GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT:
        case GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT:
        case GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT:
            return true;

        default:
            return false;
    }
}

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_RGBX8_ANGLE:
        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_
