tor-browser

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

Caps.cpp (63665B)


      1 //
      2 // Copyright 2014 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 #include "libANGLE/Caps.h"
      8 
      9 #include "common/angleutils.h"
     10 #include "common/debug.h"
     11 
     12 #include "libANGLE/formatutils.h"
     13 
     14 #include "angle_gl.h"
     15 
     16 #include <algorithm>
     17 #include <sstream>
     18 
     19 static void InsertExtensionString(const std::string &extension,
     20                                  bool supported,
     21                                  std::vector<std::string> *extensionVector)
     22 {
     23    if (supported)
     24    {
     25        extensionVector->push_back(extension);
     26    }
     27 }
     28 
     29 namespace gl
     30 {
     31 
     32 TextureCaps::TextureCaps() = default;
     33 
     34 TextureCaps::TextureCaps(const TextureCaps &other) = default;
     35 
     36 TextureCaps &TextureCaps::operator=(const TextureCaps &other) = default;
     37 
     38 TextureCaps::~TextureCaps() = default;
     39 
     40 GLuint TextureCaps::getMaxSamples() const
     41 {
     42    return !sampleCounts.empty() ? *sampleCounts.rbegin() : 0;
     43 }
     44 
     45 GLuint TextureCaps::getNearestSamples(GLuint requestedSamples) const
     46 {
     47    if (requestedSamples == 0)
     48    {
     49        return 0;
     50    }
     51 
     52    for (SupportedSampleSet::const_iterator i = sampleCounts.begin(); i != sampleCounts.end(); i++)
     53    {
     54        GLuint samples = *i;
     55        if (samples >= requestedSamples)
     56        {
     57            return samples;
     58        }
     59    }
     60 
     61    return 0;
     62 }
     63 
     64 TextureCaps GenerateMinimumTextureCaps(GLenum sizedInternalFormat,
     65                                       const Version &clientVersion,
     66                                       const Extensions &extensions)
     67 {
     68    TextureCaps caps;
     69 
     70    const InternalFormat &internalFormatInfo = GetSizedInternalFormatInfo(sizedInternalFormat);
     71    caps.texturable        = internalFormatInfo.textureSupport(clientVersion, extensions);
     72    caps.filterable        = internalFormatInfo.filterSupport(clientVersion, extensions);
     73    caps.textureAttachment = internalFormatInfo.textureAttachmentSupport(clientVersion, extensions);
     74    caps.renderbuffer      = internalFormatInfo.renderbufferSupport(clientVersion, extensions);
     75    caps.blendable         = internalFormatInfo.blendSupport(clientVersion, extensions);
     76 
     77    caps.sampleCounts.insert(0);
     78    if (internalFormatInfo.isRequiredRenderbufferFormat(clientVersion))
     79    {
     80        if ((clientVersion.major >= 3 && clientVersion.minor >= 1) ||
     81            (clientVersion.major >= 3 && !internalFormatInfo.isInt()))
     82        {
     83            caps.sampleCounts.insert(4);
     84        }
     85    }
     86 
     87    return caps;
     88 }
     89 
     90 TextureCapsMap::TextureCapsMap() {}
     91 
     92 TextureCapsMap::~TextureCapsMap() {}
     93 
     94 void TextureCapsMap::insert(GLenum internalFormat, const TextureCaps &caps)
     95 {
     96    angle::FormatID formatID = angle::Format::InternalFormatToID(internalFormat);
     97    get(formatID)            = caps;
     98 }
     99 
    100 void TextureCapsMap::clear()
    101 {
    102    mFormatData.fill(TextureCaps());
    103 }
    104 
    105 const TextureCaps &TextureCapsMap::get(GLenum internalFormat) const
    106 {
    107    angle::FormatID formatID = angle::Format::InternalFormatToID(internalFormat);
    108    return get(formatID);
    109 }
    110 
    111 const TextureCaps &TextureCapsMap::get(angle::FormatID formatID) const
    112 {
    113    return mFormatData[formatID];
    114 }
    115 
    116 TextureCaps &TextureCapsMap::get(angle::FormatID formatID)
    117 {
    118    return mFormatData[formatID];
    119 }
    120 
    121 void TextureCapsMap::set(angle::FormatID formatID, const TextureCaps &caps)
    122 {
    123    get(formatID) = caps;
    124 }
    125 
    126 void InitMinimumTextureCapsMap(const Version &clientVersion,
    127                               const Extensions &extensions,
    128                               TextureCapsMap *capsMap)
    129 {
    130    for (GLenum internalFormat : GetAllSizedInternalFormats())
    131    {
    132        capsMap->insert(internalFormat,
    133                        GenerateMinimumTextureCaps(internalFormat, clientVersion, extensions));
    134    }
    135 }
    136 
    137 Extensions::Extensions() = default;
    138 
    139 Extensions::Extensions(const Extensions &other) = default;
    140 
    141 Extensions &Extensions::operator=(const Extensions &other) = default;
    142 
    143 std::vector<std::string> Extensions::getStrings() const
    144 {
    145    std::vector<std::string> extensionStrings;
    146 
    147    for (const auto &extensionInfo : GetExtensionInfoMap())
    148    {
    149        if (this->*(extensionInfo.second.ExtensionsMember))
    150        {
    151            extensionStrings.push_back(extensionInfo.first);
    152        }
    153    }
    154 
    155    return extensionStrings;
    156 }
    157 
    158 Limitations::Limitations()                         = default;
    159 Limitations::Limitations(const Limitations &other) = default;
    160 
    161 Limitations &Limitations::operator=(const Limitations &other) = default;
    162 
    163 static bool GetFormatSupportBase(const TextureCapsMap &textureCaps,
    164                                 const GLenum *requiredFormats,
    165                                 size_t requiredFormatsSize,
    166                                 bool requiresTexturing,
    167                                 bool requiresFiltering,
    168                                 bool requiresAttachingTexture,
    169                                 bool requiresRenderbufferSupport,
    170                                 bool requiresBlending)
    171 {
    172    for (size_t i = 0; i < requiredFormatsSize; i++)
    173    {
    174        const TextureCaps &cap = textureCaps.get(requiredFormats[i]);
    175        if (requiresTexturing && !cap.texturable)
    176        {
    177            return false;
    178        }
    179 
    180        if (requiresFiltering && !cap.filterable)
    181        {
    182            return false;
    183        }
    184 
    185        if (requiresAttachingTexture && !cap.textureAttachment)
    186        {
    187            return false;
    188        }
    189 
    190        if (requiresRenderbufferSupport && !cap.renderbuffer)
    191        {
    192            return false;
    193        }
    194 
    195        if (requiresBlending && !cap.blendable)
    196        {
    197            return false;
    198        }
    199    }
    200 
    201    return true;
    202 }
    203 
    204 template <size_t N>
    205 static bool GetFormatSupport(const TextureCapsMap &textureCaps,
    206                             const GLenum (&requiredFormats)[N],
    207                             bool requiresTexturing,
    208                             bool requiresFiltering,
    209                             bool requiresAttachingTexture,
    210                             bool requiresRenderbufferSupport,
    211                             bool requiresBlending)
    212 {
    213    return GetFormatSupportBase(textureCaps, requiredFormats, N, requiresTexturing,
    214                                requiresFiltering, requiresAttachingTexture,
    215                                requiresRenderbufferSupport, requiresBlending);
    216 }
    217 
    218 // Check for GL_OES_packed_depth_stencil support
    219 static bool DeterminePackedDepthStencilSupport(const TextureCapsMap &textureCaps)
    220 {
    221    constexpr GLenum requiredFormats[] = {
    222        GL_DEPTH24_STENCIL8,
    223    };
    224 
    225    return GetFormatSupport(textureCaps, requiredFormats, false, false, true, true, false);
    226 }
    227 
    228 // Checks for GL_NV_read_depth support
    229 static bool DetermineReadDepthSupport(const TextureCapsMap &textureCaps)
    230 {
    231    constexpr GLenum requiredFormats[] = {
    232        GL_DEPTH_COMPONENT16,
    233    };
    234 
    235    return GetFormatSupport(textureCaps, requiredFormats, true, false, true, false, false);
    236 }
    237 
    238 // Checks for GL_NV_read_stencil support
    239 static bool DetermineReadStencilSupport(const TextureCapsMap &textureCaps)
    240 {
    241    constexpr GLenum requiredFormats[] = {
    242        GL_STENCIL_INDEX8,
    243    };
    244 
    245    return GetFormatSupport(textureCaps, requiredFormats, false, false, true, false, false);
    246 }
    247 
    248 // Checks for GL_NV_depth_buffer_float2 support
    249 static bool DetermineDepthBufferFloat2Support(const TextureCapsMap &textureCaps)
    250 {
    251    constexpr GLenum requiredFormats[] = {
    252        GL_DEPTH_COMPONENT32F,
    253        GL_DEPTH32F_STENCIL8,
    254    };
    255 
    256    return GetFormatSupport(textureCaps, requiredFormats, true, false, true, false, false);
    257 }
    258 
    259 // Checks for GL_OES_rgb8_rgba8 support
    260 static bool DetermineRGB8AndRGBA8TextureSupport(const TextureCapsMap &textureCaps)
    261 {
    262    constexpr GLenum requiredFormats[] = {
    263        GL_RGB8,
    264        GL_RGBA8,
    265    };
    266 
    267    return GetFormatSupport(textureCaps, requiredFormats, false, false, false, true, false);
    268 }
    269 
    270 // Checks for GL_EXT_texture_format_BGRA8888 support
    271 static bool DetermineBGRA8TextureSupport(const TextureCapsMap &textureCaps)
    272 {
    273    constexpr GLenum requiredFormats[] = {
    274        GL_BGRA8_EXT,
    275    };
    276 
    277    return GetFormatSupport(textureCaps, requiredFormats, true, true, true, true, false);
    278 }
    279 
    280 // Checks for GL_EXT_read_format_bgra support
    281 static bool DetermineBGRAReadFormatSupport(const TextureCapsMap &textureCaps)
    282 {
    283    constexpr GLenum requiredFormats[] = {
    284        GL_BGRA8_EXT,
    285        // TODO(http://anglebug.com/4302): GL_EXT_read_format_bgra specifies 2 more types, which are
    286        // currently ignored. The equivalent formats would be: GL_BGRA4_ANGLEX, GL_BGR5_A1_ANGLEX
    287    };
    288 
    289    return GetFormatSupport(textureCaps, requiredFormats, true, false, true, true, false);
    290 }
    291 
    292 // Checks for GL_OES_color_buffer_half_float support
    293 static bool DetermineColorBufferHalfFloatSupport(const TextureCapsMap &textureCaps)
    294 {
    295    // EXT_color_buffer_half_float issue #2 states that an implementation doesn't need to support
    296    // rendering to any of the formats but is expected to be able to render to at least one. WebGL
    297    // requires that at least RGBA16F is renderable so we make the same requirement.
    298    constexpr GLenum requiredFormats[] = {
    299        GL_RGBA16F,
    300    };
    301 
    302    return GetFormatSupport(textureCaps, requiredFormats, false, false, true, true, false);
    303 }
    304 
    305 // Checks for GL_OES_texture_half_float support
    306 static bool DetermineHalfFloatTextureSupport(const TextureCapsMap &textureCaps)
    307 {
    308    constexpr GLenum requiredFormats[] = {
    309        GL_RGBA16F, GL_RGB16F, GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE16F_EXT, GL_ALPHA16F_EXT,
    310    };
    311 
    312    return GetFormatSupport(textureCaps, requiredFormats, true, false, false, false, false);
    313 }
    314 
    315 // Checks for GL_OES_texture_half_float_linear support
    316 static bool DetermineHalfFloatTextureFilteringSupport(const TextureCapsMap &textureCaps,
    317                                                      bool checkLegacyFormats)
    318 {
    319    constexpr GLenum requiredFormats[] = {GL_RGBA16F, GL_RGB16F};
    320    // If GL_OES_texture_half_float is present, this extension must also support legacy formats
    321    // introduced by that extension
    322    constexpr GLenum requiredFormatsES2[] = {GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE16F_EXT,
    323                                             GL_ALPHA16F_EXT};
    324 
    325    if (checkLegacyFormats &&
    326        !GetFormatSupport(textureCaps, requiredFormatsES2, false, true, false, false, false))
    327    {
    328        return false;
    329    }
    330 
    331    return GetFormatSupport(textureCaps, requiredFormats, false, true, false, false, false);
    332 }
    333 
    334 // Checks for GL_OES_texture_float support
    335 static bool DetermineFloatTextureSupport(const TextureCapsMap &textureCaps)
    336 {
    337    constexpr GLenum requiredFormats[] = {
    338        GL_RGBA32F, GL_RGB32F, GL_LUMINANCE_ALPHA32F_EXT, GL_LUMINANCE32F_EXT, GL_ALPHA32F_EXT,
    339    };
    340 
    341    return GetFormatSupport(textureCaps, requiredFormats, true, false, false, false, false);
    342 }
    343 
    344 // Checks for GL_OES_texture_float_linear support
    345 static bool DetermineFloatTextureFilteringSupport(const TextureCapsMap &textureCaps,
    346                                                  bool checkLegacyFormats)
    347 {
    348    constexpr GLenum requiredFormats[] = {
    349        GL_RGBA32F,
    350        GL_RGB32F,
    351    };
    352    // If GL_OES_texture_float is present, this extension must also support legacy formats
    353    // introduced by that extension
    354    constexpr GLenum requiredFormatsES2[] = {
    355        GL_LUMINANCE_ALPHA32F_EXT,
    356        GL_LUMINANCE32F_EXT,
    357        GL_ALPHA32F_EXT,
    358    };
    359 
    360    if (checkLegacyFormats &&
    361        !GetFormatSupport(textureCaps, requiredFormatsES2, false, true, false, false, false))
    362    {
    363        return false;
    364    }
    365 
    366    return GetFormatSupport(textureCaps, requiredFormats, false, true, false, false, false);
    367 }
    368 
    369 // Checks for GL_EXT_texture_rg support
    370 static bool DetermineRGTextureSupport(const TextureCapsMap &textureCaps,
    371                                      bool checkHalfFloatFormats,
    372                                      bool checkFloatFormats)
    373 {
    374    constexpr GLenum requiredFormats[] = {
    375        GL_R8,
    376        GL_RG8,
    377    };
    378    constexpr GLenum requiredHalfFloatFormats[] = {
    379        GL_R16F,
    380        GL_RG16F,
    381    };
    382    constexpr GLenum requiredFloatFormats[] = {
    383        GL_R32F,
    384        GL_RG32F,
    385    };
    386 
    387    if (checkHalfFloatFormats &&
    388        !GetFormatSupport(textureCaps, requiredHalfFloatFormats, true, false, false, false, false))
    389    {
    390        return false;
    391    }
    392 
    393    if (checkFloatFormats &&
    394        !GetFormatSupport(textureCaps, requiredFloatFormats, true, false, false, false, false))
    395    {
    396        return false;
    397    }
    398 
    399    return GetFormatSupport(textureCaps, requiredFormats, true, true, true, true, false);
    400 }
    401 
    402 static bool DetermineTextureFormat2101010Support(const TextureCapsMap &textureCaps)
    403 {
    404    // GL_EXT_texture_type_2_10_10_10_REV specifies both RGBA and RGB support whereas desktop GL
    405    // only specifies RGBA support, so check both RGBA and RGB before marking as supported.
    406    constexpr GLenum requiredFormats[] = {
    407        GL_RGB10_A2,
    408        GL_RGB10_UNORM_ANGLEX,
    409    };
    410 
    411    return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
    412 }
    413 
    414 // Check for GL_EXT_texture_compression_dxt1 support
    415 static bool DetermineDXT1TextureSupport(const TextureCapsMap &textureCaps)
    416 {
    417    constexpr GLenum requiredFormats[] = {
    418        GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
    419        GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
    420    };
    421 
    422    return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
    423 }
    424 
    425 // Check for GL_ANGLE_texture_compression_dxt3 support
    426 static bool DetermineDXT3TextureSupport(const TextureCapsMap &textureCaps)
    427 {
    428    constexpr GLenum requiredFormats[] = {
    429        GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE,
    430    };
    431 
    432    return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
    433 }
    434 
    435 // Check for GL_ANGLE_texture_compression_dxt5 support
    436 static bool DetermineDXT5TextureSupport(const TextureCapsMap &textureCaps)
    437 {
    438    constexpr GLenum requiredFormats[] = {
    439        GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE,
    440    };
    441 
    442    return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
    443 }
    444 
    445 // Check for GL_EXT_texture_compression_s3tc_srgb support
    446 static bool DetermineS3TCsRGBTextureSupport(const TextureCapsMap &textureCaps)
    447 {
    448    constexpr GLenum requiredFormats[] = {
    449        GL_COMPRESSED_SRGB_S3TC_DXT1_EXT,
    450        GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT,
    451        GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT,
    452        GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT,
    453    };
    454 
    455    return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
    456 }
    457 
    458 // Check for GL_KHR_texture_compression_astc_ldr support
    459 static bool DetermineASTCLDRTextureSupport(const TextureCapsMap &textureCaps)
    460 {
    461    constexpr GLenum requiredFormats[] = {
    462        GL_COMPRESSED_RGBA_ASTC_4x4_KHR,           GL_COMPRESSED_RGBA_ASTC_5x4_KHR,
    463        GL_COMPRESSED_RGBA_ASTC_5x5_KHR,           GL_COMPRESSED_RGBA_ASTC_6x5_KHR,
    464        GL_COMPRESSED_RGBA_ASTC_6x6_KHR,           GL_COMPRESSED_RGBA_ASTC_8x5_KHR,
    465        GL_COMPRESSED_RGBA_ASTC_8x6_KHR,           GL_COMPRESSED_RGBA_ASTC_8x8_KHR,
    466        GL_COMPRESSED_RGBA_ASTC_10x5_KHR,          GL_COMPRESSED_RGBA_ASTC_10x6_KHR,
    467        GL_COMPRESSED_RGBA_ASTC_10x8_KHR,          GL_COMPRESSED_RGBA_ASTC_10x10_KHR,
    468        GL_COMPRESSED_RGBA_ASTC_12x10_KHR,         GL_COMPRESSED_RGBA_ASTC_12x12_KHR,
    469        GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR,   GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR,
    470        GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR,   GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR,
    471        GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR,   GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR,
    472        GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR,   GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR,
    473        GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR,  GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR,
    474        GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR,  GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR,
    475        GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR,
    476    };
    477 
    478    return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
    479 }
    480 
    481 // Check for GL_OES_texture_compression_astc support
    482 static bool DetermineASTCOESTExtureSupport(const TextureCapsMap &textureCaps)
    483 {
    484    if (!DetermineASTCLDRTextureSupport(textureCaps))
    485    {
    486        return false;
    487    }
    488 
    489    // The OES version of the extension also requires the 3D ASTC formats
    490    constexpr GLenum requiredFormats[] = {
    491        GL_COMPRESSED_RGBA_ASTC_3x3x3_OES,         GL_COMPRESSED_RGBA_ASTC_4x3x3_OES,
    492        GL_COMPRESSED_RGBA_ASTC_4x4x3_OES,         GL_COMPRESSED_RGBA_ASTC_4x4x4_OES,
    493        GL_COMPRESSED_RGBA_ASTC_5x4x4_OES,         GL_COMPRESSED_RGBA_ASTC_5x5x4_OES,
    494        GL_COMPRESSED_RGBA_ASTC_5x5x5_OES,         GL_COMPRESSED_RGBA_ASTC_6x5x5_OES,
    495        GL_COMPRESSED_RGBA_ASTC_6x6x5_OES,         GL_COMPRESSED_RGBA_ASTC_6x6x6_OES,
    496        GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES,
    497        GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES,
    498        GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES,
    499        GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES,
    500        GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES,
    501    };
    502 
    503    return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
    504 }
    505 
    506 // Check for GL_ETC1_RGB8_OES support
    507 static bool DetermineETC1RGB8TextureSupport(const TextureCapsMap &textureCaps)
    508 {
    509    constexpr GLenum requiredFormats[] = {
    510        GL_ETC1_RGB8_OES,
    511    };
    512 
    513    return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
    514 }
    515 
    516 // Check for OES_compressed_ETC2_RGB8_texture support
    517 static bool DetermineETC2RGB8TextureSupport(const TextureCapsMap &textureCaps)
    518 {
    519    constexpr GLenum requiredFormats[] = {
    520        GL_COMPRESSED_RGB8_ETC2,
    521    };
    522 
    523    return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
    524 }
    525 
    526 // Check for OES_compressed_ETC2_sRGB8_texture support
    527 static bool DetermineETC2sRGB8TextureSupport(const TextureCapsMap &textureCaps)
    528 {
    529    constexpr GLenum requiredFormats[] = {
    530        GL_COMPRESSED_SRGB8_ETC2,
    531    };
    532 
    533    return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
    534 }
    535 
    536 // Check for OES_compressed_ETC2_punchthroughA_RGBA8_texture support
    537 static bool DetermineETC2PunchthroughARGB8TextureSupport(const TextureCapsMap &textureCaps)
    538 {
    539    constexpr GLenum requiredFormats[] = {
    540        GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,
    541    };
    542 
    543    return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
    544 }
    545 
    546 // Check for OES_compressed_ETC2_punchthroughA_sRGB8_alpha_texture support
    547 static bool DetermineETC2PunchthroughAsRGB8AlphaTextureSupport(const TextureCapsMap &textureCaps)
    548 {
    549    constexpr GLenum requiredFormats[] = {
    550        GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2,
    551    };
    552 
    553    return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
    554 }
    555 
    556 // Check for OES_compressed_ETC2_RGBA8_texture support
    557 static bool DetermineETC2RGBA8TextureSupport(const TextureCapsMap &textureCaps)
    558 {
    559    constexpr GLenum requiredFormats[] = {
    560        GL_COMPRESSED_RGBA8_ETC2_EAC,
    561    };
    562 
    563    return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
    564 }
    565 
    566 // Check for OES_compressed_ETC2_sRGB8_alpha8_texture support
    567 static bool DetermineETC2sRGB8Alpha8TextureSupport(const TextureCapsMap &textureCaps)
    568 {
    569    constexpr GLenum requiredFormats[] = {
    570        GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,
    571    };
    572 
    573    return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
    574 }
    575 
    576 // Check for OES_compressed_EAC_R11_unsigned_texture support
    577 static bool DetermineEACR11UnsignedTextureSupport(const TextureCapsMap &textureCaps)
    578 {
    579    constexpr GLenum requiredFormats[] = {
    580        GL_COMPRESSED_R11_EAC,
    581    };
    582 
    583    return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
    584 }
    585 
    586 // Check for OES_compressed_EAC_R11_signed_texture support
    587 static bool DetermineEACR11SignedTextureSupport(const TextureCapsMap &textureCaps)
    588 {
    589    constexpr GLenum requiredFormats[] = {
    590        GL_COMPRESSED_SIGNED_R11_EAC,
    591    };
    592 
    593    return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
    594 }
    595 
    596 // Check for OES_compressed_EAC_RG11_unsigned_texture support
    597 static bool DetermineEACRG11UnsignedTextureSupport(const TextureCapsMap &textureCaps)
    598 {
    599    constexpr GLenum requiredFormats[] = {
    600        GL_COMPRESSED_RG11_EAC,
    601    };
    602 
    603    return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
    604 }
    605 
    606 // Check for OES_compressed_EAC_RG11_signed_texture support
    607 static bool DetermineEACRG11SignedTextureSupport(const TextureCapsMap &textureCaps)
    608 {
    609    constexpr GLenum requiredFormats[] = {
    610        GL_COMPRESSED_SIGNED_RG11_EAC,
    611    };
    612 
    613    return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
    614 }
    615 
    616 // Check for GL_EXT_sRGB support
    617 static bool DetermineSRGBTextureSupport(const TextureCapsMap &textureCaps)
    618 {
    619    constexpr GLenum requiredFilterFormats[] = {
    620        GL_SRGB8,
    621        GL_SRGB8_ALPHA8,
    622    };
    623 
    624    constexpr GLenum requiredRenderFormats[] = {
    625        GL_SRGB8_ALPHA8,
    626    };
    627 
    628    return GetFormatSupport(textureCaps, requiredFilterFormats, true, true, false, false, false) &&
    629           GetFormatSupport(textureCaps, requiredRenderFormats, true, false, true, true, false);
    630 }
    631 
    632 // Check for GL_EXT_texture_sRGB_R8 support
    633 static bool DetermineSRGBR8TextureSupport(const TextureCapsMap &textureCaps)
    634 {
    635    constexpr GLenum requiredFilterFormats[] = {GL_SR8_EXT};
    636 
    637    return GetFormatSupport(textureCaps, requiredFilterFormats, true, true, false, false, false);
    638 }
    639 
    640 // Check for GL_EXT_texture_sRGB_RG8 support
    641 static bool DetermineSRGBRG8TextureSupport(const TextureCapsMap &textureCaps)
    642 {
    643    constexpr GLenum requiredFilterFormats[] = {GL_SRG8_EXT};
    644 
    645    return GetFormatSupport(textureCaps, requiredFilterFormats, true, true, false, false, false);
    646 }
    647 
    648 // Check for GL_ANGLE_depth_texture support
    649 static bool DetermineDepthTextureANGLESupport(const TextureCapsMap &textureCaps)
    650 {
    651    constexpr GLenum requiredFormats[] = {
    652        GL_DEPTH_COMPONENT16,
    653 #if !defined(ANGLE_PLATFORM_IOS) && \
    654    (!defined(ANGLE_PLATFORM_MACCATALYST) || !defined(ANGLE_CPU_ARM64))
    655        // anglebug.com/6082
    656        // TODO(dino): Temporarily Removing the need for GL_DEPTH_COMPONENT32_OES
    657        // because it is not supported on iOS.
    658        // TODO(dino): I think this needs to be a runtime check when running an iOS app on Mac.
    659        GL_DEPTH_COMPONENT32_OES,
    660 #endif
    661        GL_DEPTH24_STENCIL8_OES,
    662    };
    663 
    664    return GetFormatSupport(textureCaps, requiredFormats, true, false, true, false, false);
    665 }
    666 
    667 // Check for GL_OES_depth_texture support
    668 static bool DetermineDepthTextureOESSupport(const TextureCapsMap &textureCaps)
    669 {
    670    constexpr GLenum requiredFormats[] = {
    671        GL_DEPTH_COMPONENT16,
    672 #if !defined(ANGLE_PLATFORM_IOS) && \
    673    (!defined(ANGLE_PLATFORM_MACCATALYST) || !defined(ANGLE_CPU_ARM64))
    674        // anglebug.com/6082
    675        // TODO(dino): Temporarily Removing the need for GL_DEPTH_COMPONENT32_OES
    676        // because it is not supported on iOS.
    677        // TODO(dino): I think this needs to be a runtime check when running an iOS app on Mac.
    678        GL_DEPTH_COMPONENT32_OES,
    679 #endif
    680    };
    681 
    682    return GetFormatSupport(textureCaps, requiredFormats, true, false, true, true, false);
    683 }
    684 
    685 // Check for GL_OES_depth24
    686 static bool DetermineDepth24OESSupport(const TextureCapsMap &textureCaps)
    687 {
    688    constexpr GLenum requiredFormats[] = {
    689        GL_DEPTH_COMPONENT24_OES,
    690    };
    691 
    692    return GetFormatSupport(textureCaps, requiredFormats, false, false, false, true, false);
    693 }
    694 
    695 // Check for GL_OES_depth32 support
    696 static bool DetermineDepth32Support(const TextureCapsMap &textureCaps)
    697 {
    698    constexpr GLenum requiredFormats[] = {
    699        GL_DEPTH_COMPONENT32_OES,
    700    };
    701 
    702    return GetFormatSupport(textureCaps, requiredFormats, false, false, true, true, false);
    703 }
    704 
    705 // Check for GL_CHROMIUM_color_buffer_float_rgb support
    706 static bool DetermineColorBufferFloatRGBSupport(const TextureCapsMap &textureCaps)
    707 {
    708    constexpr GLenum requiredFormats[] = {
    709        GL_RGB32F,
    710    };
    711 
    712    return GetFormatSupport(textureCaps, requiredFormats, true, false, true, false, false);
    713 }
    714 
    715 // Check for GL_CHROMIUM_color_buffer_float_rgba support
    716 static bool DetermineColorBufferFloatRGBASupport(const TextureCapsMap &textureCaps)
    717 {
    718    constexpr GLenum requiredFormats[] = {
    719        GL_RGBA32F,
    720    };
    721 
    722    return GetFormatSupport(textureCaps, requiredFormats, true, false, true, true, false);
    723 }
    724 
    725 // Check for GL_EXT_color_buffer_float support
    726 static bool DetermineColorBufferFloatSupport(const TextureCapsMap &textureCaps)
    727 {
    728    constexpr GLenum nonBlendableFormats[] = {
    729        GL_R32F,
    730        GL_RG32F,
    731        GL_RGBA32F,
    732    };
    733 
    734    constexpr GLenum blendableFormats[] = {
    735        GL_R16F,
    736        GL_RG16F,
    737        GL_RGBA16F,
    738        GL_R11F_G11F_B10F,
    739    };
    740 
    741    return GetFormatSupport(textureCaps, nonBlendableFormats, true, false, true, true, false) &&
    742           GetFormatSupport(textureCaps, blendableFormats, true, false, true, true, true);
    743 }
    744 
    745 // Check for GL_EXT_float_blend support
    746 static bool DetermineFloatBlendSupport(const TextureCapsMap &textureCaps)
    747 {
    748    constexpr GLenum requiredFormats[] = {
    749        GL_R32F,
    750        GL_RG32F,
    751        GL_RGBA32F,
    752    };
    753 
    754    return GetFormatSupport(textureCaps, requiredFormats, true, false, true, true, true);
    755 }
    756 
    757 // Check for GL_EXT_texture_norm16 support
    758 static bool DetermineTextureNorm16Support(const TextureCapsMap &textureCaps)
    759 {
    760    constexpr GLenum requiredFilterFormats[] = {
    761        GL_R16_EXT,       GL_RG16_EXT,       GL_RGB16_EXT,       GL_RGBA16_EXT,
    762        GL_R16_SNORM_EXT, GL_RG16_SNORM_EXT, GL_RGB16_SNORM_EXT, GL_RGBA16_SNORM_EXT,
    763    };
    764 
    765    constexpr GLenum requiredRenderFormats[] = {
    766        GL_R16_EXT,
    767        GL_RG16_EXT,
    768        GL_RGBA16_EXT,
    769    };
    770 
    771    return GetFormatSupport(textureCaps, requiredFilterFormats, true, true, false, false, false) &&
    772           GetFormatSupport(textureCaps, requiredRenderFormats, true, false, true, true, false);
    773 }
    774 
    775 // Check for EXT_texture_compression_rgtc support
    776 static bool DetermineRGTCTextureSupport(const TextureCapsMap &textureCaps)
    777 {
    778    constexpr GLenum requiredFormats[] = {
    779        GL_COMPRESSED_RED_RGTC1_EXT, GL_COMPRESSED_SIGNED_RED_RGTC1_EXT,
    780        GL_COMPRESSED_RED_GREEN_RGTC2_EXT, GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT};
    781 
    782    return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
    783 }
    784 
    785 // Check for EXT_texture_compression_bptc support
    786 static bool DetermineBPTCTextureSupport(const TextureCapsMap &textureCaps)
    787 {
    788    constexpr GLenum requiredFormats[] = {
    789        GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT,
    790        GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT, GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT};
    791 
    792    return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
    793 }
    794 
    795 // Check for GL_IMG_texture_compression_pvrtc support
    796 static bool DeterminePVRTCTextureSupport(const TextureCapsMap &textureCaps)
    797 {
    798    constexpr GLenum requiredFormats[] = {
    799        GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG, GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG,
    800        GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG};
    801 
    802    return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
    803 }
    804 
    805 // Check for GL_EXT_pvrtc_sRGB support
    806 static bool DeterminePVRTCsRGBTextureSupport(const TextureCapsMap &textureCaps)
    807 {
    808    constexpr GLenum requiredFormats[] = {
    809        GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT, GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT,
    810        GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT, GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT};
    811 
    812    return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
    813 }
    814 
    815 bool DetermineCompressedTextureETCSupport(const TextureCapsMap &textureCaps)
    816 {
    817    constexpr GLenum requiredFormats[] = {GL_COMPRESSED_R11_EAC,
    818                                          GL_COMPRESSED_SIGNED_R11_EAC,
    819                                          GL_COMPRESSED_RG11_EAC,
    820                                          GL_COMPRESSED_SIGNED_RG11_EAC,
    821                                          GL_COMPRESSED_RGB8_ETC2,
    822                                          GL_COMPRESSED_SRGB8_ETC2,
    823                                          GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,
    824                                          GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2,
    825                                          GL_COMPRESSED_RGBA8_ETC2_EAC,
    826                                          GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC};
    827 
    828    return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
    829 }
    830 
    831 // Checks for GL_OES_texture_stencil8 support
    832 static bool DetermineStencilIndex8Support(const TextureCapsMap &textureCaps)
    833 {
    834    constexpr GLenum requiredFormats[] = {
    835        GL_STENCIL_INDEX8,
    836    };
    837 
    838    return GetFormatSupport(textureCaps, requiredFormats, false, false, true, false, false);
    839 }
    840 
    841 void Extensions::setTextureExtensionSupport(const TextureCapsMap &textureCaps)
    842 {
    843    // TODO(ynovikov): rgb8Rgba8OES, colorBufferHalfFloatEXT, textureHalfFloatOES,
    844    // textureHalfFloatLinearOES, textureFloatOES, textureFloatLinearOES, textureRgEXT, sRGB,
    845    // colorBufferFloatRgbCHROMIUM, colorBufferFloatRgbaCHROMIUM and colorBufferFloatEXT were
    846    // verified. Verify the rest.
    847    packedDepthStencilOES    = DeterminePackedDepthStencilSupport(textureCaps);
    848    rgb8Rgba8OES             = DetermineRGB8AndRGBA8TextureSupport(textureCaps);
    849    readDepthNV              = DetermineReadDepthSupport(textureCaps);
    850    readStencilNV            = DetermineReadStencilSupport(textureCaps);
    851    depthBufferFloat2NV      = DetermineDepthBufferFloat2Support(textureCaps);
    852    textureFormatBGRA8888EXT = DetermineBGRA8TextureSupport(textureCaps);
    853    readFormatBgraEXT        = DetermineBGRAReadFormatSupport(textureCaps);
    854    textureHalfFloatOES      = DetermineHalfFloatTextureSupport(textureCaps);
    855    textureHalfFloatLinearOES =
    856        DetermineHalfFloatTextureFilteringSupport(textureCaps, textureHalfFloatOES);
    857    textureFloatOES       = DetermineFloatTextureSupport(textureCaps);
    858    textureFloatLinearOES = DetermineFloatTextureFilteringSupport(textureCaps, textureFloatOES);
    859    textureRgEXT = DetermineRGTextureSupport(textureCaps, textureHalfFloatOES, textureFloatOES);
    860    colorBufferHalfFloatEXT =
    861        textureHalfFloatOES && DetermineColorBufferHalfFloatSupport(textureCaps);
    862    textureType2101010REVEXT      = DetermineTextureFormat2101010Support(textureCaps);
    863    textureCompressionDxt1EXT     = DetermineDXT1TextureSupport(textureCaps);
    864    textureCompressionDxt3ANGLE   = DetermineDXT3TextureSupport(textureCaps);
    865    textureCompressionDxt5ANGLE   = DetermineDXT5TextureSupport(textureCaps);
    866    textureCompressionS3tcSrgbEXT = DetermineS3TCsRGBTextureSupport(textureCaps);
    867    textureCompressionAstcLdrKHR  = DetermineASTCLDRTextureSupport(textureCaps);
    868    textureCompressionAstcOES     = DetermineASTCOESTExtureSupport(textureCaps);
    869    compressedETC1RGB8TextureOES  = DetermineETC1RGB8TextureSupport(textureCaps);
    870    compressedETC2RGB8TextureOES  = DetermineETC2RGB8TextureSupport(textureCaps);
    871    compressedETC2SRGB8TextureOES = DetermineETC2sRGB8TextureSupport(textureCaps);
    872    compressedETC2PunchthroughARGBA8TextureOES =
    873        DetermineETC2PunchthroughARGB8TextureSupport(textureCaps);
    874    compressedETC2PunchthroughASRGB8AlphaTextureOES =
    875        DetermineETC2PunchthroughAsRGB8AlphaTextureSupport(textureCaps);
    876    compressedETC2RGBA8TextureOES       = DetermineETC2RGBA8TextureSupport(textureCaps);
    877    compressedETC2SRGB8Alpha8TextureOES = DetermineETC2sRGB8Alpha8TextureSupport(textureCaps);
    878    compressedEACR11UnsignedTextureOES  = DetermineEACR11UnsignedTextureSupport(textureCaps);
    879    compressedEACR11SignedTextureOES    = DetermineEACR11SignedTextureSupport(textureCaps);
    880    compressedEACRG11UnsignedTextureOES = DetermineEACRG11UnsignedTextureSupport(textureCaps);
    881    compressedEACRG11SignedTextureOES   = DetermineEACRG11SignedTextureSupport(textureCaps);
    882    sRGBEXT                             = DetermineSRGBTextureSupport(textureCaps);
    883    textureSRGBR8EXT                    = DetermineSRGBR8TextureSupport(textureCaps);
    884    textureSRGBRG8EXT                   = DetermineSRGBRG8TextureSupport(textureCaps);
    885    depthTextureANGLE                   = DetermineDepthTextureANGLESupport(textureCaps);
    886    depthTextureOES                     = DetermineDepthTextureOESSupport(textureCaps);
    887    depth24OES                          = DetermineDepth24OESSupport(textureCaps);
    888    depth32OES                          = DetermineDepth32Support(textureCaps);
    889    colorBufferFloatRgbCHROMIUM         = DetermineColorBufferFloatRGBSupport(textureCaps);
    890    colorBufferFloatRgbaCHROMIUM        = DetermineColorBufferFloatRGBASupport(textureCaps);
    891    colorBufferFloatEXT                 = DetermineColorBufferFloatSupport(textureCaps);
    892    floatBlendEXT                       = DetermineFloatBlendSupport(textureCaps);
    893    textureNorm16EXT                    = DetermineTextureNorm16Support(textureCaps);
    894    textureCompressionRgtcEXT           = DetermineRGTCTextureSupport(textureCaps);
    895    textureCompressionBptcEXT           = DetermineBPTCTextureSupport(textureCaps);
    896    textureCompressionPvrtcIMG          = DeterminePVRTCTextureSupport(textureCaps);
    897    pvrtcSRGBEXT                        = DeterminePVRTCsRGBTextureSupport(textureCaps);
    898    textureStencil8OES                  = DetermineStencilIndex8Support(textureCaps);
    899 }
    900 
    901 TypePrecision::TypePrecision() = default;
    902 
    903 TypePrecision::TypePrecision(const TypePrecision &other) = default;
    904 
    905 TypePrecision &TypePrecision::operator=(const TypePrecision &other) = default;
    906 
    907 void TypePrecision::setIEEEFloat()
    908 {
    909    range     = {{127, 127}};
    910    precision = 23;
    911 }
    912 
    913 void TypePrecision::setIEEEHalfFloat()
    914 {
    915    range     = {{15, 15}};
    916    precision = 10;
    917 }
    918 
    919 void TypePrecision::setTwosComplementInt(unsigned int bits)
    920 {
    921    range     = {{static_cast<GLint>(bits) - 1, static_cast<GLint>(bits) - 2}};
    922    precision = 0;
    923 }
    924 
    925 void TypePrecision::setSimulatedFloat(unsigned int r, unsigned int p)
    926 {
    927    range     = {{static_cast<GLint>(r), static_cast<GLint>(r)}};
    928    precision = static_cast<GLint>(p);
    929 }
    930 
    931 void TypePrecision::setSimulatedInt(unsigned int r)
    932 {
    933    range     = {{static_cast<GLint>(r), static_cast<GLint>(r)}};
    934    precision = 0;
    935 }
    936 
    937 void TypePrecision::get(GLint *returnRange, GLint *returnPrecision) const
    938 {
    939    std::copy(range.begin(), range.end(), returnRange);
    940    *returnPrecision = precision;
    941 }
    942 
    943 Caps::Caps()                             = default;
    944 Caps::Caps(const Caps &other)            = default;
    945 Caps::~Caps()                            = default;
    946 Caps &Caps::operator=(const Caps &other) = default;
    947 
    948 Caps GenerateMinimumCaps(const Version &clientVersion, const Extensions &extensions)
    949 {
    950    Caps caps;
    951 
    952    // GLES1 emulation (Minimums taken from Table 6.20 / 6.22 (ES 1.1 spec))
    953    if (clientVersion < Version(2, 0))
    954    {
    955        caps.maxMultitextureUnits = 2;
    956        caps.maxLights            = 8;
    957        caps.maxClipPlanes        = 1;
    958 
    959        caps.maxModelviewMatrixStackDepth  = 16;
    960        caps.maxProjectionMatrixStackDepth = 2;
    961        caps.maxTextureMatrixStackDepth    = 2;
    962 
    963        caps.minSmoothPointSize = 1.0f;
    964        caps.maxSmoothPointSize = 1.0f;
    965    }
    966 
    967    if (clientVersion >= Version(2, 0))
    968    {
    969        // Table 6.18
    970        caps.max2DTextureSize      = 64;
    971        caps.maxCubeMapTextureSize = 16;
    972        caps.maxViewportWidth      = caps.max2DTextureSize;
    973        caps.maxViewportHeight     = caps.max2DTextureSize;
    974        caps.minAliasedPointSize   = 1;
    975        caps.maxAliasedPointSize   = 1;
    976        caps.minAliasedLineWidth   = 1;
    977        caps.maxAliasedLineWidth   = 1;
    978 
    979        // Table 6.19
    980        caps.vertexHighpFloat.setSimulatedFloat(62, 16);
    981        caps.vertexMediumpFloat.setSimulatedFloat(14, 10);
    982        caps.vertexLowpFloat.setSimulatedFloat(1, 8);
    983        caps.vertexHighpInt.setSimulatedInt(16);
    984        caps.vertexMediumpInt.setSimulatedInt(10);
    985        caps.vertexLowpInt.setSimulatedInt(8);
    986        caps.fragmentHighpFloat.setSimulatedFloat(62, 16);
    987        caps.fragmentMediumpFloat.setSimulatedFloat(14, 10);
    988        caps.fragmentLowpFloat.setSimulatedFloat(1, 8);
    989        caps.fragmentHighpInt.setSimulatedInt(16);
    990        caps.fragmentMediumpInt.setSimulatedInt(10);
    991        caps.fragmentLowpInt.setSimulatedInt(8);
    992 
    993        // Table 6.20
    994        caps.maxVertexAttributes                              = 8;
    995        caps.maxVertexUniformVectors                          = 128;
    996        caps.maxVaryingVectors                                = 8;
    997        caps.maxCombinedTextureImageUnits                     = 8;
    998        caps.maxShaderTextureImageUnits[ShaderType::Fragment] = 8;
    999        caps.maxFragmentUniformVectors                        = 16;
   1000        caps.maxRenderbufferSize                              = 1;
   1001 
   1002        // Table 3.35
   1003        caps.maxSamples = 4;
   1004    }
   1005 
   1006    if (clientVersion >= Version(3, 0))
   1007    {
   1008        // Table 6.28
   1009        caps.maxElementIndex       = (1 << 24) - 1;
   1010        caps.max3DTextureSize      = 256;
   1011        caps.max2DTextureSize      = 2048;
   1012        caps.maxArrayTextureLayers = 256;
   1013        caps.maxLODBias            = 2.0f;
   1014        caps.maxCubeMapTextureSize = 2048;
   1015        caps.maxRenderbufferSize   = 2048;
   1016        caps.maxDrawBuffers        = 4;
   1017        caps.maxColorAttachments   = 4;
   1018        caps.maxViewportWidth      = caps.max2DTextureSize;
   1019        caps.maxViewportHeight     = caps.max2DTextureSize;
   1020 
   1021        // Table 6.29
   1022        caps.compressedTextureFormats.push_back(GL_COMPRESSED_R11_EAC);
   1023        caps.compressedTextureFormats.push_back(GL_COMPRESSED_SIGNED_R11_EAC);
   1024        caps.compressedTextureFormats.push_back(GL_COMPRESSED_RG11_EAC);
   1025        caps.compressedTextureFormats.push_back(GL_COMPRESSED_SIGNED_RG11_EAC);
   1026        caps.compressedTextureFormats.push_back(GL_COMPRESSED_RGB8_ETC2);
   1027        caps.compressedTextureFormats.push_back(GL_COMPRESSED_SRGB8_ETC2);
   1028        caps.compressedTextureFormats.push_back(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2);
   1029        caps.compressedTextureFormats.push_back(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2);
   1030        caps.compressedTextureFormats.push_back(GL_COMPRESSED_RGBA8_ETC2_EAC);
   1031        caps.compressedTextureFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC);
   1032        caps.vertexHighpFloat.setIEEEFloat();
   1033        caps.vertexHighpInt.setTwosComplementInt(32);
   1034        caps.vertexMediumpInt.setTwosComplementInt(16);
   1035        caps.vertexLowpInt.setTwosComplementInt(8);
   1036        caps.fragmentHighpFloat.setIEEEFloat();
   1037        caps.fragmentHighpInt.setSimulatedInt(32);
   1038        caps.fragmentMediumpInt.setTwosComplementInt(16);
   1039        caps.fragmentLowpInt.setTwosComplementInt(8);
   1040        caps.maxServerWaitTimeout = 0;
   1041 
   1042        // Table 6.31
   1043        caps.maxVertexAttributes                            = 16;
   1044        caps.maxShaderUniformComponents[ShaderType::Vertex] = 1024;
   1045        caps.maxVertexUniformVectors                        = 256;
   1046        caps.maxShaderUniformBlocks[ShaderType::Vertex]     = limits::kMinimumShaderUniformBlocks;
   1047        caps.maxVertexOutputComponents = limits::kMinimumVertexOutputComponents;
   1048        caps.maxShaderTextureImageUnits[ShaderType::Vertex] = 16;
   1049 
   1050        // Table 6.32
   1051        caps.maxShaderUniformComponents[ShaderType::Fragment] = 896;
   1052        caps.maxFragmentUniformVectors                        = 224;
   1053        caps.maxShaderUniformBlocks[ShaderType::Fragment]     = limits::kMinimumShaderUniformBlocks;
   1054        caps.maxFragmentInputComponents                       = 60;
   1055        caps.maxShaderTextureImageUnits[ShaderType::Fragment] = 16;
   1056        caps.minProgramTexelOffset                            = -8;
   1057        caps.maxProgramTexelOffset                            = 7;
   1058 
   1059        // Table 6.33
   1060        caps.maxUniformBufferBindings     = 24;
   1061        caps.maxUniformBlockSize          = 16384;
   1062        caps.uniformBufferOffsetAlignment = 256;
   1063        caps.maxCombinedUniformBlocks     = 24;
   1064        caps.maxVaryingComponents         = 60;
   1065        caps.maxVaryingVectors            = 15;
   1066        caps.maxCombinedTextureImageUnits = 32;
   1067 
   1068        // Table 6.34
   1069        caps.maxTransformFeedbackInterleavedComponents = 64;
   1070        caps.maxTransformFeedbackSeparateAttributes    = 4;
   1071        caps.maxTransformFeedbackSeparateComponents    = 4;
   1072    }
   1073 
   1074    if (clientVersion >= Version(3, 1))
   1075    {
   1076        // Table 20.40
   1077        caps.maxFramebufferWidth    = 2048;
   1078        caps.maxFramebufferHeight   = 2048;
   1079        caps.maxFramebufferSamples  = 4;
   1080        caps.maxSampleMaskWords     = 1;
   1081        caps.maxColorTextureSamples = 1;
   1082        caps.maxDepthTextureSamples = 1;
   1083        caps.maxIntegerSamples      = 1;
   1084 
   1085        // Table 20.41
   1086        caps.maxVertexAttribRelativeOffset = 2047;
   1087        caps.maxVertexAttribBindings       = 16;
   1088        caps.maxVertexAttribStride         = 2048;
   1089 
   1090        // Table 20.43
   1091        caps.maxShaderAtomicCounterBuffers[ShaderType::Vertex] = 0;
   1092        caps.maxShaderAtomicCounters[ShaderType::Vertex]       = 0;
   1093        caps.maxShaderImageUniforms[ShaderType::Vertex]        = 0;
   1094        caps.maxShaderStorageBlocks[ShaderType::Vertex]        = 0;
   1095 
   1096        // Table 20.44
   1097        caps.maxShaderUniformComponents[ShaderType::Fragment]    = 1024;
   1098        caps.maxFragmentUniformVectors                           = 256;
   1099        caps.maxShaderAtomicCounterBuffers[ShaderType::Fragment] = 0;
   1100        caps.maxShaderAtomicCounters[ShaderType::Fragment]       = 0;
   1101        caps.maxShaderImageUniforms[ShaderType::Fragment]        = 0;
   1102        caps.maxShaderStorageBlocks[ShaderType::Fragment]        = 0;
   1103        caps.minProgramTextureGatherOffset                       = 0;
   1104        caps.maxProgramTextureGatherOffset                       = 0;
   1105 
   1106        // Table 20.45
   1107        caps.maxComputeWorkGroupCount                        = {{65535, 65535, 65535}};
   1108        caps.maxComputeWorkGroupSize                         = {{128, 128, 64}};
   1109        caps.maxComputeWorkGroupInvocations                  = 12;
   1110        caps.maxShaderUniformBlocks[ShaderType::Compute]     = limits::kMinimumShaderUniformBlocks;
   1111        caps.maxShaderTextureImageUnits[ShaderType::Compute] = 16;
   1112        caps.maxComputeSharedMemorySize                      = 16384;
   1113        caps.maxShaderUniformComponents[ShaderType::Compute] = 1024;
   1114        caps.maxShaderAtomicCounterBuffers[ShaderType::Compute] = 1;
   1115        caps.maxShaderAtomicCounters[ShaderType::Compute]       = 8;
   1116        caps.maxShaderImageUniforms[ShaderType::Compute]        = 4;
   1117        caps.maxShaderStorageBlocks[ShaderType::Compute]        = 4;
   1118 
   1119        // Table 20.46
   1120        caps.maxUniformBufferBindings         = 36;
   1121        caps.maxCombinedTextureImageUnits     = 48;
   1122        caps.maxCombinedShaderOutputResources = 4;
   1123 
   1124        // Table 20.47
   1125        caps.maxUniformLocations                = 1024;
   1126        caps.maxAtomicCounterBufferBindings     = 1;
   1127        caps.maxAtomicCounterBufferSize         = 32;
   1128        caps.maxCombinedAtomicCounterBuffers    = 1;
   1129        caps.maxCombinedAtomicCounters          = 8;
   1130        caps.maxImageUnits                      = 4;
   1131        caps.maxCombinedImageUniforms           = 4;
   1132        caps.maxShaderStorageBufferBindings     = 4;
   1133        caps.maxShaderStorageBlockSize          = 1 << 27;
   1134        caps.maxCombinedShaderStorageBlocks     = 4;
   1135        caps.shaderStorageBufferOffsetAlignment = 256;
   1136    }
   1137 
   1138    if (extensions.textureRectangleANGLE)
   1139    {
   1140        caps.maxRectangleTextureSize = 64;
   1141    }
   1142 
   1143    if (extensions.geometryShaderAny())
   1144    {
   1145        // Table 20.40 (GL_EXT_geometry_shader)
   1146        caps.maxFramebufferLayers = 256;
   1147        caps.layerProvokingVertex = GL_LAST_VERTEX_CONVENTION_EXT;
   1148 
   1149        // Table 20.43gs (GL_EXT_geometry_shader)
   1150        caps.maxShaderUniformComponents[ShaderType::Geometry] = 1024;
   1151        caps.maxShaderUniformBlocks[ShaderType::Geometry]     = limits::kMinimumShaderUniformBlocks;
   1152        caps.maxGeometryInputComponents                       = 64;
   1153        caps.maxGeometryOutputComponents                      = 64;
   1154        caps.maxGeometryOutputVertices                        = 256;
   1155        caps.maxGeometryTotalOutputComponents                 = 1024;
   1156        caps.maxShaderTextureImageUnits[ShaderType::Geometry] = 16;
   1157        caps.maxShaderAtomicCounterBuffers[ShaderType::Geometry] = 0;
   1158        caps.maxShaderAtomicCounters[ShaderType::Geometry]       = 0;
   1159        caps.maxShaderStorageBlocks[ShaderType::Geometry]        = 0;
   1160        caps.maxGeometryShaderInvocations                        = 32;
   1161 
   1162        // Table 20.46 (GL_EXT_geometry_shader)
   1163        caps.maxShaderImageUniforms[ShaderType::Geometry] = 0;
   1164 
   1165        // Table 20.46 (GL_EXT_geometry_shader)
   1166        caps.maxUniformBufferBindings     = 48;
   1167        caps.maxCombinedUniformBlocks     = 36;
   1168        caps.maxCombinedTextureImageUnits = 64;
   1169    }
   1170 
   1171    if (extensions.tessellationShaderEXT)
   1172    {
   1173        // Table 20.43 "Implementation Dependent Tessellation Shader Limits"
   1174        caps.maxTessControlInputComponents                          = 64;
   1175        caps.maxTessControlOutputComponents                         = 64;
   1176        caps.maxShaderTextureImageUnits[ShaderType::TessControl]    = 16;
   1177        caps.maxShaderUniformComponents[ShaderType::TessControl]    = 1024;
   1178        caps.maxTessControlTotalOutputComponents                    = 2048;
   1179        caps.maxShaderImageUniforms[ShaderType::TessControl]        = 0;
   1180        caps.maxShaderAtomicCounters[ShaderType::TessControl]       = 0;
   1181        caps.maxShaderAtomicCounterBuffers[ShaderType::TessControl] = 0;
   1182 
   1183        caps.maxTessPatchComponents = 120;
   1184        caps.maxPatchVertices       = 32;
   1185        caps.maxTessGenLevel        = 64;
   1186 
   1187        caps.maxTessEvaluationInputComponents                          = 64;
   1188        caps.maxTessEvaluationOutputComponents                         = 64;
   1189        caps.maxShaderTextureImageUnits[ShaderType::TessEvaluation]    = 16;
   1190        caps.maxShaderUniformComponents[ShaderType::TessEvaluation]    = 1024;
   1191        caps.maxShaderImageUniforms[ShaderType::TessEvaluation]        = 0;
   1192        caps.maxShaderAtomicCounters[ShaderType::TessEvaluation]       = 0;
   1193        caps.maxShaderAtomicCounterBuffers[ShaderType::TessEvaluation] = 0;
   1194 
   1195        // Table 20.46 "Implementation Dependent Aggregate Shader Limits"
   1196        caps.maxUniformBufferBindings     = 72;
   1197        caps.maxCombinedUniformBlocks     = 60;
   1198        caps.maxCombinedTextureImageUnits = 96;
   1199    }
   1200 
   1201    for (ShaderType shaderType : AllShaderTypes())
   1202    {
   1203        caps.maxCombinedShaderUniformComponents[shaderType] =
   1204            caps.maxShaderUniformBlocks[shaderType] *
   1205                static_cast<GLuint>(caps.maxUniformBlockSize / 4) +
   1206            caps.maxShaderUniformComponents[shaderType];
   1207    }
   1208 
   1209    return caps;
   1210 }
   1211 }  // namespace gl
   1212 
   1213 namespace egl
   1214 {
   1215 
   1216 Caps::Caps() = default;
   1217 
   1218 DisplayExtensions::DisplayExtensions() = default;
   1219 
   1220 std::vector<std::string> DisplayExtensions::getStrings() const
   1221 {
   1222    std::vector<std::string> extensionStrings;
   1223 
   1224    // clang-format off
   1225    //                   | Extension name                                       | Supported flag                    | Output vector   |
   1226    InsertExtensionString("EGL_EXT_create_context_robustness",                   createContextRobustness,            &extensionStrings);
   1227    InsertExtensionString("EGL_ANGLE_d3d_share_handle_client_buffer",            d3dShareHandleClientBuffer,         &extensionStrings);
   1228    InsertExtensionString("EGL_ANGLE_d3d_texture_client_buffer",                 d3dTextureClientBuffer,             &extensionStrings);
   1229    InsertExtensionString("EGL_ANGLE_surface_d3d_texture_2d_share_handle",       surfaceD3DTexture2DShareHandle,     &extensionStrings);
   1230    InsertExtensionString("EGL_ANGLE_query_surface_pointer",                     querySurfacePointer,                &extensionStrings);
   1231    InsertExtensionString("EGL_ANGLE_window_fixed_size",                         windowFixedSize,                    &extensionStrings);
   1232    InsertExtensionString("EGL_ANGLE_keyed_mutex",                               keyedMutex,                         &extensionStrings);
   1233    InsertExtensionString("EGL_ANGLE_surface_orientation",                       surfaceOrientation,                 &extensionStrings);
   1234    InsertExtensionString("EGL_ANGLE_direct_composition",                        directComposition,                  &extensionStrings);
   1235    InsertExtensionString("EGL_ANGLE_windows_ui_composition",                    windowsUIComposition,               &extensionStrings);
   1236    InsertExtensionString("EGL_NV_post_sub_buffer",                              postSubBuffer,                      &extensionStrings);
   1237    InsertExtensionString("EGL_KHR_create_context",                              createContext,                      &extensionStrings);
   1238    InsertExtensionString("EGL_KHR_image",                                       image,                              &extensionStrings);
   1239    InsertExtensionString("EGL_KHR_image_base",                                  imageBase,                          &extensionStrings);
   1240    InsertExtensionString("EGL_KHR_image_pixmap",                                imagePixmap,                        &extensionStrings);
   1241    InsertExtensionString("EGL_EXT_image_gl_colorspace",                         imageGlColorspace,                  &extensionStrings);
   1242    InsertExtensionString("EGL_KHR_gl_colorspace",                               glColorspace,                       &extensionStrings);
   1243    InsertExtensionString("EGL_EXT_gl_colorspace_scrgb",                         glColorspaceScrgb,                  &extensionStrings);
   1244    InsertExtensionString("EGL_EXT_gl_colorspace_scrgb_linear",                  glColorspaceScrgbLinear,            &extensionStrings);
   1245    InsertExtensionString("EGL_EXT_gl_colorspace_display_p3",                    glColorspaceDisplayP3,              &extensionStrings);
   1246    InsertExtensionString("EGL_EXT_gl_colorspace_display_p3_linear",             glColorspaceDisplayP3Linear,        &extensionStrings);
   1247    InsertExtensionString("EGL_EXT_gl_colorspace_display_p3_passthrough",        glColorspaceDisplayP3Passthrough,   &extensionStrings);
   1248    InsertExtensionString("EGL_ANGLE_colorspace_attribute_passthrough",          eglColorspaceAttributePassthroughANGLE,  &extensionStrings);
   1249    InsertExtensionString("EGL_KHR_gl_texture_2D_image",                         glTexture2DImage,                   &extensionStrings);
   1250    InsertExtensionString("EGL_KHR_gl_texture_cubemap_image",                    glTextureCubemapImage,              &extensionStrings);
   1251    InsertExtensionString("EGL_KHR_gl_texture_3D_image",                         glTexture3DImage,                   &extensionStrings);
   1252    InsertExtensionString("EGL_KHR_gl_renderbuffer_image",                       glRenderbufferImage,                &extensionStrings);
   1253    InsertExtensionString("EGL_KHR_get_all_proc_addresses",                      getAllProcAddresses,                &extensionStrings);
   1254    InsertExtensionString("EGL_KHR_stream",                                      stream,                             &extensionStrings);
   1255    InsertExtensionString("EGL_KHR_stream_consumer_gltexture",                   streamConsumerGLTexture,            &extensionStrings);
   1256    InsertExtensionString("EGL_NV_stream_consumer_gltexture_yuv",                streamConsumerGLTextureYUV,         &extensionStrings);
   1257    InsertExtensionString("EGL_KHR_fence_sync",                                  fenceSync,                          &extensionStrings);
   1258    InsertExtensionString("EGL_KHR_wait_sync",                                   waitSync,                           &extensionStrings);
   1259    InsertExtensionString("EGL_ANGLE_stream_producer_d3d_texture",               streamProducerD3DTexture,           &extensionStrings);
   1260    InsertExtensionString("EGL_ANGLE_create_context_webgl_compatibility",        createContextWebGLCompatibility,    &extensionStrings);
   1261    InsertExtensionString("EGL_CHROMIUM_create_context_bind_generates_resource", createContextBindGeneratesResource, &extensionStrings);
   1262    InsertExtensionString("EGL_CHROMIUM_sync_control",                           syncControlCHROMIUM,                &extensionStrings);
   1263    InsertExtensionString("EGL_ANGLE_sync_control_rate",                         syncControlRateANGLE,               &extensionStrings);
   1264    InsertExtensionString("EGL_KHR_swap_buffers_with_damage",                    swapBuffersWithDamage,              &extensionStrings);
   1265    InsertExtensionString("EGL_EXT_pixel_format_float",                          pixelFormatFloat,                   &extensionStrings);
   1266    InsertExtensionString("EGL_KHR_surfaceless_context",                         surfacelessContext,                 &extensionStrings);
   1267    InsertExtensionString("EGL_ANGLE_display_texture_share_group",               displayTextureShareGroup,           &extensionStrings);
   1268    InsertExtensionString("EGL_ANGLE_display_semaphore_share_group",             displaySemaphoreShareGroup,         &extensionStrings);
   1269    InsertExtensionString("EGL_ANGLE_create_context_client_arrays",              createContextClientArrays,          &extensionStrings);
   1270    InsertExtensionString("EGL_ANGLE_program_cache_control",                     programCacheControlANGLE,                &extensionStrings);
   1271    InsertExtensionString("EGL_ANGLE_robust_resource_initialization",            robustResourceInitializationANGLE,       &extensionStrings);
   1272    InsertExtensionString("EGL_ANGLE_iosurface_client_buffer",                   iosurfaceClientBuffer,              &extensionStrings);
   1273    InsertExtensionString("EGL_ANGLE_metal_texture_client_buffer",               mtlTextureClientBuffer,             &extensionStrings);
   1274    InsertExtensionString("EGL_ANGLE_create_context_extensions_enabled",         createContextExtensionsEnabled,     &extensionStrings);
   1275    InsertExtensionString("EGL_ANDROID_presentation_time",                       presentationTime,                   &extensionStrings);
   1276    InsertExtensionString("EGL_ANDROID_blob_cache",                              blobCache,                          &extensionStrings);
   1277    InsertExtensionString("EGL_ANDROID_framebuffer_target",                      framebufferTargetANDROID,           &extensionStrings);
   1278    InsertExtensionString("EGL_ANDROID_image_native_buffer",                     imageNativeBuffer,                  &extensionStrings);
   1279    InsertExtensionString("EGL_ANDROID_get_frame_timestamps",                    getFrameTimestamps,                 &extensionStrings);
   1280    InsertExtensionString("EGL_ANGLE_timestamp_surface_attribute",               timestampSurfaceAttributeANGLE,     &extensionStrings);
   1281    InsertExtensionString("EGL_ANDROID_recordable",                              recordable,                         &extensionStrings);
   1282    InsertExtensionString("EGL_ANGLE_power_preference",                          powerPreference,                    &extensionStrings);
   1283    InsertExtensionString("EGL_ANGLE_image_d3d11_texture",                       imageD3D11Texture,                  &extensionStrings);
   1284    InsertExtensionString("EGL_ANDROID_create_native_client_buffer",             createNativeClientBufferANDROID,    &extensionStrings);
   1285    InsertExtensionString("EGL_ANDROID_get_native_client_buffer",                getNativeClientBufferANDROID,       &extensionStrings);
   1286    InsertExtensionString("EGL_ANDROID_native_fence_sync",                       nativeFenceSyncANDROID,             &extensionStrings);
   1287    InsertExtensionString("EGL_ANGLE_create_context_backwards_compatible",       createContextBackwardsCompatible,   &extensionStrings);
   1288    InsertExtensionString("EGL_KHR_no_config_context",                           noConfigContext,                    &extensionStrings);
   1289    InsertExtensionString("EGL_IMG_context_priority",                            contextPriority,                    &extensionStrings);
   1290    InsertExtensionString("EGL_KHR_create_context_no_error",                     createContextNoError,               &extensionStrings);
   1291    InsertExtensionString("EGL_EXT_image_dma_buf_import",                        imageDmaBufImportEXT,               &extensionStrings);
   1292    InsertExtensionString("EGL_EXT_image_dma_buf_import_modifiers",              imageDmaBufImportModifiersEXT,      &extensionStrings);
   1293    InsertExtensionString("EGL_NOK_texture_from_pixmap",                         textureFromPixmapNOK,               &extensionStrings);
   1294    InsertExtensionString("EGL_NV_robustness_video_memory_purge",                robustnessVideoMemoryPurgeNV,       &extensionStrings);
   1295    InsertExtensionString("EGL_KHR_reusable_sync",                               reusableSyncKHR,                    &extensionStrings);
   1296    InsertExtensionString("EGL_ANGLE_external_context_and_surface",              externalContextAndSurface,          &extensionStrings);
   1297    InsertExtensionString("EGL_EXT_buffer_age",                                  bufferAgeEXT,                       &extensionStrings);
   1298    InsertExtensionString("EGL_KHR_mutable_render_buffer",                       mutableRenderBufferKHR,             &extensionStrings);
   1299    InsertExtensionString("EGL_EXT_protected_content",                           protectedContentEXT,                &extensionStrings);
   1300    InsertExtensionString("EGL_ANGLE_create_surface_swap_interval",              createSurfaceSwapIntervalANGLE,     &extensionStrings);
   1301    InsertExtensionString("EGL_ANGLE_context_virtualization",                    contextVirtualizationANGLE,         &extensionStrings);
   1302    InsertExtensionString("EGL_KHR_lock_surface3",                               lockSurface3KHR,                    &extensionStrings);
   1303    InsertExtensionString("EGL_ANGLE_vulkan_image",                              vulkanImageANGLE,                   &extensionStrings);
   1304    InsertExtensionString("EGL_ANGLE_metal_create_context_ownership_identity",   metalCreateContextOwnershipIdentityANGLE, &extensionStrings);
   1305    InsertExtensionString("EGL_KHR_partial_update",                              partialUpdateKHR,                   &extensionStrings);
   1306    InsertExtensionString("EGL_ANGLE_metal_shared_event_sync",                   mtlSyncSharedEventANGLE,            &extensionStrings);
   1307    // clang-format on
   1308 
   1309    return extensionStrings;
   1310 }
   1311 
   1312 DeviceExtensions::DeviceExtensions() = default;
   1313 
   1314 std::vector<std::string> DeviceExtensions::getStrings() const
   1315 {
   1316    std::vector<std::string> extensionStrings;
   1317 
   1318    // clang-format off
   1319    //                   | Extension name                                 | Supported flag                | Output vector   |
   1320    InsertExtensionString("EGL_ANGLE_device_d3d",                          deviceD3D,                      &extensionStrings);
   1321    InsertExtensionString("EGL_ANGLE_device_cgl",                          deviceCGL,                      &extensionStrings);
   1322    InsertExtensionString("EGL_ANGLE_device_eagl",                         deviceEAGL,                     &extensionStrings);
   1323    InsertExtensionString("EGL_ANGLE_device_metal",                        deviceMetal,                    &extensionStrings);
   1324    InsertExtensionString("EGL_ANGLE_device_vulkan",                       deviceVulkan,                   &extensionStrings);
   1325 
   1326    // clang-format on
   1327 
   1328    return extensionStrings;
   1329 }
   1330 
   1331 ClientExtensions::ClientExtensions()                              = default;
   1332 ClientExtensions::ClientExtensions(const ClientExtensions &other) = default;
   1333 
   1334 std::vector<std::string> ClientExtensions::getStrings() const
   1335 {
   1336    std::vector<std::string> extensionStrings;
   1337 
   1338    // clang-format off
   1339    //                   | Extension name                                    | Supported flag                   | Output vector   |
   1340    InsertExtensionString("EGL_EXT_client_extensions",                        clientExtensions,                   &extensionStrings);
   1341    InsertExtensionString("EGL_EXT_device_query",                             deviceQueryEXT,                     &extensionStrings);
   1342    InsertExtensionString("EGL_EXT_platform_base",                            platformBase,                       &extensionStrings);
   1343    InsertExtensionString("EGL_EXT_platform_device",                          platformDevice,                     &extensionStrings);
   1344    InsertExtensionString("EGL_KHR_platform_gbm",                             platformGbmKHR,                     &extensionStrings);
   1345    InsertExtensionString("EGL_EXT_platform_wayland",                         platformWaylandEXT,                 &extensionStrings);
   1346    InsertExtensionString("EGL_ANGLE_platform_angle",                         platformANGLE,                      &extensionStrings);
   1347    InsertExtensionString("EGL_ANGLE_platform_angle_d3d",                     platformANGLED3D,                   &extensionStrings);
   1348    InsertExtensionString("EGL_ANGLE_platform_angle_d3d11on12",               platformANGLED3D11ON12,             &extensionStrings);
   1349    InsertExtensionString("EGL_ANGLE_platform_angle_device_type_egl_angle",   platformANGLEDeviceTypeEGLANGLE,    &extensionStrings);
   1350    InsertExtensionString("EGL_ANGLE_platform_angle_device_type_swiftshader", platformANGLEDeviceTypeSwiftShader, &extensionStrings);
   1351    InsertExtensionString("EGL_ANGLE_platform_angle_opengl",                  platformANGLEOpenGL,                &extensionStrings);
   1352    InsertExtensionString("EGL_ANGLE_platform_angle_null",                    platformANGLENULL,                  &extensionStrings);
   1353    InsertExtensionString("EGL_ANGLE_platform_angle_vulkan",                  platformANGLEVulkan,                &extensionStrings);
   1354    InsertExtensionString("EGL_ANGLE_platform_angle_metal",                   platformANGLEMetal,                 &extensionStrings);
   1355    InsertExtensionString("EGL_ANGLE_platform_device_context_volatile_eagl",  platformANGLEDeviceContextVolatileEagl, &extensionStrings);
   1356    InsertExtensionString("EGL_ANGLE_platform_device_context_volatile_cgl",   platformANGLEDeviceContextVolatileCgl, &extensionStrings);
   1357    InsertExtensionString("EGL_ANGLE_platform_angle_device_id",               platformANGLEDeviceId,              &extensionStrings);
   1358    InsertExtensionString("EGL_ANGLE_device_creation",                        deviceCreation,                     &extensionStrings);
   1359    InsertExtensionString("EGL_ANGLE_device_creation_d3d11",                  deviceCreationD3D11,                &extensionStrings);
   1360    InsertExtensionString("EGL_ANGLE_x11_visual",                             x11Visual,                          &extensionStrings);
   1361    InsertExtensionString("EGL_ANGLE_experimental_present_path",              experimentalPresentPath,            &extensionStrings);
   1362    InsertExtensionString("EGL_KHR_client_get_all_proc_addresses",            clientGetAllProcAddresses,          &extensionStrings);
   1363    InsertExtensionString("EGL_KHR_debug",                                    debug,                              &extensionStrings);
   1364    InsertExtensionString("EGL_ANGLE_feature_control",                        featureControlANGLE,                &extensionStrings);
   1365    InsertExtensionString("EGL_ANGLE_display_power_preference",               displayPowerPreferenceANGLE,        &extensionStrings);
   1366    // clang-format on
   1367 
   1368    return extensionStrings;
   1369 }
   1370 
   1371 }  // namespace egl