tor-browser

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

utilities.cpp (43267B)


      1 //
      2 // Copyright 2002 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 // utilities.cpp: Conversion functions and other utility routines.
      8 
      9 #include "common/utilities.h"
     10 #include "GLES3/gl3.h"
     11 #include "common/mathutil.h"
     12 #include "common/platform.h"
     13 #include "common/string_utils.h"
     14 
     15 #include <set>
     16 
     17 #if defined(ANGLE_ENABLE_WINDOWS_UWP)
     18 #    include <windows.applicationmodel.core.h>
     19 #    include <windows.graphics.display.h>
     20 #    include <wrl.h>
     21 #    include <wrl/wrappers/corewrappers.h>
     22 #endif
     23 
     24 namespace
     25 {
     26 
     27 template <class IndexType>
     28 gl::IndexRange ComputeTypedIndexRange(const IndexType *indices,
     29                                      size_t count,
     30                                      bool primitiveRestartEnabled,
     31                                      GLuint primitiveRestartIndex)
     32 {
     33    ASSERT(count > 0);
     34 
     35    IndexType minIndex                = 0;
     36    IndexType maxIndex                = 0;
     37    size_t nonPrimitiveRestartIndices = 0;
     38 
     39    if (primitiveRestartEnabled)
     40    {
     41        // Find the first non-primitive restart index to initialize the min and max values
     42        size_t i = 0;
     43        for (; i < count; i++)
     44        {
     45            if (indices[i] != primitiveRestartIndex)
     46            {
     47                minIndex = indices[i];
     48                maxIndex = indices[i];
     49                nonPrimitiveRestartIndices++;
     50                break;
     51            }
     52        }
     53 
     54        // Loop over the rest of the indices
     55        for (; i < count; i++)
     56        {
     57            if (indices[i] != primitiveRestartIndex)
     58            {
     59                if (minIndex > indices[i])
     60                {
     61                    minIndex = indices[i];
     62                }
     63                if (maxIndex < indices[i])
     64                {
     65                    maxIndex = indices[i];
     66                }
     67                nonPrimitiveRestartIndices++;
     68            }
     69        }
     70    }
     71    else
     72    {
     73        minIndex                   = indices[0];
     74        maxIndex                   = indices[0];
     75        nonPrimitiveRestartIndices = count;
     76 
     77        for (size_t i = 1; i < count; i++)
     78        {
     79            if (minIndex > indices[i])
     80            {
     81                minIndex = indices[i];
     82            }
     83            if (maxIndex < indices[i])
     84            {
     85                maxIndex = indices[i];
     86            }
     87        }
     88    }
     89 
     90    return gl::IndexRange(static_cast<size_t>(minIndex), static_cast<size_t>(maxIndex),
     91                          nonPrimitiveRestartIndices);
     92 }
     93 
     94 }  // anonymous namespace
     95 
     96 namespace gl
     97 {
     98 
     99 int VariableComponentCount(GLenum type)
    100 {
    101    return VariableRowCount(type) * VariableColumnCount(type);
    102 }
    103 
    104 GLenum VariableComponentType(GLenum type)
    105 {
    106    switch (type)
    107    {
    108        case GL_BOOL:
    109        case GL_BOOL_VEC2:
    110        case GL_BOOL_VEC3:
    111        case GL_BOOL_VEC4:
    112            return GL_BOOL;
    113        case GL_FLOAT:
    114        case GL_FLOAT_VEC2:
    115        case GL_FLOAT_VEC3:
    116        case GL_FLOAT_VEC4:
    117        case GL_FLOAT_MAT2:
    118        case GL_FLOAT_MAT3:
    119        case GL_FLOAT_MAT4:
    120        case GL_FLOAT_MAT2x3:
    121        case GL_FLOAT_MAT3x2:
    122        case GL_FLOAT_MAT2x4:
    123        case GL_FLOAT_MAT4x2:
    124        case GL_FLOAT_MAT3x4:
    125        case GL_FLOAT_MAT4x3:
    126            return GL_FLOAT;
    127        case GL_INT:
    128        case GL_SAMPLER_2D:
    129        case GL_SAMPLER_2D_RECT_ANGLE:
    130        case GL_SAMPLER_3D:
    131        case GL_SAMPLER_CUBE:
    132        case GL_SAMPLER_CUBE_MAP_ARRAY:
    133        case GL_SAMPLER_2D_ARRAY:
    134        case GL_SAMPLER_EXTERNAL_OES:
    135        case GL_SAMPLER_2D_MULTISAMPLE:
    136        case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
    137        case GL_INT_SAMPLER_BUFFER:
    138        case GL_INT_SAMPLER_2D:
    139        case GL_INT_SAMPLER_3D:
    140        case GL_INT_SAMPLER_CUBE:
    141        case GL_INT_SAMPLER_CUBE_MAP_ARRAY:
    142        case GL_INT_SAMPLER_2D_ARRAY:
    143        case GL_INT_SAMPLER_2D_MULTISAMPLE:
    144        case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
    145        case GL_UNSIGNED_INT_SAMPLER_2D:
    146        case GL_UNSIGNED_INT_SAMPLER_3D:
    147        case GL_UNSIGNED_INT_SAMPLER_CUBE:
    148        case GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY:
    149        case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
    150        case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
    151        case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
    152        case GL_SAMPLER_2D_SHADOW:
    153        case GL_SAMPLER_BUFFER:
    154        case GL_SAMPLER_CUBE_SHADOW:
    155        case GL_SAMPLER_2D_ARRAY_SHADOW:
    156        case GL_INT_VEC2:
    157        case GL_INT_VEC3:
    158        case GL_INT_VEC4:
    159        case GL_IMAGE_2D:
    160        case GL_INT_IMAGE_2D:
    161        case GL_UNSIGNED_INT_IMAGE_2D:
    162        case GL_IMAGE_3D:
    163        case GL_INT_IMAGE_3D:
    164        case GL_UNSIGNED_INT_IMAGE_3D:
    165        case GL_IMAGE_2D_ARRAY:
    166        case GL_INT_IMAGE_2D_ARRAY:
    167        case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
    168        case GL_IMAGE_CUBE:
    169        case GL_INT_IMAGE_CUBE:
    170        case GL_UNSIGNED_INT_IMAGE_CUBE:
    171        case GL_IMAGE_CUBE_MAP_ARRAY:
    172        case GL_INT_IMAGE_CUBE_MAP_ARRAY:
    173        case GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY:
    174        case GL_IMAGE_BUFFER:
    175        case GL_INT_IMAGE_BUFFER:
    176        case GL_UNSIGNED_INT_SAMPLER_BUFFER:
    177        case GL_UNSIGNED_INT_IMAGE_BUFFER:
    178        case GL_UNSIGNED_INT_ATOMIC_COUNTER:
    179        case GL_SAMPLER_VIDEO_IMAGE_WEBGL:
    180        case GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT:
    181            return GL_INT;
    182        case GL_UNSIGNED_INT:
    183        case GL_UNSIGNED_INT_VEC2:
    184        case GL_UNSIGNED_INT_VEC3:
    185        case GL_UNSIGNED_INT_VEC4:
    186            return GL_UNSIGNED_INT;
    187        default:
    188            UNREACHABLE();
    189    }
    190 
    191    return GL_NONE;
    192 }
    193 
    194 size_t VariableComponentSize(GLenum type)
    195 {
    196    switch (type)
    197    {
    198        case GL_BOOL:
    199            return sizeof(GLint);
    200        case GL_FLOAT:
    201            return sizeof(GLfloat);
    202        case GL_INT:
    203            return sizeof(GLint);
    204        case GL_UNSIGNED_INT:
    205            return sizeof(GLuint);
    206        default:
    207            UNREACHABLE();
    208    }
    209 
    210    return 0;
    211 }
    212 
    213 size_t VariableInternalSize(GLenum type)
    214 {
    215    // Expanded to 4-element vectors
    216    return VariableComponentSize(VariableComponentType(type)) * VariableRowCount(type) * 4;
    217 }
    218 
    219 size_t VariableExternalSize(GLenum type)
    220 {
    221    return VariableComponentSize(VariableComponentType(type)) * VariableComponentCount(type);
    222 }
    223 
    224 std::string GetGLSLTypeString(GLenum type)
    225 {
    226    switch (type)
    227    {
    228        case GL_BOOL:
    229            return "bool";
    230        case GL_INT:
    231            return "int";
    232        case GL_UNSIGNED_INT:
    233            return "uint";
    234        case GL_FLOAT:
    235            return "float";
    236        case GL_BOOL_VEC2:
    237            return "bvec2";
    238        case GL_BOOL_VEC3:
    239            return "bvec3";
    240        case GL_BOOL_VEC4:
    241            return "bvec4";
    242        case GL_INT_VEC2:
    243            return "ivec2";
    244        case GL_INT_VEC3:
    245            return "ivec3";
    246        case GL_INT_VEC4:
    247            return "ivec4";
    248        case GL_FLOAT_VEC2:
    249            return "vec2";
    250        case GL_FLOAT_VEC3:
    251            return "vec3";
    252        case GL_FLOAT_VEC4:
    253            return "vec4";
    254        case GL_UNSIGNED_INT_VEC2:
    255            return "uvec2";
    256        case GL_UNSIGNED_INT_VEC3:
    257            return "uvec3";
    258        case GL_UNSIGNED_INT_VEC4:
    259            return "uvec4";
    260        case GL_FLOAT_MAT2:
    261            return "mat2";
    262        case GL_FLOAT_MAT3:
    263            return "mat3";
    264        case GL_FLOAT_MAT4:
    265            return "mat4";
    266        default:
    267            UNREACHABLE();
    268            return "";
    269    }
    270 }
    271 
    272 GLenum VariableBoolVectorType(GLenum type)
    273 {
    274    switch (type)
    275    {
    276        case GL_FLOAT:
    277        case GL_INT:
    278        case GL_UNSIGNED_INT:
    279            return GL_BOOL;
    280        case GL_FLOAT_VEC2:
    281        case GL_INT_VEC2:
    282        case GL_UNSIGNED_INT_VEC2:
    283            return GL_BOOL_VEC2;
    284        case GL_FLOAT_VEC3:
    285        case GL_INT_VEC3:
    286        case GL_UNSIGNED_INT_VEC3:
    287            return GL_BOOL_VEC3;
    288        case GL_FLOAT_VEC4:
    289        case GL_INT_VEC4:
    290        case GL_UNSIGNED_INT_VEC4:
    291            return GL_BOOL_VEC4;
    292 
    293        default:
    294            UNREACHABLE();
    295            return GL_NONE;
    296    }
    297 }
    298 
    299 int VariableRowCount(GLenum type)
    300 {
    301    switch (type)
    302    {
    303        case GL_NONE:
    304            return 0;
    305        case GL_BOOL:
    306        case GL_FLOAT:
    307        case GL_INT:
    308        case GL_UNSIGNED_INT:
    309        case GL_BOOL_VEC2:
    310        case GL_FLOAT_VEC2:
    311        case GL_INT_VEC2:
    312        case GL_UNSIGNED_INT_VEC2:
    313        case GL_BOOL_VEC3:
    314        case GL_FLOAT_VEC3:
    315        case GL_INT_VEC3:
    316        case GL_UNSIGNED_INT_VEC3:
    317        case GL_BOOL_VEC4:
    318        case GL_FLOAT_VEC4:
    319        case GL_INT_VEC4:
    320        case GL_UNSIGNED_INT_VEC4:
    321        case GL_SAMPLER_2D:
    322        case GL_SAMPLER_3D:
    323        case GL_SAMPLER_CUBE:
    324        case GL_SAMPLER_2D_ARRAY:
    325        case GL_SAMPLER_EXTERNAL_OES:
    326        case GL_SAMPLER_2D_RECT_ANGLE:
    327        case GL_SAMPLER_2D_MULTISAMPLE:
    328        case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
    329        case GL_SAMPLER_CUBE_MAP_ARRAY:
    330        case GL_SAMPLER_BUFFER:
    331        case GL_INT_SAMPLER_2D:
    332        case GL_INT_SAMPLER_3D:
    333        case GL_INT_SAMPLER_CUBE:
    334        case GL_INT_SAMPLER_2D_ARRAY:
    335        case GL_INT_SAMPLER_2D_MULTISAMPLE:
    336        case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
    337        case GL_INT_SAMPLER_CUBE_MAP_ARRAY:
    338        case GL_INT_SAMPLER_BUFFER:
    339        case GL_UNSIGNED_INT_SAMPLER_2D:
    340        case GL_UNSIGNED_INT_SAMPLER_3D:
    341        case GL_UNSIGNED_INT_SAMPLER_CUBE:
    342        case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
    343        case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
    344        case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
    345        case GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY:
    346        case GL_UNSIGNED_INT_SAMPLER_BUFFER:
    347        case GL_SAMPLER_2D_SHADOW:
    348        case GL_SAMPLER_CUBE_SHADOW:
    349        case GL_SAMPLER_2D_ARRAY_SHADOW:
    350        case GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW:
    351        case GL_IMAGE_2D:
    352        case GL_INT_IMAGE_2D:
    353        case GL_UNSIGNED_INT_IMAGE_2D:
    354        case GL_IMAGE_2D_ARRAY:
    355        case GL_INT_IMAGE_2D_ARRAY:
    356        case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
    357        case GL_IMAGE_3D:
    358        case GL_INT_IMAGE_3D:
    359        case GL_UNSIGNED_INT_IMAGE_3D:
    360        case GL_IMAGE_CUBE:
    361        case GL_INT_IMAGE_CUBE:
    362        case GL_UNSIGNED_INT_IMAGE_CUBE:
    363        case GL_UNSIGNED_INT_ATOMIC_COUNTER:
    364        case GL_IMAGE_CUBE_MAP_ARRAY:
    365        case GL_INT_IMAGE_CUBE_MAP_ARRAY:
    366        case GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY:
    367        case GL_IMAGE_BUFFER:
    368        case GL_INT_IMAGE_BUFFER:
    369        case GL_UNSIGNED_INT_IMAGE_BUFFER:
    370        case GL_SAMPLER_VIDEO_IMAGE_WEBGL:
    371        case GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT:
    372            return 1;
    373        case GL_FLOAT_MAT2:
    374        case GL_FLOAT_MAT3x2:
    375        case GL_FLOAT_MAT4x2:
    376            return 2;
    377        case GL_FLOAT_MAT3:
    378        case GL_FLOAT_MAT2x3:
    379        case GL_FLOAT_MAT4x3:
    380            return 3;
    381        case GL_FLOAT_MAT4:
    382        case GL_FLOAT_MAT2x4:
    383        case GL_FLOAT_MAT3x4:
    384            return 4;
    385        default:
    386            UNREACHABLE();
    387    }
    388 
    389    return 0;
    390 }
    391 
    392 int VariableColumnCount(GLenum type)
    393 {
    394    switch (type)
    395    {
    396        case GL_NONE:
    397            return 0;
    398        case GL_BOOL:
    399        case GL_FLOAT:
    400        case GL_INT:
    401        case GL_UNSIGNED_INT:
    402        case GL_SAMPLER_2D:
    403        case GL_SAMPLER_3D:
    404        case GL_SAMPLER_CUBE:
    405        case GL_SAMPLER_2D_ARRAY:
    406        case GL_SAMPLER_2D_MULTISAMPLE:
    407        case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
    408        case GL_SAMPLER_CUBE_MAP_ARRAY:
    409        case GL_SAMPLER_BUFFER:
    410        case GL_INT_SAMPLER_2D:
    411        case GL_INT_SAMPLER_3D:
    412        case GL_INT_SAMPLER_CUBE:
    413        case GL_INT_SAMPLER_2D_ARRAY:
    414        case GL_INT_SAMPLER_2D_MULTISAMPLE:
    415        case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
    416        case GL_INT_SAMPLER_CUBE_MAP_ARRAY:
    417        case GL_INT_SAMPLER_BUFFER:
    418        case GL_SAMPLER_EXTERNAL_OES:
    419        case GL_SAMPLER_2D_RECT_ANGLE:
    420        case GL_UNSIGNED_INT_SAMPLER_2D:
    421        case GL_UNSIGNED_INT_SAMPLER_3D:
    422        case GL_UNSIGNED_INT_SAMPLER_CUBE:
    423        case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
    424        case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
    425        case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
    426        case GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY:
    427        case GL_UNSIGNED_INT_SAMPLER_BUFFER:
    428        case GL_SAMPLER_2D_SHADOW:
    429        case GL_SAMPLER_CUBE_SHADOW:
    430        case GL_SAMPLER_2D_ARRAY_SHADOW:
    431        case GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW:
    432        case GL_IMAGE_2D:
    433        case GL_INT_IMAGE_2D:
    434        case GL_UNSIGNED_INT_IMAGE_2D:
    435        case GL_IMAGE_3D:
    436        case GL_INT_IMAGE_3D:
    437        case GL_UNSIGNED_INT_IMAGE_3D:
    438        case GL_IMAGE_2D_ARRAY:
    439        case GL_INT_IMAGE_2D_ARRAY:
    440        case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
    441        case GL_IMAGE_CUBE_MAP_ARRAY:
    442        case GL_INT_IMAGE_CUBE_MAP_ARRAY:
    443        case GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY:
    444        case GL_IMAGE_BUFFER:
    445        case GL_INT_IMAGE_BUFFER:
    446        case GL_UNSIGNED_INT_IMAGE_BUFFER:
    447        case GL_IMAGE_CUBE:
    448        case GL_INT_IMAGE_CUBE:
    449        case GL_UNSIGNED_INT_IMAGE_CUBE:
    450        case GL_UNSIGNED_INT_ATOMIC_COUNTER:
    451        case GL_SAMPLER_VIDEO_IMAGE_WEBGL:
    452        case GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT:
    453            return 1;
    454        case GL_BOOL_VEC2:
    455        case GL_FLOAT_VEC2:
    456        case GL_INT_VEC2:
    457        case GL_UNSIGNED_INT_VEC2:
    458        case GL_FLOAT_MAT2:
    459        case GL_FLOAT_MAT2x3:
    460        case GL_FLOAT_MAT2x4:
    461            return 2;
    462        case GL_BOOL_VEC3:
    463        case GL_FLOAT_VEC3:
    464        case GL_INT_VEC3:
    465        case GL_UNSIGNED_INT_VEC3:
    466        case GL_FLOAT_MAT3:
    467        case GL_FLOAT_MAT3x2:
    468        case GL_FLOAT_MAT3x4:
    469            return 3;
    470        case GL_BOOL_VEC4:
    471        case GL_FLOAT_VEC4:
    472        case GL_INT_VEC4:
    473        case GL_UNSIGNED_INT_VEC4:
    474        case GL_FLOAT_MAT4:
    475        case GL_FLOAT_MAT4x2:
    476        case GL_FLOAT_MAT4x3:
    477            return 4;
    478        default:
    479            UNREACHABLE();
    480    }
    481 
    482    return 0;
    483 }
    484 
    485 bool IsSamplerType(GLenum type)
    486 {
    487    switch (type)
    488    {
    489        case GL_SAMPLER_2D:
    490        case GL_SAMPLER_3D:
    491        case GL_SAMPLER_CUBE:
    492        case GL_SAMPLER_2D_ARRAY:
    493        case GL_SAMPLER_EXTERNAL_OES:
    494        case GL_SAMPLER_2D_MULTISAMPLE:
    495        case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
    496        case GL_SAMPLER_CUBE_MAP_ARRAY:
    497        case GL_SAMPLER_BUFFER:
    498        case GL_SAMPLER_2D_RECT_ANGLE:
    499        case GL_INT_SAMPLER_2D:
    500        case GL_INT_SAMPLER_3D:
    501        case GL_INT_SAMPLER_CUBE:
    502        case GL_INT_SAMPLER_2D_ARRAY:
    503        case GL_INT_SAMPLER_2D_MULTISAMPLE:
    504        case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
    505        case GL_INT_SAMPLER_CUBE_MAP_ARRAY:
    506        case GL_INT_SAMPLER_BUFFER:
    507        case GL_UNSIGNED_INT_SAMPLER_2D:
    508        case GL_UNSIGNED_INT_SAMPLER_3D:
    509        case GL_UNSIGNED_INT_SAMPLER_CUBE:
    510        case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
    511        case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
    512        case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
    513        case GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY:
    514        case GL_UNSIGNED_INT_SAMPLER_BUFFER:
    515        case GL_SAMPLER_2D_SHADOW:
    516        case GL_SAMPLER_CUBE_SHADOW:
    517        case GL_SAMPLER_2D_ARRAY_SHADOW:
    518        case GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW:
    519        case GL_SAMPLER_VIDEO_IMAGE_WEBGL:
    520        case GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT:
    521            return true;
    522    }
    523 
    524    return false;
    525 }
    526 
    527 bool IsSamplerCubeType(GLenum type)
    528 {
    529    switch (type)
    530    {
    531        case GL_SAMPLER_CUBE:
    532        case GL_INT_SAMPLER_CUBE:
    533        case GL_UNSIGNED_INT_SAMPLER_CUBE:
    534        case GL_SAMPLER_CUBE_SHADOW:
    535            return true;
    536    }
    537 
    538    return false;
    539 }
    540 
    541 bool IsSamplerYUVType(GLenum type)
    542 {
    543    switch (type)
    544    {
    545        case GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT:
    546            return true;
    547 
    548        default:
    549            return false;
    550    }
    551 }
    552 
    553 bool IsImageType(GLenum type)
    554 {
    555    switch (type)
    556    {
    557        case GL_IMAGE_2D:
    558        case GL_INT_IMAGE_2D:
    559        case GL_UNSIGNED_INT_IMAGE_2D:
    560        case GL_IMAGE_3D:
    561        case GL_INT_IMAGE_3D:
    562        case GL_UNSIGNED_INT_IMAGE_3D:
    563        case GL_IMAGE_2D_ARRAY:
    564        case GL_INT_IMAGE_2D_ARRAY:
    565        case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
    566        case GL_IMAGE_CUBE_MAP_ARRAY:
    567        case GL_INT_IMAGE_CUBE_MAP_ARRAY:
    568        case GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY:
    569        case GL_IMAGE_BUFFER:
    570        case GL_INT_IMAGE_BUFFER:
    571        case GL_UNSIGNED_INT_IMAGE_BUFFER:
    572        case GL_IMAGE_CUBE:
    573        case GL_INT_IMAGE_CUBE:
    574        case GL_UNSIGNED_INT_IMAGE_CUBE:
    575            return true;
    576    }
    577    return false;
    578 }
    579 
    580 bool IsImage2DType(GLenum type)
    581 {
    582    switch (type)
    583    {
    584        case GL_IMAGE_2D:
    585        case GL_INT_IMAGE_2D:
    586        case GL_UNSIGNED_INT_IMAGE_2D:
    587            return true;
    588        case GL_IMAGE_3D:
    589        case GL_INT_IMAGE_3D:
    590        case GL_UNSIGNED_INT_IMAGE_3D:
    591        case GL_IMAGE_2D_ARRAY:
    592        case GL_INT_IMAGE_2D_ARRAY:
    593        case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
    594        case GL_IMAGE_CUBE_MAP_ARRAY:
    595        case GL_INT_IMAGE_CUBE_MAP_ARRAY:
    596        case GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY:
    597        case GL_IMAGE_CUBE:
    598        case GL_INT_IMAGE_CUBE:
    599        case GL_UNSIGNED_INT_IMAGE_CUBE:
    600        case GL_IMAGE_BUFFER:
    601        case GL_INT_IMAGE_BUFFER:
    602        case GL_UNSIGNED_INT_IMAGE_BUFFER:
    603            return false;
    604        default:
    605            UNREACHABLE();
    606            return false;
    607    }
    608 }
    609 
    610 bool IsAtomicCounterType(GLenum type)
    611 {
    612    return type == GL_UNSIGNED_INT_ATOMIC_COUNTER;
    613 }
    614 
    615 bool IsOpaqueType(GLenum type)
    616 {
    617    // ESSL 3.10 section 4.1.7 defines opaque types as: samplers, images and atomic counters.
    618    return IsImageType(type) || IsSamplerType(type) || IsAtomicCounterType(type);
    619 }
    620 
    621 bool IsMatrixType(GLenum type)
    622 {
    623    return VariableRowCount(type) > 1;
    624 }
    625 
    626 GLenum TransposeMatrixType(GLenum type)
    627 {
    628    if (!IsMatrixType(type))
    629    {
    630        return type;
    631    }
    632 
    633    switch (type)
    634    {
    635        case GL_FLOAT_MAT2:
    636            return GL_FLOAT_MAT2;
    637        case GL_FLOAT_MAT3:
    638            return GL_FLOAT_MAT3;
    639        case GL_FLOAT_MAT4:
    640            return GL_FLOAT_MAT4;
    641        case GL_FLOAT_MAT2x3:
    642            return GL_FLOAT_MAT3x2;
    643        case GL_FLOAT_MAT3x2:
    644            return GL_FLOAT_MAT2x3;
    645        case GL_FLOAT_MAT2x4:
    646            return GL_FLOAT_MAT4x2;
    647        case GL_FLOAT_MAT4x2:
    648            return GL_FLOAT_MAT2x4;
    649        case GL_FLOAT_MAT3x4:
    650            return GL_FLOAT_MAT4x3;
    651        case GL_FLOAT_MAT4x3:
    652            return GL_FLOAT_MAT3x4;
    653        default:
    654            UNREACHABLE();
    655            return GL_NONE;
    656    }
    657 }
    658 
    659 int MatrixRegisterCount(GLenum type, bool isRowMajorMatrix)
    660 {
    661    ASSERT(IsMatrixType(type));
    662    return isRowMajorMatrix ? VariableRowCount(type) : VariableColumnCount(type);
    663 }
    664 
    665 int MatrixComponentCount(GLenum type, bool isRowMajorMatrix)
    666 {
    667    ASSERT(IsMatrixType(type));
    668    return isRowMajorMatrix ? VariableColumnCount(type) : VariableRowCount(type);
    669 }
    670 
    671 int VariableRegisterCount(GLenum type)
    672 {
    673    return IsMatrixType(type) ? VariableColumnCount(type) : 1;
    674 }
    675 
    676 int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize)
    677 {
    678    ASSERT(allocationSize <= bitsSize);
    679 
    680    unsigned int mask = std::numeric_limits<unsigned int>::max() >>
    681                        (std::numeric_limits<unsigned int>::digits - allocationSize);
    682 
    683    for (unsigned int i = 0; i < bitsSize - allocationSize + 1; i++)
    684    {
    685        if ((*bits & mask) == 0)
    686        {
    687            *bits |= mask;
    688            return i;
    689        }
    690 
    691        mask <<= 1;
    692    }
    693 
    694    return -1;
    695 }
    696 
    697 IndexRange ComputeIndexRange(DrawElementsType indexType,
    698                             const GLvoid *indices,
    699                             size_t count,
    700                             bool primitiveRestartEnabled)
    701 {
    702    switch (indexType)
    703    {
    704        case DrawElementsType::UnsignedByte:
    705            return ComputeTypedIndexRange(static_cast<const GLubyte *>(indices), count,
    706                                          primitiveRestartEnabled,
    707                                          GetPrimitiveRestartIndex(indexType));
    708        case DrawElementsType::UnsignedShort:
    709            return ComputeTypedIndexRange(static_cast<const GLushort *>(indices), count,
    710                                          primitiveRestartEnabled,
    711                                          GetPrimitiveRestartIndex(indexType));
    712        case DrawElementsType::UnsignedInt:
    713            return ComputeTypedIndexRange(static_cast<const GLuint *>(indices), count,
    714                                          primitiveRestartEnabled,
    715                                          GetPrimitiveRestartIndex(indexType));
    716        default:
    717            UNREACHABLE();
    718            return IndexRange();
    719    }
    720 }
    721 
    722 GLuint GetPrimitiveRestartIndex(DrawElementsType indexType)
    723 {
    724    switch (indexType)
    725    {
    726        case DrawElementsType::UnsignedByte:
    727            return 0xFF;
    728        case DrawElementsType::UnsignedShort:
    729            return 0xFFFF;
    730        case DrawElementsType::UnsignedInt:
    731            return 0xFFFFFFFF;
    732        default:
    733            UNREACHABLE();
    734            return 0;
    735    }
    736 }
    737 
    738 bool IsTriangleMode(PrimitiveMode drawMode)
    739 {
    740    switch (drawMode)
    741    {
    742        case PrimitiveMode::Triangles:
    743        case PrimitiveMode::TriangleFan:
    744        case PrimitiveMode::TriangleStrip:
    745            return true;
    746        case PrimitiveMode::Points:
    747        case PrimitiveMode::Lines:
    748        case PrimitiveMode::LineLoop:
    749        case PrimitiveMode::LineStrip:
    750            return false;
    751        default:
    752            UNREACHABLE();
    753    }
    754 
    755    return false;
    756 }
    757 
    758 bool IsPolygonMode(PrimitiveMode mode)
    759 {
    760    switch (mode)
    761    {
    762        case PrimitiveMode::Points:
    763        case PrimitiveMode::Lines:
    764        case PrimitiveMode::LineStrip:
    765        case PrimitiveMode::LineLoop:
    766        case PrimitiveMode::LinesAdjacency:
    767        case PrimitiveMode::LineStripAdjacency:
    768            return false;
    769        default:
    770            break;
    771    }
    772 
    773    return true;
    774 }
    775 
    776 namespace priv
    777 {
    778 const angle::PackedEnumMap<PrimitiveMode, bool> gLineModes = {
    779    {{PrimitiveMode::LineLoop, true},
    780     {PrimitiveMode::LineStrip, true},
    781     {PrimitiveMode::LineStripAdjacency, true},
    782     {PrimitiveMode::Lines, true}}};
    783 }  // namespace priv
    784 
    785 bool IsIntegerFormat(GLenum unsizedFormat)
    786 {
    787    switch (unsizedFormat)
    788    {
    789        case GL_RGBA_INTEGER:
    790        case GL_RGB_INTEGER:
    791        case GL_RG_INTEGER:
    792        case GL_RED_INTEGER:
    793            return true;
    794 
    795        default:
    796            return false;
    797    }
    798 }
    799 
    800 // [OpenGL ES SL 3.00.4] Section 11 p. 120
    801 // Vertex Outs/Fragment Ins packing priorities
    802 int VariableSortOrder(GLenum type)
    803 {
    804    switch (type)
    805    {
    806        // 1. Arrays of mat4 and mat4
    807        // Non-square matrices of type matCxR consume the same space as a square
    808        // matrix of type matN where N is the greater of C and R
    809        case GL_FLOAT_MAT4:
    810        case GL_FLOAT_MAT2x4:
    811        case GL_FLOAT_MAT3x4:
    812        case GL_FLOAT_MAT4x2:
    813        case GL_FLOAT_MAT4x3:
    814            return 0;
    815 
    816        // 2. Arrays of mat2 and mat2 (since they occupy full rows)
    817        case GL_FLOAT_MAT2:
    818            return 1;
    819 
    820        // 3. Arrays of vec4 and vec4
    821        case GL_FLOAT_VEC4:
    822        case GL_INT_VEC4:
    823        case GL_BOOL_VEC4:
    824        case GL_UNSIGNED_INT_VEC4:
    825            return 2;
    826 
    827        // 4. Arrays of mat3 and mat3
    828        case GL_FLOAT_MAT3:
    829        case GL_FLOAT_MAT2x3:
    830        case GL_FLOAT_MAT3x2:
    831            return 3;
    832 
    833        // 5. Arrays of vec3 and vec3
    834        case GL_FLOAT_VEC3:
    835        case GL_INT_VEC3:
    836        case GL_BOOL_VEC3:
    837        case GL_UNSIGNED_INT_VEC3:
    838            return 4;
    839 
    840        // 6. Arrays of vec2 and vec2
    841        case GL_FLOAT_VEC2:
    842        case GL_INT_VEC2:
    843        case GL_BOOL_VEC2:
    844        case GL_UNSIGNED_INT_VEC2:
    845            return 5;
    846 
    847        // 7. Single component types
    848        case GL_FLOAT:
    849        case GL_INT:
    850        case GL_BOOL:
    851        case GL_UNSIGNED_INT:
    852        case GL_SAMPLER_2D:
    853        case GL_SAMPLER_CUBE:
    854        case GL_SAMPLER_EXTERNAL_OES:
    855        case GL_SAMPLER_2D_RECT_ANGLE:
    856        case GL_SAMPLER_2D_ARRAY:
    857        case GL_SAMPLER_2D_MULTISAMPLE:
    858        case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
    859        case GL_SAMPLER_3D:
    860        case GL_INT_SAMPLER_2D:
    861        case GL_INT_SAMPLER_3D:
    862        case GL_INT_SAMPLER_CUBE:
    863        case GL_INT_SAMPLER_2D_ARRAY:
    864        case GL_INT_SAMPLER_2D_MULTISAMPLE:
    865        case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
    866        case GL_UNSIGNED_INT_SAMPLER_2D:
    867        case GL_UNSIGNED_INT_SAMPLER_3D:
    868        case GL_UNSIGNED_INT_SAMPLER_CUBE:
    869        case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
    870        case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
    871        case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
    872        case GL_SAMPLER_2D_SHADOW:
    873        case GL_SAMPLER_2D_ARRAY_SHADOW:
    874        case GL_SAMPLER_CUBE_SHADOW:
    875        case GL_IMAGE_2D:
    876        case GL_INT_IMAGE_2D:
    877        case GL_UNSIGNED_INT_IMAGE_2D:
    878        case GL_IMAGE_3D:
    879        case GL_INT_IMAGE_3D:
    880        case GL_UNSIGNED_INT_IMAGE_3D:
    881        case GL_IMAGE_2D_ARRAY:
    882        case GL_INT_IMAGE_2D_ARRAY:
    883        case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
    884        case GL_IMAGE_CUBE:
    885        case GL_INT_IMAGE_CUBE:
    886        case GL_UNSIGNED_INT_IMAGE_CUBE:
    887        case GL_UNSIGNED_INT_ATOMIC_COUNTER:
    888        case GL_SAMPLER_VIDEO_IMAGE_WEBGL:
    889        case GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT:
    890            return 6;
    891 
    892        default:
    893            UNREACHABLE();
    894            return 0;
    895    }
    896 }
    897 
    898 std::string ParseResourceName(const std::string &name, std::vector<unsigned int> *outSubscripts)
    899 {
    900    if (outSubscripts)
    901    {
    902        outSubscripts->clear();
    903    }
    904    // Strip any trailing array indexing operators and retrieve the subscripts.
    905    size_t baseNameLength = name.length();
    906    bool hasIndex         = true;
    907    while (hasIndex)
    908    {
    909        size_t open  = name.find_last_of('[', baseNameLength - 1);
    910        size_t close = name.find_last_of(']', baseNameLength - 1);
    911        hasIndex     = (open != std::string::npos) && (close == baseNameLength - 1);
    912        if (hasIndex)
    913        {
    914            baseNameLength = open;
    915            if (outSubscripts)
    916            {
    917                int index = atoi(name.substr(open + 1).c_str());
    918                if (index >= 0)
    919                {
    920                    outSubscripts->push_back(index);
    921                }
    922                else
    923                {
    924                    outSubscripts->push_back(GL_INVALID_INDEX);
    925                }
    926            }
    927        }
    928    }
    929 
    930    return name.substr(0, baseNameLength);
    931 }
    932 
    933 bool IsBuiltInName(const char *name)
    934 {
    935    return angle::BeginsWith(name, "gl_");
    936 }
    937 
    938 std::string StripLastArrayIndex(const std::string &name)
    939 {
    940    size_t strippedNameLength = name.find_last_of('[');
    941    if (strippedNameLength != std::string::npos && name.back() == ']')
    942    {
    943        return name.substr(0, strippedNameLength);
    944    }
    945    return name;
    946 }
    947 
    948 bool SamplerNameContainsNonZeroArrayElement(const std::string &name)
    949 {
    950    constexpr char kZERO_ELEMENT[] = "[0]";
    951 
    952    size_t start = 0;
    953    while (true)
    954    {
    955        start = name.find(kZERO_ELEMENT[0], start);
    956        if (start == std::string::npos)
    957        {
    958            break;
    959        }
    960        if (name.compare(start, strlen(kZERO_ELEMENT), kZERO_ELEMENT) != 0)
    961        {
    962            return true;
    963        }
    964        start++;
    965    }
    966    return false;
    967 }
    968 
    969 unsigned int ArraySizeProduct(const std::vector<unsigned int> &arraySizes)
    970 {
    971    unsigned int arraySizeProduct = 1u;
    972    for (unsigned int arraySize : arraySizes)
    973    {
    974        arraySizeProduct *= arraySize;
    975    }
    976    return arraySizeProduct;
    977 }
    978 
    979 unsigned int InnerArraySizeProduct(const std::vector<unsigned int> &arraySizes)
    980 {
    981    unsigned int arraySizeProduct = 1u;
    982    for (size_t index = 0; index + 1 < arraySizes.size(); ++index)
    983    {
    984        arraySizeProduct *= arraySizes[index];
    985    }
    986    return arraySizeProduct;
    987 }
    988 
    989 unsigned int OutermostArraySize(const std::vector<unsigned int> &arraySizes)
    990 {
    991    return arraySizes.empty() || arraySizes.back() == 0 ? 1 : arraySizes.back();
    992 }
    993 
    994 unsigned int ParseArrayIndex(const std::string &name, size_t *nameLengthWithoutArrayIndexOut)
    995 {
    996    ASSERT(nameLengthWithoutArrayIndexOut != nullptr);
    997 
    998    // Strip any trailing array operator and retrieve the subscript
    999    size_t open = name.find_last_of('[');
   1000    if (open != std::string::npos && name.back() == ']')
   1001    {
   1002        bool indexIsValidDecimalNumber = true;
   1003        for (size_t i = open + 1; i < name.length() - 1u; ++i)
   1004        {
   1005            if (!isdigit(name[i]))
   1006            {
   1007                indexIsValidDecimalNumber = false;
   1008                break;
   1009            }
   1010 
   1011            // Leading zeroes are invalid
   1012            if ((i == (open + 1)) && (name[i] == '0') && (name[i + 1] != ']'))
   1013            {
   1014                indexIsValidDecimalNumber = false;
   1015                break;
   1016            }
   1017        }
   1018        if (indexIsValidDecimalNumber)
   1019        {
   1020            errno = 0;  // reset global error flag.
   1021            unsigned long subscript =
   1022                strtoul(name.c_str() + open + 1, /*endptr*/ nullptr, /*radix*/ 10);
   1023 
   1024            // Check if resulting integer is out-of-range or conversion error.
   1025            if (angle::base::IsValueInRangeForNumericType<uint32_t>(subscript) &&
   1026                !(subscript == ULONG_MAX && errno == ERANGE) && !(errno != 0 && subscript == 0))
   1027            {
   1028                *nameLengthWithoutArrayIndexOut = open;
   1029                return static_cast<unsigned int>(subscript);
   1030            }
   1031        }
   1032    }
   1033 
   1034    *nameLengthWithoutArrayIndexOut = name.length();
   1035    return GL_INVALID_INDEX;
   1036 }
   1037 
   1038 const char *GetGenericErrorMessage(GLenum error)
   1039 {
   1040    switch (error)
   1041    {
   1042        case GL_NO_ERROR:
   1043            return "";
   1044        case GL_INVALID_ENUM:
   1045            return "Invalid enum.";
   1046        case GL_INVALID_VALUE:
   1047            return "Invalid value.";
   1048        case GL_INVALID_OPERATION:
   1049            return "Invalid operation.";
   1050        case GL_STACK_OVERFLOW:
   1051            return "Stack overflow.";
   1052        case GL_STACK_UNDERFLOW:
   1053            return "Stack underflow.";
   1054        case GL_OUT_OF_MEMORY:
   1055            return "Out of memory.";
   1056        case GL_INVALID_FRAMEBUFFER_OPERATION:
   1057            return "Invalid framebuffer operation.";
   1058        default:
   1059            UNREACHABLE();
   1060            return "Unknown error.";
   1061    }
   1062 }
   1063 
   1064 unsigned int ElementTypeSize(GLenum elementType)
   1065 {
   1066    switch (elementType)
   1067    {
   1068        case GL_UNSIGNED_BYTE:
   1069            return sizeof(GLubyte);
   1070        case GL_UNSIGNED_SHORT:
   1071            return sizeof(GLushort);
   1072        case GL_UNSIGNED_INT:
   1073            return sizeof(GLuint);
   1074        default:
   1075            UNREACHABLE();
   1076            return 0;
   1077    }
   1078 }
   1079 
   1080 bool IsMipmapFiltered(GLenum minFilterMode)
   1081 {
   1082    switch (minFilterMode)
   1083    {
   1084        case GL_NEAREST:
   1085        case GL_LINEAR:
   1086            return false;
   1087        case GL_NEAREST_MIPMAP_NEAREST:
   1088        case GL_LINEAR_MIPMAP_NEAREST:
   1089        case GL_NEAREST_MIPMAP_LINEAR:
   1090        case GL_LINEAR_MIPMAP_LINEAR:
   1091            return true;
   1092        default:
   1093            UNREACHABLE();
   1094            return false;
   1095    }
   1096 }
   1097 
   1098 PipelineType GetPipelineType(ShaderType type)
   1099 {
   1100    switch (type)
   1101    {
   1102        case ShaderType::Vertex:
   1103        case ShaderType::Fragment:
   1104        case ShaderType::Geometry:
   1105            return PipelineType::GraphicsPipeline;
   1106        case ShaderType::Compute:
   1107            return PipelineType::ComputePipeline;
   1108        default:
   1109            UNREACHABLE();
   1110            return PipelineType::GraphicsPipeline;
   1111    }
   1112 }
   1113 
   1114 const char *GetDebugMessageSourceString(GLenum source)
   1115 {
   1116    switch (source)
   1117    {
   1118        case GL_DEBUG_SOURCE_API:
   1119            return "API";
   1120        case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
   1121            return "Window System";
   1122        case GL_DEBUG_SOURCE_SHADER_COMPILER:
   1123            return "Shader Compiler";
   1124        case GL_DEBUG_SOURCE_THIRD_PARTY:
   1125            return "Third Party";
   1126        case GL_DEBUG_SOURCE_APPLICATION:
   1127            return "Application";
   1128        case GL_DEBUG_SOURCE_OTHER:
   1129            return "Other";
   1130        default:
   1131            return "Unknown Source";
   1132    }
   1133 }
   1134 
   1135 const char *GetDebugMessageTypeString(GLenum type)
   1136 {
   1137    switch (type)
   1138    {
   1139        case GL_DEBUG_TYPE_ERROR:
   1140            return "Error";
   1141        case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
   1142            return "Deprecated behavior";
   1143        case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
   1144            return "Undefined behavior";
   1145        case GL_DEBUG_TYPE_PORTABILITY:
   1146            return "Portability";
   1147        case GL_DEBUG_TYPE_PERFORMANCE:
   1148            return "Performance";
   1149        case GL_DEBUG_TYPE_OTHER:
   1150            return "Other";
   1151        case GL_DEBUG_TYPE_MARKER:
   1152            return "Marker";
   1153        default:
   1154            return "Unknown Type";
   1155    }
   1156 }
   1157 
   1158 const char *GetDebugMessageSeverityString(GLenum severity)
   1159 {
   1160    switch (severity)
   1161    {
   1162        case GL_DEBUG_SEVERITY_HIGH:
   1163            return "High";
   1164        case GL_DEBUG_SEVERITY_MEDIUM:
   1165            return "Medium";
   1166        case GL_DEBUG_SEVERITY_LOW:
   1167            return "Low";
   1168        case GL_DEBUG_SEVERITY_NOTIFICATION:
   1169            return "Notification";
   1170        default:
   1171            return "Unknown Severity";
   1172    }
   1173 }
   1174 
   1175 ShaderType GetShaderTypeFromBitfield(size_t singleShaderType)
   1176 {
   1177    switch (singleShaderType)
   1178    {
   1179        case GL_VERTEX_SHADER_BIT:
   1180            return ShaderType::Vertex;
   1181        case GL_FRAGMENT_SHADER_BIT:
   1182            return ShaderType::Fragment;
   1183        case GL_COMPUTE_SHADER_BIT:
   1184            return ShaderType::Compute;
   1185        case GL_GEOMETRY_SHADER_BIT:
   1186            return ShaderType::Geometry;
   1187        case GL_TESS_CONTROL_SHADER_BIT:
   1188            return ShaderType::TessControl;
   1189        case GL_TESS_EVALUATION_SHADER_BIT:
   1190            return ShaderType::TessEvaluation;
   1191        default:
   1192            return ShaderType::InvalidEnum;
   1193    }
   1194 }
   1195 
   1196 GLbitfield GetBitfieldFromShaderType(ShaderType shaderType)
   1197 {
   1198    switch (shaderType)
   1199    {
   1200        case ShaderType::Vertex:
   1201            return GL_VERTEX_SHADER_BIT;
   1202        case ShaderType::Fragment:
   1203            return GL_FRAGMENT_SHADER_BIT;
   1204        case ShaderType::Compute:
   1205            return GL_COMPUTE_SHADER_BIT;
   1206        case ShaderType::Geometry:
   1207            return GL_GEOMETRY_SHADER_BIT;
   1208        case ShaderType::TessControl:
   1209            return GL_TESS_CONTROL_SHADER_BIT;
   1210        case ShaderType::TessEvaluation:
   1211            return GL_TESS_EVALUATION_SHADER_BIT;
   1212        default:
   1213            UNREACHABLE();
   1214            return GL_ZERO;
   1215    }
   1216 }
   1217 
   1218 bool ShaderTypeSupportsTransformFeedback(ShaderType shaderType)
   1219 {
   1220    switch (shaderType)
   1221    {
   1222        case ShaderType::Vertex:
   1223        case ShaderType::Geometry:
   1224        case ShaderType::TessEvaluation:
   1225            return true;
   1226        default:
   1227            return false;
   1228    }
   1229 }
   1230 
   1231 ShaderType GetLastPreFragmentStage(ShaderBitSet shaderTypes)
   1232 {
   1233    shaderTypes.reset(ShaderType::Fragment);
   1234    shaderTypes.reset(ShaderType::Compute);
   1235    return shaderTypes.any() ? shaderTypes.last() : ShaderType::InvalidEnum;
   1236 }
   1237 }  // namespace gl
   1238 
   1239 namespace egl
   1240 {
   1241 static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 1,
   1242              "Unexpected EGL cube map enum value.");
   1243 static_assert(EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 2,
   1244              "Unexpected EGL cube map enum value.");
   1245 static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 3,
   1246              "Unexpected EGL cube map enum value.");
   1247 static_assert(EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 4,
   1248              "Unexpected EGL cube map enum value.");
   1249 static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 5,
   1250              "Unexpected EGL cube map enum value.");
   1251 
   1252 bool IsCubeMapTextureTarget(EGLenum target)
   1253 {
   1254    return (target >= FirstCubeMapTextureTarget && target <= LastCubeMapTextureTarget);
   1255 }
   1256 
   1257 size_t CubeMapTextureTargetToLayerIndex(EGLenum target)
   1258 {
   1259    ASSERT(IsCubeMapTextureTarget(target));
   1260    return target - static_cast<size_t>(FirstCubeMapTextureTarget);
   1261 }
   1262 
   1263 EGLenum LayerIndexToCubeMapTextureTarget(size_t index)
   1264 {
   1265    ASSERT(index <= (LastCubeMapTextureTarget - FirstCubeMapTextureTarget));
   1266    return FirstCubeMapTextureTarget + static_cast<GLenum>(index);
   1267 }
   1268 
   1269 bool IsTextureTarget(EGLenum target)
   1270 {
   1271    switch (target)
   1272    {
   1273        case EGL_GL_TEXTURE_2D_KHR:
   1274        case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
   1275        case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
   1276        case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
   1277        case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
   1278        case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
   1279        case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
   1280        case EGL_GL_TEXTURE_3D_KHR:
   1281            return true;
   1282 
   1283        default:
   1284            return false;
   1285    }
   1286 }
   1287 
   1288 bool IsRenderbufferTarget(EGLenum target)
   1289 {
   1290    return target == EGL_GL_RENDERBUFFER_KHR;
   1291 }
   1292 
   1293 bool IsExternalImageTarget(EGLenum target)
   1294 {
   1295    switch (target)
   1296    {
   1297        case EGL_NATIVE_BUFFER_ANDROID:
   1298        case EGL_D3D11_TEXTURE_ANGLE:
   1299        case EGL_LINUX_DMA_BUF_EXT:
   1300        case EGL_METAL_TEXTURE_ANGLE:
   1301        case EGL_VULKAN_IMAGE_ANGLE:
   1302            return true;
   1303 
   1304        default:
   1305            return false;
   1306    }
   1307 }
   1308 
   1309 const char *GetGenericErrorMessage(EGLint error)
   1310 {
   1311    switch (error)
   1312    {
   1313        case EGL_SUCCESS:
   1314            return "";
   1315        case EGL_NOT_INITIALIZED:
   1316            return "Not initialized.";
   1317        case EGL_BAD_ACCESS:
   1318            return "Bad access.";
   1319        case EGL_BAD_ALLOC:
   1320            return "Bad allocation.";
   1321        case EGL_BAD_ATTRIBUTE:
   1322            return "Bad attribute.";
   1323        case EGL_BAD_CONFIG:
   1324            return "Bad config.";
   1325        case EGL_BAD_CONTEXT:
   1326            return "Bad context.";
   1327        case EGL_BAD_CURRENT_SURFACE:
   1328            return "Bad current surface.";
   1329        case EGL_BAD_DISPLAY:
   1330            return "Bad display.";
   1331        case EGL_BAD_MATCH:
   1332            return "Bad match.";
   1333        case EGL_BAD_NATIVE_WINDOW:
   1334            return "Bad native window.";
   1335        case EGL_BAD_NATIVE_PIXMAP:
   1336            return "Bad native pixmap.";
   1337        case EGL_BAD_PARAMETER:
   1338            return "Bad parameter.";
   1339        case EGL_BAD_SURFACE:
   1340            return "Bad surface.";
   1341        case EGL_CONTEXT_LOST:
   1342            return "Context lost.";
   1343        case EGL_BAD_STREAM_KHR:
   1344            return "Bad stream.";
   1345        case EGL_BAD_STATE_KHR:
   1346            return "Bad state.";
   1347        case EGL_BAD_DEVICE_EXT:
   1348            return "Bad device.";
   1349        default:
   1350            UNREACHABLE();
   1351            return "Unknown error.";
   1352    }
   1353 }
   1354 
   1355 }  // namespace egl
   1356 
   1357 namespace egl_gl
   1358 {
   1359 GLuint EGLClientBufferToGLObjectHandle(EGLClientBuffer buffer)
   1360 {
   1361    return static_cast<GLuint>(reinterpret_cast<uintptr_t>(buffer));
   1362 }
   1363 }  // namespace egl_gl
   1364 
   1365 namespace gl_egl
   1366 {
   1367 EGLenum GLComponentTypeToEGLColorComponentType(GLenum glComponentType)
   1368 {
   1369    switch (glComponentType)
   1370    {
   1371        case GL_FLOAT:
   1372            return EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT;
   1373 
   1374        case GL_UNSIGNED_NORMALIZED:
   1375            return EGL_COLOR_COMPONENT_TYPE_FIXED_EXT;
   1376 
   1377        default:
   1378            UNREACHABLE();
   1379            return EGL_NONE;
   1380    }
   1381 }
   1382 
   1383 EGLClientBuffer GLObjectHandleToEGLClientBuffer(GLuint handle)
   1384 {
   1385    return reinterpret_cast<EGLClientBuffer>(static_cast<uintptr_t>(handle));
   1386 }
   1387 
   1388 }  // namespace gl_egl
   1389 
   1390 namespace angle
   1391 {
   1392 bool IsDrawEntryPoint(EntryPoint entryPoint)
   1393 {
   1394    switch (entryPoint)
   1395    {
   1396        case EntryPoint::GLDrawArrays:
   1397        case EntryPoint::GLDrawArraysIndirect:
   1398        case EntryPoint::GLDrawArraysInstanced:
   1399        case EntryPoint::GLDrawArraysInstancedANGLE:
   1400        case EntryPoint::GLDrawArraysInstancedBaseInstance:
   1401        case EntryPoint::GLDrawArraysInstancedBaseInstanceANGLE:
   1402        case EntryPoint::GLDrawArraysInstancedEXT:
   1403        case EntryPoint::GLDrawElements:
   1404        case EntryPoint::GLDrawElementsBaseVertex:
   1405        case EntryPoint::GLDrawElementsBaseVertexEXT:
   1406        case EntryPoint::GLDrawElementsBaseVertexOES:
   1407        case EntryPoint::GLDrawElementsIndirect:
   1408        case EntryPoint::GLDrawElementsInstanced:
   1409        case EntryPoint::GLDrawElementsInstancedANGLE:
   1410        case EntryPoint::GLDrawElementsInstancedBaseInstance:
   1411        case EntryPoint::GLDrawElementsInstancedBaseVertex:
   1412        case EntryPoint::GLDrawElementsInstancedBaseVertexBaseInstance:
   1413        case EntryPoint::GLDrawElementsInstancedBaseVertexBaseInstanceANGLE:
   1414        case EntryPoint::GLDrawElementsInstancedBaseVertexEXT:
   1415        case EntryPoint::GLDrawElementsInstancedBaseVertexOES:
   1416        case EntryPoint::GLDrawElementsInstancedEXT:
   1417        case EntryPoint::GLDrawPixels:
   1418        case EntryPoint::GLDrawRangeElements:
   1419        case EntryPoint::GLDrawRangeElementsBaseVertex:
   1420        case EntryPoint::GLDrawRangeElementsBaseVertexEXT:
   1421        case EntryPoint::GLDrawRangeElementsBaseVertexOES:
   1422        case EntryPoint::GLDrawTexfOES:
   1423        case EntryPoint::GLDrawTexfvOES:
   1424        case EntryPoint::GLDrawTexiOES:
   1425        case EntryPoint::GLDrawTexivOES:
   1426        case EntryPoint::GLDrawTexsOES:
   1427        case EntryPoint::GLDrawTexsvOES:
   1428        case EntryPoint::GLDrawTexxOES:
   1429        case EntryPoint::GLDrawTexxvOES:
   1430        case EntryPoint::GLDrawTransformFeedback:
   1431        case EntryPoint::GLDrawTransformFeedbackInstanced:
   1432        case EntryPoint::GLDrawTransformFeedbackStream:
   1433        case EntryPoint::GLDrawTransformFeedbackStreamInstanced:
   1434            return true;
   1435        default:
   1436            return false;
   1437    }
   1438 }
   1439 
   1440 bool IsDispatchEntryPoint(EntryPoint entryPoint)
   1441 {
   1442    switch (entryPoint)
   1443    {
   1444        case EntryPoint::GLDispatchCompute:
   1445        case EntryPoint::GLDispatchComputeIndirect:
   1446            return true;
   1447        default:
   1448            return false;
   1449    }
   1450 }
   1451 
   1452 bool IsClearEntryPoint(EntryPoint entryPoint)
   1453 {
   1454    switch (entryPoint)
   1455    {
   1456        case EntryPoint::GLClear:
   1457        case EntryPoint::GLClearBufferfi:
   1458        case EntryPoint::GLClearBufferfv:
   1459        case EntryPoint::GLClearBufferiv:
   1460        case EntryPoint::GLClearBufferuiv:
   1461            return true;
   1462        default:
   1463            return false;
   1464    }
   1465 }
   1466 
   1467 bool IsQueryEntryPoint(EntryPoint entryPoint)
   1468 {
   1469    switch (entryPoint)
   1470    {
   1471        case EntryPoint::GLBeginQuery:
   1472        case EntryPoint::GLBeginQueryEXT:
   1473        case EntryPoint::GLBeginQueryIndexed:
   1474        case EntryPoint::GLEndQuery:
   1475        case EntryPoint::GLEndQueryEXT:
   1476        case EntryPoint::GLEndQueryIndexed:
   1477            return true;
   1478        default:
   1479            return false;
   1480    }
   1481 }
   1482 }  // namespace angle
   1483 
   1484 #if !defined(ANGLE_ENABLE_WINDOWS_UWP)
   1485 void writeFile(const char *path, const void *content, size_t size)
   1486 {
   1487    FILE *file = fopen(path, "w");
   1488    if (!file)
   1489    {
   1490        UNREACHABLE();
   1491        return;
   1492    }
   1493 
   1494    fwrite(content, sizeof(char), size, file);
   1495    fclose(file);
   1496 }
   1497 #endif  // !ANGLE_ENABLE_WINDOWS_UWP
   1498 
   1499 #if defined(ANGLE_PLATFORM_WINDOWS)
   1500 
   1501 // Causes the thread to relinquish the remainder of its time slice to any
   1502 // other thread that is ready to run.If there are no other threads ready
   1503 // to run, the function returns immediately, and the thread continues execution.
   1504 void ScheduleYield()
   1505 {
   1506    Sleep(0);
   1507 }
   1508 
   1509 #endif