tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

formatutils.h (18362B)


      1 //
      2 // Copyright 2013 The ANGLE Project Authors. All rights reserved.
      3 // Use of this source code is governed by a BSD-style license that can be
      4 // found in the LICENSE file.
      5 //
      6 
      7 // formatutils.h: Queries for GL image formats.
      8 
      9 #ifndef LIBANGLE_FORMATUTILS_H_
     10 #define LIBANGLE_FORMATUTILS_H_
     11 
     12 #include <stdint.h>
     13 #include <cstddef>
     14 #include <ostream>
     15 
     16 #include "angle_gl.h"
     17 #include "common/android_util.h"
     18 #include "libANGLE/Caps.h"
     19 #include "libANGLE/Config.h"
     20 #include "libANGLE/Error.h"
     21 #include "libANGLE/Version.h"
     22 #include "libANGLE/VertexAttribute.h"
     23 #include "libANGLE/angletypes.h"
     24 
     25 namespace gl
     26 {
     27 struct VertexAttribute;
     28 
     29 struct FormatType final
     30 {
     31    FormatType();
     32    FormatType(GLenum format_, GLenum type_);
     33    FormatType(const FormatType &other)            = default;
     34    FormatType &operator=(const FormatType &other) = default;
     35 
     36    bool operator<(const FormatType &other) const;
     37 
     38    GLenum format;
     39    GLenum type;
     40 };
     41 
     42 struct Type
     43 {
     44    Type() : bytes(0), bytesShift(0), specialInterpretation(0) {}
     45 
     46    explicit Type(uint32_t packedTypeInfo)
     47        : bytes(packedTypeInfo & 0xff),
     48          bytesShift((packedTypeInfo >> 8) & 0xff),
     49          specialInterpretation((packedTypeInfo >> 16) & 1)
     50    {}
     51 
     52    GLuint bytes;
     53    GLuint bytesShift;  // Bit shift by this value to effectively divide/multiply by "bytes" in a
     54                        // more optimal way
     55    bool specialInterpretation;
     56 };
     57 
     58 uint32_t GetPackedTypeInfo(GLenum type);
     59 
     60 ANGLE_INLINE GLenum GetNonLinearFormat(const GLenum format)
     61 {
     62    switch (format)
     63    {
     64        case GL_BGRA8_EXT:
     65            return GL_BGRA8_SRGB_ANGLEX;
     66        case GL_RGBA8:
     67            return GL_SRGB8_ALPHA8;
     68        case GL_RGB8:
     69        case GL_BGRX8_ANGLEX:
     70        case GL_RGBX8_ANGLE:
     71            return GL_SRGB8;
     72        case GL_RGBA16F:
     73            return GL_RGBA16F;
     74        default:
     75            return GL_NONE;
     76    }
     77 }
     78 
     79 ANGLE_INLINE bool ColorspaceFormatOverride(const EGLenum colorspace, GLenum *rendertargetformat)
     80 {
     81    // Override the rendertargetformat based on colorpsace
     82    switch (colorspace)
     83    {
     84        case EGL_GL_COLORSPACE_LINEAR:                 // linear colorspace no translation needed
     85        case EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT:       // linear colorspace no translation needed
     86        case EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT:  // linear colorspace no translation needed
     87        case EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT:  // App, not the HW, will specify the
     88                                                            // transfer function
     89        case EGL_GL_COLORSPACE_SCRGB_EXT:  // App, not the HW, will specify the transfer function
     90            // No translation
     91            return true;
     92        case EGL_GL_COLORSPACE_SRGB_KHR:
     93        case EGL_GL_COLORSPACE_DISPLAY_P3_EXT:
     94        {
     95            GLenum nonLinearFormat = GetNonLinearFormat(*rendertargetformat);
     96            if (nonLinearFormat != GL_NONE)
     97            {
     98                *rendertargetformat = nonLinearFormat;
     99                return true;
    100            }
    101            else
    102            {
    103                return false;
    104            }
    105        }
    106        break;
    107        default:
    108            UNREACHABLE();
    109            return false;
    110    }
    111 }
    112 
    113 ANGLE_INLINE const Type GetTypeInfo(GLenum type)
    114 {
    115    return Type(GetPackedTypeInfo(type));
    116 }
    117 
    118 // This helpers use tricks based on the assumption that the type has certain values.
    119 static_assert(static_cast<GLuint>(DrawElementsType::UnsignedByte) == 0, "Please update this code.");
    120 static_assert(static_cast<GLuint>(DrawElementsType::UnsignedShort) == 1,
    121              "Please update this code.");
    122 static_assert(static_cast<GLuint>(DrawElementsType::UnsignedInt) == 2, "Please update this code.");
    123 ANGLE_INLINE GLuint GetDrawElementsTypeSize(DrawElementsType type)
    124 {
    125    return (1 << static_cast<GLuint>(type));
    126 }
    127 
    128 ANGLE_INLINE GLuint GetDrawElementsTypeShift(DrawElementsType type)
    129 {
    130    return static_cast<GLuint>(type);
    131 }
    132 
    133 // Information about an OpenGL internal format.  Can be keyed on the internalFormat and type
    134 // members.
    135 struct InternalFormat
    136 {
    137    InternalFormat();
    138    InternalFormat(const InternalFormat &other);
    139    InternalFormat &operator=(const InternalFormat &other);
    140 
    141    GLuint computePixelBytes(GLenum formatType) const;
    142 
    143    [[nodiscard]] bool computeBufferRowLength(uint32_t width, uint32_t *resultOut) const;
    144    [[nodiscard]] bool computeBufferImageHeight(uint32_t height, uint32_t *resultOut) const;
    145 
    146    [[nodiscard]] bool computeRowPitch(GLenum formatType,
    147                                       GLsizei width,
    148                                       GLint alignment,
    149                                       GLint rowLength,
    150                                       GLuint *resultOut) const;
    151    [[nodiscard]] bool computeDepthPitch(GLsizei height,
    152                                         GLint imageHeight,
    153                                         GLuint rowPitch,
    154                                         GLuint *resultOut) const;
    155    [[nodiscard]] bool computeDepthPitch(GLenum formatType,
    156                                         GLsizei width,
    157                                         GLsizei height,
    158                                         GLint alignment,
    159                                         GLint rowLength,
    160                                         GLint imageHeight,
    161                                         GLuint *resultOut) const;
    162 
    163    [[nodiscard]] bool computePalettedImageRowPitch(GLsizei width, GLuint *resultOut) const;
    164 
    165    [[nodiscard]] bool computeCompressedImageSize(const Extents &size, GLuint *resultOut) const;
    166 
    167    [[nodiscard]] std::pair<GLuint, GLuint> getCompressedImageMinBlocks() const;
    168 
    169    [[nodiscard]] bool computeSkipBytes(GLenum formatType,
    170                                        GLuint rowPitch,
    171                                        GLuint depthPitch,
    172                                        const PixelStoreStateBase &state,
    173                                        bool is3D,
    174                                        GLuint *resultOut) const;
    175 
    176    [[nodiscard]] bool computePackUnpackEndByte(GLenum formatType,
    177                                                const Extents &size,
    178                                                const PixelStoreStateBase &state,
    179                                                bool is3D,
    180                                                GLuint *resultOut) const;
    181 
    182    bool isLUMA() const;
    183    GLenum getReadPixelsFormat(const Extensions &extensions) const;
    184    GLenum getReadPixelsType(const Version &version) const;
    185 
    186    // Support upload a portion of image?
    187    bool supportSubImage() const;
    188 
    189    ANGLE_INLINE bool isChannelSizeCompatible(GLuint redSize,
    190                                              GLuint greenSize,
    191                                              GLuint blueSize,
    192                                              GLuint alphaSize) const
    193    {
    194        // We only check for equality in all channel sizes
    195        return ((redSize == redBits) && (greenSize == greenBits) && (blueSize == blueBits) &&
    196                (alphaSize == alphaBits));
    197    }
    198 
    199    // Return true if the format is a required renderbuffer format in the given version of the core
    200    // spec. Note that it isn't always clear whether all the rules that apply to core required
    201    // renderbuffer formats also apply to additional formats added by extensions. Because of this
    202    // extension formats are conservatively not included.
    203    bool isRequiredRenderbufferFormat(const Version &version) const;
    204 
    205    bool isInt() const;
    206    bool isDepthOrStencil() const;
    207 
    208    bool operator==(const InternalFormat &other) const;
    209    bool operator!=(const InternalFormat &other) const;
    210 
    211    GLenum internalFormat;
    212 
    213    bool sized;
    214    GLenum sizedInternalFormat;
    215 
    216    GLuint redBits;
    217    GLuint greenBits;
    218    GLuint blueBits;
    219 
    220    GLuint luminanceBits;
    221 
    222    GLuint alphaBits;
    223    GLuint sharedBits;
    224 
    225    GLuint depthBits;
    226    GLuint stencilBits;
    227 
    228    GLuint pixelBytes;
    229 
    230    GLuint componentCount;
    231 
    232    bool compressed;
    233    GLuint compressedBlockWidth;
    234    GLuint compressedBlockHeight;
    235    GLuint compressedBlockDepth;
    236 
    237    bool paletted;
    238    GLuint paletteBits;
    239 
    240    GLenum format;
    241    GLenum type;
    242 
    243    GLenum componentType;
    244    GLenum colorEncoding;
    245 
    246    typedef bool (*SupportCheckFunction)(const Version &, const Extensions &);
    247    SupportCheckFunction textureSupport;
    248    SupportCheckFunction filterSupport;
    249    SupportCheckFunction textureAttachmentSupport;  // glFramebufferTexture2D
    250    SupportCheckFunction renderbufferSupport;       // glFramebufferRenderbuffer
    251    SupportCheckFunction blendSupport;
    252 };
    253 
    254 // A "Format" wraps an InternalFormat struct, querying it from either a sized internal format or
    255 // unsized internal format and type.
    256 // TODO(geofflang): Remove this, it doesn't add any more information than the InternalFormat object.
    257 struct Format
    258 {
    259    // Sized types only.
    260    explicit Format(GLenum internalFormat);
    261 
    262    // Sized or unsized types.
    263    explicit Format(const InternalFormat &internalFormat);
    264    Format(GLenum internalFormat, GLenum type);
    265 
    266    Format(const Format &other);
    267    Format &operator=(const Format &other);
    268 
    269    bool valid() const;
    270 
    271    static Format Invalid();
    272    static bool SameSized(const Format &a, const Format &b);
    273    static bool EquivalentForBlit(const Format &a, const Format &b);
    274 
    275    friend std::ostream &operator<<(std::ostream &os, const Format &fmt);
    276 
    277    // This is the sized info.
    278    const InternalFormat *info;
    279 };
    280 
    281 const InternalFormat &GetSizedInternalFormatInfo(GLenum internalFormat);
    282 const InternalFormat &GetInternalFormatInfo(GLenum internalFormat, GLenum type);
    283 
    284 // Strip sizing information from an internal format.  Doesn't necessarily validate that the internal
    285 // format is valid.
    286 GLenum GetUnsizedFormat(GLenum internalFormat);
    287 
    288 // Return whether the compressed format requires whole image/mip level to be uploaded to texture.
    289 bool CompressedFormatRequiresWholeImage(GLenum internalFormat);
    290 
    291 // In support of GetImage, check for LUMA formats and override with real format
    292 void MaybeOverrideLuminance(GLenum &format, GLenum &type, GLenum actualFormat, GLenum actualType);
    293 
    294 typedef std::set<GLenum> FormatSet;
    295 const FormatSet &GetAllSizedInternalFormats();
    296 
    297 typedef angle::HashMap<GLenum, angle::HashMap<GLenum, InternalFormat>> InternalFormatInfoMap;
    298 const InternalFormatInfoMap &GetInternalFormatMap();
    299 
    300 int GetAndroidHardwareBufferFormatFromChannelSizes(const egl::AttributeMap &attribMap);
    301 
    302 GLenum GetConfigColorBufferFormat(const egl::Config *config);
    303 GLenum GetConfigDepthStencilBufferFormat(const egl::Config *config);
    304 
    305 ANGLE_INLINE int GetNativeVisualID(const InternalFormat &internalFormat)
    306 {
    307    int nativeVisualId = 0;
    308 #if defined(ANGLE_PLATFORM_ANDROID)
    309    nativeVisualId =
    310        angle::android::GLInternalFormatToNativePixelFormat(internalFormat.internalFormat);
    311 #endif
    312 #if defined(ANGLE_PLATFORM_LINUX) && defined(ANGLE_USES_GBM)
    313    nativeVisualId = angle::GLInternalFormatToGbmFourCCFormat(internalFormat.internalFormat);
    314 #endif
    315 
    316    return nativeVisualId;
    317 }
    318 
    319 // From the ESSL 3.00.4 spec:
    320 // Vertex shader inputs can only be float, floating-point vectors, matrices, signed and unsigned
    321 // integers and integer vectors. Vertex shader inputs cannot be arrays or structures.
    322 
    323 enum AttributeType
    324 {
    325    ATTRIBUTE_FLOAT,
    326    ATTRIBUTE_VEC2,
    327    ATTRIBUTE_VEC3,
    328    ATTRIBUTE_VEC4,
    329    ATTRIBUTE_INT,
    330    ATTRIBUTE_IVEC2,
    331    ATTRIBUTE_IVEC3,
    332    ATTRIBUTE_IVEC4,
    333    ATTRIBUTE_UINT,
    334    ATTRIBUTE_UVEC2,
    335    ATTRIBUTE_UVEC3,
    336    ATTRIBUTE_UVEC4,
    337    ATTRIBUTE_MAT2,
    338    ATTRIBUTE_MAT3,
    339    ATTRIBUTE_MAT4,
    340    ATTRIBUTE_MAT2x3,
    341    ATTRIBUTE_MAT2x4,
    342    ATTRIBUTE_MAT3x2,
    343    ATTRIBUTE_MAT3x4,
    344    ATTRIBUTE_MAT4x2,
    345    ATTRIBUTE_MAT4x3,
    346 };
    347 
    348 AttributeType GetAttributeType(GLenum enumValue);
    349 
    350 typedef std::vector<angle::FormatID> InputLayout;
    351 
    352 struct VertexFormat : private angle::NonCopyable
    353 {
    354    VertexFormat(GLenum typeIn, GLboolean normalizedIn, GLuint componentsIn, bool pureIntegerIn);
    355 
    356    GLenum type;
    357    GLboolean normalized;
    358    GLuint components;
    359    bool pureInteger;
    360 };
    361 
    362 angle::FormatID GetVertexFormatID(VertexAttribType type,
    363                                  GLboolean normalized,
    364                                  GLuint components,
    365                                  bool pureInteger);
    366 
    367 angle::FormatID GetVertexFormatID(const VertexAttribute &attrib, VertexAttribType currentValueType);
    368 angle::FormatID GetCurrentValueFormatID(VertexAttribType currentValueType);
    369 const VertexFormat &GetVertexFormatFromID(angle::FormatID vertexFormatID);
    370 size_t GetVertexFormatSize(angle::FormatID vertexFormatID);
    371 angle::FormatID ConvertFormatSignedness(const angle::Format &format);
    372 
    373 ANGLE_INLINE bool IsS3TCFormat(const GLenum format)
    374 {
    375    switch (format)
    376    {
    377        case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
    378        case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
    379        case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
    380        case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
    381        case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
    382        case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
    383        case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
    384        case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
    385            return true;
    386 
    387        default:
    388            return false;
    389    }
    390 }
    391 
    392 ANGLE_INLINE bool IsRGTCFormat(const GLenum format)
    393 {
    394    switch (format)
    395    {
    396        case GL_COMPRESSED_RED_RGTC1_EXT:
    397        case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT:
    398        case GL_COMPRESSED_RED_GREEN_RGTC2_EXT:
    399        case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT:
    400            return true;
    401 
    402        default:
    403            return false;
    404    }
    405 }
    406 
    407 ANGLE_INLINE bool IsBPTCFormat(const GLenum format)
    408 {
    409    switch (format)
    410    {
    411        case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
    412        case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT:
    413        case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT:
    414        case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT:
    415            return true;
    416 
    417        default:
    418            return false;
    419    }
    420 }
    421 
    422 ANGLE_INLINE bool IsASTC2DFormat(const GLenum format)
    423 {
    424    if ((format >= GL_COMPRESSED_RGBA_ASTC_4x4_KHR &&
    425         format <= GL_COMPRESSED_RGBA_ASTC_12x12_KHR) ||
    426        (format >= GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR &&
    427         format <= GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR))
    428    {
    429        return true;
    430    }
    431    return false;
    432 }
    433 
    434 ANGLE_INLINE bool IsETC1Format(const GLenum format)
    435 {
    436    switch (format)
    437    {
    438        case GL_ETC1_RGB8_OES:
    439            return true;
    440 
    441        default:
    442            return false;
    443    }
    444 }
    445 
    446 ANGLE_INLINE bool IsETC2EACFormat(const GLenum format)
    447 {
    448    // ES 3.1, Table 8.19
    449    switch (format)
    450    {
    451        case GL_COMPRESSED_R11_EAC:
    452        case GL_COMPRESSED_SIGNED_R11_EAC:
    453        case GL_COMPRESSED_RG11_EAC:
    454        case GL_COMPRESSED_SIGNED_RG11_EAC:
    455        case GL_COMPRESSED_RGB8_ETC2:
    456        case GL_COMPRESSED_SRGB8_ETC2:
    457        case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
    458        case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
    459        case GL_COMPRESSED_RGBA8_ETC2_EAC:
    460        case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
    461            return true;
    462 
    463        default:
    464            return false;
    465    }
    466 }
    467 
    468 ANGLE_INLINE bool IsPVRTC1Format(const GLenum format)
    469 {
    470    switch (format)
    471    {
    472        case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
    473        case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
    474        case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
    475        case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
    476        case GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT:
    477        case GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT:
    478        case GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT:
    479        case GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT:
    480            return true;
    481 
    482        default:
    483            return false;
    484    }
    485 }
    486 
    487 ANGLE_INLINE bool IsBGRAFormat(const GLenum internalFormat)
    488 {
    489    switch (internalFormat)
    490    {
    491        case GL_BGRA8_EXT:
    492        case GL_BGRA4_ANGLEX:
    493        case GL_BGR5_A1_ANGLEX:
    494        case GL_BGRA8_SRGB_ANGLEX:
    495        case GL_BGRX8_ANGLEX:
    496        case GL_RGBX8_ANGLE:
    497        case GL_BGR565_ANGLEX:
    498        case GL_BGR10_A2_ANGLEX:
    499            return true;
    500 
    501        default:
    502            return false;
    503    }
    504 }
    505 
    506 // Check if an internal format is ever valid in ES3.  Makes no checks about support for a specific
    507 // context.
    508 bool ValidES3InternalFormat(GLenum internalFormat);
    509 
    510 // Implemented in format_map_autogen.cpp
    511 bool ValidES3Format(GLenum format);
    512 bool ValidES3Type(GLenum type);
    513 bool ValidES3FormatCombination(GLenum format, GLenum type, GLenum internalFormat);
    514 
    515 // Implemented in format_map_desktop.cpp
    516 bool ValidDesktopFormat(GLenum format);
    517 bool ValidDesktopType(GLenum type);
    518 bool ValidDesktopFormatCombination(GLenum format, GLenum type, GLenum internalFormat);
    519 
    520 // Implemented in es3_copy_conversion_table_autogen.cpp
    521 bool ValidES3CopyConversion(GLenum textureFormat, GLenum framebufferFormat);
    522 
    523 ANGLE_INLINE ComponentType GetVertexAttributeComponentType(bool pureInteger, VertexAttribType type)
    524 {
    525    if (pureInteger)
    526    {
    527        switch (type)
    528        {
    529            case VertexAttribType::Byte:
    530            case VertexAttribType::Short:
    531            case VertexAttribType::Int:
    532                return ComponentType::Int;
    533 
    534            case VertexAttribType::UnsignedByte:
    535            case VertexAttribType::UnsignedShort:
    536            case VertexAttribType::UnsignedInt:
    537                return ComponentType::UnsignedInt;
    538 
    539            default:
    540                UNREACHABLE();
    541                return ComponentType::NoType;
    542        }
    543    }
    544    else
    545    {
    546        return ComponentType::Float;
    547    }
    548 }
    549 
    550 constexpr std::size_t kMaxYuvPlaneCount = 3;
    551 template <typename T>
    552 using YuvPlaneArray = std::array<T, kMaxYuvPlaneCount>;
    553 
    554 struct YuvFormatInfo
    555 {
    556    // Sized types only.
    557    YuvFormatInfo(GLenum internalFormat, const Extents &yPlaneExtent);
    558 
    559    GLenum glInternalFormat;
    560    uint32_t planeCount;
    561    YuvPlaneArray<uint32_t> planeBpp;
    562    YuvPlaneArray<Extents> planeExtent;
    563    YuvPlaneArray<uint32_t> planePitch;
    564    YuvPlaneArray<uint32_t> planeSize;
    565    YuvPlaneArray<uint32_t> planeOffset;
    566 };
    567 
    568 bool IsYuvFormat(GLenum format);
    569 uint32_t GetPlaneCount(GLenum format);
    570 uint32_t GetYPlaneBpp(GLenum format);
    571 uint32_t GetChromaPlaneBpp(GLenum format);
    572 void GetSubSampleFactor(GLenum format,
    573                        int *horizontalSubsampleFactor,
    574                        int *verticalSubsampleFactor);
    575 }  // namespace gl
    576 
    577 #endif  // LIBANGLE_FORMATUTILS_H_