Home | History | Annotate | Download | only in libGLESv2
      1 #include "precompiled.h"
      2 //
      3 // Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
      4 // Use of this source code is governed by a BSD-style license that can be
      5 // found in the LICENSE file.
      6 //
      7 
      8 // formatutils.cpp: Queries for GL image formats.
      9 
     10 #include "common/mathutil.h"
     11 #include "libGLESv2/formatutils.h"
     12 #include "libGLESv2/Context.h"
     13 #include "libGLESv2/Framebuffer.h"
     14 #include "libGLESv2/renderer/Renderer.h"
     15 #include "libGLESv2/renderer/imageformats.h"
     16 #include "libGLESv2/renderer/copyimage.h"
     17 
     18 namespace gl
     19 {
     20 
     21 // ES2 requires that format is equal to internal format at all glTex*Image2D entry points and the implementation
     22 // can decide the true, sized, internal format. The ES2FormatMap determines the internal format for all valid
     23 // format and type combinations.
     24 
     25 struct FormatTypeInfo
     26 {
     27     GLenum mInternalFormat;
     28     ColorWriteFunction mColorWriteFunction;
     29 
     30     FormatTypeInfo(GLenum internalFormat, ColorWriteFunction writeFunc)
     31         : mInternalFormat(internalFormat), mColorWriteFunction(writeFunc)
     32     { }
     33 };
     34 
     35 typedef std::pair<GLenum, GLenum> FormatTypePair;
     36 typedef std::pair<FormatTypePair, FormatTypeInfo> FormatPair;
     37 typedef std::map<FormatTypePair, FormatTypeInfo> FormatMap;
     38 
     39 // A helper function to insert data into the format map with fewer characters.
     40 static inline void InsertFormatMapping(FormatMap *map, GLenum format, GLenum type, GLenum internalFormat, ColorWriteFunction writeFunc)
     41 {
     42     map->insert(FormatPair(FormatTypePair(format, type), FormatTypeInfo(internalFormat, writeFunc)));
     43 }
     44 
     45 FormatMap BuildES2FormatMap()
     46 {
     47     FormatMap map;
     48 
     49     using namespace rx;
     50 
     51     //                       | Format                            | Type                             | Internal format                   | Color write function             |
     52     InsertFormatMapping(&map, GL_ALPHA,                           GL_UNSIGNED_BYTE,                  GL_ALPHA8_EXT,                      WriteColor<A8, GLfloat>           );
     53     InsertFormatMapping(&map, GL_ALPHA,                           GL_FLOAT,                          GL_ALPHA32F_EXT,                    WriteColor<A32F, GLfloat>         );
     54     InsertFormatMapping(&map, GL_ALPHA,                           GL_HALF_FLOAT_OES,                 GL_ALPHA16F_EXT,                    WriteColor<A16F, GLfloat>         );
     55 
     56     InsertFormatMapping(&map, GL_LUMINANCE,                       GL_UNSIGNED_BYTE,                  GL_LUMINANCE8_EXT,                  WriteColor<L8, GLfloat>           );
     57     InsertFormatMapping(&map, GL_LUMINANCE,                       GL_FLOAT,                          GL_LUMINANCE32F_EXT,                WriteColor<L32F, GLfloat>         );
     58     InsertFormatMapping(&map, GL_LUMINANCE,                       GL_HALF_FLOAT_OES,                 GL_LUMINANCE16F_EXT,                WriteColor<L16F, GLfloat>         );
     59 
     60     InsertFormatMapping(&map, GL_LUMINANCE_ALPHA,                 GL_UNSIGNED_BYTE,                  GL_LUMINANCE8_ALPHA8_EXT,           WriteColor<L8A8, GLfloat>         );
     61     InsertFormatMapping(&map, GL_LUMINANCE_ALPHA,                 GL_FLOAT,                          GL_LUMINANCE_ALPHA32F_EXT,          WriteColor<L32A32F, GLfloat>      );
     62     InsertFormatMapping(&map, GL_LUMINANCE_ALPHA,                 GL_HALF_FLOAT_OES,                 GL_LUMINANCE_ALPHA16F_EXT,          WriteColor<L16A16F, GLfloat>      );
     63 
     64     InsertFormatMapping(&map, GL_RED,                             GL_UNSIGNED_BYTE,                  GL_R8_EXT,                          WriteColor<R8, GLfloat>           );
     65     InsertFormatMapping(&map, GL_RED,                             GL_FLOAT,                          GL_R32F_EXT,                        WriteColor<R32F, GLfloat>         );
     66     InsertFormatMapping(&map, GL_RED,                             GL_HALF_FLOAT_OES,                 GL_R16F_EXT,                        WriteColor<R16F, GLfloat>         );
     67 
     68     InsertFormatMapping(&map, GL_RG,                              GL_UNSIGNED_BYTE,                  GL_RG8_EXT,                         WriteColor<R8G8, GLfloat>         );
     69     InsertFormatMapping(&map, GL_RG,                              GL_FLOAT,                          GL_RG32F_EXT,                       WriteColor<R32G32F, GLfloat>      );
     70     InsertFormatMapping(&map, GL_RG,                              GL_HALF_FLOAT_OES,                 GL_RG16F_EXT,                       WriteColor<R16G16F, GLfloat>      );
     71 
     72     InsertFormatMapping(&map, GL_RGB,                             GL_UNSIGNED_BYTE,                  GL_RGB8_OES,                        WriteColor<R8G8B8, GLfloat>       );
     73     InsertFormatMapping(&map, GL_RGB,                             GL_UNSIGNED_SHORT_5_6_5,           GL_RGB565,                          WriteColor<R5G6B5, GLfloat>       );
     74     InsertFormatMapping(&map, GL_RGB,                             GL_FLOAT,                          GL_RGB32F_EXT,                      WriteColor<R32G32B32F, GLfloat>   );
     75     InsertFormatMapping(&map, GL_RGB,                             GL_HALF_FLOAT_OES,                 GL_RGB16F_EXT,                      WriteColor<R16G16B16F, GLfloat>   );
     76 
     77     InsertFormatMapping(&map, GL_RGBA,                            GL_UNSIGNED_BYTE,                  GL_RGBA8_OES,                       WriteColor<R8G8B8A8, GLfloat>     );
     78     InsertFormatMapping(&map, GL_RGBA,                            GL_UNSIGNED_SHORT_4_4_4_4,         GL_RGBA4,                           WriteColor<R4G4B4A4, GLfloat>     );
     79     InsertFormatMapping(&map, GL_RGBA,                            GL_UNSIGNED_SHORT_5_5_5_1,         GL_RGB5_A1,                         WriteColor<R5G5B5A1, GLfloat>     );
     80     InsertFormatMapping(&map, GL_RGBA,                            GL_FLOAT,                          GL_RGBA32F_EXT,                     WriteColor<R32G32B32A32F, GLfloat>);
     81     InsertFormatMapping(&map, GL_RGBA,                            GL_HALF_FLOAT_OES,                 GL_RGBA16F_EXT,                     WriteColor<R16G16B16A16F, GLfloat>);
     82 
     83     InsertFormatMapping(&map, GL_BGRA_EXT,                        GL_UNSIGNED_BYTE,                  GL_BGRA8_EXT,                       WriteColor<B8G8R8A8, GLfloat>     );
     84     InsertFormatMapping(&map, GL_BGRA_EXT,                        GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, GL_BGRA4_ANGLEX,                    WriteColor<B4G4R4A4, GLfloat>     );
     85     InsertFormatMapping(&map, GL_BGRA_EXT,                        GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, GL_BGR5_A1_ANGLEX,                  WriteColor<B5G5R5A1, GLfloat>     );
     86 
     87     InsertFormatMapping(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,    GL_UNSIGNED_BYTE,                  GL_COMPRESSED_RGB_S3TC_DXT1_EXT,    NULL                              );
     88     InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,   GL_UNSIGNED_BYTE,                  GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,   NULL                              );
     89     InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE,                  GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, NULL                              );
     90     InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE,                  GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, NULL                              );
     91 
     92     InsertFormatMapping(&map, GL_DEPTH_COMPONENT,                 GL_UNSIGNED_SHORT,                 GL_DEPTH_COMPONENT16,               NULL                              );
     93     InsertFormatMapping(&map, GL_DEPTH_COMPONENT,                 GL_UNSIGNED_INT,                   GL_DEPTH_COMPONENT32_OES,           NULL                              );
     94 
     95     InsertFormatMapping(&map, GL_DEPTH_STENCIL_OES,               GL_UNSIGNED_INT_24_8_OES,          GL_DEPTH24_STENCIL8_OES,            NULL                              );
     96 
     97     return map;
     98 }
     99 
    100 FormatMap BuildES3FormatMap()
    101 {
    102     FormatMap map;
    103 
    104     using namespace rx;
    105 
    106     //                       | Format               | Type                             | Internal format          | Color write function             |
    107     InsertFormatMapping(&map, GL_RGBA,               GL_UNSIGNED_BYTE,                  GL_RGBA8,                  WriteColor<R8G8B8A8, GLfloat>     );
    108     InsertFormatMapping(&map, GL_RGBA,               GL_BYTE,                           GL_RGBA8_SNORM,            WriteColor<R8G8B8A8S, GLfloat>    );
    109     InsertFormatMapping(&map, GL_RGBA,               GL_UNSIGNED_SHORT_4_4_4_4,         GL_RGBA4,                  WriteColor<R4G4B4A4, GLfloat>     );
    110     InsertFormatMapping(&map, GL_RGBA,               GL_UNSIGNED_SHORT_5_5_5_1,         GL_RGB5_A1,                WriteColor<R5G5B5A1, GLfloat>     );
    111     InsertFormatMapping(&map, GL_RGBA,               GL_UNSIGNED_INT_2_10_10_10_REV,    GL_RGB10_A2,               WriteColor<R10G10B10A2, GLfloat>  );
    112     InsertFormatMapping(&map, GL_RGBA,               GL_FLOAT,                          GL_RGBA32F,                WriteColor<R32G32B32A32F, GLfloat>);
    113     InsertFormatMapping(&map, GL_RGBA,               GL_HALF_FLOAT,                     GL_RGBA16F,                WriteColor<R16G16B16A16F, GLfloat>);
    114 
    115     InsertFormatMapping(&map, GL_RGBA_INTEGER,       GL_UNSIGNED_BYTE,                  GL_RGBA8UI,                WriteColor<R8G8B8A8, GLuint>      );
    116     InsertFormatMapping(&map, GL_RGBA_INTEGER,       GL_BYTE,                           GL_RGBA8I,                 WriteColor<R8G8B8A8S, GLint>      );
    117     InsertFormatMapping(&map, GL_RGBA_INTEGER,       GL_UNSIGNED_SHORT,                 GL_RGBA16UI,               WriteColor<R16G16B16A16, GLuint>  );
    118     InsertFormatMapping(&map, GL_RGBA_INTEGER,       GL_SHORT,                          GL_RGBA16I,                WriteColor<R16G16B16A16S, GLint>  );
    119     InsertFormatMapping(&map, GL_RGBA_INTEGER,       GL_UNSIGNED_INT,                   GL_RGBA32UI,               WriteColor<R32G32B32A32, GLuint>  );
    120     InsertFormatMapping(&map, GL_RGBA_INTEGER,       GL_INT,                            GL_RGBA32I,                WriteColor<R32G32B32A32S, GLint>  );
    121     InsertFormatMapping(&map, GL_RGBA_INTEGER,       GL_UNSIGNED_INT_2_10_10_10_REV,    GL_RGB10_A2UI,             WriteColor<R10G10B10A2, GLuint>   );
    122 
    123     InsertFormatMapping(&map, GL_RGB,                GL_UNSIGNED_BYTE,                  GL_RGB8,                   WriteColor<R8G8B8, GLfloat>       );
    124     InsertFormatMapping(&map, GL_RGB,                GL_BYTE,                           GL_RGB8_SNORM,             WriteColor<R8G8B8S, GLfloat>      );
    125     InsertFormatMapping(&map, GL_RGB,                GL_UNSIGNED_SHORT_5_6_5,           GL_RGB565,                 WriteColor<R5G6B5, GLfloat>       );
    126     InsertFormatMapping(&map, GL_RGB,                GL_UNSIGNED_INT_10F_11F_11F_REV,   GL_R11F_G11F_B10F,         WriteColor<R11G11B10F, GLfloat>   );
    127     InsertFormatMapping(&map, GL_RGB,                GL_UNSIGNED_INT_5_9_9_9_REV,       GL_RGB9_E5,                WriteColor<R9G9B9E5, GLfloat>     );
    128     InsertFormatMapping(&map, GL_RGB,                GL_FLOAT,                          GL_RGB32F,                 WriteColor<R32G32B32F, GLfloat>   );
    129     InsertFormatMapping(&map, GL_RGB,                GL_HALF_FLOAT,                     GL_RGB16F,                 WriteColor<R16G16B16F, GLfloat>   );
    130 
    131     InsertFormatMapping(&map, GL_RGB_INTEGER,        GL_UNSIGNED_BYTE,                  GL_RGB8UI,                 WriteColor<R8G8B8, GLuint>        );
    132     InsertFormatMapping(&map, GL_RGB_INTEGER,        GL_BYTE,                           GL_RGB8I,                  WriteColor<R8G8B8S, GLint>        );
    133     InsertFormatMapping(&map, GL_RGB_INTEGER,        GL_UNSIGNED_SHORT,                 GL_RGB16UI,                WriteColor<R16G16B16, GLuint>     );
    134     InsertFormatMapping(&map, GL_RGB_INTEGER,        GL_SHORT,                          GL_RGB16I,                 WriteColor<R16G16B16S, GLint>     );
    135     InsertFormatMapping(&map, GL_RGB_INTEGER,        GL_UNSIGNED_INT,                   GL_RGB32UI,                WriteColor<R32G32B32, GLuint>     );
    136     InsertFormatMapping(&map, GL_RGB_INTEGER,        GL_INT,                            GL_RGB32I,                 WriteColor<R32G32B32S, GLint>     );
    137 
    138     InsertFormatMapping(&map, GL_RG,                 GL_UNSIGNED_BYTE,                  GL_RG8,                    WriteColor<R8G8, GLfloat>         );
    139     InsertFormatMapping(&map, GL_RG,                 GL_BYTE,                           GL_RG8_SNORM,              WriteColor<R8G8S, GLfloat>        );
    140     InsertFormatMapping(&map, GL_RG,                 GL_FLOAT,                          GL_RG32F,                  WriteColor<R32G32F, GLfloat>      );
    141     InsertFormatMapping(&map, GL_RG,                 GL_HALF_FLOAT,                     GL_RG16F,                  WriteColor<R16G16F, GLfloat>      );
    142 
    143     InsertFormatMapping(&map, GL_RG_INTEGER,         GL_UNSIGNED_BYTE,                  GL_RG8UI,                  WriteColor<R8G8, GLuint>          );
    144     InsertFormatMapping(&map, GL_RG_INTEGER,         GL_BYTE,                           GL_RG8I,                   WriteColor<R8G8S, GLint>          );
    145     InsertFormatMapping(&map, GL_RG_INTEGER,         GL_UNSIGNED_SHORT,                 GL_RG16UI,                 WriteColor<R16G16, GLuint>        );
    146     InsertFormatMapping(&map, GL_RG_INTEGER,         GL_SHORT,                          GL_RG16I,                  WriteColor<R16G16S, GLint>        );
    147     InsertFormatMapping(&map, GL_RG_INTEGER,         GL_UNSIGNED_INT,                   GL_RG32UI,                 WriteColor<R32G32, GLuint>        );
    148     InsertFormatMapping(&map, GL_RG_INTEGER,         GL_INT,                            GL_RG32I,                  WriteColor<R32G32S, GLint>        );
    149 
    150     InsertFormatMapping(&map, GL_RED,                GL_UNSIGNED_BYTE,                  GL_R8,                     WriteColor<R8, GLfloat>           );
    151     InsertFormatMapping(&map, GL_RED,                GL_BYTE,                           GL_R8_SNORM,               WriteColor<R8S, GLfloat>          );
    152     InsertFormatMapping(&map, GL_RED,                GL_FLOAT,                          GL_R32F,                   WriteColor<R32F, GLfloat>         );
    153     InsertFormatMapping(&map, GL_RED,                GL_HALF_FLOAT,                     GL_R16F,                   WriteColor<R16F, GLfloat>         );
    154 
    155     InsertFormatMapping(&map, GL_RED_INTEGER,        GL_UNSIGNED_BYTE,                  GL_R8UI,                   WriteColor<R8, GLuint>            );
    156     InsertFormatMapping(&map, GL_RED_INTEGER,        GL_BYTE,                           GL_R8I,                    WriteColor<R8S, GLint>            );
    157     InsertFormatMapping(&map, GL_RED_INTEGER,        GL_UNSIGNED_SHORT,                 GL_R16UI,                  WriteColor<R16, GLuint>           );
    158     InsertFormatMapping(&map, GL_RED_INTEGER,        GL_SHORT,                          GL_R16I,                   WriteColor<R16S, GLint>           );
    159     InsertFormatMapping(&map, GL_RED_INTEGER,        GL_UNSIGNED_INT,                   GL_R32UI,                  WriteColor<R32, GLuint>           );
    160     InsertFormatMapping(&map, GL_RED_INTEGER,        GL_INT,                            GL_R32I,                   WriteColor<R32S, GLint>           );
    161 
    162     InsertFormatMapping(&map, GL_LUMINANCE_ALPHA,    GL_UNSIGNED_BYTE,                  GL_LUMINANCE8_ALPHA8_EXT,  WriteColor<L8A8, GLfloat>         );
    163     InsertFormatMapping(&map, GL_LUMINANCE,          GL_UNSIGNED_BYTE,                  GL_LUMINANCE8_EXT,         WriteColor<L8, GLfloat>           );
    164     InsertFormatMapping(&map, GL_ALPHA,              GL_UNSIGNED_BYTE,                  GL_ALPHA8_EXT,             WriteColor<A8, GLfloat>           );
    165     InsertFormatMapping(&map, GL_LUMINANCE_ALPHA,    GL_FLOAT,                          GL_LUMINANCE_ALPHA32F_EXT, WriteColor<L32A32F, GLfloat>      );
    166     InsertFormatMapping(&map, GL_LUMINANCE,          GL_FLOAT,                          GL_LUMINANCE32F_EXT,       WriteColor<L32F, GLfloat>         );
    167     InsertFormatMapping(&map, GL_ALPHA,              GL_FLOAT,                          GL_ALPHA32F_EXT,           WriteColor<A32F, GLfloat>         );
    168     InsertFormatMapping(&map, GL_LUMINANCE_ALPHA,    GL_HALF_FLOAT,                     GL_LUMINANCE_ALPHA16F_EXT, WriteColor<L16A16F, GLfloat>      );
    169     InsertFormatMapping(&map, GL_LUMINANCE,          GL_HALF_FLOAT,                     GL_LUMINANCE16F_EXT,       WriteColor<L16F, GLfloat>         );
    170     InsertFormatMapping(&map, GL_ALPHA,              GL_HALF_FLOAT,                     GL_ALPHA16F_EXT,           WriteColor<A16F, GLfloat>         );
    171 
    172     InsertFormatMapping(&map, GL_BGRA_EXT,           GL_UNSIGNED_BYTE,                  GL_BGRA8_EXT,              WriteColor<B8G8R8A8, GLfloat>     );
    173     InsertFormatMapping(&map, GL_BGRA_EXT,           GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, GL_BGRA4_ANGLEX,           WriteColor<B4G4R4A4, GLfloat>     );
    174     InsertFormatMapping(&map, GL_BGRA_EXT,           GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, GL_BGR5_A1_ANGLEX,         WriteColor<B5G5R5A1, GLfloat>     );
    175 
    176     InsertFormatMapping(&map, GL_DEPTH_COMPONENT,    GL_UNSIGNED_SHORT,                 GL_DEPTH_COMPONENT16,      NULL                              );
    177     InsertFormatMapping(&map, GL_DEPTH_COMPONENT,    GL_UNSIGNED_INT,                   GL_DEPTH_COMPONENT24,      NULL                              );
    178     InsertFormatMapping(&map, GL_DEPTH_COMPONENT,    GL_FLOAT,                          GL_DEPTH_COMPONENT32F,     NULL                              );
    179 
    180     InsertFormatMapping(&map, GL_DEPTH_STENCIL,      GL_UNSIGNED_INT_24_8,              GL_DEPTH24_STENCIL8,       NULL                              );
    181     InsertFormatMapping(&map, GL_DEPTH_STENCIL,      GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_DEPTH32F_STENCIL8,      NULL                              );
    182 
    183     return map;
    184 }
    185 
    186 static const FormatMap &GetFormatMap(GLuint clientVersion)
    187 {
    188     if (clientVersion == 2)
    189     {
    190         static const FormatMap formats = BuildES2FormatMap();
    191         return formats;
    192     }
    193     else if (clientVersion == 3)
    194     {
    195         static const FormatMap formats = BuildES3FormatMap();
    196         return formats;
    197     }
    198     else
    199     {
    200         UNREACHABLE();
    201         static FormatMap emptyMap;
    202         return emptyMap;
    203     }
    204 }
    205 
    206 struct FormatInfo
    207 {
    208     GLenum mInternalformat;
    209     GLenum mFormat;
    210     GLenum mType;
    211 
    212     FormatInfo(GLenum internalformat, GLenum format, GLenum type)
    213         : mInternalformat(internalformat), mFormat(format), mType(type) { }
    214 
    215     bool operator<(const FormatInfo& other) const
    216     {
    217         return memcmp(this, &other, sizeof(FormatInfo)) < 0;
    218     }
    219 };
    220 
    221 // ES3 has a specific set of permutations of internal formats, formats and types which are acceptable.
    222 typedef std::set<FormatInfo> ES3FormatSet;
    223 
    224 ES3FormatSet BuildES3FormatSet()
    225 {
    226     ES3FormatSet set;
    227 
    228     // Format combinations from ES 3.0.1 spec, table 3.2
    229 
    230     //                   | Internal format      | Format            | Type                            |
    231     //                   |                      |                   |                                 |
    232     set.insert(FormatInfo(GL_RGBA8,              GL_RGBA,            GL_UNSIGNED_BYTE                 ));
    233     set.insert(FormatInfo(GL_RGB5_A1,            GL_RGBA,            GL_UNSIGNED_BYTE                 ));
    234     set.insert(FormatInfo(GL_RGBA4,              GL_RGBA,            GL_UNSIGNED_BYTE                 ));
    235     set.insert(FormatInfo(GL_SRGB8_ALPHA8,       GL_RGBA,            GL_UNSIGNED_BYTE                 ));
    236     set.insert(FormatInfo(GL_RGBA8_SNORM,        GL_RGBA,            GL_BYTE                          ));
    237     set.insert(FormatInfo(GL_RGBA4,              GL_RGBA,            GL_UNSIGNED_SHORT_4_4_4_4        ));
    238     set.insert(FormatInfo(GL_RGB10_A2,           GL_RGBA,            GL_UNSIGNED_INT_2_10_10_10_REV   ));
    239     set.insert(FormatInfo(GL_RGB5_A1,            GL_RGBA,            GL_UNSIGNED_INT_2_10_10_10_REV   ));
    240     set.insert(FormatInfo(GL_RGB5_A1,            GL_RGBA,            GL_UNSIGNED_SHORT_5_5_5_1        ));
    241     set.insert(FormatInfo(GL_RGBA16F,            GL_RGBA,            GL_HALF_FLOAT                    ));
    242     set.insert(FormatInfo(GL_RGBA32F,            GL_RGBA,            GL_FLOAT                         ));
    243     set.insert(FormatInfo(GL_RGBA16F,            GL_RGBA,            GL_FLOAT                         ));
    244     set.insert(FormatInfo(GL_RGBA8UI,            GL_RGBA_INTEGER,    GL_UNSIGNED_BYTE                 ));
    245     set.insert(FormatInfo(GL_RGBA8I,             GL_RGBA_INTEGER,    GL_BYTE                          ));
    246     set.insert(FormatInfo(GL_RGBA16UI,           GL_RGBA_INTEGER,    GL_UNSIGNED_SHORT                ));
    247     set.insert(FormatInfo(GL_RGBA16I,            GL_RGBA_INTEGER,    GL_SHORT                         ));
    248     set.insert(FormatInfo(GL_RGBA32UI,           GL_RGBA_INTEGER,    GL_UNSIGNED_INT                  ));
    249     set.insert(FormatInfo(GL_RGBA32I,            GL_RGBA_INTEGER,    GL_INT                           ));
    250     set.insert(FormatInfo(GL_RGB10_A2UI,         GL_RGBA_INTEGER,    GL_UNSIGNED_INT_2_10_10_10_REV   ));
    251     set.insert(FormatInfo(GL_RGB8,               GL_RGB,             GL_UNSIGNED_BYTE                 ));
    252     set.insert(FormatInfo(GL_RGB565,             GL_RGB,             GL_UNSIGNED_BYTE                 ));
    253     set.insert(FormatInfo(GL_SRGB8,              GL_RGB,             GL_UNSIGNED_BYTE                 ));
    254     set.insert(FormatInfo(GL_RGB8_SNORM,         GL_RGB,             GL_BYTE                          ));
    255     set.insert(FormatInfo(GL_RGB565,             GL_RGB,             GL_UNSIGNED_SHORT_5_6_5          ));
    256     set.insert(FormatInfo(GL_R11F_G11F_B10F,     GL_RGB,             GL_UNSIGNED_INT_10F_11F_11F_REV  ));
    257     set.insert(FormatInfo(GL_RGB9_E5,            GL_RGB,             GL_UNSIGNED_INT_5_9_9_9_REV      ));
    258     set.insert(FormatInfo(GL_RGB16F,             GL_RGB,             GL_HALF_FLOAT                    ));
    259     set.insert(FormatInfo(GL_R11F_G11F_B10F,     GL_RGB,             GL_HALF_FLOAT                    ));
    260     set.insert(FormatInfo(GL_RGB9_E5,            GL_RGB,             GL_HALF_FLOAT                    ));
    261     set.insert(FormatInfo(GL_RGB32F,             GL_RGB,             GL_FLOAT                         ));
    262     set.insert(FormatInfo(GL_RGB16F,             GL_RGB,             GL_FLOAT                         ));
    263     set.insert(FormatInfo(GL_R11F_G11F_B10F,     GL_RGB,             GL_FLOAT                         ));
    264     set.insert(FormatInfo(GL_RGB9_E5,            GL_RGB,             GL_FLOAT                         ));
    265     set.insert(FormatInfo(GL_RGB8UI,             GL_RGB_INTEGER,     GL_UNSIGNED_BYTE                 ));
    266     set.insert(FormatInfo(GL_RGB8I,              GL_RGB_INTEGER,     GL_BYTE                          ));
    267     set.insert(FormatInfo(GL_RGB16UI,            GL_RGB_INTEGER,     GL_UNSIGNED_SHORT                ));
    268     set.insert(FormatInfo(GL_RGB16I,             GL_RGB_INTEGER,     GL_SHORT                         ));
    269     set.insert(FormatInfo(GL_RGB32UI,            GL_RGB_INTEGER,     GL_UNSIGNED_INT                  ));
    270     set.insert(FormatInfo(GL_RGB32I,             GL_RGB_INTEGER,     GL_INT                           ));
    271     set.insert(FormatInfo(GL_RG8,                GL_RG,              GL_UNSIGNED_BYTE                 ));
    272     set.insert(FormatInfo(GL_RG8_SNORM,          GL_RG,              GL_BYTE                          ));
    273     set.insert(FormatInfo(GL_RG16F,              GL_RG,              GL_HALF_FLOAT                    ));
    274     set.insert(FormatInfo(GL_RG32F,              GL_RG,              GL_FLOAT                         ));
    275     set.insert(FormatInfo(GL_RG16F,              GL_RG,              GL_FLOAT                         ));
    276     set.insert(FormatInfo(GL_RG8UI,              GL_RG_INTEGER,      GL_UNSIGNED_BYTE                 ));
    277     set.insert(FormatInfo(GL_RG8I,               GL_RG_INTEGER,      GL_BYTE                          ));
    278     set.insert(FormatInfo(GL_RG16UI,             GL_RG_INTEGER,      GL_UNSIGNED_SHORT                ));
    279     set.insert(FormatInfo(GL_RG16I,              GL_RG_INTEGER,      GL_SHORT                         ));
    280     set.insert(FormatInfo(GL_RG32UI,             GL_RG_INTEGER,      GL_UNSIGNED_INT                  ));
    281     set.insert(FormatInfo(GL_RG32I,              GL_RG_INTEGER,      GL_INT                           ));
    282     set.insert(FormatInfo(GL_R8,                 GL_RED,             GL_UNSIGNED_BYTE                 ));
    283     set.insert(FormatInfo(GL_R8_SNORM,           GL_RED,             GL_BYTE                          ));
    284     set.insert(FormatInfo(GL_R16F,               GL_RED,             GL_HALF_FLOAT                    ));
    285     set.insert(FormatInfo(GL_R32F,               GL_RED,             GL_FLOAT                         ));
    286     set.insert(FormatInfo(GL_R16F,               GL_RED,             GL_FLOAT                         ));
    287     set.insert(FormatInfo(GL_R8UI,               GL_RED_INTEGER,     GL_UNSIGNED_BYTE                 ));
    288     set.insert(FormatInfo(GL_R8I,                GL_RED_INTEGER,     GL_BYTE                          ));
    289     set.insert(FormatInfo(GL_R16UI,              GL_RED_INTEGER,     GL_UNSIGNED_SHORT                ));
    290     set.insert(FormatInfo(GL_R16I,               GL_RED_INTEGER,     GL_SHORT                         ));
    291     set.insert(FormatInfo(GL_R32UI,              GL_RED_INTEGER,     GL_UNSIGNED_INT                  ));
    292     set.insert(FormatInfo(GL_R32I,               GL_RED_INTEGER,     GL_INT                           ));
    293 
    294     // Unsized formats
    295     set.insert(FormatInfo(GL_RGBA,               GL_RGBA,            GL_UNSIGNED_BYTE                 ));
    296     set.insert(FormatInfo(GL_RGBA,               GL_RGBA,            GL_UNSIGNED_SHORT_4_4_4_4        ));
    297     set.insert(FormatInfo(GL_RGBA,               GL_RGBA,            GL_UNSIGNED_SHORT_5_5_5_1        ));
    298     set.insert(FormatInfo(GL_RGB,                GL_RGB,             GL_UNSIGNED_BYTE                 ));
    299     set.insert(FormatInfo(GL_RGB,                GL_RGB,             GL_UNSIGNED_SHORT_5_6_5          ));
    300     set.insert(FormatInfo(GL_LUMINANCE_ALPHA,    GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE                 ));
    301     set.insert(FormatInfo(GL_LUMINANCE,          GL_LUMINANCE,       GL_UNSIGNED_BYTE                 ));
    302     set.insert(FormatInfo(GL_ALPHA,              GL_ALPHA,           GL_UNSIGNED_BYTE                 ));
    303 
    304     // Depth stencil formats
    305     set.insert(FormatInfo(GL_DEPTH_COMPONENT16,  GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT                ));
    306     set.insert(FormatInfo(GL_DEPTH_COMPONENT24,  GL_DEPTH_COMPONENT, GL_UNSIGNED_INT                  ));
    307     set.insert(FormatInfo(GL_DEPTH_COMPONENT16,  GL_DEPTH_COMPONENT, GL_UNSIGNED_INT                  ));
    308     set.insert(FormatInfo(GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT                         ));
    309     set.insert(FormatInfo(GL_DEPTH24_STENCIL8,   GL_DEPTH_STENCIL,   GL_UNSIGNED_INT_24_8             ));
    310     set.insert(FormatInfo(GL_DEPTH32F_STENCIL8,  GL_DEPTH_STENCIL,   GL_FLOAT_32_UNSIGNED_INT_24_8_REV));
    311 
    312     // From GL_OES_texture_float
    313     set.insert(FormatInfo(GL_LUMINANCE_ALPHA,    GL_LUMINANCE_ALPHA, GL_FLOAT                         ));
    314     set.insert(FormatInfo(GL_LUMINANCE,          GL_LUMINANCE,       GL_FLOAT                         ));
    315     set.insert(FormatInfo(GL_ALPHA,              GL_ALPHA,           GL_FLOAT                         ));
    316 
    317     // From GL_OES_texture_half_float
    318     set.insert(FormatInfo(GL_LUMINANCE_ALPHA,    GL_LUMINANCE_ALPHA, GL_HALF_FLOAT                    ));
    319     set.insert(FormatInfo(GL_LUMINANCE,          GL_LUMINANCE,       GL_HALF_FLOAT                    ));
    320     set.insert(FormatInfo(GL_ALPHA,              GL_ALPHA,           GL_HALF_FLOAT                    ));
    321 
    322     // From GL_EXT_texture_format_BGRA8888
    323     set.insert(FormatInfo(GL_BGRA_EXT,           GL_BGRA_EXT,        GL_UNSIGNED_BYTE                 ));
    324 
    325     // From GL_EXT_texture_storage
    326     //                   | Internal format          | Format            | Type                            |
    327     //                   |                          |                   |                                 |
    328     set.insert(FormatInfo(GL_ALPHA8_EXT,             GL_ALPHA,           GL_UNSIGNED_BYTE                 ));
    329     set.insert(FormatInfo(GL_LUMINANCE8_EXT,         GL_LUMINANCE,       GL_UNSIGNED_BYTE                 ));
    330     set.insert(FormatInfo(GL_LUMINANCE8_ALPHA8_EXT,  GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE                 ));
    331     set.insert(FormatInfo(GL_ALPHA32F_EXT,           GL_ALPHA,           GL_FLOAT                         ));
    332     set.insert(FormatInfo(GL_LUMINANCE32F_EXT,       GL_LUMINANCE,       GL_FLOAT                         ));
    333     set.insert(FormatInfo(GL_LUMINANCE_ALPHA32F_EXT, GL_LUMINANCE_ALPHA, GL_FLOAT                         ));
    334     set.insert(FormatInfo(GL_ALPHA16F_EXT,           GL_ALPHA,           GL_HALF_FLOAT                    ));
    335     set.insert(FormatInfo(GL_LUMINANCE16F_EXT,       GL_LUMINANCE,       GL_HALF_FLOAT                    ));
    336     set.insert(FormatInfo(GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT                    ));
    337 
    338     // From GL_EXT_texture_storage and GL_EXT_texture_format_BGRA8888
    339     set.insert(FormatInfo(GL_BGRA8_EXT,              GL_BGRA_EXT,        GL_UNSIGNED_BYTE                 ));
    340     set.insert(FormatInfo(GL_BGRA4_ANGLEX,           GL_BGRA_EXT,        GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT));
    341     set.insert(FormatInfo(GL_BGRA4_ANGLEX,           GL_BGRA_EXT,        GL_UNSIGNED_BYTE                 ));
    342     set.insert(FormatInfo(GL_BGR5_A1_ANGLEX,         GL_BGRA_EXT,        GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT));
    343     set.insert(FormatInfo(GL_BGR5_A1_ANGLEX,         GL_BGRA_EXT,        GL_UNSIGNED_BYTE                 ));
    344 
    345     // From GL_ANGLE_depth_texture
    346     set.insert(FormatInfo(GL_DEPTH_COMPONENT32_OES,  GL_DEPTH_COMPONENT, GL_UNSIGNED_INT_24_8_OES         ));
    347 
    348     // Compressed formats
    349     // From ES 3.0.1 spec, table 3.16
    350     //                   | Internal format                             | Format                                      | Type           |
    351     //                   |                                             |                                             |                |
    352     set.insert(FormatInfo(GL_COMPRESSED_R11_EAC,                        GL_COMPRESSED_R11_EAC,                        GL_UNSIGNED_BYTE));
    353     set.insert(FormatInfo(GL_COMPRESSED_R11_EAC,                        GL_COMPRESSED_R11_EAC,                        GL_UNSIGNED_BYTE));
    354     set.insert(FormatInfo(GL_COMPRESSED_SIGNED_R11_EAC,                 GL_COMPRESSED_SIGNED_R11_EAC,                 GL_UNSIGNED_BYTE));
    355     set.insert(FormatInfo(GL_COMPRESSED_RG11_EAC,                       GL_COMPRESSED_RG11_EAC,                       GL_UNSIGNED_BYTE));
    356     set.insert(FormatInfo(GL_COMPRESSED_SIGNED_RG11_EAC,                GL_COMPRESSED_SIGNED_RG11_EAC,                GL_UNSIGNED_BYTE));
    357     set.insert(FormatInfo(GL_COMPRESSED_RGB8_ETC2,                      GL_COMPRESSED_RGB8_ETC2,                      GL_UNSIGNED_BYTE));
    358     set.insert(FormatInfo(GL_COMPRESSED_SRGB8_ETC2,                     GL_COMPRESSED_SRGB8_ETC2,                     GL_UNSIGNED_BYTE));
    359     set.insert(FormatInfo(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,  GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,  GL_UNSIGNED_BYTE));
    360     set.insert(FormatInfo(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE));
    361     set.insert(FormatInfo(GL_COMPRESSED_RGBA8_ETC2_EAC,                 GL_COMPRESSED_RGBA8_ETC2_EAC,                 GL_UNSIGNED_BYTE));
    362     set.insert(FormatInfo(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,          GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,          GL_UNSIGNED_BYTE));
    363 
    364 
    365     // From GL_EXT_texture_compression_dxt1
    366     set.insert(FormatInfo(GL_COMPRESSED_RGB_S3TC_DXT1_EXT,              GL_COMPRESSED_RGB_S3TC_DXT1_EXT,              GL_UNSIGNED_BYTE));
    367     set.insert(FormatInfo(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,             GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,             GL_UNSIGNED_BYTE));
    368 
    369     // From GL_ANGLE_texture_compression_dxt3
    370     set.insert(FormatInfo(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE,           GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE,           GL_UNSIGNED_BYTE));
    371 
    372     // From GL_ANGLE_texture_compression_dxt5
    373     set.insert(FormatInfo(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE,           GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE,           GL_UNSIGNED_BYTE));
    374 
    375     return set;
    376 }
    377 
    378 static const ES3FormatSet &GetES3FormatSet()
    379 {
    380     static const ES3FormatSet es3FormatSet = BuildES3FormatSet();
    381     return es3FormatSet;
    382 }
    383 
    384 // Map of sizes of input types
    385 struct TypeInfo
    386 {
    387     GLuint mTypeBytes;
    388     bool mSpecialInterpretation;
    389 
    390     TypeInfo()
    391         : mTypeBytes(0), mSpecialInterpretation(false) { }
    392 
    393     TypeInfo(GLuint typeBytes, bool specialInterpretation)
    394         : mTypeBytes(typeBytes), mSpecialInterpretation(specialInterpretation) { }
    395 
    396     bool operator<(const TypeInfo& other) const
    397     {
    398         return memcmp(this, &other, sizeof(TypeInfo)) < 0;
    399     }
    400 };
    401 
    402 typedef std::pair<GLenum, TypeInfo> TypeInfoPair;
    403 typedef std::map<GLenum, TypeInfo> TypeInfoMap;
    404 
    405 static TypeInfoMap BuildTypeInfoMap()
    406 {
    407     TypeInfoMap map;
    408 
    409     map.insert(TypeInfoPair(GL_UNSIGNED_BYTE,                  TypeInfo( 1, false)));
    410     map.insert(TypeInfoPair(GL_BYTE,                           TypeInfo( 1, false)));
    411     map.insert(TypeInfoPair(GL_UNSIGNED_SHORT,                 TypeInfo( 2, false)));
    412     map.insert(TypeInfoPair(GL_SHORT,                          TypeInfo( 2, false)));
    413     map.insert(TypeInfoPair(GL_UNSIGNED_INT,                   TypeInfo( 4, false)));
    414     map.insert(TypeInfoPair(GL_INT,                            TypeInfo( 4, false)));
    415     map.insert(TypeInfoPair(GL_HALF_FLOAT,                     TypeInfo( 2, false)));
    416     map.insert(TypeInfoPair(GL_HALF_FLOAT_OES,                 TypeInfo( 2, false)));
    417     map.insert(TypeInfoPair(GL_FLOAT,                          TypeInfo( 4, false)));
    418     map.insert(TypeInfoPair(GL_UNSIGNED_SHORT_5_6_5,           TypeInfo( 2, true )));
    419     map.insert(TypeInfoPair(GL_UNSIGNED_SHORT_4_4_4_4,         TypeInfo( 2, true )));
    420     map.insert(TypeInfoPair(GL_UNSIGNED_SHORT_5_5_5_1,         TypeInfo( 2, true )));
    421     map.insert(TypeInfoPair(GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, TypeInfo( 2, true )));
    422     map.insert(TypeInfoPair(GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, TypeInfo( 2, true )));
    423     map.insert(TypeInfoPair(GL_UNSIGNED_INT_2_10_10_10_REV,    TypeInfo( 4, true )));
    424     map.insert(TypeInfoPair(GL_UNSIGNED_INT_24_8,              TypeInfo( 4, true )));
    425     map.insert(TypeInfoPair(GL_UNSIGNED_INT_10F_11F_11F_REV,   TypeInfo( 4, true )));
    426     map.insert(TypeInfoPair(GL_UNSIGNED_INT_5_9_9_9_REV,       TypeInfo( 4, true )));
    427     map.insert(TypeInfoPair(GL_UNSIGNED_INT_24_8_OES,          TypeInfo( 4, true )));
    428     map.insert(TypeInfoPair(GL_FLOAT_32_UNSIGNED_INT_24_8_REV, TypeInfo( 8, true )));
    429 
    430     return map;
    431 }
    432 
    433 static bool GetTypeInfo(GLenum type, TypeInfo *outTypeInfo)
    434 {
    435     static const TypeInfoMap infoMap = BuildTypeInfoMap();
    436     TypeInfoMap::const_iterator iter = infoMap.find(type);
    437     if (iter != infoMap.end())
    438     {
    439         if (outTypeInfo)
    440         {
    441             *outTypeInfo = iter->second;
    442         }
    443         return true;
    444     }
    445     else
    446     {
    447         return false;
    448     }
    449 }
    450 
    451 // Information about internal formats
    452 typedef bool ((Context::*ContextSupportCheckMemberFunction)(void) const);
    453 typedef bool (*ContextSupportCheckFunction)(const Context *context);
    454 
    455 typedef bool ((rx::Renderer::*RendererSupportCheckMemberFunction)(void) const);
    456 typedef bool (*ContextRendererSupportCheckFunction)(const Context *context, const rx::Renderer *renderer);
    457 
    458 template <ContextSupportCheckMemberFunction func>
    459 bool CheckSupport(const Context *context)
    460 {
    461     return (context->*func)();
    462 }
    463 
    464 template <ContextSupportCheckMemberFunction contextFunc, RendererSupportCheckMemberFunction rendererFunc>
    465 bool CheckSupport(const Context *context, const rx::Renderer *renderer)
    466 {
    467     if (context)
    468     {
    469         return (context->*contextFunc)();
    470     }
    471     else if (renderer)
    472     {
    473         return (renderer->*rendererFunc)();
    474     }
    475     else
    476     {
    477         UNREACHABLE();
    478         return false;
    479     }
    480 }
    481 
    482 template <typename objectType>
    483 bool AlwaysSupported(const objectType*)
    484 {
    485     return true;
    486 }
    487 
    488 template <typename objectTypeA, typename objectTypeB>
    489 bool AlwaysSupported(const objectTypeA*, const objectTypeB*)
    490 {
    491     return true;
    492 }
    493 
    494 template <typename objectType>
    495 bool NeverSupported(const objectType*)
    496 {
    497     return false;
    498 }
    499 
    500 template <typename objectTypeA, typename objectTypeB>
    501 bool NeverSupported(const objectTypeA *, const objectTypeB *)
    502 {
    503     return false;
    504 }
    505 
    506 template <typename objectType>
    507 bool UnimplementedSupport(const objectType*)
    508 {
    509     UNIMPLEMENTED();
    510     return false;
    511 }
    512 
    513 template <typename objectTypeA, typename objectTypeB>
    514 bool UnimplementedSupport(const objectTypeA*, const objectTypeB*)
    515 {
    516     UNIMPLEMENTED();
    517     return false;
    518 }
    519 
    520 struct InternalFormatInfo
    521 {
    522     GLuint mRedBits;
    523     GLuint mGreenBits;
    524     GLuint mBlueBits;
    525 
    526     GLuint mLuminanceBits;
    527 
    528     GLuint mAlphaBits;
    529     GLuint mSharedBits;
    530 
    531     GLuint mDepthBits;
    532     GLuint mStencilBits;
    533 
    534     GLuint mPixelBits;
    535 
    536     GLuint mComponentCount;
    537 
    538     GLuint mCompressedBlockWidth;
    539     GLuint mCompressedBlockHeight;
    540 
    541     GLenum mFormat;
    542     GLenum mType;
    543 
    544     GLenum mComponentType;
    545     GLenum mColorEncoding;
    546 
    547     bool mIsCompressed;
    548 
    549     ContextRendererSupportCheckFunction mIsColorRenderable;
    550     ContextRendererSupportCheckFunction mIsDepthRenderable;
    551     ContextRendererSupportCheckFunction mIsStencilRenderable;
    552     ContextRendererSupportCheckFunction mIsTextureFilterable;
    553 
    554     ContextSupportCheckFunction mSupportFunction;
    555 
    556     InternalFormatInfo() : mRedBits(0), mGreenBits(0), mBlueBits(0), mLuminanceBits(0), mAlphaBits(0), mSharedBits(0), mDepthBits(0), mStencilBits(0),
    557                            mPixelBits(0), mComponentCount(0), mCompressedBlockWidth(0), mCompressedBlockHeight(0), mFormat(GL_NONE), mType(GL_NONE),
    558                            mComponentType(GL_NONE), mColorEncoding(GL_NONE), mIsCompressed(false), mIsColorRenderable(NeverSupported),
    559                            mIsDepthRenderable(NeverSupported), mIsStencilRenderable(NeverSupported), mIsTextureFilterable(NeverSupported),
    560                            mSupportFunction(NeverSupported)
    561     {
    562     }
    563 
    564     static InternalFormatInfo UnsizedFormat(GLenum format, ContextSupportCheckFunction supportFunction)
    565     {
    566         InternalFormatInfo formatInfo;
    567         formatInfo.mFormat = format;
    568         formatInfo.mSupportFunction = supportFunction;
    569 
    570         if (format == GL_RGB || format == GL_RGBA)
    571             formatInfo.mIsColorRenderable = AlwaysSupported;
    572 
    573         return formatInfo;
    574     }
    575 
    576     static InternalFormatInfo RGBAFormat(GLuint red, GLuint green, GLuint blue, GLuint alpha, GLuint shared,
    577                                          GLenum format, GLenum type, GLenum componentType, bool srgb,
    578                                          ContextRendererSupportCheckFunction colorRenderable,
    579                                          ContextRendererSupportCheckFunction textureFilterable,
    580                                          ContextSupportCheckFunction supportFunction)
    581     {
    582         InternalFormatInfo formatInfo;
    583         formatInfo.mRedBits = red;
    584         formatInfo.mGreenBits = green;
    585         formatInfo.mBlueBits = blue;
    586         formatInfo.mAlphaBits = alpha;
    587         formatInfo.mSharedBits = shared;
    588         formatInfo.mPixelBits = red + green + blue + alpha + shared;
    589         formatInfo.mComponentCount = ((red > 0) ? 1 : 0) + ((green > 0) ? 1 : 0) + ((blue > 0) ? 1 : 0) + ((alpha > 0) ? 1 : 0);
    590         formatInfo.mFormat = format;
    591         formatInfo.mType = type;
    592         formatInfo.mComponentType = componentType;
    593         formatInfo.mColorEncoding = (srgb ? GL_SRGB : GL_LINEAR);
    594         formatInfo.mIsColorRenderable = colorRenderable;
    595         formatInfo.mIsTextureFilterable = textureFilterable;
    596         formatInfo.mSupportFunction = supportFunction;
    597         return formatInfo;
    598     }
    599 
    600     static InternalFormatInfo LUMAFormat(GLuint luminance, GLuint alpha, GLenum format, GLenum type, GLenum componentType,
    601                                          ContextSupportCheckFunction supportFunction)
    602     {
    603         InternalFormatInfo formatInfo;
    604         formatInfo.mLuminanceBits = luminance;
    605         formatInfo.mAlphaBits = alpha;
    606         formatInfo.mPixelBits = luminance + alpha;
    607         formatInfo.mComponentCount = ((luminance > 0) ? 1 : 0) + ((alpha > 0) ? 1 : 0);
    608         formatInfo.mFormat = format;
    609         formatInfo.mType = type;
    610         formatInfo.mComponentType = componentType;
    611         formatInfo.mColorEncoding = GL_LINEAR;
    612         formatInfo.mIsTextureFilterable = AlwaysSupported;
    613         formatInfo.mSupportFunction = supportFunction;
    614         return formatInfo;
    615     }
    616 
    617     static InternalFormatInfo DepthStencilFormat(GLuint depthBits, GLuint stencilBits, GLuint unusedBits, GLenum format,
    618                                                  GLenum type, GLenum componentType,
    619                                                  ContextRendererSupportCheckFunction depthRenderable,
    620                                                  ContextRendererSupportCheckFunction stencilRenderable,
    621                                                  ContextSupportCheckFunction supportFunction)
    622     {
    623         InternalFormatInfo formatInfo;
    624         formatInfo.mDepthBits = depthBits;
    625         formatInfo.mStencilBits = stencilBits;
    626         formatInfo.mPixelBits = depthBits + stencilBits + unusedBits;
    627         formatInfo.mComponentCount = ((depthBits > 0) ? 1 : 0) + ((stencilBits > 0) ? 1 : 0);
    628         formatInfo.mFormat = format;
    629         formatInfo.mType = type;
    630         formatInfo.mComponentType = componentType;
    631         formatInfo.mColorEncoding = GL_LINEAR;
    632         formatInfo.mIsDepthRenderable = depthRenderable;
    633         formatInfo.mIsStencilRenderable = stencilRenderable;
    634         formatInfo.mIsTextureFilterable = AlwaysSupported;
    635         formatInfo.mSupportFunction = supportFunction;
    636         return formatInfo;
    637     }
    638 
    639     static InternalFormatInfo CompressedFormat(GLuint compressedBlockWidth, GLuint compressedBlockHeight, GLuint compressedBlockSize,
    640                                                GLuint componentCount, GLenum format, GLenum type, bool srgb,
    641                                                ContextSupportCheckFunction supportFunction)
    642     {
    643         InternalFormatInfo formatInfo;
    644         formatInfo.mCompressedBlockWidth = compressedBlockWidth;
    645         formatInfo.mCompressedBlockHeight = compressedBlockHeight;
    646         formatInfo.mPixelBits = compressedBlockSize;
    647         formatInfo.mComponentCount = componentCount;
    648         formatInfo.mFormat = format;
    649         formatInfo.mType = type;
    650         formatInfo.mComponentType = GL_UNSIGNED_NORMALIZED;
    651         formatInfo.mColorEncoding = (srgb ? GL_SRGB : GL_LINEAR);
    652         formatInfo.mIsCompressed = true;
    653         formatInfo.mIsTextureFilterable = AlwaysSupported;
    654         formatInfo.mSupportFunction = supportFunction;
    655         return formatInfo;
    656     }
    657 };
    658 
    659 typedef std::pair<GLenum, InternalFormatInfo> InternalFormatInfoPair;
    660 typedef std::map<GLenum, InternalFormatInfo> InternalFormatInfoMap;
    661 
    662 static InternalFormatInfoMap BuildES3InternalFormatInfoMap()
    663 {
    664     InternalFormatInfoMap map;
    665 
    666     // From ES 3.0.1 spec, table 3.12
    667     map.insert(InternalFormatInfoPair(GL_NONE,              InternalFormatInfo()));
    668 
    669     //                               | Internal format     |                              | R | G | B | A |S | Format         | Type                           | Component type        | SRGB | Color          | Texture        | Supported          |
    670     //                               |                     |                              |   |   |   |   |  |                |                                |                       |      | renderable     | filterable     |                    |
    671     map.insert(InternalFormatInfoPair(GL_R8,                InternalFormatInfo::RGBAFormat( 8,  0,  0,  0, 0, GL_RED,          GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported     )));
    672     map.insert(InternalFormatInfoPair(GL_R8_SNORM,          InternalFormatInfo::RGBAFormat( 8,  0,  0,  0, 0, GL_RED,          GL_BYTE,                         GL_SIGNED_NORMALIZED,   false, NeverSupported,  AlwaysSupported, AlwaysSupported     )));
    673     map.insert(InternalFormatInfoPair(GL_RG8,               InternalFormatInfo::RGBAFormat( 8,  8,  0,  0, 0, GL_RG,           GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported     )));
    674     map.insert(InternalFormatInfoPair(GL_RG8_SNORM,         InternalFormatInfo::RGBAFormat( 8,  8,  0,  0, 0, GL_RG,           GL_BYTE,                         GL_SIGNED_NORMALIZED,   false, NeverSupported,  AlwaysSupported, AlwaysSupported     )));
    675     map.insert(InternalFormatInfoPair(GL_RGB8,              InternalFormatInfo::RGBAFormat( 8,  8,  8,  0, 0, GL_RGB,          GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported     )));
    676     map.insert(InternalFormatInfoPair(GL_RGB8_SNORM,        InternalFormatInfo::RGBAFormat( 8,  8,  8,  0, 0, GL_RGB,          GL_BYTE,                         GL_SIGNED_NORMALIZED,   false, NeverSupported,  AlwaysSupported, AlwaysSupported     )));
    677     map.insert(InternalFormatInfoPair(GL_RGB565,            InternalFormatInfo::RGBAFormat( 5,  6,  5,  0, 0, GL_RGB,          GL_UNSIGNED_SHORT_5_6_5,         GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported     )));
    678     map.insert(InternalFormatInfoPair(GL_RGBA4,             InternalFormatInfo::RGBAFormat( 4,  4,  4,  4, 0, GL_RGBA,         GL_UNSIGNED_SHORT_4_4_4_4,       GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported     )));
    679     map.insert(InternalFormatInfoPair(GL_RGB5_A1,           InternalFormatInfo::RGBAFormat( 5,  5,  5,  1, 0, GL_RGBA,         GL_UNSIGNED_SHORT_5_5_5_1,       GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported     )));
    680     map.insert(InternalFormatInfoPair(GL_RGBA8,             InternalFormatInfo::RGBAFormat( 8,  8,  8,  8, 0, GL_RGBA,         GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported     )));
    681     map.insert(InternalFormatInfoPair(GL_RGBA8_SNORM,       InternalFormatInfo::RGBAFormat( 8,  8,  8,  8, 0, GL_RGBA,         GL_BYTE,                         GL_SIGNED_NORMALIZED,   false, NeverSupported,  AlwaysSupported, AlwaysSupported     )));
    682     map.insert(InternalFormatInfoPair(GL_RGB10_A2,          InternalFormatInfo::RGBAFormat(10, 10, 10,  2, 0, GL_RGBA,         GL_UNSIGNED_INT_2_10_10_10_REV,  GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported     )));
    683     map.insert(InternalFormatInfoPair(GL_RGB10_A2UI,        InternalFormatInfo::RGBAFormat(10, 10, 10,  2, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV,  GL_UNSIGNED_INT,        false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
    684     map.insert(InternalFormatInfoPair(GL_SRGB8,             InternalFormatInfo::RGBAFormat( 8,  8,  8,  0, 0, GL_RGB,          GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, true,  NeverSupported,  AlwaysSupported, AlwaysSupported     )));
    685     map.insert(InternalFormatInfoPair(GL_SRGB8_ALPHA8,      InternalFormatInfo::RGBAFormat( 8,  8,  8,  8, 0, GL_RGBA,         GL_UNSIGNED_BYTE,                GL_UNSIGNED_NORMALIZED, true,  AlwaysSupported, AlwaysSupported, AlwaysSupported     )));
    686     map.insert(InternalFormatInfoPair(GL_R11F_G11F_B10F,    InternalFormatInfo::RGBAFormat(11, 11, 10,  0, 0, GL_RGB,          GL_UNSIGNED_INT_10F_11F_11F_REV, GL_FLOAT,               false, AlwaysSupported, AlwaysSupported, AlwaysSupported     )));
    687     map.insert(InternalFormatInfoPair(GL_RGB9_E5,           InternalFormatInfo::RGBAFormat( 9,  9,  9,  0, 5, GL_RGB,          GL_UNSIGNED_INT_5_9_9_9_REV,     GL_FLOAT,               false, NeverSupported,  AlwaysSupported, AlwaysSupported     )));
    688     map.insert(InternalFormatInfoPair(GL_R8I,               InternalFormatInfo::RGBAFormat( 8,  0,  0,  0, 0, GL_RED_INTEGER,  GL_BYTE,                         GL_INT,                 false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
    689     map.insert(InternalFormatInfoPair(GL_R8UI,              InternalFormatInfo::RGBAFormat( 8,  0,  0,  0, 0, GL_RED_INTEGER,  GL_UNSIGNED_BYTE,                GL_UNSIGNED_INT,        false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
    690     map.insert(InternalFormatInfoPair(GL_R16I,              InternalFormatInfo::RGBAFormat(16,  0,  0,  0, 0, GL_RED_INTEGER,  GL_SHORT,                        GL_INT,                 false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
    691     map.insert(InternalFormatInfoPair(GL_R16UI,             InternalFormatInfo::RGBAFormat(16,  0,  0,  0, 0, GL_RED_INTEGER,  GL_UNSIGNED_SHORT,               GL_UNSIGNED_INT,        false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
    692     map.insert(InternalFormatInfoPair(GL_R32I,              InternalFormatInfo::RGBAFormat(32,  0,  0,  0, 0, GL_RED_INTEGER,  GL_INT,                          GL_INT,                 false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
    693     map.insert(InternalFormatInfoPair(GL_R32UI,             InternalFormatInfo::RGBAFormat(32,  0,  0,  0, 0, GL_RED_INTEGER,  GL_UNSIGNED_INT,                 GL_UNSIGNED_INT,        false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
    694     map.insert(InternalFormatInfoPair(GL_RG8I,              InternalFormatInfo::RGBAFormat( 8,  8,  0,  0, 0, GL_RG_INTEGER,   GL_BYTE,                         GL_INT,                 false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
    695     map.insert(InternalFormatInfoPair(GL_RG8UI,             InternalFormatInfo::RGBAFormat( 8,  8,  0,  0, 0, GL_RG_INTEGER,   GL_UNSIGNED_BYTE,                GL_UNSIGNED_INT,        false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
    696     map.insert(InternalFormatInfoPair(GL_RG16I,             InternalFormatInfo::RGBAFormat(16, 16,  0,  0, 0, GL_RG_INTEGER,   GL_SHORT,                        GL_INT,                 false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
    697     map.insert(InternalFormatInfoPair(GL_RG16UI,            InternalFormatInfo::RGBAFormat(16, 16,  0,  0, 0, GL_RG_INTEGER,   GL_UNSIGNED_SHORT,               GL_UNSIGNED_INT,        false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
    698     map.insert(InternalFormatInfoPair(GL_RG32I,             InternalFormatInfo::RGBAFormat(32, 32,  0,  0, 0, GL_RG_INTEGER,   GL_INT,                          GL_INT,                 false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
    699     map.insert(InternalFormatInfoPair(GL_RG32UI,            InternalFormatInfo::RGBAFormat(32, 32,  0,  0, 0, GL_RG_INTEGER,   GL_UNSIGNED_INT,                 GL_UNSIGNED_INT,        false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
    700     map.insert(InternalFormatInfoPair(GL_RGB8I,             InternalFormatInfo::RGBAFormat( 8,  8,  8,  0, 0, GL_RGB_INTEGER,  GL_BYTE,                         GL_INT,                 false, NeverSupported,  NeverSupported,  AlwaysSupported     )));
    701     map.insert(InternalFormatInfoPair(GL_RGB8UI,            InternalFormatInfo::RGBAFormat( 8,  8,  8,  0, 0, GL_RGB_INTEGER,  GL_UNSIGNED_BYTE,                GL_UNSIGNED_INT,        false, NeverSupported,  NeverSupported,  AlwaysSupported     )));
    702     map.insert(InternalFormatInfoPair(GL_RGB16I,            InternalFormatInfo::RGBAFormat(16, 16, 16,  0, 0, GL_RGB_INTEGER,  GL_SHORT,                        GL_INT,                 false, NeverSupported,  NeverSupported,  AlwaysSupported     )));
    703     map.insert(InternalFormatInfoPair(GL_RGB16UI,           InternalFormatInfo::RGBAFormat(16, 16, 16,  0, 0, GL_RGB_INTEGER,  GL_UNSIGNED_SHORT,               GL_UNSIGNED_INT,        false, NeverSupported,  NeverSupported,  AlwaysSupported     )));
    704     map.insert(InternalFormatInfoPair(GL_RGB32I,            InternalFormatInfo::RGBAFormat(32, 32, 32,  0, 0, GL_RGB_INTEGER,  GL_INT,                          GL_INT,                 false, NeverSupported,  NeverSupported,  AlwaysSupported     )));
    705     map.insert(InternalFormatInfoPair(GL_RGB32UI,           InternalFormatInfo::RGBAFormat(32, 32, 32,  0, 0, GL_RGB_INTEGER,  GL_UNSIGNED_INT,                 GL_UNSIGNED_INT,        false, NeverSupported,  NeverSupported,  AlwaysSupported     )));
    706     map.insert(InternalFormatInfoPair(GL_RGBA8I,            InternalFormatInfo::RGBAFormat( 8,  8,  8,  8, 0, GL_RGBA_INTEGER, GL_BYTE,                         GL_INT,                 false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
    707     map.insert(InternalFormatInfoPair(GL_RGBA8UI,           InternalFormatInfo::RGBAFormat( 8,  8,  8,  8, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE,                GL_UNSIGNED_INT,        false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
    708     map.insert(InternalFormatInfoPair(GL_RGBA16I,           InternalFormatInfo::RGBAFormat(16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_SHORT,                        GL_INT,                 false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
    709     map.insert(InternalFormatInfoPair(GL_RGBA16UI,          InternalFormatInfo::RGBAFormat(16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT,               GL_UNSIGNED_INT,        false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
    710     map.insert(InternalFormatInfoPair(GL_RGBA32I,           InternalFormatInfo::RGBAFormat(32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_INT,                          GL_INT,                 false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
    711     map.insert(InternalFormatInfoPair(GL_RGBA32UI,          InternalFormatInfo::RGBAFormat(32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT,                 GL_UNSIGNED_INT,        false, AlwaysSupported, NeverSupported,  AlwaysSupported     )));
    712 
    713     map.insert(InternalFormatInfoPair(GL_BGRA8_EXT,         InternalFormatInfo::RGBAFormat( 8,  8,  8,  8, 0, GL_BGRA_EXT,     GL_UNSIGNED_BYTE,                  GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported     )));
    714     map.insert(InternalFormatInfoPair(GL_BGRA4_ANGLEX,      InternalFormatInfo::RGBAFormat( 4,  4,  4,  4, 0, GL_BGRA_EXT,     GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported     )));
    715     map.insert(InternalFormatInfoPair(GL_BGR5_A1_ANGLEX,    InternalFormatInfo::RGBAFormat( 5,  5,  5,  1, 0, GL_BGRA_EXT,     GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported     )));
    716 
    717     // Floating point renderability and filtering is provided by OES_texture_float and OES_texture_half_float
    718     //                               | Internal format        |                                   | D |S | Format             | Type                           | Comp   | SRGB | Color renderable                                                                                           | Texture filterable                                                                                    | Supported          |
    719     //                               |                        |                                   |   |  |                    |                                | type   |      |                                                                                                            |                                                                                                       |                    |
    720     map.insert(InternalFormatInfoPair(GL_R16F,              InternalFormatInfo::RGBAFormat(16,  0,  0,  0, 0, GL_RED,          GL_HALF_FLOAT,                   GL_FLOAT, false, CheckSupport<&Context::supportsFloat16RenderableTextures, &rx::Renderer::getFloat16TextureRenderingSupport>, CheckSupport<&Context::supportsFloat16LinearFilter, &rx::Renderer::getFloat16TextureFilteringSupport>, AlwaysSupported     )));
    721     map.insert(InternalFormatInfoPair(GL_RG16F,             InternalFormatInfo::RGBAFormat(16, 16,  0,  0, 0, GL_RG,           GL_HALF_FLOAT,                   GL_FLOAT, false, CheckSupport<&Context::supportsFloat16RenderableTextures, &rx::Renderer::getFloat16TextureRenderingSupport>, CheckSupport<&Context::supportsFloat16LinearFilter, &rx::Renderer::getFloat16TextureFilteringSupport>, AlwaysSupported     )));
    722     map.insert(InternalFormatInfoPair(GL_RGB16F,            InternalFormatInfo::RGBAFormat(16, 16, 16,  0, 0, GL_RGB,          GL_HALF_FLOAT,                   GL_FLOAT, false, CheckSupport<&Context::supportsFloat16RenderableTextures, &rx::Renderer::getFloat16TextureRenderingSupport>, CheckSupport<&Context::supportsFloat16LinearFilter, &rx::Renderer::getFloat16TextureFilteringSupport>, AlwaysSupported     )));
    723     map.insert(InternalFormatInfoPair(GL_RGBA16F,           InternalFormatInfo::RGBAFormat(16, 16, 16, 16, 0, GL_RGBA,         GL_HALF_FLOAT,                   GL_FLOAT, false, CheckSupport<&Context::supportsFloat16RenderableTextures, &rx::Renderer::getFloat16TextureRenderingSupport>, CheckSupport<&Context::supportsFloat16LinearFilter, &rx::Renderer::getFloat16TextureFilteringSupport>, AlwaysSupported     )));
    724     map.insert(InternalFormatInfoPair(GL_R32F,              InternalFormatInfo::RGBAFormat(32,  0,  0,  0, 0, GL_RED,          GL_FLOAT,                        GL_FLOAT, false, CheckSupport<&Context::supportsFloat32RenderableTextures, &rx::Renderer::getFloat32TextureRenderingSupport>, CheckSupport<&Context::supportsFloat32LinearFilter, &rx::Renderer::getFloat32TextureFilteringSupport>, AlwaysSupported     )));
    725     map.insert(InternalFormatInfoPair(GL_RG32F,             InternalFormatInfo::RGBAFormat(32, 32,  0,  0, 0, GL_RG,           GL_FLOAT,                        GL_FLOAT, false, CheckSupport<&Context::supportsFloat32RenderableTextures, &rx::Renderer::getFloat32TextureRenderingSupport>, CheckSupport<&Context::supportsFloat32LinearFilter, &rx::Renderer::getFloat32TextureFilteringSupport>, AlwaysSupported     )));
    726     map.insert(InternalFormatInfoPair(GL_RGB32F,            InternalFormatInfo::RGBAFormat(32, 32, 32,  0, 0, GL_RGB,          GL_FLOAT,                        GL_FLOAT, false, CheckSupport<&Context::supportsFloat32RenderableTextures, &rx::Renderer::getFloat32TextureRenderingSupport>, CheckSupport<&Context::supportsFloat32LinearFilter, &rx::Renderer::getFloat32TextureFilteringSupport>, AlwaysSupported     )));
    727     map.insert(InternalFormatInfoPair(GL_RGBA32F,           InternalFormatInfo::RGBAFormat(32, 32, 32, 32, 0, GL_RGBA,         GL_FLOAT,                        GL_FLOAT, false, CheckSupport<&Context::supportsFloat32RenderableTextures, &rx::Renderer::getFloat32TextureRenderingSupport>, CheckSupport<&Context::supportsFloat32LinearFilter, &rx::Renderer::getFloat32TextureFilteringSupport>, AlwaysSupported     )));
    728 
    729     // Depth stencil formats
    730     //                               | Internal format         |                                      | D |S | X | Format            | Type                             | Component type        | Depth          | Stencil        | Supported     |
    731     //                               |                         |                                      |   |  |   |                   |                                  |                       | renderable     | renderable     |               |
    732     map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT16,     InternalFormatInfo::DepthStencilFormat(16, 0,  0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,                 GL_UNSIGNED_NORMALIZED, AlwaysSupported, NeverSupported,  AlwaysSupported)));
    733     map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT24,     InternalFormatInfo::DepthStencilFormat(24, 0,  0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,                   GL_UNSIGNED_NORMALIZED, AlwaysSupported, NeverSupported,  AlwaysSupported)));
    734     map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT32F,    InternalFormatInfo::DepthStencilFormat(32, 0,  0, GL_DEPTH_COMPONENT, GL_FLOAT,                          GL_FLOAT,               AlwaysSupported, NeverSupported,  AlwaysSupported)));
    735     map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT32_OES, InternalFormatInfo::DepthStencilFormat(32, 0,  0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,                   GL_UNSIGNED_NORMALIZED, AlwaysSupported, NeverSupported,  AlwaysSupported)));
    736     map.insert(InternalFormatInfoPair(GL_DEPTH24_STENCIL8,      InternalFormatInfo::DepthStencilFormat(24, 8,  0, GL_DEPTH_STENCIL,   GL_UNSIGNED_INT_24_8,              GL_UNSIGNED_NORMALIZED, AlwaysSupported, AlwaysSupported, AlwaysSupported)));
    737     map.insert(InternalFormatInfoPair(GL_DEPTH32F_STENCIL8,     InternalFormatInfo::DepthStencilFormat(32, 8, 24, GL_DEPTH_STENCIL,   GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_FLOAT,               AlwaysSupported, AlwaysSupported, AlwaysSupported)));
    738     map.insert(InternalFormatInfoPair(GL_STENCIL_INDEX8,        InternalFormatInfo::DepthStencilFormat( 0, 8,  0, GL_DEPTH_STENCIL,   GL_UNSIGNED_BYTE,                  GL_UNSIGNED_INT,        NeverSupported,  AlwaysSupported, AlwaysSupported)));
    739 
    740     // Luminance alpha formats
    741     //                               | Internal format          |                              | L | A | Format            | Type            | Component type        | Supported     |
    742     map.insert(InternalFormatInfoPair(GL_ALPHA8_EXT,             InternalFormatInfo::LUMAFormat( 0,  8, GL_ALPHA,           GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, AlwaysSupported)));
    743     map.insert(InternalFormatInfoPair(GL_LUMINANCE8_EXT,         InternalFormatInfo::LUMAFormat( 8,  0, GL_LUMINANCE,       GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, AlwaysSupported)));
    744     map.insert(InternalFormatInfoPair(GL_ALPHA32F_EXT,           InternalFormatInfo::LUMAFormat( 0, 32, GL_ALPHA,           GL_FLOAT,         GL_FLOAT,               AlwaysSupported)));
    745     map.insert(InternalFormatInfoPair(GL_LUMINANCE32F_EXT,       InternalFormatInfo::LUMAFormat(32,  0, GL_LUMINANCE,       GL_FLOAT,         GL_FLOAT,               AlwaysSupported)));
    746     map.insert(InternalFormatInfoPair(GL_ALPHA16F_EXT,           InternalFormatInfo::LUMAFormat( 0, 16, GL_ALPHA,           GL_HALF_FLOAT,    GL_FLOAT,               AlwaysSupported)));
    747     map.insert(InternalFormatInfoPair(GL_LUMINANCE16F_EXT,       InternalFormatInfo::LUMAFormat(16,  0, GL_LUMINANCE,       GL_HALF_FLOAT,    GL_FLOAT,               AlwaysSupported)));
    748     map.insert(InternalFormatInfoPair(GL_LUMINANCE8_ALPHA8_EXT,  InternalFormatInfo::LUMAFormat( 8,  8, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, AlwaysSupported)));
    749     map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA32F_EXT, InternalFormatInfo::LUMAFormat(32, 32, GL_LUMINANCE_ALPHA, GL_FLOAT,         GL_FLOAT,               AlwaysSupported)));
    750     map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA16F_EXT, InternalFormatInfo::LUMAFormat(16, 16, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT,    GL_FLOAT,               AlwaysSupported)));
    751 
    752     // Unsized formats
    753     //                               | Internal format   |                                 | Format            | Supported     |
    754     map.insert(InternalFormatInfoPair(GL_ALPHA,           InternalFormatInfo::UnsizedFormat(GL_ALPHA,           AlwaysSupported)));
    755     map.insert(InternalFormatInfoPair(GL_LUMINANCE,       InternalFormatInfo::UnsizedFormat(GL_LUMINANCE,       AlwaysSupported)));
    756     map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA, InternalFormatInfo::UnsizedFormat(GL_LUMINANCE_ALPHA, AlwaysSupported)));
    757     map.insert(InternalFormatInfoPair(GL_RED,             InternalFormatInfo::UnsizedFormat(GL_RED,             AlwaysSupported)));
    758     map.insert(InternalFormatInfoPair(GL_RG,              InternalFormatInfo::UnsizedFormat(GL_RG,              AlwaysSupported)));
    759     map.insert(InternalFormatInfoPair(GL_RGB,             InternalFormatInfo::UnsizedFormat(GL_RGB,             AlwaysSupported)));
    760     map.insert(InternalFormatInfoPair(GL_RGBA,            InternalFormatInfo::UnsizedFormat(GL_RGBA,            AlwaysSupported)));
    761     map.insert(InternalFormatInfoPair(GL_RED_INTEGER,     InternalFormatInfo::UnsizedFormat(GL_RED_INTEGER,     AlwaysSupported)));
    762     map.insert(InternalFormatInfoPair(GL_RG_INTEGER,      InternalFormatInfo::UnsizedFormat(GL_RG_INTEGER,      AlwaysSupported)));
    763     map.insert(InternalFormatInfoPair(GL_RGB_INTEGER,     InternalFormatInfo::UnsizedFormat(GL_RGB_INTEGER,     AlwaysSupported)));
    764     map.insert(InternalFormatInfoPair(GL_RGBA_INTEGER,    InternalFormatInfo::UnsizedFormat(GL_RGBA_INTEGER,    AlwaysSupported)));
    765     map.insert(InternalFormatInfoPair(GL_BGRA_EXT,        InternalFormatInfo::UnsizedFormat(GL_BGRA_EXT,        AlwaysSupported)));
    766 
    767     // Compressed formats, From ES 3.0.1 spec, table 3.16
    768     //                               | Internal format                             |                                    |W |H | BS |CC| Format                                      | Type            | SRGB | Supported          |
    769     map.insert(InternalFormatInfoPair(GL_COMPRESSED_R11_EAC,                        InternalFormatInfo::CompressedFormat(4, 4,  64, 1, GL_COMPRESSED_R11_EAC,                        GL_UNSIGNED_BYTE, false, UnimplementedSupport)));
    770     map.insert(InternalFormatInfoPair(GL_COMPRESSED_SIGNED_R11_EAC,                 InternalFormatInfo::CompressedFormat(4, 4,  64, 1, GL_COMPRESSED_SIGNED_R11_EAC,                 GL_UNSIGNED_BYTE, false, UnimplementedSupport)));
    771     map.insert(InternalFormatInfoPair(GL_COMPRESSED_RG11_EAC,                       InternalFormatInfo::CompressedFormat(4, 4, 128, 2, GL_COMPRESSED_RG11_EAC,                       GL_UNSIGNED_BYTE, false, UnimplementedSupport)));
    772     map.insert(InternalFormatInfoPair(GL_COMPRESSED_SIGNED_RG11_EAC,                InternalFormatInfo::CompressedFormat(4, 4, 128, 2, GL_COMPRESSED_SIGNED_RG11_EAC,                GL_UNSIGNED_BYTE, false, UnimplementedSupport)));
    773     map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB8_ETC2,                      InternalFormatInfo::CompressedFormat(4, 4,  64, 3, GL_COMPRESSED_RGB8_ETC2,                      GL_UNSIGNED_BYTE, false, UnimplementedSupport)));
    774     map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ETC2,                     InternalFormatInfo::CompressedFormat(4, 4,  64, 3, GL_COMPRESSED_SRGB8_ETC2,                     GL_UNSIGNED_BYTE, true,  UnimplementedSupport)));
    775     map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,  InternalFormatInfo::CompressedFormat(4, 4,  64, 3, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,  GL_UNSIGNED_BYTE, false, UnimplementedSupport)));
    776     map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, InternalFormatInfo::CompressedFormat(4, 4,  64, 3, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE, true,  UnimplementedSupport)));
    777     map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA8_ETC2_EAC,                 InternalFormatInfo::CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA8_ETC2_EAC,                 GL_UNSIGNED_BYTE, false, UnimplementedSupport)));
    778     map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,          InternalFormatInfo::CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,          GL_UNSIGNED_BYTE, true,  UnimplementedSupport)));
    779 
    780     // From GL_EXT_texture_compression_dxt1
    781     //                               | Internal format                   |                                    |W |H | BS |CC| Format                            | Type            | SRGB | Supported     |
    782     map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB_S3TC_DXT1_EXT,    InternalFormatInfo::CompressedFormat(4, 4,  64, 3, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,    GL_UNSIGNED_BYTE, false, AlwaysSupported)));
    783     map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,   InternalFormatInfo::CompressedFormat(4, 4,  64, 4, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,   GL_UNSIGNED_BYTE, false, AlwaysSupported)));
    784 
    785     // From GL_ANGLE_texture_compression_dxt3
    786     map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, InternalFormatInfo::CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE, false, AlwaysSupported)));
    787 
    788     // From GL_ANGLE_texture_compression_dxt5
    789     map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, InternalFormatInfo::CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE, false, AlwaysSupported)));
    790 
    791     return map;
    792 }
    793 
    794 static InternalFormatInfoMap BuildES2InternalFormatInfoMap()
    795 {
    796     InternalFormatInfoMap map;
    797 
    798     // From ES 2.0.25 table 4.5
    799     map.insert(InternalFormatInfoPair(GL_NONE,                 InternalFormatInfo()));
    800 
    801     //                               | Internal format        |                              | R | G | B | A |S | Format          | Type                     | Component type        | SRGB | Color         | Texture        | Supported      |
    802     //                               |                        |                              |   |   |   |   |  |                 |                          |                       |      | renderable    | filterable     |                |
    803     map.insert(InternalFormatInfoPair(GL_RGBA4,                InternalFormatInfo::RGBAFormat( 4,  4,  4,  4, 0, GL_RGBA,          GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported)));
    804     map.insert(InternalFormatInfoPair(GL_RGB5_A1,              InternalFormatInfo::RGBAFormat( 5,  5,  5,  1, 0, GL_RGBA,          GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported)));
    805     map.insert(InternalFormatInfoPair(GL_RGB565,               InternalFormatInfo::RGBAFormat( 5,  6,  5,  0, 0, GL_RGB,           GL_UNSIGNED_SHORT_5_6_5,   GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported)));
    806 
    807     // Extension formats
    808     map.insert(InternalFormatInfoPair(GL_R8_EXT,               InternalFormatInfo::RGBAFormat( 8,  0,  0,  0, 0, GL_RED_EXT,       GL_UNSIGNED_BYTE,          GL_UNSIGNED_NORMALIZED, false, CheckSupport<&Context::supportsRGTextures, &rx::Renderer::getRGTextureSupport>, CheckSupport<&Context::supportsRGTextures, &rx::Renderer::getRGTextureSupport>, CheckSupport<&Context::supportsRGTextures>)));
    809     map.insert(InternalFormatInfoPair(GL_RG8_EXT,              InternalFormatInfo::RGBAFormat( 8,  8,  0,  0, 0, GL_RG_EXT,        GL_UNSIGNED_BYTE,          GL_UNSIGNED_NORMALIZED, false, CheckSupport<&Context::supportsRGTextures, &rx::Renderer::getRGTextureSupport>, CheckSupport<&Context::supportsRGTextures, &rx::Renderer::getRGTextureSupport>, CheckSupport<&Context::supportsRGTextures>)));
    810     map.insert(InternalFormatInfoPair(GL_RGB8_OES,             InternalFormatInfo::RGBAFormat( 8,  8,  8,  0, 0, GL_RGB,           GL_UNSIGNED_BYTE,          GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported)));
    811     map.insert(InternalFormatInfoPair(GL_RGBA8_OES,            InternalFormatInfo::RGBAFormat( 8,  8,  8,  8, 0, GL_RGBA,          GL_UNSIGNED_BYTE,          GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported)));
    812     map.insert(InternalFormatInfoPair(GL_BGRA8_EXT,            InternalFormatInfo::RGBAFormat( 8,  8,  8,  8, 0, GL_BGRA_EXT,      GL_UNSIGNED_BYTE,          GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported)));
    813     map.insert(InternalFormatInfoPair(GL_BGRA4_ANGLEX,         InternalFormatInfo::RGBAFormat( 4,  4,  4,  4, 0, GL_BGRA_EXT,      GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_NORMALIZED, false, NeverSupported,  AlwaysSupported, AlwaysSupported)));
    814     map.insert(InternalFormatInfoPair(GL_BGR5_A1_ANGLEX,       InternalFormatInfo::RGBAFormat( 5,  5,  5,  1, 0, GL_BGRA_EXT,      GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_NORMALIZED, false, NeverSupported,  AlwaysSupported, AlwaysSupported)));
    815 
    816     // Floating point formats have to query the renderer for support
    817     //                               | Internal format        |                              | R | G | B | A |S | Format          | Type                     | Comp    | SRGB | Color renderable                                                                                           | Texture filterable                                                                                   | Supported                                     |
    818     //                               |                        |                              |   |   |   |   |  |                 |                          | type    |      |                                                                                                            |                                                                                                      |                                               |
    819     map.insert(InternalFormatInfoPair(GL_R16F_EXT,             InternalFormatInfo::RGBAFormat(16,  0,  0,  0, 0, GL_RED,           GL_HALF_FLOAT_OES,         GL_FLOAT, false, CheckSupport<&Context::supportsRGTextures, &rx::Renderer::getRGTextureSupport>,                              CheckSupport<&Context::supportsRGTextures, &rx::Renderer::getRGTextureSupport>,                        CheckSupport<&Context::supportsRGTextures>     )));
    820     map.insert(InternalFormatInfoPair(GL_R32F_EXT,             InternalFormatInfo::RGBAFormat(32,  0,  0,  0, 0, GL_RED,           GL_FLOAT,                  GL_FLOAT, false, CheckSupport<&Context::supportsRGTextures, &rx::Renderer::getRGTextureSupport>,                              CheckSupport<&Context::supportsRGTextures, &rx::Renderer::getRGTextureSupport>,                        CheckSupport<&Context::supportsRGTextures>     )));
    821     map.insert(InternalFormatInfoPair(GL_RG16F_EXT,            InternalFormatInfo::RGBAFormat(16, 16,  0,  0, 0, GL_RG,            GL_HALF_FLOAT_OES,         GL_FLOAT, false, CheckSupport<&Context::supportsRGTextures, &rx::Renderer::getRGTextureSupport>,                              CheckSupport<&Context::supportsRGTextures, &rx::Renderer::getRGTextureSupport>,                        CheckSupport<&Context::supportsRGTextures>     )));
    822     map.insert(InternalFormatInfoPair(GL_RG32F_EXT,            InternalFormatInfo::RGBAFormat(32, 32,  0,  0, 0, GL_RG,            GL_FLOAT,                  GL_FLOAT, false, CheckSupport<&Context::supportsRGTextures, &rx::Renderer::getRGTextureSupport>,                              CheckSupport<&Context::supportsRGTextures, &rx::Renderer::getRGTextureSupport>,                        CheckSupport<&Context::supportsRGTextures>     )));
    823     map.insert(InternalFormatInfoPair(GL_RGB16F_EXT,           InternalFormatInfo::RGBAFormat(16, 16, 16,  0, 0, GL_RGB,           GL_HALF_FLOAT_OES,         GL_FLOAT, false, CheckSupport<&Context::supportsFloat16RenderableTextures, &rx::Renderer::getFloat16TextureRenderingSupport>, CheckSupport<&Context::supportsFloat16LinearFilter, &rx::Renderer::getFloat16TextureFilteringSupport>, CheckSupport<&Context::supportsFloat16Textures>)));
    824     map.insert(InternalFormatInfoPair(GL_RGB32F_EXT,           InternalFormatInfo::RGBAFormat(32, 32, 32,  0, 0, GL_RGB,           GL_FLOAT,                  GL_FLOAT, false, CheckSupport<&Context::supportsFloat32RenderableTextures, &rx::Renderer::getFloat32TextureRenderingSupport>, CheckSupport<&Context::supportsFloat32LinearFilter, &rx::Renderer::getFloat32TextureFilteringSupport>, CheckSupport<&Context::supportsFloat32Textures>)));
    825     map.insert(InternalFormatInfoPair(GL_RGBA16F_EXT,          InternalFormatInfo::RGBAFormat(16, 16, 16, 16, 0, GL_RGBA,          GL_HALF_FLOAT_OES,         GL_FLOAT, false, CheckSupport<&Context::supportsFloat16RenderableTextures, &rx::Renderer::getFloat16TextureRenderingSupport>, CheckSupport<&Context::supportsFloat16LinearFilter, &rx::Renderer::getFloat16TextureFilteringSupport>, CheckSupport<&Context::supportsFloat16Textures>)));
    826     map.insert(InternalFormatInfoPair(GL_RGBA32F_EXT,          InternalFormatInfo::RGBAFormat(32, 32, 32, 32, 0, GL_RGBA,          GL_FLOAT,                  GL_FLOAT, false, CheckSupport<&Context::supportsFloat32RenderableTextures, &rx::Renderer::getFloat32TextureRenderingSupport>, CheckSupport<&Context::supportsFloat32LinearFilter, &rx::Renderer::getFloat32TextureFilteringSupport>, CheckSupport<&Context::supportsFloat32Textures>)));
    827 
    828     // Depth and stencil formats
    829     //                               | Internal format        |                                      | D |S |X | Format              | Type                     | Internal format     | Depth          | Stencil         | Supported                                  |
    830     //                               |                        |                                      |   |  |  |                     |                          | type                | renderable     | renderable      |                                            |
    831     map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT32_OES,InternalFormatInfo::DepthStencilFormat(32, 0, 0, GL_DEPTH_COMPONENT,   GL_UNSIGNED_INT,           GL_UNSIGNED_NORMALIZED, AlwaysSupported, NeverSupported,  CheckSupport<&Context::supportsDepthTextures>)));
    832     map.insert(InternalFormatInfoPair(GL_DEPTH24_STENCIL8_OES, InternalFormatInfo::DepthStencilFormat(24, 8, 0, GL_DEPTH_STENCIL_OES, GL_UNSIGNED_INT_24_8_OES,  GL_UNSIGNED_NORMALIZED, AlwaysSupported, AlwaysSupported, CheckSupport<&Context::supportsDepthTextures>)));
    833     map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT16,    InternalFormatInfo::DepthStencilFormat(16, 0, 0, GL_DEPTH_COMPONENT,   GL_UNSIGNED_SHORT,         GL_UNSIGNED_NORMALIZED, AlwaysSupported, NeverSupported,  AlwaysSupported)));
    834     map.insert(InternalFormatInfoPair(GL_STENCIL_INDEX8,       InternalFormatInfo::DepthStencilFormat( 0, 8, 0, GL_DEPTH_STENCIL_OES, GL_UNSIGNED_BYTE,          GL_UNSIGNED_NORMALIZED, NeverSupported,  AlwaysSupported, AlwaysSupported)));
    835 
    836     // Unsized formats
    837     //                               | Internal format        |                                 | Format              | Supported     |
    838     map.insert(InternalFormatInfoPair(GL_ALPHA,                InternalFormatInfo::UnsizedFormat(GL_ALPHA,             AlwaysSupported)));
    839     map.insert(InternalFormatInfoPair(GL_LUMINANCE,            InternalFormatInfo::UnsizedFormat(GL_LUMINANCE,         AlwaysSupported)));
    840     map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA,      InternalFormatInfo::UnsizedFormat(GL_LUMINANCE_ALPHA,   AlwaysSupported)));
    841     map.insert(InternalFormatInfoPair(GL_RED_EXT,              InternalFormatInfo::UnsizedFormat(GL_RED_EXT,           CheckSupport<&Context::supportsRGTextures>)));
    842     map.insert(InternalFormatInfoPair(GL_RG_EXT,               InternalFormatInfo::UnsizedFormat(GL_RG_EXT,            CheckSupport<&Context::supportsRGTextures>)));
    843     map.insert(InternalFormatInfoPair(GL_RGB,                  InternalFormatInfo::UnsizedFormat(GL_RGB,               AlwaysSupported)));
    844     map.insert(InternalFormatInfoPair(GL_RGBA,                 InternalFormatInfo::UnsizedFormat(GL_RGBA,              AlwaysSupported)));
    845     map.insert(InternalFormatInfoPair(GL_BGRA_EXT,             InternalFormatInfo::UnsizedFormat(GL_BGRA_EXT,          AlwaysSupported)));
    846     map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT,      InternalFormatInfo::UnsizedFormat(GL_DEPTH_COMPONENT,   AlwaysSupported)));
    847     map.insert(InternalFormatInfoPair(GL_DEPTH_STENCIL_OES,    InternalFormatInfo::UnsizedFormat(GL_DEPTH_STENCIL_OES, AlwaysSupported)));
    848 
    849     // Luminance alpha formats from GL_EXT_texture_storage
    850     //                               | Internal format          |                              | L | A | Format                   | Type                     | Component type        | Supported     |
    851     map.insert(InternalFormatInfoPair(GL_ALPHA8_EXT,             InternalFormatInfo::LUMAFormat( 0,  8, GL_ALPHA,                  GL_UNSIGNED_BYTE,          GL_UNSIGNED_NORMALIZED, AlwaysSupported)));
    852     map.insert(InternalFormatInfoPair(GL_LUMINANCE8_EXT,         InternalFormatInfo::LUMAFormat( 8,  0, GL_LUMINANCE,              GL_UNSIGNED_BYTE,          GL_UNSIGNED_NORMALIZED, AlwaysSupported)));
    853     map.insert(InternalFormatInfoPair(GL_ALPHA32F_EXT,           InternalFormatInfo::LUMAFormat( 0, 32, GL_ALPHA,                  GL_FLOAT,                  GL_FLOAT,               AlwaysSupported)));
    854     map.insert(InternalFormatInfoPair(GL_LUMINANCE32F_EXT,       InternalFormatInfo::LUMAFormat(32,  0, GL_LUMINANCE,              GL_FLOAT,                  GL_FLOAT,               AlwaysSupported)));
    855     map.insert(InternalFormatInfoPair(GL_ALPHA16F_EXT,           InternalFormatInfo::LUMAFormat( 0, 16, GL_ALPHA,                  GL_HALF_FLOAT_OES,         GL_FLOAT,               AlwaysSupported)));
    856     map.insert(InternalFormatInfoPair(GL_LUMINANCE16F_EXT,       InternalFormatInfo::LUMAFormat(16,  0, GL_LUMINANCE,              GL_HALF_FLOAT_OES,         GL_FLOAT,               AlwaysSupported)));
    857     map.insert(InternalFormatInfoPair(GL_LUMINANCE8_ALPHA8_EXT,  InternalFormatInfo::LUMAFormat( 8,  8, GL_LUMINANCE_ALPHA,        GL_UNSIGNED_BYTE,          GL_UNSIGNED_NORMALIZED, AlwaysSupported)));
    858     map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA32F_EXT, InternalFormatInfo::LUMAFormat(32, 32, GL_LUMINANCE_ALPHA,        GL_FLOAT,                  GL_FLOAT,               AlwaysSupported)));
    859     map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA16F_EXT, InternalFormatInfo::LUMAFormat(16, 16, GL_LUMINANCE_ALPHA,        GL_HALF_FLOAT_OES,         GL_FLOAT,               AlwaysSupported)));
    860 
    861     // From GL_EXT_texture_compression_dxt1
    862     //                               | Internal format                   |                                    |W |H | BS |CC|Format                             | Type            | SRGB | Supported                                  |
    863     map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB_S3TC_DXT1_EXT,    InternalFormatInfo::CompressedFormat(4, 4,  64, 3, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,    GL_UNSIGNED_BYTE, false, CheckSupport<&Context::supportsDXT1Textures>)));
    864     map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,   InternalFormatInfo::CompressedFormat(4, 4,  64, 4, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,   GL_UNSIGNED_BYTE, false, CheckSupport<&Context::supportsDXT1Textures>)));
    865 
    866     // From GL_ANGLE_texture_compression_dxt3
    867     map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, InternalFormatInfo::CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE, false, CheckSupport<&Context::supportsDXT3Textures>)));
    868 
    869     // From GL_ANGLE_texture_compression_dxt5
    870     map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, InternalFormatInfo::CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE, false, CheckSupport<&Context::supportsDXT5Textures>)));
    871 
    872     return map;
    873 }
    874 
    875 static bool GetInternalFormatInfo(GLenum internalFormat, GLuint clientVersion, InternalFormatInfo *outFormatInfo)
    876 {
    877     const InternalFormatInfoMap* map = NULL;
    878 
    879     if (clientVersion == 2)
    880     {
    881         static const InternalFormatInfoMap formatMap = BuildES2InternalFormatInfoMap();
    882         map = &formatMap;
    883     }
    884     else if (clientVersion == 3)
    885     {
    886         static const InternalFormatInfoMap formatMap = BuildES3InternalFormatInfoMap();
    887         map = &formatMap;
    888     }
    889     else
    890     {
    891         UNREACHABLE();
    892     }
    893 
    894     InternalFormatInfoMap::const_iterator iter = map->find(internalFormat);
    895     if (iter != map->end())
    896     {
    897         if (outFormatInfo)
    898         {
    899             *outFormatInfo = iter->second;
    900         }
    901         return true;
    902     }
    903     else
    904     {
    905         return false;
    906     }
    907 }
    908 
    909 typedef std::set<GLenum> FormatSet;
    910 
    911 static FormatSet BuildES2ValidFormatSet()
    912 {
    913     static const FormatMap &formatMap = GetFormatMap(2);
    914 
    915     FormatSet set;
    916 
    917     for (FormatMap::const_iterator i = formatMap.begin(); i != formatMap.end(); i++)
    918     {
    919         const FormatTypePair& formatPair = i->first;
    920         set.insert(formatPair.first);
    921     }
    922 
    923     return set;
    924 }
    925 
    926 static FormatSet BuildES3ValidFormatSet()
    927 {
    928     static const ES3FormatSet &formatSet = GetES3FormatSet();
    929 
    930     FormatSet set;
    931 
    932     for (ES3FormatSet::const_iterator i = formatSet.begin(); i != formatSet.end(); i++)
    933     {
    934         const FormatInfo& formatInfo = *i;
    935         set.insert(formatInfo.mFormat);
    936     }
    937 
    938     return set;
    939 }
    940 
    941 typedef std::set<GLenum> TypeSet;
    942 
    943 static TypeSet BuildES2ValidTypeSet()
    944 {
    945     static const FormatMap &formatMap = GetFormatMap(2);
    946 
    947     TypeSet set;
    948 
    949     for (FormatMap::const_iterator i = formatMap.begin(); i != formatMap.end(); i++)
    950     {
    951         const FormatTypePair& formatPair = i->first;
    952         set.insert(formatPair.second);
    953     }
    954 
    955     return set;
    956 }
    957 
    958 static TypeSet BuildES3ValidTypeSet()
    959 {
    960     static const ES3FormatSet &formatSet = GetES3FormatSet();
    961 
    962     TypeSet set;
    963 
    964     for (ES3FormatSet::const_iterator i = formatSet.begin(); i != formatSet.end(); i++)
    965     {
    966         const FormatInfo& formatInfo = *i;
    967         set.insert(formatInfo.mType);
    968     }
    969 
    970     return set;
    971 }
    972 
    973 struct EffectiveInternalFormatInfo
    974 {
    975     GLenum mEffectiveFormat;
    976     GLenum mDestFormat;
    977     GLuint mMinRedBits;
    978     GLuint mMaxRedBits;
    979     GLuint mMinGreenBits;
    980     GLuint mMaxGreenBits;
    981     GLuint mMinBlueBits;
    982     GLuint mMaxBlueBits;
    983     GLuint mMinAlphaBits;
    984     GLuint mMaxAlphaBits;
    985 
    986     EffectiveInternalFormatInfo(GLenum effectiveFormat, GLenum destFormat, GLuint minRedBits, GLuint maxRedBits,
    987                                 GLuint minGreenBits, GLuint maxGreenBits, GLuint minBlueBits, GLuint maxBlueBits,
    988                                 GLuint minAlphaBits, GLuint maxAlphaBits)
    989         : mEffectiveFormat(effectiveFormat), mDestFormat(destFormat), mMinRedBits(minRedBits),
    990           mMaxRedBits(maxRedBits), mMinGreenBits(minGreenBits), mMaxGreenBits(maxGreenBits),
    991           mMinBlueBits(minBlueBits), mMaxBlueBits(maxBlueBits), mMinAlphaBits(minAlphaBits),
    992           mMaxAlphaBits(maxAlphaBits) {};
    993 };
    994 
    995 typedef std::vector<EffectiveInternalFormatInfo> EffectiveInternalFormatList;
    996 
    997 static EffectiveInternalFormatList BuildSizedEffectiveInternalFormatList()
    998 {
    999     EffectiveInternalFormatList list;
   1000 
   1001     // OpenGL ES 3.0.3 Specification, Table 3.17, pg 141: Effective internal format coresponding to destination internal format and
   1002     //                                                    linear source buffer component sizes.
   1003     //                                                                            | Source channel min/max sizes |
   1004     //                                         Effective Internal Format |  N/A   |  R   |  G   |  B   |  A      |
   1005     list.push_back(EffectiveInternalFormatInfo(GL_ALPHA8_EXT,              GL_NONE, 0,  0, 0,  0, 0,  0, 1, 8));
   1006     list.push_back(EffectiveInternalFormatInfo(GL_R8,                      GL_NONE, 1,  8, 0,  0, 0,  0, 0, 0));
   1007     list.push_back(EffectiveInternalFormatInfo(GL_RG8,                     GL_NONE, 1,  8, 1,  8, 0,  0, 0, 0));
   1008     list.push_back(EffectiveInternalFormatInfo(GL_RGB565,                  GL_NONE, 1,  5, 1,  6, 1,  5, 0, 0));
   1009     list.push_back(EffectiveInternalFormatInfo(GL_RGB8,                    GL_NONE, 6,  8, 7,  8, 6,  8, 0, 0));
   1010     list.push_back(EffectiveInternalFormatInfo(GL_RGBA4,                   GL_NONE, 1,  4, 1,  4, 1,  4, 1, 4));
   1011     list.push_back(EffectiveInternalFormatInfo(GL_RGB5_A1,                 GL_NONE, 5,  5, 5,  5, 5,  5, 1, 1));
   1012     list.push_back(EffectiveInternalFormatInfo(GL_RGBA8,                   GL_NONE, 5,  8, 5,  8, 5,  8, 2, 8));
   1013     list.push_back(EffectiveInternalFormatInfo(GL_RGB10_A2,                GL_NONE, 9, 10, 9, 10, 9, 10, 2, 2));
   1014 
   1015     return list;
   1016 }
   1017 
   1018 
   1019 static EffectiveInternalFormatList BuildUnsizedEffectiveInternalFormatList()
   1020 {
   1021     EffectiveInternalFormatList list;
   1022 
   1023     // OpenGL ES 3.0.3 Specification, Table 3.17, pg 141: Effective internal format coresponding to destination internal format and
   1024     //                                                    linear source buffer component sizes.
   1025     //                                                                                        |          Source channel min/max sizes            |
   1026     //                                         Effective Internal Format |    Dest Format     |     R     |      G     |      B     |      A     |
   1027     list.push_back(EffectiveInternalFormatInfo(GL_ALPHA8_EXT,              GL_ALPHA,           0, UINT_MAX, 0, UINT_MAX, 0, UINT_MAX, 1,        8));
   1028     list.push_back(EffectiveInternalFormatInfo(GL_LUMINANCE8_EXT,          GL_LUMINANCE,       1,        8, 0, UINT_MAX, 0, UINT_MAX, 0, UINT_MAX));
   1029     list.push_back(EffectiveInternalFormatInfo(GL_LUMINANCE8_ALPHA8_EXT,   GL_LUMINANCE_ALPHA, 1,        8, 0, UINT_MAX, 0, UINT_MAX, 1,        8));
   1030     list.push_back(EffectiveInternalFormatInfo(GL_RGB565,                  GL_RGB,             1,        5, 1,        6, 1,        5, 0, UINT_MAX));
   1031     list.push_back(EffectiveInternalFormatInfo(GL_RGB8,                    GL_RGB,             6,        8, 7,        8, 6,        8, 0, UINT_MAX));
   1032     list.push_back(EffectiveInternalFormatInfo(GL_RGBA4,                   GL_RGBA,            1,        4, 1,        4, 1,        4, 1,        4));
   1033     list.push_back(EffectiveInternalFormatInfo(GL_RGB5_A1,                 GL_RGBA,            5,        5, 5,        5, 5,        5, 1,        1));
   1034     list.push_back(EffectiveInternalFormatInfo(GL_RGBA8,                   GL_RGBA,            5,        8, 5,        8, 5,        8, 5,        8));
   1035 
   1036     return list;
   1037 }
   1038 
   1039 static bool GetEffectiveInternalFormat(const InternalFormatInfo &srcFormat, const InternalFormatInfo &destFormat,
   1040                                        GLuint clientVersion, GLenum *outEffectiveFormat)
   1041 {
   1042     const EffectiveInternalFormatList *list = NULL;
   1043     GLenum targetFormat = GL_NONE;
   1044 
   1045     if (gl::IsSizedInternalFormat(destFormat.mFormat, clientVersion))
   1046     {
   1047         static const EffectiveInternalFormatList sizedList = BuildSizedEffectiveInternalFormatList();
   1048         list = &sizedList;
   1049     }
   1050     else
   1051     {
   1052         static const EffectiveInternalFormatList unsizedList = BuildUnsizedEffectiveInternalFormatList();
   1053         list = &unsizedList;
   1054         targetFormat = destFormat.mFormat;
   1055     }
   1056 
   1057     for (size_t curFormat = 0; curFormat < list->size(); ++curFormat)
   1058     {
   1059         const EffectiveInternalFormatInfo& formatInfo = list->at(curFormat);
   1060         if ((formatInfo.mDestFormat == targetFormat) &&
   1061             (formatInfo.mMinRedBits   <= srcFormat.mRedBits   && formatInfo.mMaxRedBits   >= srcFormat.mRedBits)   &&
   1062             (formatInfo.mMinGreenBits <= srcFormat.mGreenBits && formatInfo.mMaxGreenBits >= srcFormat.mGreenBits) &&
   1063             (formatInfo.mMinBlueBits  <= srcFormat.mBlueBits  && formatInfo.mMaxBlueBits  >= srcFormat.mBlueBits)  &&
   1064             (formatInfo.mMinAlphaBits <= srcFormat.mAlphaBits && formatInfo.mMaxAlphaBits >= srcFormat.mAlphaBits))
   1065         {
   1066             *outEffectiveFormat = formatInfo.mEffectiveFormat;
   1067             return true;
   1068         }
   1069     }
   1070 
   1071     return false;
   1072 }
   1073 
   1074 struct CopyConversion
   1075 {
   1076     GLenum mTextureFormat;
   1077     GLenum mFramebufferFormat;
   1078 
   1079     CopyConversion(GLenum textureFormat, GLenum framebufferFormat)
   1080         : mTextureFormat(textureFormat), mFramebufferFormat(framebufferFormat) { }
   1081 
   1082     bool operator<(const CopyConversion& other) const
   1083     {
   1084         return memcmp(this, &other, sizeof(CopyConversion)) < 0;
   1085     }
   1086 };
   1087 
   1088 typedef std::set<CopyConversion> CopyConversionSet;
   1089 
   1090 static CopyConversionSet BuildValidES3CopyTexImageCombinations()
   1091 {
   1092     CopyConversionSet set;
   1093 
   1094     // From ES 3.0.1 spec, table 3.15
   1095     set.insert(CopyConversion(GL_ALPHA,           GL_RGBA));
   1096     set.insert(CopyConversion(GL_LUMINANCE,       GL_RED));
   1097     set.insert(CopyConversion(GL_LUMINANCE,       GL_RG));
   1098     set.insert(CopyConversion(GL_LUMINANCE,       GL_RGB));
   1099     set.insert(CopyConversion(GL_LUMINANCE,       GL_RGBA));
   1100     set.insert(CopyConversion(GL_LUMINANCE_ALPHA, GL_RGBA));
   1101     set.insert(CopyConversion(GL_RED,             GL_RED));
   1102     set.insert(CopyConversion(GL_RED,             GL_RG));
   1103     set.insert(CopyConversion(GL_RED,             GL_RGB));
   1104     set.insert(CopyConversion(GL_RED,             GL_RGBA));
   1105     set.insert(CopyConversion(GL_RG,              GL_RG));
   1106     set.insert(CopyConversion(GL_RG,              GL_RGB));
   1107     set.insert(CopyConversion(GL_RG,              GL_RGBA));
   1108     set.insert(CopyConversion(GL_RGB,             GL_RGB));
   1109     set.insert(CopyConversion(GL_RGB,             GL_RGBA));
   1110     set.insert(CopyConversion(GL_RGBA,            GL_RGBA));
   1111 
   1112     // Necessary for ANGLE back-buffers
   1113     set.insert(CopyConversion(GL_ALPHA,           GL_BGRA_EXT));
   1114     set.insert(CopyConversion(GL_LUMINANCE,       GL_BGRA_EXT));
   1115     set.insert(CopyConversion(GL_LUMINANCE_ALPHA, GL_BGRA_EXT));
   1116     set.insert(CopyConversion(GL_RED,             GL_BGRA_EXT));
   1117     set.insert(CopyConversion(GL_RG,              GL_BGRA_EXT));
   1118     set.insert(CopyConversion(GL_RGB,             GL_BGRA_EXT));
   1119     set.insert(CopyConversion(GL_RGBA,            GL_BGRA_EXT));
   1120 
   1121     set.insert(CopyConversion(GL_RED_INTEGER,     GL_RED_INTEGER));
   1122     set.insert(CopyConversion(GL_RED_INTEGER,     GL_RG_INTEGER));
   1123     set.insert(CopyConversion(GL_RED_INTEGER,     GL_RGB_INTEGER));
   1124     set.insert(CopyConversion(GL_RED_INTEGER,     GL_RGBA_INTEGER));
   1125     set.insert(CopyConversion(GL_RG_INTEGER,      GL_RG_INTEGER));
   1126     set.insert(CopyConversion(GL_RG_INTEGER,      GL_RGB_INTEGER));
   1127     set.insert(CopyConversion(GL_RG_INTEGER,      GL_RGBA_INTEGER));
   1128     set.insert(CopyConversion(GL_RGB_INTEGER,     GL_RGB_INTEGER));
   1129     set.insert(CopyConversion(GL_RGB_INTEGER,     GL_RGBA_INTEGER));
   1130     set.insert(CopyConversion(GL_RGBA_INTEGER,    GL_RGBA_INTEGER));
   1131 
   1132     return set;
   1133 }
   1134 
   1135 bool IsValidInternalFormat(GLenum internalFormat, const Context *context)
   1136 {
   1137     if (!context)
   1138     {
   1139         return false;
   1140     }
   1141 
   1142     InternalFormatInfo internalFormatInfo;
   1143     if (GetInternalFormatInfo(internalFormat, context->getClientVersion(), &internalFormatInfo))
   1144     {
   1145         ASSERT(internalFormatInfo.mSupportFunction != NULL);
   1146         return internalFormatInfo.mSupportFunction(context);
   1147     }
   1148     else
   1149     {
   1150         return false;
   1151     }
   1152 }
   1153 
   1154 bool IsValidFormat(GLenum format, GLuint clientVersion)
   1155 {
   1156     if (clientVersion == 2)
   1157     {
   1158         static const FormatSet formatSet = BuildES2ValidFormatSet();
   1159         return formatSet.find(format) != formatSet.end();
   1160     }
   1161     else if (clientVersion == 3)
   1162     {
   1163         static const FormatSet formatSet = BuildES3ValidFormatSet();
   1164         return formatSet.find(format) != formatSet.end();
   1165     }
   1166     else
   1167     {
   1168         UNREACHABLE();
   1169         return false;
   1170     }
   1171 }
   1172 
   1173 bool IsValidType(GLenum type, GLuint clientVersion)
   1174 {
   1175     if (clientVersion == 2)
   1176     {
   1177         static const TypeSet typeSet = BuildES2ValidTypeSet();
   1178         return typeSet.find(type) != typeSet.end();
   1179     }
   1180     else if (clientVersion == 3)
   1181     {
   1182         static const TypeSet typeSet = BuildES3ValidTypeSet();
   1183         return typeSet.find(type) != typeSet.end();
   1184     }
   1185     else
   1186     {
   1187         UNREACHABLE();
   1188         return false;
   1189     }
   1190 }
   1191 
   1192 bool IsValidFormatCombination(GLenum internalFormat, GLenum format, GLenum type, GLuint clientVersion)
   1193 {
   1194     if (clientVersion == 2)
   1195     {
   1196         static const FormatMap &formats = GetFormatMap(clientVersion);
   1197         FormatMap::const_iterator iter = formats.find(FormatTypePair(format, type));
   1198 
   1199         return (iter != formats.end()) && ((internalFormat == (GLint)type) || (internalFormat == iter->second.mInternalFormat));
   1200     }
   1201     else if (clientVersion == 3)
   1202     {
   1203         static const ES3FormatSet &formats = GetES3FormatSet();
   1204         return formats.find(FormatInfo(internalFormat, format, type)) != formats.end();
   1205     }
   1206     else
   1207     {
   1208         UNREACHABLE();
   1209         return false;
   1210     }
   1211 }
   1212 
   1213 bool IsValidCopyTexImageCombination(GLenum textureInternalFormat, GLenum frameBufferInternalFormat, GLuint readBufferHandle, GLuint clientVersion)
   1214 {
   1215     InternalFormatInfo textureInternalFormatInfo;
   1216     InternalFormatInfo framebufferInternalFormatInfo;
   1217     if (GetInternalFormatInfo(textureInternalFormat, clientVersion, &textureInternalFormatInfo) &&
   1218         GetInternalFormatInfo(frameBufferInternalFormat, clientVersion, &framebufferInternalFormatInfo))
   1219     {
   1220         if (clientVersion == 2)
   1221         {
   1222             UNIMPLEMENTED();
   1223             return false;
   1224         }
   1225         else if (clientVersion == 3)
   1226         {
   1227             static const CopyConversionSet conversionSet = BuildValidES3CopyTexImageCombinations();
   1228             const CopyConversion conversion = CopyConversion(textureInternalFormatInfo.mFormat,
   1229                                                              framebufferInternalFormatInfo.mFormat);
   1230             if (conversionSet.find(conversion) != conversionSet.end())
   1231             {
   1232                 // Section 3.8.5 of the GLES 3.0.3 spec states that source and destination formats
   1233                 // must both be signed, unsigned, or fixed point and both source and destinations
   1234                 // must be either both SRGB or both not SRGB. EXT_color_buffer_float adds allowed
   1235                 // conversion between fixed and floating point.
   1236 
   1237                 if ((textureInternalFormatInfo.mColorEncoding == GL_SRGB) != (framebufferInternalFormatInfo.mColorEncoding == GL_SRGB))
   1238                 {
   1239                     return false;
   1240                 }
   1241 
   1242                 if (((textureInternalFormatInfo.mComponentType == GL_INT) != (framebufferInternalFormatInfo.mComponentType == GL_INT)) ||
   1243                     ((textureInternalFormatInfo.mComponentType == GL_UNSIGNED_INT) != (framebufferInternalFormatInfo.mComponentType == GL_UNSIGNED_INT)))
   1244                 {
   1245                     return false;
   1246                 }
   1247 
   1248                 if (gl::IsFloatOrFixedComponentType(textureInternalFormatInfo.mComponentType) &&
   1249                     !gl::IsFloatOrFixedComponentType(framebufferInternalFormatInfo.mComponentType))
   1250                 {
   1251                     return false;
   1252                 }
   1253 
   1254                 // GLES specification 3.0.3, sec 3.8.5, pg 139-140:
   1255                 // The effective internal format of the source buffer is determined with the following rules applied in order:
   1256                 //    * If the source buffer is a texture or renderbuffer that was created with a sized internal format then the
   1257                 //      effective internal format is the source buffer's sized internal format.
   1258                 //    * If the source buffer is a texture that was created with an unsized base internal format, then the
   1259                 //      effective internal format is the source image array's effective internal format, as specified by table
   1260                 //      3.12, which is determined from the <format> and <type> that were used when the source image array was
   1261                 //      specified by TexImage*.
   1262                 //    * Otherwise the effective internal format is determined by the row in table 3.17 or 3.18 where
   1263                 //      Destination Internal Format matches internalformat and where the [source channel sizes] are consistent
   1264                 //      with the values of the source buffer's [channel sizes]. Table 3.17 is used if the
   1265                 //      FRAMEBUFFER_ATTACHMENT_ENCODING is LINEAR and table 3.18 is used if the FRAMEBUFFER_ATTACHMENT_ENCODING
   1266                 //      is SRGB.
   1267                 InternalFormatInfo sourceEffectiveFormat;
   1268                 if (readBufferHandle != 0)
   1269                 {
   1270                     // Not the default framebuffer, therefore the read buffer must be a user-created texture or renderbuffer
   1271                     if (gl::IsSizedInternalFormat(framebufferInternalFormatInfo.mFormat, clientVersion))
   1272                     {
   1273                         sourceEffectiveFormat = framebufferInternalFormatInfo;
   1274                     }
   1275                     else
   1276                     {
   1277                         // Renderbuffers cannot be created with an unsized internal format, so this must be an unsized-format
   1278                         // texture. We can use the same table we use when creating textures to get its effective sized format.
   1279                         GLenum effectiveFormat = gl::GetSizedInternalFormat(framebufferInternalFormatInfo.mFormat,
   1280                                                                             framebufferInternalFormatInfo.mType, clientVersion);
   1281                         gl::GetInternalFormatInfo(effectiveFormat, clientVersion, &sourceEffectiveFormat);
   1282                     }
   1283                 }
   1284                 else
   1285                 {
   1286                     // The effective internal format must be derived from the source framebuffer's channel sizes.
   1287                     // This is done in GetEffectiveInternalFormat for linear buffers (table 3.17)
   1288                     if (framebufferInternalFormatInfo.mColorEncoding == GL_LINEAR)
   1289                     {
   1290                         GLenum effectiveFormat;
   1291                         if (GetEffectiveInternalFormat(framebufferInternalFormatInfo, textureInternalFormatInfo, clientVersion, &effectiveFormat))
   1292                         {
   1293                             gl::GetInternalFormatInfo(effectiveFormat, clientVersion, &sourceEffectiveFormat);
   1294                         }
   1295                         else
   1296                         {
   1297                             return false;
   1298                         }
   1299                     }
   1300                     else if (framebufferInternalFormatInfo.mColorEncoding == GL_SRGB)
   1301                     {
   1302                         // SRGB buffers can only be copied to sized format destinations according to table 3.18
   1303                         if (gl::IsSizedInternalFormat(textureInternalFormat, clientVersion) &&
   1304                             (framebufferInternalFormatInfo.mRedBits   >= 1 && framebufferInternalFormatInfo.mRedBits   <= 8) &&
   1305                             (framebufferInternalFormatInfo.mGreenBits >= 1 && framebufferInternalFormatInfo.mGreenBits <= 8) &&
   1306                             (framebufferInternalFormatInfo.mBlueBits  >= 1 && framebufferInternalFormatInfo.mBlueBits  <= 8) &&
   1307                             (framebufferInternalFormatInfo.mAlphaBits >= 1 && framebufferInternalFormatInfo.mAlphaBits <= 8))
   1308                         {
   1309                             gl::GetInternalFormatInfo(GL_SRGB8_ALPHA8, clientVersion, &sourceEffectiveFormat);
   1310                         }
   1311                         else
   1312                         {
   1313                             return false;
   1314                         }
   1315                     }
   1316                     else
   1317                     {
   1318                         UNREACHABLE();
   1319                     }
   1320                 }
   1321 
   1322                 if (gl::IsSizedInternalFormat(textureInternalFormatInfo.mFormat, clientVersion))
   1323                 {
   1324                     // Section 3.8.5 of the GLES 3.0.3 spec, pg 139, requires that, if the destination format is sized,
   1325                     // component sizes of the source and destination formats must exactly match
   1326                     if (textureInternalFormatInfo.mRedBits != sourceEffectiveFormat.mRedBits ||
   1327                         textureInternalFormatInfo.mGreenBits != sourceEffectiveFormat.mGreenBits ||
   1328                         textureInternalFormatInfo.mBlueBits != sourceEffectiveFormat.mBlueBits ||
   1329                         textureInternalFormatInfo.mAlphaBits != sourceEffectiveFormat.mAlphaBits)
   1330                     {
   1331                         return false;
   1332                     }
   1333                 }
   1334 
   1335 
   1336                 return true; // A conversion function exists, and no rule in the specification has precluded conversion
   1337                              // between these formats.
   1338             }
   1339 
   1340             return false;
   1341         }
   1342         else
   1343         {
   1344             UNREACHABLE();
   1345             return false;
   1346         }
   1347     }
   1348     else
   1349     {
   1350         UNREACHABLE();
   1351         return false;
   1352     }
   1353 }
   1354 
   1355 bool IsSizedInternalFormat(GLenum internalFormat, GLuint clientVersion)
   1356 {
   1357     InternalFormatInfo internalFormatInfo;
   1358     if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
   1359     {
   1360         return internalFormatInfo.mPixelBits > 0;
   1361     }
   1362     else
   1363     {
   1364         UNREACHABLE();
   1365         return false;
   1366     }
   1367 }
   1368 
   1369 GLenum GetSizedInternalFormat(GLenum format, GLenum type, GLuint clientVersion)
   1370 {
   1371     const FormatMap &formats = GetFormatMap(clientVersion);
   1372     FormatMap::const_iterator iter = formats.find(FormatTypePair(format, type));
   1373     return (iter != formats.end()) ? iter->second.mInternalFormat : GL_NONE;
   1374 }
   1375 
   1376 GLuint GetPixelBytes(GLenum internalFormat, GLuint clientVersion)
   1377 {
   1378     InternalFormatInfo internalFormatInfo;
   1379     if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
   1380     {
   1381         return internalFormatInfo.mPixelBits / 8;
   1382     }
   1383     else
   1384     {
   1385         UNREACHABLE();
   1386         return 0;
   1387     }
   1388 }
   1389 
   1390 GLuint GetAlphaBits(GLenum internalFormat, GLuint clientVersion)
   1391 {
   1392     InternalFormatInfo internalFormatInfo;
   1393     if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
   1394     {
   1395         return internalFormatInfo.mAlphaBits;
   1396     }
   1397     else
   1398     {
   1399         UNREACHABLE();
   1400         return 0;
   1401     }
   1402 }
   1403 
   1404 GLuint GetRedBits(GLenum internalFormat, GLuint clientVersion)
   1405 {
   1406     InternalFormatInfo internalFormatInfo;
   1407     if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
   1408     {
   1409         return internalFormatInfo.mRedBits;
   1410     }
   1411     else
   1412     {
   1413         UNREACHABLE();
   1414         return 0;
   1415     }
   1416 }
   1417 
   1418 GLuint GetGreenBits(GLenum internalFormat, GLuint clientVersion)
   1419 {
   1420     InternalFormatInfo internalFormatInfo;
   1421     if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
   1422     {
   1423         return internalFormatInfo.mGreenBits;
   1424     }
   1425     else
   1426     {
   1427         UNREACHABLE();
   1428         return 0;
   1429     }
   1430 }
   1431 
   1432 GLuint GetBlueBits(GLenum internalFormat, GLuint clientVersion)
   1433 {
   1434     InternalFormatInfo internalFormatInfo;
   1435     if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
   1436     {
   1437         return internalFormatInfo.mBlueBits;
   1438     }
   1439     else
   1440     {
   1441         UNREACHABLE();
   1442         return 0;
   1443     }
   1444 }
   1445 
   1446 GLuint GetLuminanceBits(GLenum internalFormat, GLuint clientVersion)
   1447 {
   1448     InternalFormatInfo internalFormatInfo;
   1449     if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
   1450     {
   1451         return internalFormatInfo.mLuminanceBits;
   1452     }
   1453     else
   1454     {
   1455         UNREACHABLE();
   1456         return 0;
   1457     }
   1458 }
   1459 
   1460 GLuint GetDepthBits(GLenum internalFormat, GLuint clientVersion)
   1461 {
   1462     InternalFormatInfo internalFormatInfo;
   1463     if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
   1464     {
   1465         return internalFormatInfo.mDepthBits;
   1466     }
   1467     else
   1468     {
   1469         UNREACHABLE();
   1470         return 0;
   1471     }
   1472 }
   1473 
   1474 GLuint GetStencilBits(GLenum internalFormat, GLuint clientVersion)
   1475 {
   1476     InternalFormatInfo internalFormatInfo;
   1477     if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
   1478     {
   1479         return internalFormatInfo.mStencilBits;
   1480     }
   1481     else
   1482     {
   1483         UNREACHABLE();
   1484         return 0;
   1485     }
   1486 }
   1487 
   1488 GLuint GetTypeBytes(GLenum type)
   1489 {
   1490     TypeInfo typeInfo;
   1491     if (GetTypeInfo(type, &typeInfo))
   1492     {
   1493         return typeInfo.mTypeBytes;
   1494     }
   1495     else
   1496     {
   1497         UNREACHABLE();
   1498         return 0;
   1499     }
   1500 }
   1501 
   1502 bool IsSpecialInterpretationType(GLenum type)
   1503 {
   1504     TypeInfo typeInfo;
   1505     if (GetTypeInfo(type, &typeInfo))
   1506     {
   1507         return typeInfo.mSpecialInterpretation;
   1508     }
   1509     else
   1510     {
   1511         UNREACHABLE();
   1512         return false;
   1513     }
   1514 }
   1515 
   1516 bool IsFloatOrFixedComponentType(GLenum type)
   1517 {
   1518     if (type == GL_UNSIGNED_NORMALIZED ||
   1519         type == GL_SIGNED_NORMALIZED ||
   1520         type == GL_FLOAT)
   1521     {
   1522         return true;
   1523     }
   1524     else
   1525     {
   1526         return false;
   1527     }
   1528 }
   1529 
   1530 GLenum GetFormat(GLenum internalFormat, GLuint clientVersion)
   1531 {
   1532     InternalFormatInfo internalFormatInfo;
   1533     if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
   1534     {
   1535         return internalFormatInfo.mFormat;
   1536     }
   1537     else
   1538     {
   1539         UNREACHABLE();
   1540         return GL_NONE;
   1541     }
   1542 }
   1543 
   1544 GLenum GetType(GLenum internalFormat, GLuint clientVersion)
   1545 {
   1546     InternalFormatInfo internalFormatInfo;
   1547     if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
   1548     {
   1549         return internalFormatInfo.mType;
   1550     }
   1551     else
   1552     {
   1553         UNREACHABLE();
   1554         return GL_NONE;
   1555     }
   1556 }
   1557 
   1558 GLenum GetComponentType(GLenum internalFormat, GLuint clientVersion)
   1559 {
   1560     InternalFormatInfo internalFormatInfo;
   1561     if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
   1562     {
   1563         return internalFormatInfo.mComponentType;
   1564     }
   1565     else
   1566     {
   1567         UNREACHABLE();
   1568         return GL_NONE;
   1569     }
   1570 }
   1571 
   1572 GLuint GetComponentCount(GLenum internalFormat, GLuint clientVersion)
   1573 {
   1574     InternalFormatInfo internalFormatInfo;
   1575     if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
   1576     {
   1577         return internalFormatInfo.mComponentCount;
   1578     }
   1579     else
   1580     {
   1581         UNREACHABLE();
   1582         return false;
   1583     }
   1584 }
   1585 
   1586 GLenum GetColorEncoding(GLenum internalFormat, GLuint clientVersion)
   1587 {
   1588     InternalFormatInfo internalFormatInfo;
   1589     if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
   1590     {
   1591         return internalFormatInfo.mColorEncoding;
   1592     }
   1593     else
   1594     {
   1595         UNREACHABLE();
   1596         return false;
   1597     }
   1598 }
   1599 
   1600 bool IsColorRenderingSupported(GLenum internalFormat, const rx::Renderer *renderer)
   1601 {
   1602     InternalFormatInfo internalFormatInfo;
   1603     if (renderer && GetInternalFormatInfo(internalFormat, renderer->getCurrentClientVersion(), &internalFormatInfo))
   1604     {
   1605         return internalFormatInfo.mIsColorRenderable(NULL, renderer);
   1606     }
   1607     else
   1608     {
   1609         UNREACHABLE();
   1610         return false;
   1611     }
   1612 }
   1613 
   1614 bool IsColorRenderingSupported(GLenum internalFormat, const Context *context)
   1615 {
   1616     InternalFormatInfo internalFormatInfo;
   1617     if (context && GetInternalFormatInfo(internalFormat, context->getClientVersion(), &internalFormatInfo))
   1618     {
   1619         return internalFormatInfo.mIsColorRenderable(context, NULL);
   1620     }
   1621     else
   1622     {
   1623         UNREACHABLE();
   1624         return false;
   1625     }
   1626 }
   1627 
   1628 bool IsTextureFilteringSupported(GLenum internalFormat, const rx::Renderer *renderer)
   1629 {
   1630     InternalFormatInfo internalFormatInfo;
   1631     if (renderer && GetInternalFormatInfo(internalFormat, renderer->getCurrentClientVersion(), &internalFormatInfo))
   1632     {
   1633         return internalFormatInfo.mIsTextureFilterable(NULL, renderer);
   1634     }
   1635     else
   1636     {
   1637         UNREACHABLE();
   1638         return false;
   1639     }
   1640 }
   1641 
   1642 bool IsTextureFilteringSupported(GLenum internalFormat, const Context *context)
   1643 {
   1644     InternalFormatInfo internalFormatInfo;
   1645     if (context && GetInternalFormatInfo(internalFormat, context->getClientVersion(), &internalFormatInfo))
   1646     {
   1647         return internalFormatInfo.mIsTextureFilterable(context, NULL);
   1648     }
   1649     else
   1650     {
   1651         UNREACHABLE();
   1652         return false;
   1653     }
   1654 }
   1655 
   1656 bool IsDepthRenderingSupported(GLenum internalFormat, const rx::Renderer *renderer)
   1657 {
   1658     InternalFormatInfo internalFormatInfo;
   1659     if (renderer && GetInternalFormatInfo(internalFormat, renderer->getCurrentClientVersion(), &internalFormatInfo))
   1660     {
   1661         return internalFormatInfo.mIsDepthRenderable(NULL, renderer);
   1662     }
   1663     else
   1664     {
   1665         UNREACHABLE();
   1666         return false;
   1667     }
   1668 }
   1669 
   1670 bool IsDepthRenderingSupported(GLenum internalFormat, const Context *context)
   1671 {
   1672     InternalFormatInfo internalFormatInfo;
   1673     if (context && GetInternalFormatInfo(internalFormat, context->getClientVersion(), &internalFormatInfo))
   1674     {
   1675         return internalFormatInfo.mIsDepthRenderable(context, NULL);
   1676     }
   1677     else
   1678     {
   1679         UNREACHABLE();
   1680         return false;
   1681     }
   1682 }
   1683 
   1684 bool IsStencilRenderingSupported(GLenum internalFormat, const rx::Renderer *renderer)
   1685 {
   1686     InternalFormatInfo internalFormatInfo;
   1687     if (renderer && GetInternalFormatInfo(internalFormat, renderer->getCurrentClientVersion(), &internalFormatInfo))
   1688     {
   1689         return internalFormatInfo.mIsStencilRenderable(NULL, renderer);
   1690     }
   1691     else
   1692     {
   1693         UNREACHABLE();
   1694         return false;
   1695     }
   1696 }
   1697 
   1698 bool IsStencilRenderingSupported(GLenum internalFormat, const Context *context)
   1699 {
   1700     InternalFormatInfo internalFormatInfo;
   1701     if (context && GetInternalFormatInfo(internalFormat, context->getClientVersion(), &internalFormatInfo))
   1702     {
   1703         return internalFormatInfo.mIsStencilRenderable(context, NULL);
   1704     }
   1705     else
   1706     {
   1707         UNREACHABLE();
   1708         return false;
   1709     }
   1710 }
   1711 
   1712 GLuint GetRowPitch(GLenum internalFormat, GLenum type, GLuint clientVersion, GLsizei width, GLint alignment)
   1713 {
   1714     ASSERT(alignment > 0 && isPow2(alignment));
   1715     return rx::roundUp(GetBlockSize(internalFormat, type, clientVersion, width, 1), static_cast<GLuint>(alignment));
   1716 }
   1717 
   1718 GLuint GetDepthPitch(GLenum internalFormat, GLenum type, GLuint clientVersion, GLsizei width, GLsizei height, GLint alignment)
   1719 {
   1720     return GetRowPitch(internalFormat, type, clientVersion, width, alignment) * height;
   1721 }
   1722 
   1723 GLuint GetBlockSize(GLenum internalFormat, GLenum type, GLuint clientVersion, GLsizei width, GLsizei height)
   1724 {
   1725     InternalFormatInfo internalFormatInfo;
   1726     if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
   1727     {
   1728         if (internalFormatInfo.mIsCompressed)
   1729         {
   1730             GLsizei numBlocksWide = (width + internalFormatInfo.mCompressedBlockWidth - 1) / internalFormatInfo.mCompressedBlockWidth;
   1731             GLsizei numBlocksHight = (height + internalFormatInfo.mCompressedBlockHeight - 1) / internalFormatInfo.mCompressedBlockHeight;
   1732 
   1733             return (internalFormatInfo.mPixelBits * numBlocksWide * numBlocksHight) / 8;
   1734         }
   1735         else
   1736         {
   1737             TypeInfo typeInfo;
   1738             if (GetTypeInfo(type, &typeInfo))
   1739             {
   1740                 if (typeInfo.mSpecialInterpretation)
   1741                 {
   1742                     return typeInfo.mTypeBytes * width * height;
   1743                 }
   1744                 else
   1745                 {
   1746                     return internalFormatInfo.mComponentCount * typeInfo.mTypeBytes * width * height;
   1747                 }
   1748             }
   1749             else
   1750             {
   1751                 UNREACHABLE();
   1752                 return 0;
   1753             }
   1754         }
   1755     }
   1756     else
   1757     {
   1758         UNREACHABLE();
   1759         return 0;
   1760     }
   1761 }
   1762 
   1763 bool IsFormatCompressed(GLenum internalFormat, GLuint clientVersion)
   1764 {
   1765     InternalFormatInfo internalFormatInfo;
   1766     if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
   1767     {
   1768         return internalFormatInfo.mIsCompressed;
   1769     }
   1770     else
   1771     {
   1772         UNREACHABLE();
   1773         return false;
   1774     }
   1775 }
   1776 
   1777 GLuint GetCompressedBlockWidth(GLenum internalFormat, GLuint clientVersion)
   1778 {
   1779     InternalFormatInfo internalFormatInfo;
   1780     if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
   1781     {
   1782         return internalFormatInfo.mCompressedBlockWidth;
   1783     }
   1784     else
   1785     {
   1786         UNREACHABLE();
   1787         return 0;
   1788     }
   1789 }
   1790 
   1791 GLuint GetCompressedBlockHeight(GLenum internalFormat, GLuint clientVersion)
   1792 {
   1793     InternalFormatInfo internalFormatInfo;
   1794     if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
   1795     {
   1796         return internalFormatInfo.mCompressedBlockHeight;
   1797     }
   1798     else
   1799     {
   1800         UNREACHABLE();
   1801         return 0;
   1802     }
   1803 }
   1804 
   1805 ColorWriteFunction GetColorWriteFunction(GLenum format, GLenum type, GLuint clientVersion)
   1806 {
   1807     static const FormatMap &formats = GetFormatMap(clientVersion);
   1808     FormatMap::const_iterator iter = formats.find(FormatTypePair(format, type));
   1809     return (iter != formats.end()) ? iter->second.mColorWriteFunction : NULL;
   1810 }
   1811 
   1812 }
   1813