tor-browser

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

queryutils.cpp (153527B)


      1 //
      2 // Copyright 2016 The ANGLE Project Authors. All rights reserved.
      3 // Use of this source code is governed by a BSD-style license that can be
      4 // found in the LICENSE file.
      5 //
      6 
      7 // queryutils.cpp: Utilities for querying values from GL objects
      8 
      9 #include "libANGLE/queryutils.h"
     10 
     11 #include <algorithm>
     12 
     13 #include "common/utilities.h"
     14 
     15 #include "libANGLE/Buffer.h"
     16 #include "libANGLE/Config.h"
     17 #include "libANGLE/Context.h"
     18 #include "libANGLE/Display.h"
     19 #include "libANGLE/EGLSync.h"
     20 #include "libANGLE/Fence.h"
     21 #include "libANGLE/Framebuffer.h"
     22 #include "libANGLE/GLES1State.h"
     23 #include "libANGLE/MemoryObject.h"
     24 #include "libANGLE/Program.h"
     25 #include "libANGLE/Renderbuffer.h"
     26 #include "libANGLE/Sampler.h"
     27 #include "libANGLE/Shader.h"
     28 #include "libANGLE/Surface.h"
     29 #include "libANGLE/Texture.h"
     30 #include "libANGLE/Uniform.h"
     31 #include "libANGLE/VertexAttribute.h"
     32 #include "libANGLE/queryconversions.h"
     33 
     34 namespace gl
     35 {
     36 
     37 namespace
     38 {
     39 
     40 template <bool isPureInteger>
     41 ColorGeneric ConvertToColor(const GLfloat *params)
     42 {
     43    if (isPureInteger)
     44    {
     45        UNREACHABLE();
     46        return ColorGeneric(ColorI());
     47    }
     48    else
     49    {
     50        return ColorGeneric(ColorF::fromData(params));
     51    }
     52 }
     53 
     54 template <bool isPureInteger>
     55 ColorGeneric ConvertToColor(const GLint *params)
     56 {
     57    if (isPureInteger)
     58    {
     59        return ColorGeneric(ColorI(params[0], params[1], params[2], params[3]));
     60    }
     61    else
     62    {
     63        return ColorGeneric(ColorF(normalizedToFloat(params[0]), normalizedToFloat(params[1]),
     64                                   normalizedToFloat(params[2]), normalizedToFloat(params[3])));
     65    }
     66 }
     67 
     68 template <bool isPureInteger>
     69 ColorGeneric ConvertToColor(const GLuint *params)
     70 {
     71    if (isPureInteger)
     72    {
     73        return ColorGeneric(ColorUI(params[0], params[1], params[2], params[3]));
     74    }
     75    else
     76    {
     77        UNREACHABLE();
     78        return ColorGeneric(ColorF());
     79    }
     80 }
     81 
     82 template <bool isPureInteger>
     83 void ConvertFromColor(const ColorGeneric &color, GLfloat *outParams)
     84 {
     85    if (isPureInteger)
     86    {
     87        UNREACHABLE();
     88    }
     89    else
     90    {
     91        color.colorF.writeData(outParams);
     92    }
     93 }
     94 
     95 template <bool isPureInteger>
     96 void ConvertFromColor(const ColorGeneric &color, GLint *outParams)
     97 {
     98    if (isPureInteger)
     99    {
    100        outParams[0] = color.colorI.red;
    101        outParams[1] = color.colorI.green;
    102        outParams[2] = color.colorI.blue;
    103        outParams[3] = color.colorI.alpha;
    104    }
    105    else
    106    {
    107        outParams[0] = floatToNormalized<GLint>(color.colorF.red);
    108        outParams[1] = floatToNormalized<GLint>(color.colorF.green);
    109        outParams[2] = floatToNormalized<GLint>(color.colorF.blue);
    110        outParams[3] = floatToNormalized<GLint>(color.colorF.alpha);
    111    }
    112 }
    113 
    114 template <bool isPureInteger>
    115 void ConvertFromColor(const ColorGeneric &color, GLuint *outParams)
    116 {
    117    if (isPureInteger)
    118    {
    119        constexpr unsigned int kMinValue = 0;
    120 
    121        outParams[0] = std::max(color.colorUI.red, kMinValue);
    122        outParams[1] = std::max(color.colorUI.green, kMinValue);
    123        outParams[2] = std::max(color.colorUI.blue, kMinValue);
    124        outParams[3] = std::max(color.colorUI.alpha, kMinValue);
    125    }
    126    else
    127    {
    128        UNREACHABLE();
    129    }
    130 }
    131 
    132 template <typename ParamType>
    133 void QueryTexLevelParameterBase(const Texture *texture,
    134                                TextureTarget target,
    135                                GLint level,
    136                                GLenum pname,
    137                                ParamType *params)
    138 {
    139    ASSERT(texture != nullptr);
    140    const InternalFormat *info = texture->getTextureState().getImageDesc(target, level).format.info;
    141 
    142    switch (pname)
    143    {
    144        case GL_TEXTURE_RED_TYPE:
    145            *params = CastFromGLintStateValue<ParamType>(
    146                pname, info->redBits ? info->componentType : GL_NONE);
    147            break;
    148        case GL_TEXTURE_GREEN_TYPE:
    149            *params = CastFromGLintStateValue<ParamType>(
    150                pname, info->greenBits ? info->componentType : GL_NONE);
    151            break;
    152        case GL_TEXTURE_BLUE_TYPE:
    153            *params = CastFromGLintStateValue<ParamType>(
    154                pname, info->blueBits ? info->componentType : GL_NONE);
    155            break;
    156        case GL_TEXTURE_ALPHA_TYPE:
    157            *params = CastFromGLintStateValue<ParamType>(
    158                pname, info->alphaBits ? info->componentType : GL_NONE);
    159            break;
    160        case GL_TEXTURE_DEPTH_TYPE:
    161            *params = CastFromGLintStateValue<ParamType>(
    162                pname, info->depthBits ? info->componentType : GL_NONE);
    163            break;
    164        case GL_TEXTURE_RED_SIZE:
    165            *params = CastFromGLintStateValue<ParamType>(pname, info->redBits);
    166            break;
    167        case GL_TEXTURE_GREEN_SIZE:
    168            *params = CastFromGLintStateValue<ParamType>(pname, info->greenBits);
    169            break;
    170        case GL_TEXTURE_BLUE_SIZE:
    171            *params = CastFromGLintStateValue<ParamType>(pname, info->blueBits);
    172            break;
    173        case GL_TEXTURE_ALPHA_SIZE:
    174            *params = CastFromGLintStateValue<ParamType>(pname, info->alphaBits);
    175            break;
    176        case GL_TEXTURE_DEPTH_SIZE:
    177            *params = CastFromGLintStateValue<ParamType>(pname, info->depthBits);
    178            break;
    179        case GL_TEXTURE_STENCIL_SIZE:
    180            *params = CastFromGLintStateValue<ParamType>(pname, info->stencilBits);
    181            break;
    182        case GL_TEXTURE_SHARED_SIZE:
    183            *params = CastFromGLintStateValue<ParamType>(pname, info->sharedBits);
    184            break;
    185        case GL_TEXTURE_INTERNAL_FORMAT:
    186            *params = CastFromGLintStateValue<ParamType>(
    187                pname, info->internalFormat ? info->internalFormat : GL_RGBA);
    188            break;
    189        case GL_TEXTURE_WIDTH:
    190            *params = CastFromGLintStateValue<ParamType>(
    191                pname, static_cast<uint32_t>(texture->getWidth(target, level)));
    192            break;
    193        case GL_TEXTURE_HEIGHT:
    194            *params = CastFromGLintStateValue<ParamType>(
    195                pname, static_cast<uint32_t>(texture->getHeight(target, level)));
    196            break;
    197        case GL_TEXTURE_DEPTH:
    198            *params = CastFromGLintStateValue<ParamType>(
    199                pname, static_cast<uint32_t>(texture->getDepth(target, level)));
    200            break;
    201        case GL_TEXTURE_SAMPLES:
    202            *params = CastFromStateValue<ParamType>(pname, texture->getSamples(target, level));
    203            break;
    204        case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS:
    205            *params = CastFromStateValue<ParamType>(
    206                pname, static_cast<GLint>(texture->getFixedSampleLocations(target, level)));
    207            break;
    208        case GL_TEXTURE_COMPRESSED:
    209            *params = CastFromStateValue<ParamType>(pname, static_cast<GLint>(info->compressed));
    210            break;
    211        case GL_MEMORY_SIZE_ANGLE:
    212            *params =
    213                CastFromStateValue<ParamType>(pname, texture->getLevelMemorySize(target, level));
    214            break;
    215        case GL_RESOURCE_INITIALIZED_ANGLE:
    216            *params = CastFromGLintStateValue<ParamType>(
    217                pname, texture->initState(GL_NONE, ImageIndex::MakeFromTarget(target, level)) ==
    218                           InitState::Initialized);
    219            break;
    220        case GL_TEXTURE_BUFFER_DATA_STORE_BINDING:
    221            *params = CastFromStateValue<ParamType>(
    222                pname, static_cast<GLint>(texture->getBuffer().id().value));
    223            break;
    224        case GL_TEXTURE_BUFFER_OFFSET:
    225            *params = CastFromStateValue<ParamType>(
    226                pname, static_cast<GLint>(texture->getBuffer().getOffset()));
    227            break;
    228        case GL_TEXTURE_BUFFER_SIZE:
    229            *params = CastFromStateValue<ParamType>(
    230                pname, static_cast<GLint>(GetBoundBufferAvailableSize(texture->getBuffer())));
    231            break;
    232        default:
    233            UNREACHABLE();
    234            break;
    235    }
    236 }
    237 
    238 // This function is needed to handle fixed_point data.
    239 // It can be used when some pname need special conversion from int/float/bool to fixed_point.
    240 template <bool isGLfixed, typename QueryT, typename ParamType>
    241 QueryT CastFromSpecialValue(GLenum pname, const ParamType param)
    242 {
    243    if (isGLfixed)
    244    {
    245        return static_cast<QueryT>(ConvertFloatToFixed(CastFromStateValue<GLfloat>(pname, param)));
    246    }
    247    else
    248    {
    249        return CastFromStateValue<QueryT>(pname, param);
    250    }
    251 }
    252 
    253 template <bool isPureInteger, bool isGLfixed, typename ParamType>
    254 void QueryTexParameterBase(const Context *context,
    255                           const Texture *texture,
    256                           GLenum pname,
    257                           ParamType *params)
    258 {
    259    ASSERT(texture != nullptr);
    260 
    261    switch (pname)
    262    {
    263        case GL_TEXTURE_MAG_FILTER:
    264            *params = CastFromGLintStateValue<ParamType>(pname, texture->getMagFilter());
    265            break;
    266        case GL_TEXTURE_MIN_FILTER:
    267            *params = CastFromGLintStateValue<ParamType>(pname, texture->getMinFilter());
    268            break;
    269        case GL_TEXTURE_WRAP_S:
    270            *params = CastFromGLintStateValue<ParamType>(pname, texture->getWrapS());
    271            break;
    272        case GL_TEXTURE_WRAP_T:
    273            *params = CastFromGLintStateValue<ParamType>(pname, texture->getWrapT());
    274            break;
    275        case GL_TEXTURE_WRAP_R:
    276            *params = CastFromGLintStateValue<ParamType>(pname, texture->getWrapR());
    277            break;
    278        case GL_TEXTURE_IMMUTABLE_FORMAT:
    279            *params = CastFromGLintStateValue<ParamType>(pname, texture->getImmutableFormat());
    280            break;
    281        case GL_TEXTURE_IMMUTABLE_LEVELS:
    282            *params = CastFromGLintStateValue<ParamType>(pname, texture->getImmutableLevels());
    283            break;
    284        case GL_TEXTURE_USAGE_ANGLE:
    285            *params = CastFromGLintStateValue<ParamType>(pname, texture->getUsage());
    286            break;
    287        case GL_TEXTURE_MAX_ANISOTROPY_EXT:
    288            *params =
    289                CastFromSpecialValue<isGLfixed, ParamType>(pname, texture->getMaxAnisotropy());
    290            break;
    291        case GL_TEXTURE_SWIZZLE_R:
    292            *params = CastFromGLintStateValue<ParamType>(pname, texture->getSwizzleRed());
    293            break;
    294        case GL_TEXTURE_SWIZZLE_G:
    295            *params = CastFromGLintStateValue<ParamType>(pname, texture->getSwizzleGreen());
    296            break;
    297        case GL_TEXTURE_SWIZZLE_B:
    298            *params = CastFromGLintStateValue<ParamType>(pname, texture->getSwizzleBlue());
    299            break;
    300        case GL_TEXTURE_SWIZZLE_A:
    301            *params = CastFromGLintStateValue<ParamType>(pname, texture->getSwizzleAlpha());
    302            break;
    303        case GL_TEXTURE_BASE_LEVEL:
    304            *params = CastFromGLintStateValue<ParamType>(pname, texture->getBaseLevel());
    305            break;
    306        case GL_TEXTURE_MAX_LEVEL:
    307            *params = CastFromGLintStateValue<ParamType>(pname, texture->getMaxLevel());
    308            break;
    309        case GL_TEXTURE_MIN_LOD:
    310            *params = CastFromSpecialValue<isGLfixed, ParamType>(pname, texture->getMinLod());
    311            break;
    312        case GL_TEXTURE_MAX_LOD:
    313            *params = CastFromSpecialValue<isGLfixed, ParamType>(pname, texture->getMaxLod());
    314            break;
    315        case GL_TEXTURE_COMPARE_MODE:
    316            *params = CastFromGLintStateValue<ParamType>(pname, texture->getCompareMode());
    317            break;
    318        case GL_TEXTURE_COMPARE_FUNC:
    319            *params = CastFromGLintStateValue<ParamType>(pname, texture->getCompareFunc());
    320            break;
    321        case GL_TEXTURE_SRGB_DECODE_EXT:
    322            *params = CastFromGLintStateValue<ParamType>(pname, texture->getSRGBDecode());
    323            break;
    324        case GL_TEXTURE_FORMAT_SRGB_OVERRIDE_EXT:
    325            *params = CastFromGLintStateValue<ParamType>(pname, texture->getSRGBOverride());
    326            break;
    327        case GL_DEPTH_STENCIL_TEXTURE_MODE:
    328            *params =
    329                CastFromGLintStateValue<ParamType>(pname, texture->getDepthStencilTextureMode());
    330            break;
    331        case GL_TEXTURE_CROP_RECT_OES:
    332        {
    333            const gl::Rectangle &crop = texture->getCrop();
    334            params[0]                 = CastFromSpecialValue<isGLfixed, ParamType>(pname, crop.x);
    335            params[1]                 = CastFromSpecialValue<isGLfixed, ParamType>(pname, crop.y);
    336            params[2] = CastFromSpecialValue<isGLfixed, ParamType>(pname, crop.width);
    337            params[3] = CastFromSpecialValue<isGLfixed, ParamType>(pname, crop.height);
    338            break;
    339        }
    340        case GL_GENERATE_MIPMAP:
    341            *params = CastFromGLintStateValue<ParamType>(pname, texture->getGenerateMipmapHint());
    342            break;
    343        case GL_MEMORY_SIZE_ANGLE:
    344            *params = CastFromSpecialValue<isGLfixed, ParamType>(pname, texture->getMemorySize());
    345            break;
    346        case GL_TEXTURE_BORDER_COLOR:
    347            ConvertFromColor<isPureInteger>(texture->getBorderColor(), params);
    348            break;
    349        case GL_TEXTURE_NATIVE_ID_ANGLE:
    350            *params = CastFromSpecialValue<isGLfixed, ParamType>(pname, texture->getNativeID());
    351            break;
    352        case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
    353            *params = CastFromGLintStateValue<ParamType>(
    354                pname, texture->getImplementationColorReadFormat(context));
    355            break;
    356        case GL_IMPLEMENTATION_COLOR_READ_TYPE:
    357            *params = CastFromGLintStateValue<ParamType>(
    358                pname, texture->getImplementationColorReadType(context));
    359            break;
    360        case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE:
    361            *params =
    362                CastFromGLintStateValue<ParamType>(pname, GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE);
    363            break;
    364        case GL_RESOURCE_INITIALIZED_ANGLE:
    365            *params = CastFromGLintStateValue<ParamType>(
    366                pname, texture->initState() == InitState::Initialized);
    367            break;
    368        case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
    369            *params = CastFromGLintStateValue<ParamType>(
    370                pname, texture->getRequiredTextureImageUnits(context));
    371            break;
    372        case GL_TEXTURE_PROTECTED_EXT:
    373            *params = CastFromGLintStateValue<ParamType>(pname, texture->hasProtectedContent());
    374            break;
    375        default:
    376            UNREACHABLE();
    377            break;
    378    }
    379 }
    380 
    381 // this function is needed to handle OES_FIXED_POINT.
    382 // Some pname values can take in GLfixed values and may need to be converted
    383 template <bool isGLfixed, typename ReturnType, typename ParamType>
    384 ReturnType ConvertTexParam(GLenum pname, const ParamType param)
    385 {
    386    if (isGLfixed)
    387    {
    388        return CastQueryValueTo<ReturnType>(pname,
    389                                            ConvertFixedToFloat(static_cast<GLfixed>(param)));
    390    }
    391    else
    392    {
    393        return CastQueryValueTo<ReturnType>(pname, param);
    394    }
    395 }
    396 
    397 template <bool isPureInteger, bool isGLfixed, typename ParamType>
    398 void SetTexParameterBase(Context *context, Texture *texture, GLenum pname, const ParamType *params)
    399 {
    400    ASSERT(texture != nullptr);
    401 
    402    switch (pname)
    403    {
    404        case GL_TEXTURE_WRAP_S:
    405            texture->setWrapS(context, ConvertToGLenum(pname, params[0]));
    406            break;
    407        case GL_TEXTURE_WRAP_T:
    408            texture->setWrapT(context, ConvertToGLenum(pname, params[0]));
    409            break;
    410        case GL_TEXTURE_WRAP_R:
    411            texture->setWrapR(context, ConvertToGLenum(pname, params[0]));
    412            break;
    413        case GL_TEXTURE_MIN_FILTER:
    414            texture->setMinFilter(context, ConvertToGLenum(pname, params[0]));
    415            break;
    416        case GL_TEXTURE_MAG_FILTER:
    417            texture->setMagFilter(context, ConvertToGLenum(pname, params[0]));
    418            break;
    419        case GL_TEXTURE_USAGE_ANGLE:
    420            texture->setUsage(context, ConvertToGLenum(pname, params[0]));
    421            break;
    422        case GL_TEXTURE_MAX_ANISOTROPY_EXT:
    423            texture->setMaxAnisotropy(context,
    424                                      ConvertTexParam<isGLfixed, GLfloat>(pname, params[0]));
    425            break;
    426        case GL_TEXTURE_COMPARE_MODE:
    427            texture->setCompareMode(context, ConvertToGLenum(pname, params[0]));
    428            break;
    429        case GL_TEXTURE_COMPARE_FUNC:
    430            texture->setCompareFunc(context, ConvertToGLenum(pname, params[0]));
    431            break;
    432        case GL_TEXTURE_SWIZZLE_R:
    433            texture->setSwizzleRed(context, ConvertToGLenum(pname, params[0]));
    434            break;
    435        case GL_TEXTURE_SWIZZLE_G:
    436            texture->setSwizzleGreen(context, ConvertToGLenum(pname, params[0]));
    437            break;
    438        case GL_TEXTURE_SWIZZLE_B:
    439            texture->setSwizzleBlue(context, ConvertToGLenum(pname, params[0]));
    440            break;
    441        case GL_TEXTURE_SWIZZLE_A:
    442            texture->setSwizzleAlpha(context, ConvertToGLenum(pname, params[0]));
    443            break;
    444        case GL_TEXTURE_BASE_LEVEL:
    445        {
    446            (void)(texture->setBaseLevel(
    447                context, clampCast<GLuint>(CastQueryValueTo<GLint>(pname, params[0]))));
    448            break;
    449        }
    450        case GL_TEXTURE_MAX_LEVEL:
    451            texture->setMaxLevel(context,
    452                                 clampCast<GLuint>(CastQueryValueTo<GLint>(pname, params[0])));
    453            break;
    454        case GL_TEXTURE_MIN_LOD:
    455            texture->setMinLod(context, CastQueryValueTo<GLfloat>(pname, params[0]));
    456            break;
    457        case GL_TEXTURE_MAX_LOD:
    458            texture->setMaxLod(context, CastQueryValueTo<GLfloat>(pname, params[0]));
    459            break;
    460        case GL_DEPTH_STENCIL_TEXTURE_MODE:
    461            texture->setDepthStencilTextureMode(context, ConvertToGLenum(pname, params[0]));
    462            break;
    463        case GL_TEXTURE_SRGB_DECODE_EXT:
    464            texture->setSRGBDecode(context, ConvertToGLenum(pname, params[0]));
    465            break;
    466        case GL_TEXTURE_FORMAT_SRGB_OVERRIDE_EXT:
    467            texture->setSRGBOverride(context, ConvertToGLenum(pname, params[0]));
    468            break;
    469        case GL_TEXTURE_CROP_RECT_OES:
    470            texture->setCrop(gl::Rectangle(ConvertTexParam<isGLfixed, GLint>(pname, params[0]),
    471                                           ConvertTexParam<isGLfixed, GLint>(pname, params[1]),
    472                                           ConvertTexParam<isGLfixed, GLint>(pname, params[2]),
    473                                           ConvertTexParam<isGLfixed, GLint>(pname, params[3])));
    474            break;
    475        case GL_GENERATE_MIPMAP:
    476            texture->setGenerateMipmapHint(ConvertToGLenum(params[0]));
    477            break;
    478        case GL_TEXTURE_BORDER_COLOR:
    479            texture->setBorderColor(context, ConvertToColor<isPureInteger>(params));
    480            break;
    481        case GL_RESOURCE_INITIALIZED_ANGLE:
    482            texture->setInitState(ConvertToBool(params[0]) ? InitState::Initialized
    483                                                           : InitState::MayNeedInit);
    484            break;
    485        case GL_TEXTURE_PROTECTED_EXT:
    486            texture->setProtectedContent(context, (params[0] == GL_TRUE));
    487            break;
    488        default:
    489            UNREACHABLE();
    490            break;
    491    }
    492 }
    493 
    494 template <bool isPureInteger, typename ParamType>
    495 void QuerySamplerParameterBase(const Sampler *sampler, GLenum pname, ParamType *params)
    496 {
    497    switch (pname)
    498    {
    499        case GL_TEXTURE_MIN_FILTER:
    500            *params = CastFromGLintStateValue<ParamType>(pname, sampler->getMinFilter());
    501            break;
    502        case GL_TEXTURE_MAG_FILTER:
    503            *params = CastFromGLintStateValue<ParamType>(pname, sampler->getMagFilter());
    504            break;
    505        case GL_TEXTURE_WRAP_S:
    506            *params = CastFromGLintStateValue<ParamType>(pname, sampler->getWrapS());
    507            break;
    508        case GL_TEXTURE_WRAP_T:
    509            *params = CastFromGLintStateValue<ParamType>(pname, sampler->getWrapT());
    510            break;
    511        case GL_TEXTURE_WRAP_R:
    512            *params = CastFromGLintStateValue<ParamType>(pname, sampler->getWrapR());
    513            break;
    514        case GL_TEXTURE_MAX_ANISOTROPY_EXT:
    515            *params = CastFromStateValue<ParamType>(pname, sampler->getMaxAnisotropy());
    516            break;
    517        case GL_TEXTURE_MIN_LOD:
    518            *params = CastFromStateValue<ParamType>(pname, sampler->getMinLod());
    519            break;
    520        case GL_TEXTURE_MAX_LOD:
    521            *params = CastFromStateValue<ParamType>(pname, sampler->getMaxLod());
    522            break;
    523        case GL_TEXTURE_COMPARE_MODE:
    524            *params = CastFromGLintStateValue<ParamType>(pname, sampler->getCompareMode());
    525            break;
    526        case GL_TEXTURE_COMPARE_FUNC:
    527            *params = CastFromGLintStateValue<ParamType>(pname, sampler->getCompareFunc());
    528            break;
    529        case GL_TEXTURE_SRGB_DECODE_EXT:
    530            *params = CastFromGLintStateValue<ParamType>(pname, sampler->getSRGBDecode());
    531            break;
    532        case GL_TEXTURE_BORDER_COLOR:
    533            ConvertFromColor<isPureInteger>(sampler->getBorderColor(), params);
    534            break;
    535        default:
    536            UNREACHABLE();
    537            break;
    538    }
    539 }
    540 
    541 template <bool isPureInteger, typename ParamType>
    542 void SetSamplerParameterBase(Context *context,
    543                             Sampler *sampler,
    544                             GLenum pname,
    545                             const ParamType *params)
    546 {
    547    switch (pname)
    548    {
    549        case GL_TEXTURE_WRAP_S:
    550            sampler->setWrapS(context, ConvertToGLenum(pname, params[0]));
    551            break;
    552        case GL_TEXTURE_WRAP_T:
    553            sampler->setWrapT(context, ConvertToGLenum(pname, params[0]));
    554            break;
    555        case GL_TEXTURE_WRAP_R:
    556            sampler->setWrapR(context, ConvertToGLenum(pname, params[0]));
    557            break;
    558        case GL_TEXTURE_MIN_FILTER:
    559            sampler->setMinFilter(context, ConvertToGLenum(pname, params[0]));
    560            break;
    561        case GL_TEXTURE_MAG_FILTER:
    562            sampler->setMagFilter(context, ConvertToGLenum(pname, params[0]));
    563            break;
    564        case GL_TEXTURE_MAX_ANISOTROPY_EXT:
    565            sampler->setMaxAnisotropy(context, CastQueryValueTo<GLfloat>(pname, params[0]));
    566            break;
    567        case GL_TEXTURE_COMPARE_MODE:
    568            sampler->setCompareMode(context, ConvertToGLenum(pname, params[0]));
    569            break;
    570        case GL_TEXTURE_COMPARE_FUNC:
    571            sampler->setCompareFunc(context, ConvertToGLenum(pname, params[0]));
    572            break;
    573        case GL_TEXTURE_MIN_LOD:
    574            sampler->setMinLod(context, CastQueryValueTo<GLfloat>(pname, params[0]));
    575            break;
    576        case GL_TEXTURE_MAX_LOD:
    577            sampler->setMaxLod(context, CastQueryValueTo<GLfloat>(pname, params[0]));
    578            break;
    579        case GL_TEXTURE_SRGB_DECODE_EXT:
    580            sampler->setSRGBDecode(context, ConvertToGLenum(pname, params[0]));
    581            break;
    582        case GL_TEXTURE_BORDER_COLOR:
    583            sampler->setBorderColor(context, ConvertToColor<isPureInteger>(params));
    584            break;
    585        default:
    586            UNREACHABLE();
    587            break;
    588    }
    589 
    590    sampler->onStateChange(angle::SubjectMessage::ContentsChanged);
    591 }
    592 
    593 // Warning: you should ensure binding really matches attrib.bindingIndex before using this function.
    594 template <typename ParamType, typename CurrentDataType, size_t CurrentValueCount>
    595 void QueryVertexAttribBase(const VertexAttribute &attrib,
    596                           const VertexBinding &binding,
    597                           const CurrentDataType (&currentValueData)[CurrentValueCount],
    598                           GLenum pname,
    599                           ParamType *params)
    600 {
    601    switch (pname)
    602    {
    603        case GL_CURRENT_VERTEX_ATTRIB:
    604            for (size_t i = 0; i < CurrentValueCount; ++i)
    605            {
    606                params[i] = CastFromStateValue<ParamType>(pname, currentValueData[i]);
    607            }
    608            break;
    609        case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
    610            *params = CastFromStateValue<ParamType>(pname, static_cast<GLint>(attrib.enabled));
    611            break;
    612        case GL_VERTEX_ATTRIB_ARRAY_SIZE:
    613            *params = CastFromGLintStateValue<ParamType>(pname, attrib.format->channelCount);
    614            break;
    615        case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
    616            *params = CastFromGLintStateValue<ParamType>(pname, attrib.vertexAttribArrayStride);
    617            break;
    618        case GL_VERTEX_ATTRIB_ARRAY_TYPE:
    619            *params = CastFromGLintStateValue<ParamType>(
    620                pname, gl::ToGLenum(attrib.format->vertexAttribType));
    621            break;
    622        case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
    623            *params =
    624                CastFromStateValue<ParamType>(pname, static_cast<GLint>(attrib.format->isNorm()));
    625            break;
    626        case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
    627            *params = CastFromGLintStateValue<ParamType>(pname, binding.getBuffer().id().value);
    628            break;
    629        case GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
    630            *params = CastFromStateValue<ParamType>(pname, binding.getDivisor());
    631            break;
    632        case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
    633            *params = CastFromGLintStateValue<ParamType>(pname, attrib.format->isPureInt());
    634            break;
    635        case GL_VERTEX_ATTRIB_BINDING:
    636            *params = CastFromGLintStateValue<ParamType>(pname, attrib.bindingIndex);
    637            break;
    638        case GL_VERTEX_ATTRIB_RELATIVE_OFFSET:
    639            *params = CastFromGLintStateValue<ParamType>(pname, attrib.relativeOffset);
    640            break;
    641        default:
    642            UNREACHABLE();
    643            break;
    644    }
    645 }
    646 
    647 template <typename ParamType>
    648 void QueryBufferParameterBase(const Buffer *buffer, GLenum pname, ParamType *params)
    649 {
    650    ASSERT(buffer != nullptr);
    651 
    652    switch (pname)
    653    {
    654        case GL_BUFFER_USAGE:
    655            *params = CastFromGLintStateValue<ParamType>(pname, ToGLenum(buffer->getUsage()));
    656            break;
    657        case GL_BUFFER_SIZE:
    658            *params = CastFromStateValue<ParamType>(pname, buffer->getSize());
    659            break;
    660        case GL_BUFFER_ACCESS_FLAGS:
    661            *params = CastFromGLintStateValue<ParamType>(pname, buffer->getAccessFlags());
    662            break;
    663        case GL_BUFFER_ACCESS_OES:
    664            *params = CastFromGLintStateValue<ParamType>(pname, buffer->getAccess());
    665            break;
    666        case GL_BUFFER_MAPPED:
    667            *params = CastFromStateValue<ParamType>(pname, buffer->isMapped());
    668            break;
    669        case GL_BUFFER_MAP_OFFSET:
    670            *params = CastFromStateValue<ParamType>(pname, buffer->getMapOffset());
    671            break;
    672        case GL_BUFFER_MAP_LENGTH:
    673            *params = CastFromStateValue<ParamType>(pname, buffer->getMapLength());
    674            break;
    675        case GL_MEMORY_SIZE_ANGLE:
    676            *params = CastFromStateValue<ParamType>(pname, buffer->getMemorySize());
    677            break;
    678        case GL_BUFFER_IMMUTABLE_STORAGE_EXT:
    679            *params = CastFromStateValue<ParamType>(pname, buffer->isImmutable());
    680            break;
    681        case GL_BUFFER_STORAGE_FLAGS_EXT:
    682            *params = CastFromGLintStateValue<ParamType>(pname, buffer->getStorageExtUsageFlags());
    683            break;
    684        case GL_RESOURCE_INITIALIZED_ANGLE:
    685            *params = CastFromStateValue<ParamType>(
    686                pname, ConvertToGLBoolean(buffer->initState() == InitState::Initialized));
    687            break;
    688        default:
    689            UNREACHABLE();
    690            break;
    691    }
    692 }
    693 
    694 GLint GetCommonVariableProperty(const sh::ShaderVariable &var, GLenum prop)
    695 {
    696    switch (prop)
    697    {
    698        case GL_TYPE:
    699            return clampCast<GLint>(var.type);
    700 
    701        case GL_ARRAY_SIZE:
    702            // Queryable variables are guaranteed not to be arrays of arrays or arrays of structs,
    703            // see GLES 3.1 spec section 7.3.1.1 page 77.
    704            return clampCast<GLint>(var.getBasicTypeElementCount());
    705 
    706        case GL_NAME_LENGTH:
    707            // ES31 spec p84: This counts the terminating null char.
    708            return clampCast<GLint>(var.name.size() + 1u);
    709 
    710        default:
    711            UNREACHABLE();
    712            return GL_INVALID_VALUE;
    713    }
    714 }
    715 
    716 GLint GetInputResourceProperty(const Program *program, GLuint index, GLenum prop)
    717 {
    718    const sh::ShaderVariable &variable = program->getInputResource(index);
    719 
    720    switch (prop)
    721    {
    722        case GL_TYPE:
    723        case GL_ARRAY_SIZE:
    724            return GetCommonVariableProperty(variable, prop);
    725 
    726        case GL_NAME_LENGTH:
    727            return clampCast<GLint>(program->getInputResourceName(index).size() + 1u);
    728 
    729        case GL_LOCATION:
    730            return variable.isBuiltIn() ? GL_INVALID_INDEX : variable.location;
    731 
    732        // The query is targeted at the set of active input variables used by the first shader stage
    733        // of program. If program contains multiple shader stages then input variables from any
    734        // stage other than the first will not be enumerated. Since we found the variable to get
    735        // this far, we know it exists in the first attached shader stage.
    736        case GL_REFERENCED_BY_VERTEX_SHADER:
    737            return program->getState().getFirstAttachedShaderStageType() == ShaderType::Vertex;
    738        case GL_REFERENCED_BY_FRAGMENT_SHADER:
    739            return program->getState().getFirstAttachedShaderStageType() == ShaderType::Fragment;
    740        case GL_REFERENCED_BY_COMPUTE_SHADER:
    741            return program->getState().getFirstAttachedShaderStageType() == ShaderType::Compute;
    742        case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
    743            return program->getState().getFirstAttachedShaderStageType() == ShaderType::Geometry;
    744        case GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT:
    745            return program->getState().getFirstAttachedShaderStageType() == ShaderType::TessControl;
    746        case GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT:
    747            return program->getState().getFirstAttachedShaderStageType() ==
    748                   ShaderType::TessEvaluation;
    749        case GL_IS_PER_PATCH_EXT:
    750            return variable.isPatch;
    751 
    752        default:
    753            UNREACHABLE();
    754            return GL_INVALID_VALUE;
    755    }
    756 }
    757 
    758 GLint GetOutputResourceProperty(const Program *program, GLuint index, const GLenum prop)
    759 {
    760    const sh::ShaderVariable &outputVariable = program->getOutputResource(index);
    761 
    762    switch (prop)
    763    {
    764        case GL_TYPE:
    765        case GL_ARRAY_SIZE:
    766            return GetCommonVariableProperty(outputVariable, prop);
    767 
    768        case GL_NAME_LENGTH:
    769            return clampCast<GLint>(program->getOutputResourceName(index).size() + 1u);
    770 
    771        case GL_LOCATION:
    772            return outputVariable.location;
    773 
    774        case GL_LOCATION_INDEX_EXT:
    775            // EXT_blend_func_extended
    776            if (program->getState().getLastAttachedShaderStageType() == gl::ShaderType::Fragment)
    777            {
    778                return program->getFragDataIndex(outputVariable.name);
    779            }
    780            return GL_INVALID_INDEX;
    781 
    782        // The set of active user-defined outputs from the final shader stage in this program. If
    783        // the final stage is a Fragment Shader, then this represents the fragment outputs that get
    784        // written to individual color buffers. If the program only contains a Compute Shader, then
    785        // there are no user-defined outputs.
    786        case GL_REFERENCED_BY_VERTEX_SHADER:
    787            return program->getState().getLastAttachedShaderStageType() == ShaderType::Vertex;
    788        case GL_REFERENCED_BY_FRAGMENT_SHADER:
    789            return program->getState().getLastAttachedShaderStageType() == ShaderType::Fragment;
    790        case GL_REFERENCED_BY_COMPUTE_SHADER:
    791            return program->getState().getLastAttachedShaderStageType() == ShaderType::Compute;
    792        case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
    793            return program->getState().getLastAttachedShaderStageType() == ShaderType::Geometry;
    794        case GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT:
    795            return program->getState().getLastAttachedShaderStageType() == ShaderType::TessControl;
    796        case GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT:
    797            return program->getState().getLastAttachedShaderStageType() ==
    798                   ShaderType::TessEvaluation;
    799        case GL_IS_PER_PATCH_EXT:
    800            return outputVariable.isPatch;
    801 
    802        default:
    803            UNREACHABLE();
    804            return GL_INVALID_VALUE;
    805    }
    806 }
    807 
    808 GLint GetTransformFeedbackVaryingResourceProperty(const Program *program,
    809                                                  GLuint index,
    810                                                  const GLenum prop)
    811 {
    812    const auto &tfVariable = program->getTransformFeedbackVaryingResource(index);
    813    switch (prop)
    814    {
    815        case GL_TYPE:
    816            return clampCast<GLint>(tfVariable.type);
    817 
    818        case GL_ARRAY_SIZE:
    819            return clampCast<GLint>(tfVariable.size());
    820 
    821        case GL_NAME_LENGTH:
    822            return clampCast<GLint>(tfVariable.nameWithArrayIndex().size() + 1);
    823 
    824        default:
    825            UNREACHABLE();
    826            return GL_INVALID_VALUE;
    827    }
    828 }
    829 
    830 GLint QueryProgramInterfaceActiveResources(const Program *program, GLenum programInterface)
    831 {
    832    switch (programInterface)
    833    {
    834        case GL_PROGRAM_INPUT:
    835            return clampCast<GLint>(program->getState().getProgramInputs().size());
    836 
    837        case GL_PROGRAM_OUTPUT:
    838            return clampCast<GLint>(program->getState().getOutputVariables().size());
    839 
    840        case GL_UNIFORM:
    841            return clampCast<GLint>(program->getState().getUniforms().size());
    842 
    843        case GL_UNIFORM_BLOCK:
    844            return clampCast<GLint>(program->getState().getUniformBlocks().size());
    845 
    846        case GL_ATOMIC_COUNTER_BUFFER:
    847            return clampCast<GLint>(program->getState().getAtomicCounterBuffers().size());
    848 
    849        case GL_BUFFER_VARIABLE:
    850            return clampCast<GLint>(program->getState().getBufferVariables().size());
    851 
    852        case GL_SHADER_STORAGE_BLOCK:
    853            return clampCast<GLint>(program->getState().getShaderStorageBlocks().size());
    854 
    855        case GL_TRANSFORM_FEEDBACK_VARYING:
    856            return clampCast<GLint>(program->getTransformFeedbackVaryingCount());
    857 
    858        default:
    859            UNREACHABLE();
    860            return 0;
    861    }
    862 }
    863 
    864 template <typename T, typename M>
    865 GLint FindMaxSize(const std::vector<T> &resources, M member)
    866 {
    867    GLint max = 0;
    868    for (const T &resource : resources)
    869    {
    870        max = std::max(max, clampCast<GLint>((resource.*member).size()));
    871    }
    872    return max;
    873 }
    874 
    875 GLint QueryProgramInterfaceMaxNameLength(const Program *program, GLenum programInterface)
    876 {
    877    GLint maxNameLength = 0;
    878    switch (programInterface)
    879    {
    880        case GL_PROGRAM_INPUT:
    881            maxNameLength = program->getInputResourceMaxNameSize();
    882            break;
    883 
    884        case GL_PROGRAM_OUTPUT:
    885            maxNameLength = program->getOutputResourceMaxNameSize();
    886            break;
    887 
    888        case GL_UNIFORM:
    889            maxNameLength = FindMaxSize(program->getState().getUniforms(), &LinkedUniform::name);
    890            break;
    891 
    892        case GL_UNIFORM_BLOCK:
    893            return program->getActiveUniformBlockMaxNameLength();
    894 
    895        case GL_BUFFER_VARIABLE:
    896            maxNameLength =
    897                FindMaxSize(program->getState().getBufferVariables(), &BufferVariable::name);
    898            break;
    899 
    900        case GL_SHADER_STORAGE_BLOCK:
    901            return program->getActiveShaderStorageBlockMaxNameLength();
    902 
    903        case GL_TRANSFORM_FEEDBACK_VARYING:
    904            return clampCast<GLint>(program->getTransformFeedbackVaryingMaxLength());
    905 
    906        default:
    907            UNREACHABLE();
    908            return 0;
    909    }
    910    // This length includes an extra character for the null terminator.
    911    return (maxNameLength == 0 ? 0 : maxNameLength + 1);
    912 }
    913 
    914 GLint QueryProgramInterfaceMaxNumActiveVariables(const Program *program, GLenum programInterface)
    915 {
    916    switch (programInterface)
    917    {
    918        case GL_UNIFORM_BLOCK:
    919            return FindMaxSize(program->getState().getUniformBlocks(),
    920                               &InterfaceBlock::memberIndexes);
    921        case GL_ATOMIC_COUNTER_BUFFER:
    922            return FindMaxSize(program->getState().getAtomicCounterBuffers(),
    923                               &AtomicCounterBuffer::memberIndexes);
    924 
    925        case GL_SHADER_STORAGE_BLOCK:
    926            return FindMaxSize(program->getState().getShaderStorageBlocks(),
    927                               &InterfaceBlock::memberIndexes);
    928 
    929        default:
    930            UNREACHABLE();
    931            return 0;
    932    }
    933 }
    934 
    935 GLenum GetUniformPropertyEnum(GLenum prop)
    936 {
    937    switch (prop)
    938    {
    939        case GL_UNIFORM_TYPE:
    940            return GL_TYPE;
    941        case GL_UNIFORM_SIZE:
    942            return GL_ARRAY_SIZE;
    943        case GL_UNIFORM_NAME_LENGTH:
    944            return GL_NAME_LENGTH;
    945        case GL_UNIFORM_BLOCK_INDEX:
    946            return GL_BLOCK_INDEX;
    947        case GL_UNIFORM_OFFSET:
    948            return GL_OFFSET;
    949        case GL_UNIFORM_ARRAY_STRIDE:
    950            return GL_ARRAY_STRIDE;
    951        case GL_UNIFORM_MATRIX_STRIDE:
    952            return GL_MATRIX_STRIDE;
    953        case GL_UNIFORM_IS_ROW_MAJOR:
    954            return GL_IS_ROW_MAJOR;
    955 
    956        default:
    957            return prop;
    958    }
    959 }
    960 
    961 GLenum GetUniformBlockPropertyEnum(GLenum prop)
    962 {
    963    switch (prop)
    964    {
    965        case GL_UNIFORM_BLOCK_BINDING:
    966            return GL_BUFFER_BINDING;
    967 
    968        case GL_UNIFORM_BLOCK_DATA_SIZE:
    969            return GL_BUFFER_DATA_SIZE;
    970 
    971        case GL_UNIFORM_BLOCK_NAME_LENGTH:
    972            return GL_NAME_LENGTH;
    973 
    974        case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
    975            return GL_NUM_ACTIVE_VARIABLES;
    976 
    977        case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
    978            return GL_ACTIVE_VARIABLES;
    979 
    980        case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
    981            return GL_REFERENCED_BY_VERTEX_SHADER;
    982 
    983        case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
    984            return GL_REFERENCED_BY_FRAGMENT_SHADER;
    985 
    986        default:
    987            return prop;
    988    }
    989 }
    990 
    991 void GetShaderVariableBufferResourceProperty(const ShaderVariableBuffer &buffer,
    992                                             GLenum pname,
    993                                             GLint *params,
    994                                             GLsizei bufSize,
    995                                             GLsizei *outputPosition)
    996 
    997 {
    998    switch (pname)
    999    {
   1000        case GL_BUFFER_BINDING:
   1001            params[(*outputPosition)++] = buffer.binding;
   1002            break;
   1003        case GL_BUFFER_DATA_SIZE:
   1004            params[(*outputPosition)++] = clampCast<GLint>(buffer.dataSize);
   1005            break;
   1006        case GL_NUM_ACTIVE_VARIABLES:
   1007            params[(*outputPosition)++] = buffer.numActiveVariables();
   1008            break;
   1009        case GL_ACTIVE_VARIABLES:
   1010            for (size_t memberIndex = 0;
   1011                 memberIndex < buffer.memberIndexes.size() && *outputPosition < bufSize;
   1012                 ++memberIndex)
   1013            {
   1014                params[(*outputPosition)++] = clampCast<GLint>(buffer.memberIndexes[memberIndex]);
   1015            }
   1016            break;
   1017        case GL_REFERENCED_BY_VERTEX_SHADER:
   1018            params[(*outputPosition)++] = static_cast<GLint>(buffer.isActive(ShaderType::Vertex));
   1019            break;
   1020        case GL_REFERENCED_BY_FRAGMENT_SHADER:
   1021            params[(*outputPosition)++] = static_cast<GLint>(buffer.isActive(ShaderType::Fragment));
   1022            break;
   1023        case GL_REFERENCED_BY_COMPUTE_SHADER:
   1024            params[(*outputPosition)++] = static_cast<GLint>(buffer.isActive(ShaderType::Compute));
   1025            break;
   1026        case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
   1027            params[(*outputPosition)++] = static_cast<GLint>(buffer.isActive(ShaderType::Geometry));
   1028            break;
   1029        case GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT:
   1030            params[(*outputPosition)++] =
   1031                static_cast<GLint>(buffer.isActive(ShaderType::TessControl));
   1032            break;
   1033        case GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT:
   1034            params[(*outputPosition)++] =
   1035                static_cast<GLint>(buffer.isActive(ShaderType::TessEvaluation));
   1036            break;
   1037        default:
   1038            UNREACHABLE();
   1039            break;
   1040    }
   1041 }
   1042 
   1043 void GetInterfaceBlockResourceProperty(const InterfaceBlock &block,
   1044                                       GLenum pname,
   1045                                       GLint *params,
   1046                                       GLsizei bufSize,
   1047                                       GLsizei *outputPosition)
   1048 {
   1049    if (pname == GL_NAME_LENGTH)
   1050    {
   1051        params[(*outputPosition)++] = clampCast<GLint>(block.nameWithArrayIndex().size() + 1);
   1052        return;
   1053    }
   1054    GetShaderVariableBufferResourceProperty(block, pname, params, bufSize, outputPosition);
   1055 }
   1056 
   1057 void GetUniformBlockResourceProperty(const Program *program,
   1058                                     GLuint blockIndex,
   1059                                     GLenum pname,
   1060                                     GLint *params,
   1061                                     GLsizei bufSize,
   1062                                     GLsizei *outputPosition)
   1063 
   1064 {
   1065    ASSERT(*outputPosition < bufSize);
   1066    const auto &block = program->getUniformBlockByIndex(blockIndex);
   1067    GetInterfaceBlockResourceProperty(block, pname, params, bufSize, outputPosition);
   1068 }
   1069 
   1070 void GetShaderStorageBlockResourceProperty(const Program *program,
   1071                                           GLuint blockIndex,
   1072                                           GLenum pname,
   1073                                           GLint *params,
   1074                                           GLsizei bufSize,
   1075                                           GLsizei *outputPosition)
   1076 
   1077 {
   1078    ASSERT(*outputPosition < bufSize);
   1079    const auto &block = program->getShaderStorageBlockByIndex(blockIndex);
   1080    GetInterfaceBlockResourceProperty(block, pname, params, bufSize, outputPosition);
   1081 }
   1082 
   1083 void GetAtomicCounterBufferResourceProperty(const Program *program,
   1084                                            GLuint index,
   1085                                            GLenum pname,
   1086                                            GLint *params,
   1087                                            GLsizei bufSize,
   1088                                            GLsizei *outputPosition)
   1089 
   1090 {
   1091    ASSERT(*outputPosition < bufSize);
   1092    const auto &buffer = program->getState().getAtomicCounterBuffers()[index];
   1093    GetShaderVariableBufferResourceProperty(buffer, pname, params, bufSize, outputPosition);
   1094 }
   1095 
   1096 bool IsTextureEnvEnumParameter(TextureEnvParameter pname)
   1097 {
   1098    switch (pname)
   1099    {
   1100        case TextureEnvParameter::Mode:
   1101        case TextureEnvParameter::CombineRgb:
   1102        case TextureEnvParameter::CombineAlpha:
   1103        case TextureEnvParameter::Src0Rgb:
   1104        case TextureEnvParameter::Src1Rgb:
   1105        case TextureEnvParameter::Src2Rgb:
   1106        case TextureEnvParameter::Src0Alpha:
   1107        case TextureEnvParameter::Src1Alpha:
   1108        case TextureEnvParameter::Src2Alpha:
   1109        case TextureEnvParameter::Op0Rgb:
   1110        case TextureEnvParameter::Op1Rgb:
   1111        case TextureEnvParameter::Op2Rgb:
   1112        case TextureEnvParameter::Op0Alpha:
   1113        case TextureEnvParameter::Op1Alpha:
   1114        case TextureEnvParameter::Op2Alpha:
   1115        case TextureEnvParameter::PointCoordReplace:
   1116            return true;
   1117        default:
   1118            return false;
   1119    }
   1120 }
   1121 
   1122 void GetShaderProgramId(ProgramPipeline *programPipeline, ShaderType shaderType, GLint *params)
   1123 {
   1124    ASSERT(params);
   1125 
   1126    *params = 0;
   1127    if (programPipeline)
   1128    {
   1129        const Program *program = programPipeline->getShaderProgram(shaderType);
   1130        if (program)
   1131        {
   1132            *params = program->id().value;
   1133        }
   1134    }
   1135 }
   1136 
   1137 }  // namespace
   1138 
   1139 void QueryFramebufferAttachmentParameteriv(const Context *context,
   1140                                           const Framebuffer *framebuffer,
   1141                                           GLenum attachment,
   1142                                           GLenum pname,
   1143                                           GLint *params)
   1144 {
   1145    ASSERT(framebuffer);
   1146 
   1147    const FramebufferAttachment *attachmentObject = framebuffer->getAttachment(context, attachment);
   1148 
   1149    if (attachmentObject == nullptr)
   1150    {
   1151        // ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE
   1152        // is NONE, then querying any other pname will generate INVALID_ENUM.
   1153 
   1154        // ES 3.0.2 spec pg 235 states that if the attachment type is none,
   1155        // GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an
   1156        // INVALID_OPERATION for all other pnames
   1157 
   1158        switch (pname)
   1159        {
   1160            case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
   1161                *params = GL_NONE;
   1162                break;
   1163 
   1164            case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
   1165                *params = 0;
   1166                break;
   1167 
   1168            default:
   1169                UNREACHABLE();
   1170                break;
   1171        }
   1172 
   1173        return;
   1174    }
   1175 
   1176    switch (pname)
   1177    {
   1178        case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
   1179            *params = attachmentObject->type();
   1180            break;
   1181 
   1182        case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
   1183            *params = attachmentObject->id();
   1184            break;
   1185 
   1186        case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
   1187            *params = attachmentObject->mipLevel();
   1188            break;
   1189 
   1190        case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
   1191        {
   1192            TextureTarget face = attachmentObject->cubeMapFace();
   1193            if (face != TextureTarget::InvalidEnum)
   1194            {
   1195                *params = ToGLenum(attachmentObject->cubeMapFace());
   1196            }
   1197            else
   1198            {
   1199                // This happens when the attachment isn't a texture cube map face
   1200                *params = GL_NONE;
   1201            }
   1202        }
   1203        break;
   1204 
   1205        case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
   1206            *params = attachmentObject->getRedSize();
   1207            break;
   1208 
   1209        case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
   1210            *params = attachmentObject->getGreenSize();
   1211            break;
   1212 
   1213        case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
   1214            *params = attachmentObject->getBlueSize();
   1215            break;
   1216 
   1217        case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
   1218            *params = attachmentObject->getAlphaSize();
   1219            break;
   1220 
   1221        case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
   1222            *params = attachmentObject->getDepthSize();
   1223            break;
   1224 
   1225        case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
   1226            *params = attachmentObject->getStencilSize();
   1227            break;
   1228 
   1229        case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
   1230            *params = attachmentObject->getComponentType();
   1231            break;
   1232 
   1233        case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
   1234            *params = attachmentObject->getColorEncoding();
   1235            break;
   1236 
   1237        case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
   1238            *params = attachmentObject->layer();
   1239            break;
   1240 
   1241        case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR:
   1242            *params = attachmentObject->getNumViews();
   1243            break;
   1244 
   1245        case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR:
   1246            *params = attachmentObject->getBaseViewIndex();
   1247            break;
   1248 
   1249        case GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT:
   1250            *params = attachmentObject->isLayered();
   1251            break;
   1252 
   1253        case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT:
   1254            if (attachmentObject->type() == GL_TEXTURE)
   1255            {
   1256                *params = attachmentObject->getSamples();
   1257            }
   1258            else
   1259            {
   1260                *params = 0;
   1261            }
   1262            break;
   1263 
   1264        default:
   1265            UNREACHABLE();
   1266            break;
   1267    }
   1268 }
   1269 
   1270 void QueryBufferParameteriv(const Buffer *buffer, GLenum pname, GLint *params)
   1271 {
   1272    QueryBufferParameterBase(buffer, pname, params);
   1273 }
   1274 
   1275 void QueryBufferParameteri64v(const Buffer *buffer, GLenum pname, GLint64 *params)
   1276 {
   1277    QueryBufferParameterBase(buffer, pname, params);
   1278 }
   1279 
   1280 void QueryBufferPointerv(const Buffer *buffer, GLenum pname, void **params)
   1281 {
   1282    switch (pname)
   1283    {
   1284        case GL_BUFFER_MAP_POINTER:
   1285            *params = buffer->getMapPointer();
   1286            break;
   1287 
   1288        default:
   1289            UNREACHABLE();
   1290            break;
   1291    }
   1292 }
   1293 
   1294 void QueryProgramiv(Context *context, const Program *program, GLenum pname, GLint *params)
   1295 {
   1296    ASSERT(program != nullptr || pname == GL_COMPLETION_STATUS_KHR);
   1297 
   1298    switch (pname)
   1299    {
   1300        case GL_DELETE_STATUS:
   1301            *params = program->isFlaggedForDeletion();
   1302            return;
   1303        case GL_LINK_STATUS:
   1304            *params = program->isLinked();
   1305            return;
   1306        case GL_COMPLETION_STATUS_KHR:
   1307            if (context->isContextLost())
   1308            {
   1309                *params = GL_TRUE;
   1310            }
   1311            else
   1312            {
   1313                *params = program->isLinking() ? GL_FALSE : GL_TRUE;
   1314            }
   1315            return;
   1316        case GL_VALIDATE_STATUS:
   1317            *params = program->isValidated();
   1318            return;
   1319        case GL_INFO_LOG_LENGTH:
   1320            *params = program->getExecutable().getInfoLogLength();
   1321            return;
   1322        case GL_ATTACHED_SHADERS:
   1323            *params = program->getAttachedShadersCount();
   1324            return;
   1325        case GL_ACTIVE_ATTRIBUTES:
   1326            *params = program->getActiveAttributeCount();
   1327            return;
   1328        case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
   1329            *params = program->getActiveAttributeMaxLength();
   1330            return;
   1331        case GL_ACTIVE_UNIFORMS:
   1332            *params = program->getActiveUniformCount();
   1333            return;
   1334        case GL_ACTIVE_UNIFORM_MAX_LENGTH:
   1335            *params = program->getActiveUniformMaxLength();
   1336            return;
   1337        case GL_PROGRAM_BINARY_LENGTH_OES:
   1338            *params = context->getCaps().programBinaryFormats.empty()
   1339                          ? 0
   1340                          : program->getBinaryLength(context);
   1341            return;
   1342        case GL_ACTIVE_UNIFORM_BLOCKS:
   1343            *params = program->getActiveUniformBlockCount();
   1344            return;
   1345        case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH:
   1346            *params = program->getActiveUniformBlockMaxNameLength();
   1347            break;
   1348        case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
   1349            *params = program->getTransformFeedbackBufferMode();
   1350            break;
   1351        case GL_TRANSFORM_FEEDBACK_VARYINGS:
   1352            *params = clampCast<GLint>(program->getTransformFeedbackVaryingCount());
   1353            break;
   1354        case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
   1355            *params = program->getTransformFeedbackVaryingMaxLength();
   1356            break;
   1357        case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
   1358            *params = program->getBinaryRetrievableHint();
   1359            break;
   1360        case GL_PROGRAM_SEPARABLE:
   1361            // From es31cSeparateShaderObjsTests.cpp:
   1362            // ProgramParameteri PROGRAM_SEPARABLE
   1363            // NOTE: The query for PROGRAM_SEPARABLE must query latched
   1364            //       state. In other words, the state of the binary after
   1365            //       it was linked. So in the tests below, the queries
   1366            //       should return the default state GL_FALSE since the
   1367            //       program has no linked binary.
   1368            *params = program->isSeparable() && program->isLinked();
   1369            break;
   1370        case GL_COMPUTE_WORK_GROUP_SIZE:
   1371        {
   1372            const sh::WorkGroupSize &localSize = program->getComputeShaderLocalSize();
   1373            params[0]                          = localSize[0];
   1374            params[1]                          = localSize[1];
   1375            params[2]                          = localSize[2];
   1376        }
   1377        break;
   1378        case GL_ACTIVE_ATOMIC_COUNTER_BUFFERS:
   1379            *params = program->getActiveAtomicCounterBufferCount();
   1380            break;
   1381        case GL_GEOMETRY_LINKED_INPUT_TYPE_EXT:
   1382            *params = ToGLenum(program->getGeometryShaderInputPrimitiveType());
   1383            break;
   1384        case GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT:
   1385            *params = ToGLenum(program->getGeometryShaderOutputPrimitiveType());
   1386            break;
   1387        case GL_GEOMETRY_LINKED_VERTICES_OUT_EXT:
   1388            *params = program->getGeometryShaderMaxVertices();
   1389            break;
   1390        case GL_GEOMETRY_SHADER_INVOCATIONS_EXT:
   1391            *params = program->getGeometryShaderInvocations();
   1392            break;
   1393        case GL_TESS_CONTROL_OUTPUT_VERTICES_EXT:
   1394            *params = program->getTessControlShaderVertices();
   1395            break;
   1396        case GL_TESS_GEN_MODE_EXT:
   1397            *params = program->getTessGenMode();
   1398            break;
   1399        case GL_TESS_GEN_SPACING_EXT:
   1400            *params = program->getTessGenSpacing() ? program->getTessGenSpacing() : GL_EQUAL;
   1401            break;
   1402        case GL_TESS_GEN_VERTEX_ORDER:
   1403            *params = program->getTessGenVertexOrder() ? program->getTessGenVertexOrder() : GL_CCW;
   1404            break;
   1405        case GL_TESS_GEN_POINT_MODE_EXT:
   1406            *params = program->getTessGenPointMode() ? GL_TRUE : GL_FALSE;
   1407            break;
   1408        default:
   1409            UNREACHABLE();
   1410            break;
   1411    }
   1412 }
   1413 
   1414 void QueryRenderbufferiv(const Context *context,
   1415                         const Renderbuffer *renderbuffer,
   1416                         GLenum pname,
   1417                         GLint *params)
   1418 {
   1419    ASSERT(renderbuffer != nullptr);
   1420 
   1421    switch (pname)
   1422    {
   1423        case GL_RENDERBUFFER_WIDTH:
   1424            *params = renderbuffer->getWidth();
   1425            break;
   1426        case GL_RENDERBUFFER_HEIGHT:
   1427            *params = renderbuffer->getHeight();
   1428            break;
   1429        case GL_RENDERBUFFER_INTERNAL_FORMAT:
   1430            // Special case the WebGL 1 DEPTH_STENCIL format.
   1431            if (context->isWebGL1() &&
   1432                renderbuffer->getFormat().info->internalFormat == GL_DEPTH24_STENCIL8)
   1433            {
   1434                *params = GL_DEPTH_STENCIL;
   1435            }
   1436            else
   1437            {
   1438                *params = renderbuffer->getFormat().info->internalFormat;
   1439            }
   1440            break;
   1441        case GL_RENDERBUFFER_RED_SIZE:
   1442            *params = renderbuffer->getRedSize();
   1443            break;
   1444        case GL_RENDERBUFFER_GREEN_SIZE:
   1445            *params = renderbuffer->getGreenSize();
   1446            break;
   1447        case GL_RENDERBUFFER_BLUE_SIZE:
   1448            *params = renderbuffer->getBlueSize();
   1449            break;
   1450        case GL_RENDERBUFFER_ALPHA_SIZE:
   1451            *params = renderbuffer->getAlphaSize();
   1452            break;
   1453        case GL_RENDERBUFFER_DEPTH_SIZE:
   1454            *params = renderbuffer->getDepthSize();
   1455            break;
   1456        case GL_RENDERBUFFER_STENCIL_SIZE:
   1457            *params = renderbuffer->getStencilSize();
   1458            break;
   1459        case GL_RENDERBUFFER_SAMPLES_ANGLE:
   1460            *params = renderbuffer->getState().getSamples();
   1461            break;
   1462        case GL_MEMORY_SIZE_ANGLE:
   1463            *params = renderbuffer->getMemorySize();
   1464            break;
   1465        case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
   1466            *params = static_cast<GLint>(renderbuffer->getImplementationColorReadFormat(context));
   1467            break;
   1468        case GL_IMPLEMENTATION_COLOR_READ_TYPE:
   1469            *params = static_cast<GLint>(renderbuffer->getImplementationColorReadType(context));
   1470            break;
   1471        case GL_RESOURCE_INITIALIZED_ANGLE:
   1472            *params = (renderbuffer->initState(GL_NONE, ImageIndex()) == InitState::Initialized);
   1473            break;
   1474        default:
   1475            UNREACHABLE();
   1476            break;
   1477    }
   1478 }
   1479 
   1480 void QueryShaderiv(const Context *context, Shader *shader, GLenum pname, GLint *params)
   1481 {
   1482    ASSERT(shader != nullptr || pname == GL_COMPLETION_STATUS_KHR);
   1483 
   1484    switch (pname)
   1485    {
   1486        case GL_SHADER_TYPE:
   1487            *params = static_cast<GLint>(ToGLenum(shader->getType()));
   1488            return;
   1489        case GL_DELETE_STATUS:
   1490            *params = shader->isFlaggedForDeletion();
   1491            return;
   1492        case GL_COMPILE_STATUS:
   1493            *params = shader->isCompiled(context) ? GL_TRUE : GL_FALSE;
   1494            return;
   1495        case GL_COMPLETION_STATUS_KHR:
   1496            if (context->isContextLost())
   1497            {
   1498                *params = GL_TRUE;
   1499            }
   1500            else
   1501            {
   1502                *params = shader->isCompleted() ? GL_TRUE : GL_FALSE;
   1503            }
   1504            return;
   1505        case GL_INFO_LOG_LENGTH:
   1506            *params = shader->getInfoLogLength(context);
   1507            return;
   1508        case GL_SHADER_SOURCE_LENGTH:
   1509            *params = shader->getSourceLength();
   1510            return;
   1511        case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
   1512            *params = shader->getTranslatedSourceWithDebugInfoLength(context);
   1513            return;
   1514        default:
   1515            UNREACHABLE();
   1516            break;
   1517    }
   1518 }
   1519 
   1520 void QueryTexLevelParameterfv(const Texture *texture,
   1521                              TextureTarget target,
   1522                              GLint level,
   1523                              GLenum pname,
   1524                              GLfloat *params)
   1525 {
   1526    QueryTexLevelParameterBase(texture, target, level, pname, params);
   1527 }
   1528 
   1529 void QueryTexLevelParameteriv(const Texture *texture,
   1530                              TextureTarget target,
   1531                              GLint level,
   1532                              GLenum pname,
   1533                              GLint *params)
   1534 {
   1535    QueryTexLevelParameterBase(texture, target, level, pname, params);
   1536 }
   1537 
   1538 void QueryTexParameterfv(const Context *context,
   1539                         const Texture *texture,
   1540                         GLenum pname,
   1541                         GLfloat *params)
   1542 {
   1543    QueryTexParameterBase<false, false>(context, texture, pname, params);
   1544 }
   1545 
   1546 void QueryTexParameterxv(const Context *context,
   1547                         const Texture *texture,
   1548                         GLenum pname,
   1549                         GLfixed *params)
   1550 {
   1551    QueryTexParameterBase<false, true>(context, texture, pname, params);
   1552 }
   1553 
   1554 void QueryTexParameteriv(const Context *context,
   1555                         const Texture *texture,
   1556                         GLenum pname,
   1557                         GLint *params)
   1558 {
   1559    QueryTexParameterBase<false, false>(context, texture, pname, params);
   1560 }
   1561 
   1562 void QueryTexParameterIiv(const Context *context,
   1563                          const Texture *texture,
   1564                          GLenum pname,
   1565                          GLint *params)
   1566 {
   1567    QueryTexParameterBase<true, false>(context, texture, pname, params);
   1568 }
   1569 
   1570 void QueryTexParameterIuiv(const Context *context,
   1571                           const Texture *texture,
   1572                           GLenum pname,
   1573                           GLuint *params)
   1574 {
   1575    QueryTexParameterBase<true, false>(context, texture, pname, params);
   1576 }
   1577 
   1578 void QuerySamplerParameterfv(const Sampler *sampler, GLenum pname, GLfloat *params)
   1579 {
   1580    QuerySamplerParameterBase<false>(sampler, pname, params);
   1581 }
   1582 
   1583 void QuerySamplerParameteriv(const Sampler *sampler, GLenum pname, GLint *params)
   1584 {
   1585    QuerySamplerParameterBase<false>(sampler, pname, params);
   1586 }
   1587 
   1588 void QuerySamplerParameterIiv(const Sampler *sampler, GLenum pname, GLint *params)
   1589 {
   1590    QuerySamplerParameterBase<true>(sampler, pname, params);
   1591 }
   1592 
   1593 void QuerySamplerParameterIuiv(const Sampler *sampler, GLenum pname, GLuint *params)
   1594 {
   1595    QuerySamplerParameterBase<true>(sampler, pname, params);
   1596 }
   1597 
   1598 void QueryVertexAttribfv(const VertexAttribute &attrib,
   1599                         const VertexBinding &binding,
   1600                         const VertexAttribCurrentValueData &currentValueData,
   1601                         GLenum pname,
   1602                         GLfloat *params)
   1603 {
   1604    QueryVertexAttribBase(attrib, binding, currentValueData.Values.FloatValues, pname, params);
   1605 }
   1606 
   1607 void QueryVertexAttribiv(const VertexAttribute &attrib,
   1608                         const VertexBinding &binding,
   1609                         const VertexAttribCurrentValueData &currentValueData,
   1610                         GLenum pname,
   1611                         GLint *params)
   1612 {
   1613    QueryVertexAttribBase(attrib, binding, currentValueData.Values.FloatValues, pname, params);
   1614 }
   1615 
   1616 void QueryVertexAttribPointerv(const VertexAttribute &attrib, GLenum pname, void **pointer)
   1617 {
   1618    switch (pname)
   1619    {
   1620        case GL_VERTEX_ATTRIB_ARRAY_POINTER:
   1621            *pointer = const_cast<void *>(attrib.pointer);
   1622            break;
   1623 
   1624        default:
   1625            UNREACHABLE();
   1626            break;
   1627    }
   1628 }
   1629 
   1630 void QueryVertexAttribIiv(const VertexAttribute &attrib,
   1631                          const VertexBinding &binding,
   1632                          const VertexAttribCurrentValueData &currentValueData,
   1633                          GLenum pname,
   1634                          GLint *params)
   1635 {
   1636    QueryVertexAttribBase(attrib, binding, currentValueData.Values.IntValues, pname, params);
   1637 }
   1638 
   1639 void QueryVertexAttribIuiv(const VertexAttribute &attrib,
   1640                           const VertexBinding &binding,
   1641                           const VertexAttribCurrentValueData &currentValueData,
   1642                           GLenum pname,
   1643                           GLuint *params)
   1644 {
   1645    QueryVertexAttribBase(attrib, binding, currentValueData.Values.UnsignedIntValues, pname,
   1646                          params);
   1647 }
   1648 
   1649 void QueryActiveUniformBlockiv(const Program *program,
   1650                               UniformBlockIndex uniformBlockIndex,
   1651                               GLenum pname,
   1652                               GLint *params)
   1653 {
   1654    GLenum prop = GetUniformBlockPropertyEnum(pname);
   1655    QueryProgramResourceiv(program, GL_UNIFORM_BLOCK, uniformBlockIndex, 1, &prop,
   1656                           std::numeric_limits<GLsizei>::max(), nullptr, params);
   1657 }
   1658 
   1659 void QueryInternalFormativ(const TextureCaps &format, GLenum pname, GLsizei bufSize, GLint *params)
   1660 {
   1661    switch (pname)
   1662    {
   1663        case GL_NUM_SAMPLE_COUNTS:
   1664            if (bufSize != 0)
   1665            {
   1666                *params = clampCast<GLint>(format.sampleCounts.size());
   1667            }
   1668            break;
   1669 
   1670        case GL_SAMPLES:
   1671        {
   1672            size_t returnCount   = std::min<size_t>(bufSize, format.sampleCounts.size());
   1673            auto sampleReverseIt = format.sampleCounts.rbegin();
   1674            for (size_t sampleIndex = 0; sampleIndex < returnCount; ++sampleIndex)
   1675            {
   1676                params[sampleIndex] = *sampleReverseIt++;
   1677            }
   1678        }
   1679        break;
   1680 
   1681        default:
   1682            UNREACHABLE();
   1683            break;
   1684    }
   1685 }
   1686 
   1687 void QueryFramebufferParameteriv(const Framebuffer *framebuffer, GLenum pname, GLint *params)
   1688 {
   1689    ASSERT(framebuffer);
   1690 
   1691    switch (pname)
   1692    {
   1693        case GL_FRAMEBUFFER_DEFAULT_WIDTH:
   1694            *params = framebuffer->getDefaultWidth();
   1695            break;
   1696        case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
   1697            *params = framebuffer->getDefaultHeight();
   1698            break;
   1699        case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
   1700            *params = framebuffer->getDefaultSamples();
   1701            break;
   1702        case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
   1703            *params = ConvertToGLBoolean(framebuffer->getDefaultFixedSampleLocations());
   1704            break;
   1705        case GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT:
   1706            *params = framebuffer->getDefaultLayers();
   1707            break;
   1708        case GL_FRAMEBUFFER_FLIP_Y_MESA:
   1709            *params = ConvertToGLBoolean(framebuffer->getFlipY());
   1710            break;
   1711        default:
   1712            UNREACHABLE();
   1713            break;
   1714    }
   1715 }
   1716 
   1717 angle::Result QuerySynciv(const Context *context,
   1718                          const Sync *sync,
   1719                          GLenum pname,
   1720                          GLsizei bufSize,
   1721                          GLsizei *length,
   1722                          GLint *values)
   1723 {
   1724    ASSERT(sync != nullptr || pname == GL_SYNC_STATUS);
   1725 
   1726    // All queries return one value, exit early if the buffer can't fit anything.
   1727    if (bufSize < 1)
   1728    {
   1729        if (length != nullptr)
   1730        {
   1731            *length = 0;
   1732        }
   1733        return angle::Result::Continue;
   1734    }
   1735 
   1736    switch (pname)
   1737    {
   1738        case GL_OBJECT_TYPE:
   1739            *values = clampCast<GLint>(GL_SYNC_FENCE);
   1740            break;
   1741        case GL_SYNC_CONDITION:
   1742            *values = clampCast<GLint>(sync->getCondition());
   1743            break;
   1744        case GL_SYNC_FLAGS:
   1745            *values = clampCast<GLint>(sync->getFlags());
   1746            break;
   1747        case GL_SYNC_STATUS:
   1748            if (context->isContextLost())
   1749            {
   1750                *values = GL_SIGNALED;
   1751            }
   1752            else
   1753            {
   1754                ANGLE_TRY(sync->getStatus(context, values));
   1755            }
   1756            break;
   1757 
   1758        default:
   1759            UNREACHABLE();
   1760            break;
   1761    }
   1762 
   1763    if (length != nullptr)
   1764    {
   1765        *length = 1;
   1766    }
   1767 
   1768    return angle::Result::Continue;
   1769 }
   1770 
   1771 void SetTexParameterx(Context *context, Texture *texture, GLenum pname, GLfixed param)
   1772 {
   1773    SetTexParameterBase<false, true>(context, texture, pname, &param);
   1774 }
   1775 
   1776 void SetTexParameterxv(Context *context, Texture *texture, GLenum pname, const GLfixed *params)
   1777 {
   1778    SetTexParameterBase<false, true>(context, texture, pname, params);
   1779 }
   1780 
   1781 void SetTexParameterf(Context *context, Texture *texture, GLenum pname, GLfloat param)
   1782 {
   1783    SetTexParameterBase<false, false>(context, texture, pname, &param);
   1784 }
   1785 
   1786 void SetTexParameterfv(Context *context, Texture *texture, GLenum pname, const GLfloat *params)
   1787 {
   1788    SetTexParameterBase<false, false>(context, texture, pname, params);
   1789 }
   1790 
   1791 void SetTexParameteri(Context *context, Texture *texture, GLenum pname, GLint param)
   1792 {
   1793    SetTexParameterBase<false, false>(context, texture, pname, &param);
   1794 }
   1795 
   1796 void SetTexParameteriv(Context *context, Texture *texture, GLenum pname, const GLint *params)
   1797 {
   1798    SetTexParameterBase<false, false>(context, texture, pname, params);
   1799 }
   1800 
   1801 void SetTexParameterIiv(Context *context, Texture *texture, GLenum pname, const GLint *params)
   1802 {
   1803    SetTexParameterBase<true, false>(context, texture, pname, params);
   1804 }
   1805 
   1806 void SetTexParameterIuiv(Context *context, Texture *texture, GLenum pname, const GLuint *params)
   1807 {
   1808    SetTexParameterBase<true, false>(context, texture, pname, params);
   1809 }
   1810 
   1811 void SetSamplerParameterf(Context *context, Sampler *sampler, GLenum pname, GLfloat param)
   1812 {
   1813    SetSamplerParameterBase<false>(context, sampler, pname, &param);
   1814 }
   1815 
   1816 void SetSamplerParameterfv(Context *context, Sampler *sampler, GLenum pname, const GLfloat *params)
   1817 {
   1818    SetSamplerParameterBase<false>(context, sampler, pname, params);
   1819 }
   1820 
   1821 void SetSamplerParameteri(Context *context, Sampler *sampler, GLenum pname, GLint param)
   1822 {
   1823    SetSamplerParameterBase<false>(context, sampler, pname, &param);
   1824 }
   1825 
   1826 void SetSamplerParameteriv(Context *context, Sampler *sampler, GLenum pname, const GLint *params)
   1827 {
   1828    SetSamplerParameterBase<false>(context, sampler, pname, params);
   1829 }
   1830 
   1831 void SetSamplerParameterIiv(Context *context, Sampler *sampler, GLenum pname, const GLint *params)
   1832 {
   1833    SetSamplerParameterBase<true>(context, sampler, pname, params);
   1834 }
   1835 
   1836 void SetSamplerParameterIuiv(Context *context, Sampler *sampler, GLenum pname, const GLuint *params)
   1837 {
   1838    SetSamplerParameterBase<true>(context, sampler, pname, params);
   1839 }
   1840 
   1841 void SetFramebufferParameteri(const Context *context,
   1842                              Framebuffer *framebuffer,
   1843                              GLenum pname,
   1844                              GLint param)
   1845 {
   1846    ASSERT(framebuffer);
   1847 
   1848    switch (pname)
   1849    {
   1850        case GL_FRAMEBUFFER_DEFAULT_WIDTH:
   1851            framebuffer->setDefaultWidth(context, param);
   1852            break;
   1853        case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
   1854            framebuffer->setDefaultHeight(context, param);
   1855            break;
   1856        case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
   1857            framebuffer->setDefaultSamples(context, param);
   1858            break;
   1859        case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
   1860            framebuffer->setDefaultFixedSampleLocations(context, ConvertToBool(param));
   1861            break;
   1862        case GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT:
   1863            framebuffer->setDefaultLayers(param);
   1864            break;
   1865        case GL_FRAMEBUFFER_FLIP_Y_MESA:
   1866            framebuffer->setFlipY(ConvertToBool(param));
   1867            break;
   1868        default:
   1869            UNREACHABLE();
   1870            break;
   1871    }
   1872 }
   1873 
   1874 void SetProgramParameteri(Program *program, GLenum pname, GLint value)
   1875 {
   1876    ASSERT(program);
   1877 
   1878    switch (pname)
   1879    {
   1880        case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
   1881            program->setBinaryRetrievableHint(ConvertToBool(value));
   1882            break;
   1883        case GL_PROGRAM_SEPARABLE:
   1884            program->setSeparable(ConvertToBool(value));
   1885            break;
   1886        default:
   1887            UNREACHABLE();
   1888            break;
   1889    }
   1890 }
   1891 
   1892 GLint GetUniformResourceProperty(const Program *program, GLuint index, const GLenum prop)
   1893 {
   1894    const auto &uniform = program->getUniformByIndex(index);
   1895    GLenum resourceProp = GetUniformPropertyEnum(prop);
   1896    switch (resourceProp)
   1897    {
   1898        case GL_TYPE:
   1899        case GL_ARRAY_SIZE:
   1900        case GL_NAME_LENGTH:
   1901            return GetCommonVariableProperty(uniform, resourceProp);
   1902 
   1903        case GL_LOCATION:
   1904            return program->getUniformLocation(uniform.name).value;
   1905 
   1906        case GL_BLOCK_INDEX:
   1907            return (uniform.isAtomicCounter() ? -1 : uniform.bufferIndex);
   1908 
   1909        case GL_OFFSET:
   1910            return uniform.blockInfo.offset;
   1911 
   1912        case GL_ARRAY_STRIDE:
   1913            return uniform.blockInfo.arrayStride;
   1914 
   1915        case GL_MATRIX_STRIDE:
   1916            return uniform.blockInfo.matrixStride;
   1917 
   1918        case GL_IS_ROW_MAJOR:
   1919            return static_cast<GLint>(uniform.blockInfo.isRowMajorMatrix);
   1920 
   1921        case GL_REFERENCED_BY_VERTEX_SHADER:
   1922            return uniform.isActive(ShaderType::Vertex);
   1923 
   1924        case GL_REFERENCED_BY_FRAGMENT_SHADER:
   1925            return uniform.isActive(ShaderType::Fragment);
   1926 
   1927        case GL_REFERENCED_BY_COMPUTE_SHADER:
   1928            return uniform.isActive(ShaderType::Compute);
   1929 
   1930        case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
   1931            return uniform.isActive(ShaderType::Geometry);
   1932 
   1933        case GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT:
   1934            return uniform.isActive(ShaderType::TessControl);
   1935 
   1936        case GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT:
   1937            return uniform.isActive(ShaderType::TessEvaluation);
   1938 
   1939        case GL_ATOMIC_COUNTER_BUFFER_INDEX:
   1940            return (uniform.isAtomicCounter() ? uniform.bufferIndex : -1);
   1941 
   1942        default:
   1943            UNREACHABLE();
   1944            return 0;
   1945    }
   1946 }
   1947 
   1948 GLint GetBufferVariableResourceProperty(const Program *program, GLuint index, const GLenum prop)
   1949 {
   1950    const BufferVariable &bufferVariable = program->getBufferVariableByIndex(index);
   1951    switch (prop)
   1952    {
   1953        case GL_TYPE:
   1954        case GL_ARRAY_SIZE:
   1955        case GL_NAME_LENGTH:
   1956            return GetCommonVariableProperty(bufferVariable, prop);
   1957 
   1958        case GL_BLOCK_INDEX:
   1959            return bufferVariable.bufferIndex;
   1960 
   1961        case GL_OFFSET:
   1962            return bufferVariable.blockInfo.offset;
   1963 
   1964        case GL_ARRAY_STRIDE:
   1965            return bufferVariable.blockInfo.arrayStride;
   1966 
   1967        case GL_MATRIX_STRIDE:
   1968            return bufferVariable.blockInfo.matrixStride;
   1969 
   1970        case GL_IS_ROW_MAJOR:
   1971            return static_cast<GLint>(bufferVariable.blockInfo.isRowMajorMatrix);
   1972 
   1973        case GL_REFERENCED_BY_VERTEX_SHADER:
   1974            return bufferVariable.isActive(ShaderType::Vertex);
   1975 
   1976        case GL_REFERENCED_BY_FRAGMENT_SHADER:
   1977            return bufferVariable.isActive(ShaderType::Fragment);
   1978 
   1979        case GL_REFERENCED_BY_COMPUTE_SHADER:
   1980            return bufferVariable.isActive(ShaderType::Compute);
   1981 
   1982        case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
   1983            return bufferVariable.isActive(ShaderType::Geometry);
   1984 
   1985        case GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT:
   1986            return bufferVariable.isActive(ShaderType::TessControl);
   1987 
   1988        case GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT:
   1989            return bufferVariable.isActive(ShaderType::TessEvaluation);
   1990 
   1991        case GL_TOP_LEVEL_ARRAY_SIZE:
   1992            return bufferVariable.topLevelArraySize;
   1993 
   1994        case GL_TOP_LEVEL_ARRAY_STRIDE:
   1995            return bufferVariable.blockInfo.topLevelArrayStride;
   1996 
   1997        default:
   1998            UNREACHABLE();
   1999            return 0;
   2000    }
   2001 }
   2002 
   2003 GLuint QueryProgramResourceIndex(const Program *program,
   2004                                 GLenum programInterface,
   2005                                 const GLchar *name)
   2006 {
   2007    switch (programInterface)
   2008    {
   2009        case GL_PROGRAM_INPUT:
   2010            return program->getInputResourceIndex(name);
   2011 
   2012        case GL_PROGRAM_OUTPUT:
   2013            return program->getOutputResourceIndex(name);
   2014 
   2015        case GL_UNIFORM:
   2016            return program->getState().getUniformIndexFromName(name);
   2017 
   2018        case GL_BUFFER_VARIABLE:
   2019            return program->getState().getBufferVariableIndexFromName(name);
   2020 
   2021        case GL_SHADER_STORAGE_BLOCK:
   2022            return program->getShaderStorageBlockIndex(name);
   2023 
   2024        case GL_UNIFORM_BLOCK:
   2025            return program->getUniformBlockIndex(name);
   2026 
   2027        case GL_TRANSFORM_FEEDBACK_VARYING:
   2028            return program->getTransformFeedbackVaryingResourceIndex(name);
   2029 
   2030        default:
   2031            UNREACHABLE();
   2032            return GL_INVALID_INDEX;
   2033    }
   2034 }
   2035 
   2036 void QueryProgramResourceName(const Context *context,
   2037                              const Program *program,
   2038                              GLenum programInterface,
   2039                              GLuint index,
   2040                              GLsizei bufSize,
   2041                              GLsizei *length,
   2042                              GLchar *name)
   2043 {
   2044    switch (programInterface)
   2045    {
   2046        case GL_PROGRAM_INPUT:
   2047            program->getInputResourceName(index, bufSize, length, name);
   2048            break;
   2049 
   2050        case GL_PROGRAM_OUTPUT:
   2051            program->getOutputResourceName(index, bufSize, length, name);
   2052            break;
   2053 
   2054        case GL_UNIFORM:
   2055            program->getUniformResourceName(index, bufSize, length, name);
   2056            break;
   2057 
   2058        case GL_BUFFER_VARIABLE:
   2059            program->getBufferVariableResourceName(index, bufSize, length, name);
   2060            break;
   2061 
   2062        case GL_SHADER_STORAGE_BLOCK:
   2063            program->getActiveShaderStorageBlockName(index, bufSize, length, name);
   2064            break;
   2065 
   2066        case GL_UNIFORM_BLOCK:
   2067            program->getActiveUniformBlockName(context, {index}, bufSize, length, name);
   2068            break;
   2069 
   2070        case GL_TRANSFORM_FEEDBACK_VARYING:
   2071            program->getTransformFeedbackVarying(index, bufSize, length, nullptr, nullptr, name);
   2072            break;
   2073 
   2074        default:
   2075            UNREACHABLE();
   2076    }
   2077 }
   2078 
   2079 GLint QueryProgramResourceLocation(const Program *program,
   2080                                   GLenum programInterface,
   2081                                   const GLchar *name)
   2082 {
   2083    switch (programInterface)
   2084    {
   2085        case GL_PROGRAM_INPUT:
   2086            return program->getInputResourceLocation(name);
   2087 
   2088        case GL_PROGRAM_OUTPUT:
   2089            return program->getOutputResourceLocation(name);
   2090 
   2091        case GL_UNIFORM:
   2092            return program->getUniformLocation(name).value;
   2093 
   2094        default:
   2095            UNREACHABLE();
   2096            return -1;
   2097    }
   2098 }
   2099 
   2100 void QueryProgramResourceiv(const Program *program,
   2101                            GLenum programInterface,
   2102                            UniformBlockIndex index,
   2103                            GLsizei propCount,
   2104                            const GLenum *props,
   2105                            GLsizei bufSize,
   2106                            GLsizei *length,
   2107                            GLint *params)
   2108 {
   2109    if (!program->isLinked())
   2110    {
   2111        return;
   2112    }
   2113 
   2114    if (length != nullptr)
   2115    {
   2116        *length = 0;
   2117    }
   2118 
   2119    if (bufSize == 0)
   2120    {
   2121        // No room to write the results
   2122        return;
   2123    }
   2124 
   2125    GLsizei pos = 0;
   2126    for (GLsizei i = 0; i < propCount; i++)
   2127    {
   2128        switch (programInterface)
   2129        {
   2130            case GL_PROGRAM_INPUT:
   2131                params[i] = GetInputResourceProperty(program, index.value, props[i]);
   2132                ++pos;
   2133                break;
   2134 
   2135            case GL_PROGRAM_OUTPUT:
   2136                params[i] = GetOutputResourceProperty(program, index.value, props[i]);
   2137                ++pos;
   2138                break;
   2139 
   2140            case GL_UNIFORM:
   2141                params[i] = GetUniformResourceProperty(program, index.value, props[i]);
   2142                ++pos;
   2143                break;
   2144 
   2145            case GL_BUFFER_VARIABLE:
   2146                params[i] = GetBufferVariableResourceProperty(program, index.value, props[i]);
   2147                ++pos;
   2148                break;
   2149 
   2150            case GL_UNIFORM_BLOCK:
   2151                GetUniformBlockResourceProperty(program, index.value, props[i], params, bufSize,
   2152                                                &pos);
   2153                break;
   2154 
   2155            case GL_SHADER_STORAGE_BLOCK:
   2156                GetShaderStorageBlockResourceProperty(program, index.value, props[i], params,
   2157                                                      bufSize, &pos);
   2158                break;
   2159 
   2160            case GL_ATOMIC_COUNTER_BUFFER:
   2161                GetAtomicCounterBufferResourceProperty(program, index.value, props[i], params,
   2162                                                       bufSize, &pos);
   2163                break;
   2164 
   2165            case GL_TRANSFORM_FEEDBACK_VARYING:
   2166                params[i] =
   2167                    GetTransformFeedbackVaryingResourceProperty(program, index.value, props[i]);
   2168                ++pos;
   2169                break;
   2170 
   2171            default:
   2172                UNREACHABLE();
   2173                params[i] = GL_INVALID_VALUE;
   2174        }
   2175        if (pos == bufSize)
   2176        {
   2177            // Most properties return one value, but GL_ACTIVE_VARIABLES returns an array of values.
   2178            // This checks not to break buffer bounds for such case.
   2179            break;
   2180        }
   2181    }
   2182 
   2183    if (length != nullptr)
   2184    {
   2185        *length = pos;
   2186    }
   2187 }
   2188 
   2189 void QueryProgramInterfaceiv(const Program *program,
   2190                             GLenum programInterface,
   2191                             GLenum pname,
   2192                             GLint *params)
   2193 {
   2194    switch (pname)
   2195    {
   2196        case GL_ACTIVE_RESOURCES:
   2197            *params = QueryProgramInterfaceActiveResources(program, programInterface);
   2198            break;
   2199 
   2200        case GL_MAX_NAME_LENGTH:
   2201            *params = QueryProgramInterfaceMaxNameLength(program, programInterface);
   2202            break;
   2203 
   2204        case GL_MAX_NUM_ACTIVE_VARIABLES:
   2205            *params = QueryProgramInterfaceMaxNumActiveVariables(program, programInterface);
   2206            break;
   2207 
   2208        default:
   2209            UNREACHABLE();
   2210    }
   2211 }
   2212 
   2213 angle::Result SetMemoryObjectParameteriv(const Context *context,
   2214                                         MemoryObject *memoryObject,
   2215                                         GLenum pname,
   2216                                         const GLint *params)
   2217 {
   2218    switch (pname)
   2219    {
   2220        case GL_DEDICATED_MEMORY_OBJECT_EXT:
   2221            ANGLE_TRY(memoryObject->setDedicatedMemory(context, ConvertToBool(params[0])));
   2222            break;
   2223 
   2224        case GL_PROTECTED_MEMORY_OBJECT_EXT:
   2225            ANGLE_TRY(memoryObject->setProtectedMemory(context, ConvertToBool(params[0])));
   2226            break;
   2227 
   2228        default:
   2229            UNREACHABLE();
   2230    }
   2231 
   2232    return angle::Result::Continue;
   2233 }
   2234 
   2235 void QueryMemoryObjectParameteriv(const MemoryObject *memoryObject, GLenum pname, GLint *params)
   2236 {
   2237    switch (pname)
   2238    {
   2239        case GL_DEDICATED_MEMORY_OBJECT_EXT:
   2240            *params = memoryObject->isDedicatedMemory();
   2241            break;
   2242 
   2243        case GL_PROTECTED_MEMORY_OBJECT_EXT:
   2244            *params = memoryObject->isProtectedMemory();
   2245            break;
   2246 
   2247        default:
   2248            UNREACHABLE();
   2249    }
   2250 }
   2251 
   2252 ClientVertexArrayType ParamToVertexArrayType(GLenum param)
   2253 {
   2254    switch (param)
   2255    {
   2256        case GL_VERTEX_ARRAY:
   2257        case GL_VERTEX_ARRAY_BUFFER_BINDING:
   2258        case GL_VERTEX_ARRAY_STRIDE:
   2259        case GL_VERTEX_ARRAY_SIZE:
   2260        case GL_VERTEX_ARRAY_TYPE:
   2261        case GL_VERTEX_ARRAY_POINTER:
   2262            return ClientVertexArrayType::Vertex;
   2263        case GL_NORMAL_ARRAY:
   2264        case GL_NORMAL_ARRAY_BUFFER_BINDING:
   2265        case GL_NORMAL_ARRAY_STRIDE:
   2266        case GL_NORMAL_ARRAY_TYPE:
   2267        case GL_NORMAL_ARRAY_POINTER:
   2268            return ClientVertexArrayType::Normal;
   2269        case GL_COLOR_ARRAY:
   2270        case GL_COLOR_ARRAY_BUFFER_BINDING:
   2271        case GL_COLOR_ARRAY_STRIDE:
   2272        case GL_COLOR_ARRAY_SIZE:
   2273        case GL_COLOR_ARRAY_TYPE:
   2274        case GL_COLOR_ARRAY_POINTER:
   2275            return ClientVertexArrayType::Color;
   2276        case GL_POINT_SIZE_ARRAY_OES:
   2277        case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
   2278        case GL_POINT_SIZE_ARRAY_STRIDE_OES:
   2279        case GL_POINT_SIZE_ARRAY_TYPE_OES:
   2280        case GL_POINT_SIZE_ARRAY_POINTER_OES:
   2281            return ClientVertexArrayType::PointSize;
   2282        case GL_TEXTURE_COORD_ARRAY:
   2283        case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:
   2284        case GL_TEXTURE_COORD_ARRAY_STRIDE:
   2285        case GL_TEXTURE_COORD_ARRAY_SIZE:
   2286        case GL_TEXTURE_COORD_ARRAY_TYPE:
   2287        case GL_TEXTURE_COORD_ARRAY_POINTER:
   2288            return ClientVertexArrayType::TextureCoord;
   2289        default:
   2290            UNREACHABLE();
   2291            return ClientVertexArrayType::InvalidEnum;
   2292    }
   2293 }
   2294 
   2295 void SetLightModelParameters(GLES1State *state, GLenum pname, const GLfloat *params)
   2296 {
   2297    LightModelParameters &lightModel = state->lightModelParameters();
   2298 
   2299    switch (pname)
   2300    {
   2301        case GL_LIGHT_MODEL_AMBIENT:
   2302            lightModel.color = ColorF::fromData(params);
   2303            break;
   2304        case GL_LIGHT_MODEL_TWO_SIDE:
   2305            lightModel.twoSided = *params == 1.0f ? true : false;
   2306            break;
   2307        default:
   2308            break;
   2309    }
   2310 }
   2311 
   2312 void GetLightModelParameters(const GLES1State *state, GLenum pname, GLfloat *params)
   2313 {
   2314    const LightModelParameters &lightModel = state->lightModelParameters();
   2315 
   2316    switch (pname)
   2317    {
   2318        case GL_LIGHT_MODEL_TWO_SIDE:
   2319            *params = lightModel.twoSided ? 1.0f : 0.0f;
   2320            break;
   2321        case GL_LIGHT_MODEL_AMBIENT:
   2322            lightModel.color.writeData(params);
   2323            break;
   2324        default:
   2325            break;
   2326    }
   2327 }
   2328 
   2329 bool IsLightModelTwoSided(const GLES1State *state)
   2330 {
   2331    return state->lightModelParameters().twoSided;
   2332 }
   2333 
   2334 void SetLightParameters(GLES1State *state,
   2335                        GLenum light,
   2336                        LightParameter pname,
   2337                        const GLfloat *params)
   2338 {
   2339    uint32_t lightIndex = light - GL_LIGHT0;
   2340 
   2341    LightParameters &lightParams = state->lightParameters(lightIndex);
   2342 
   2343    switch (pname)
   2344    {
   2345        case LightParameter::Ambient:
   2346            lightParams.ambient = ColorF::fromData(params);
   2347            break;
   2348        case LightParameter::Diffuse:
   2349            lightParams.diffuse = ColorF::fromData(params);
   2350            break;
   2351        case LightParameter::Specular:
   2352            lightParams.specular = ColorF::fromData(params);
   2353            break;
   2354        case LightParameter::Position:
   2355        {
   2356            angle::Mat4 mv = state->getModelviewMatrix();
   2357            angle::Vector4 transformedPos =
   2358                mv.product(angle::Vector4(params[0], params[1], params[2], params[3]));
   2359            lightParams.position[0] = transformedPos[0];
   2360            lightParams.position[1] = transformedPos[1];
   2361            lightParams.position[2] = transformedPos[2];
   2362            lightParams.position[3] = transformedPos[3];
   2363        }
   2364        break;
   2365        case LightParameter::SpotDirection:
   2366        {
   2367            angle::Mat4 mv = state->getModelviewMatrix();
   2368            angle::Vector4 transformedPos =
   2369                mv.product(angle::Vector4(params[0], params[1], params[2], 0.0f));
   2370            lightParams.direction[0] = transformedPos[0];
   2371            lightParams.direction[1] = transformedPos[1];
   2372            lightParams.direction[2] = transformedPos[2];
   2373        }
   2374        break;
   2375        case LightParameter::SpotExponent:
   2376            lightParams.spotlightExponent = *params;
   2377            break;
   2378        case LightParameter::SpotCutoff:
   2379            lightParams.spotlightCutoffAngle = *params;
   2380            break;
   2381        case LightParameter::ConstantAttenuation:
   2382            lightParams.attenuationConst = *params;
   2383            break;
   2384        case LightParameter::LinearAttenuation:
   2385            lightParams.attenuationLinear = *params;
   2386            break;
   2387        case LightParameter::QuadraticAttenuation:
   2388            lightParams.attenuationQuadratic = *params;
   2389            break;
   2390        default:
   2391            return;
   2392    }
   2393 }
   2394 
   2395 void GetLightParameters(const GLES1State *state,
   2396                        GLenum light,
   2397                        LightParameter pname,
   2398                        GLfloat *params)
   2399 {
   2400    uint32_t lightIndex                = light - GL_LIGHT0;
   2401    const LightParameters &lightParams = state->lightParameters(lightIndex);
   2402 
   2403    switch (pname)
   2404    {
   2405        case LightParameter::Ambient:
   2406            lightParams.ambient.writeData(params);
   2407            break;
   2408        case LightParameter::Diffuse:
   2409            lightParams.diffuse.writeData(params);
   2410            break;
   2411        case LightParameter::Specular:
   2412            lightParams.specular.writeData(params);
   2413            break;
   2414        case LightParameter::Position:
   2415            memcpy(params, lightParams.position.data(), 4 * sizeof(GLfloat));
   2416            break;
   2417        case LightParameter::SpotDirection:
   2418            memcpy(params, lightParams.direction.data(), 3 * sizeof(GLfloat));
   2419            break;
   2420        case LightParameter::SpotExponent:
   2421            *params = lightParams.spotlightExponent;
   2422            break;
   2423        case LightParameter::SpotCutoff:
   2424            *params = lightParams.spotlightCutoffAngle;
   2425            break;
   2426        case LightParameter::ConstantAttenuation:
   2427            *params = lightParams.attenuationConst;
   2428            break;
   2429        case LightParameter::LinearAttenuation:
   2430            *params = lightParams.attenuationLinear;
   2431            break;
   2432        case LightParameter::QuadraticAttenuation:
   2433            *params = lightParams.attenuationQuadratic;
   2434            break;
   2435        default:
   2436            break;
   2437    }
   2438 }
   2439 
   2440 void SetMaterialParameters(GLES1State *state,
   2441                           GLenum face,
   2442                           MaterialParameter pname,
   2443                           const GLfloat *params)
   2444 {
   2445    // Note: Ambient and diffuse colors are inherited from glColor when COLOR_MATERIAL is enabled,
   2446    // and can only be modified by this function if that is disabled:
   2447    //
   2448    // > the replaced values remain until changed by either sending a new color or by setting a
   2449    // > new material value when COLOR_MATERIAL is not currently enabled, to override that
   2450    // particular value.
   2451 
   2452    MaterialParameters &material = state->materialParameters();
   2453    switch (pname)
   2454    {
   2455        case MaterialParameter::Ambient:
   2456            if (!state->isColorMaterialEnabled())
   2457            {
   2458                material.ambient = ColorF::fromData(params);
   2459            }
   2460            break;
   2461        case MaterialParameter::Diffuse:
   2462            if (!state->isColorMaterialEnabled())
   2463            {
   2464                material.diffuse = ColorF::fromData(params);
   2465            }
   2466            break;
   2467        case MaterialParameter::AmbientAndDiffuse:
   2468            if (!state->isColorMaterialEnabled())
   2469            {
   2470                material.ambient = ColorF::fromData(params);
   2471                material.diffuse = ColorF::fromData(params);
   2472            }
   2473            break;
   2474        case MaterialParameter::Specular:
   2475            material.specular = ColorF::fromData(params);
   2476            break;
   2477        case MaterialParameter::Emission:
   2478            material.emissive = ColorF::fromData(params);
   2479            break;
   2480        case MaterialParameter::Shininess:
   2481            material.specularExponent = *params;
   2482            break;
   2483        default:
   2484            return;
   2485    }
   2486 }
   2487 
   2488 void GetMaterialParameters(const GLES1State *state,
   2489                           GLenum face,
   2490                           MaterialParameter pname,
   2491                           GLfloat *params)
   2492 {
   2493    const ColorF &currentColor         = state->getCurrentColor();
   2494    const MaterialParameters &material = state->materialParameters();
   2495    const bool colorMaterialEnabled    = state->isColorMaterialEnabled();
   2496 
   2497    switch (pname)
   2498    {
   2499        case MaterialParameter::Ambient:
   2500            if (colorMaterialEnabled)
   2501            {
   2502                currentColor.writeData(params);
   2503            }
   2504            else
   2505            {
   2506                material.ambient.writeData(params);
   2507            }
   2508            break;
   2509        case MaterialParameter::Diffuse:
   2510            if (colorMaterialEnabled)
   2511            {
   2512                currentColor.writeData(params);
   2513            }
   2514            else
   2515            {
   2516                material.diffuse.writeData(params);
   2517            }
   2518            break;
   2519        case MaterialParameter::Specular:
   2520            material.specular.writeData(params);
   2521            break;
   2522        case MaterialParameter::Emission:
   2523            material.emissive.writeData(params);
   2524            break;
   2525        case MaterialParameter::Shininess:
   2526            *params = material.specularExponent;
   2527            break;
   2528        default:
   2529            return;
   2530    }
   2531 }
   2532 
   2533 unsigned int GetLightModelParameterCount(GLenum pname)
   2534 {
   2535    switch (pname)
   2536    {
   2537        case GL_LIGHT_MODEL_AMBIENT:
   2538            return 4;
   2539        case GL_LIGHT_MODEL_TWO_SIDE:
   2540            return 1;
   2541        default:
   2542            UNREACHABLE();
   2543            return 0;
   2544    }
   2545 }
   2546 
   2547 unsigned int GetLightParameterCount(LightParameter pname)
   2548 {
   2549    switch (pname)
   2550    {
   2551        case LightParameter::Ambient:
   2552        case LightParameter::Diffuse:
   2553        case LightParameter::AmbientAndDiffuse:
   2554        case LightParameter::Specular:
   2555        case LightParameter::Position:
   2556            return 4;
   2557        case LightParameter::SpotDirection:
   2558            return 3;
   2559        case LightParameter::SpotExponent:
   2560        case LightParameter::SpotCutoff:
   2561        case LightParameter::ConstantAttenuation:
   2562        case LightParameter::LinearAttenuation:
   2563        case LightParameter::QuadraticAttenuation:
   2564            return 1;
   2565        default:
   2566            UNREACHABLE();
   2567            return 0;
   2568    }
   2569 }
   2570 
   2571 unsigned int GetMaterialParameterCount(MaterialParameter pname)
   2572 {
   2573    switch (pname)
   2574    {
   2575        case MaterialParameter::Ambient:
   2576        case MaterialParameter::Diffuse:
   2577        case MaterialParameter::AmbientAndDiffuse:
   2578        case MaterialParameter::Specular:
   2579        case MaterialParameter::Emission:
   2580            return 4;
   2581        case MaterialParameter::Shininess:
   2582            return 1;
   2583        default:
   2584            UNREACHABLE();
   2585            return 0;
   2586    }
   2587 }
   2588 
   2589 void SetFogParameters(GLES1State *state, GLenum pname, const GLfloat *params)
   2590 {
   2591    FogParameters &fog = state->fogParameters();
   2592    switch (pname)
   2593    {
   2594        case GL_FOG_MODE:
   2595            fog.mode = FromGLenum<FogMode>(static_cast<GLenum>(params[0]));
   2596            break;
   2597        case GL_FOG_DENSITY:
   2598            fog.density = params[0];
   2599            break;
   2600        case GL_FOG_START:
   2601            fog.start = params[0];
   2602            break;
   2603        case GL_FOG_END:
   2604            fog.end = params[0];
   2605            break;
   2606        case GL_FOG_COLOR:
   2607            fog.color = ColorF::fromData(params);
   2608            break;
   2609        default:
   2610            return;
   2611    }
   2612 }
   2613 
   2614 void GetFogParameters(const GLES1State *state, GLenum pname, GLfloat *params)
   2615 {
   2616    const FogParameters &fog = state->fogParameters();
   2617    switch (pname)
   2618    {
   2619        case GL_FOG_MODE:
   2620            params[0] = static_cast<GLfloat>(ToGLenum(fog.mode));
   2621            break;
   2622        case GL_FOG_DENSITY:
   2623            params[0] = fog.density;
   2624            break;
   2625        case GL_FOG_START:
   2626            params[0] = fog.start;
   2627            break;
   2628        case GL_FOG_END:
   2629            params[0] = fog.end;
   2630            break;
   2631        case GL_FOG_COLOR:
   2632            fog.color.writeData(params);
   2633            break;
   2634        default:
   2635            return;
   2636    }
   2637 }
   2638 
   2639 unsigned int GetFogParameterCount(GLenum pname)
   2640 {
   2641    switch (pname)
   2642    {
   2643        case GL_FOG_MODE:
   2644        case GL_FOG_DENSITY:
   2645        case GL_FOG_START:
   2646        case GL_FOG_END:
   2647            return 1;
   2648        case GL_FOG_COLOR:
   2649            return 4;
   2650        default:
   2651            return 0;
   2652    }
   2653 }
   2654 
   2655 unsigned int GetTextureEnvParameterCount(TextureEnvParameter pname)
   2656 {
   2657    switch (pname)
   2658    {
   2659        case TextureEnvParameter::Mode:
   2660        case TextureEnvParameter::CombineRgb:
   2661        case TextureEnvParameter::CombineAlpha:
   2662        case TextureEnvParameter::Src0Rgb:
   2663        case TextureEnvParameter::Src1Rgb:
   2664        case TextureEnvParameter::Src2Rgb:
   2665        case TextureEnvParameter::Src0Alpha:
   2666        case TextureEnvParameter::Src1Alpha:
   2667        case TextureEnvParameter::Src2Alpha:
   2668        case TextureEnvParameter::Op0Rgb:
   2669        case TextureEnvParameter::Op1Rgb:
   2670        case TextureEnvParameter::Op2Rgb:
   2671        case TextureEnvParameter::Op0Alpha:
   2672        case TextureEnvParameter::Op1Alpha:
   2673        case TextureEnvParameter::Op2Alpha:
   2674        case TextureEnvParameter::RgbScale:
   2675        case TextureEnvParameter::AlphaScale:
   2676        case TextureEnvParameter::PointCoordReplace:
   2677            return 1;
   2678        case TextureEnvParameter::Color:
   2679            return 4;
   2680        default:
   2681            return 0;
   2682    }
   2683 }
   2684 
   2685 void ConvertTextureEnvFromInt(TextureEnvParameter pname, const GLint *input, GLfloat *output)
   2686 {
   2687    if (IsTextureEnvEnumParameter(pname))
   2688    {
   2689        ConvertGLenumValue(input[0], output);
   2690        return;
   2691    }
   2692 
   2693    switch (pname)
   2694    {
   2695        case TextureEnvParameter::RgbScale:
   2696        case TextureEnvParameter::AlphaScale:
   2697            output[0] = static_cast<GLfloat>(input[0]);
   2698            break;
   2699        case TextureEnvParameter::Color:
   2700            for (int i = 0; i < 4; i++)
   2701            {
   2702                output[i] = input[i] / 255.0f;
   2703            }
   2704            break;
   2705        default:
   2706            UNREACHABLE();
   2707            break;
   2708    }
   2709 }
   2710 
   2711 void ConvertTextureEnvFromFixed(TextureEnvParameter pname, const GLfixed *input, GLfloat *output)
   2712 {
   2713    if (IsTextureEnvEnumParameter(pname))
   2714    {
   2715        ConvertGLenumValue(input[0], output);
   2716        return;
   2717    }
   2718 
   2719    switch (pname)
   2720    {
   2721        case TextureEnvParameter::RgbScale:
   2722        case TextureEnvParameter::AlphaScale:
   2723            output[0] = ConvertFixedToFloat(input[0]);
   2724            break;
   2725        case TextureEnvParameter::Color:
   2726            for (int i = 0; i < 4; i++)
   2727            {
   2728                output[i] = ConvertFixedToFloat(input[i]);
   2729            }
   2730            break;
   2731        default:
   2732            UNREACHABLE();
   2733            break;
   2734    }
   2735 }
   2736 
   2737 void ConvertTextureEnvToInt(TextureEnvParameter pname, const GLfloat *input, GLint *output)
   2738 {
   2739    if (IsTextureEnvEnumParameter(pname))
   2740    {
   2741        ConvertGLenumValue(input[0], output);
   2742        return;
   2743    }
   2744 
   2745    switch (pname)
   2746    {
   2747        case TextureEnvParameter::RgbScale:
   2748        case TextureEnvParameter::AlphaScale:
   2749            output[0] = static_cast<GLint>(input[0]);
   2750            break;
   2751        case TextureEnvParameter::Color:
   2752            for (int i = 0; i < 4; i++)
   2753            {
   2754                output[i] = static_cast<GLint>(input[i] * 255.0f);
   2755            }
   2756            break;
   2757        default:
   2758            UNREACHABLE();
   2759            break;
   2760    }
   2761 }
   2762 
   2763 void ConvertTextureEnvToFixed(TextureEnvParameter pname, const GLfloat *input, GLfixed *output)
   2764 {
   2765    if (IsTextureEnvEnumParameter(pname))
   2766    {
   2767        ConvertGLenumValue(input[0], output);
   2768        return;
   2769    }
   2770 
   2771    switch (pname)
   2772    {
   2773        case TextureEnvParameter::RgbScale:
   2774        case TextureEnvParameter::AlphaScale:
   2775            output[0] = ConvertFloatToFixed(input[0]);
   2776            break;
   2777        case TextureEnvParameter::Color:
   2778            for (int i = 0; i < 4; i++)
   2779            {
   2780                output[i] = ConvertFloatToFixed(input[i]);
   2781            }
   2782            break;
   2783        default:
   2784            UNREACHABLE();
   2785            break;
   2786    }
   2787 }
   2788 
   2789 void SetTextureEnv(unsigned int unit,
   2790                   GLES1State *state,
   2791                   TextureEnvTarget target,
   2792                   TextureEnvParameter pname,
   2793                   const GLfloat *params)
   2794 {
   2795    TextureEnvironmentParameters &env = state->textureEnvironment(unit);
   2796    GLenum asEnum                     = ConvertToGLenum(params[0]);
   2797 
   2798    switch (target)
   2799    {
   2800        case TextureEnvTarget::Env:
   2801            switch (pname)
   2802            {
   2803                case TextureEnvParameter::Mode:
   2804                    env.mode = FromGLenum<TextureEnvMode>(asEnum);
   2805                    break;
   2806                case TextureEnvParameter::CombineRgb:
   2807                    env.combineRgb = FromGLenum<TextureCombine>(asEnum);
   2808                    break;
   2809                case TextureEnvParameter::CombineAlpha:
   2810                    env.combineAlpha = FromGLenum<TextureCombine>(asEnum);
   2811                    break;
   2812                case TextureEnvParameter::Src0Rgb:
   2813                    env.src0Rgb = FromGLenum<TextureSrc>(asEnum);
   2814                    break;
   2815                case TextureEnvParameter::Src1Rgb:
   2816                    env.src1Rgb = FromGLenum<TextureSrc>(asEnum);
   2817                    break;
   2818                case TextureEnvParameter::Src2Rgb:
   2819                    env.src2Rgb = FromGLenum<TextureSrc>(asEnum);
   2820                    break;
   2821                case TextureEnvParameter::Src0Alpha:
   2822                    env.src0Alpha = FromGLenum<TextureSrc>(asEnum);
   2823                    break;
   2824                case TextureEnvParameter::Src1Alpha:
   2825                    env.src1Alpha = FromGLenum<TextureSrc>(asEnum);
   2826                    break;
   2827                case TextureEnvParameter::Src2Alpha:
   2828                    env.src2Alpha = FromGLenum<TextureSrc>(asEnum);
   2829                    break;
   2830                case TextureEnvParameter::Op0Rgb:
   2831                    env.op0Rgb = FromGLenum<TextureOp>(asEnum);
   2832                    break;
   2833                case TextureEnvParameter::Op1Rgb:
   2834                    env.op1Rgb = FromGLenum<TextureOp>(asEnum);
   2835                    break;
   2836                case TextureEnvParameter::Op2Rgb:
   2837                    env.op2Rgb = FromGLenum<TextureOp>(asEnum);
   2838                    break;
   2839                case TextureEnvParameter::Op0Alpha:
   2840                    env.op0Alpha = FromGLenum<TextureOp>(asEnum);
   2841                    break;
   2842                case TextureEnvParameter::Op1Alpha:
   2843                    env.op1Alpha = FromGLenum<TextureOp>(asEnum);
   2844                    break;
   2845                case TextureEnvParameter::Op2Alpha:
   2846                    env.op2Alpha = FromGLenum<TextureOp>(asEnum);
   2847                    break;
   2848                case TextureEnvParameter::Color:
   2849                    env.color = ColorF::fromData(params);
   2850                    break;
   2851                case TextureEnvParameter::RgbScale:
   2852                    env.rgbScale = params[0];
   2853                    break;
   2854                case TextureEnvParameter::AlphaScale:
   2855                    env.alphaScale = params[0];
   2856                    break;
   2857                default:
   2858                    UNREACHABLE();
   2859                    break;
   2860            }
   2861            break;
   2862        case TextureEnvTarget::PointSprite:
   2863            switch (pname)
   2864            {
   2865                case TextureEnvParameter::PointCoordReplace:
   2866                    env.pointSpriteCoordReplace = static_cast<bool>(params[0]);
   2867                    break;
   2868                default:
   2869                    UNREACHABLE();
   2870                    break;
   2871            }
   2872            break;
   2873        default:
   2874            UNREACHABLE();
   2875            break;
   2876    }
   2877 }
   2878 
   2879 void GetTextureEnv(unsigned int unit,
   2880                   const GLES1State *state,
   2881                   TextureEnvTarget target,
   2882                   TextureEnvParameter pname,
   2883                   GLfloat *params)
   2884 {
   2885    const TextureEnvironmentParameters &env = state->textureEnvironment(unit);
   2886 
   2887    switch (target)
   2888    {
   2889        case TextureEnvTarget::Env:
   2890            switch (pname)
   2891            {
   2892                case TextureEnvParameter::Mode:
   2893                    ConvertPackedEnum(env.mode, params);
   2894                    break;
   2895                case TextureEnvParameter::CombineRgb:
   2896                    ConvertPackedEnum(env.combineRgb, params);
   2897                    break;
   2898                case TextureEnvParameter::CombineAlpha:
   2899                    ConvertPackedEnum(env.combineAlpha, params);
   2900                    break;
   2901                case TextureEnvParameter::Src0Rgb:
   2902                    ConvertPackedEnum(env.src0Rgb, params);
   2903                    break;
   2904                case TextureEnvParameter::Src1Rgb:
   2905                    ConvertPackedEnum(env.src1Rgb, params);
   2906                    break;
   2907                case TextureEnvParameter::Src2Rgb:
   2908                    ConvertPackedEnum(env.src2Rgb, params);
   2909                    break;
   2910                case TextureEnvParameter::Src0Alpha:
   2911                    ConvertPackedEnum(env.src0Alpha, params);
   2912                    break;
   2913                case TextureEnvParameter::Src1Alpha:
   2914                    ConvertPackedEnum(env.src1Alpha, params);
   2915                    break;
   2916                case TextureEnvParameter::Src2Alpha:
   2917                    ConvertPackedEnum(env.src2Alpha, params);
   2918                    break;
   2919                case TextureEnvParameter::Op0Rgb:
   2920                    ConvertPackedEnum(env.op0Rgb, params);
   2921                    break;
   2922                case TextureEnvParameter::Op1Rgb:
   2923                    ConvertPackedEnum(env.op1Rgb, params);
   2924                    break;
   2925                case TextureEnvParameter::Op2Rgb:
   2926                    ConvertPackedEnum(env.op2Rgb, params);
   2927                    break;
   2928                case TextureEnvParameter::Op0Alpha:
   2929                    ConvertPackedEnum(env.op0Alpha, params);
   2930                    break;
   2931                case TextureEnvParameter::Op1Alpha:
   2932                    ConvertPackedEnum(env.op1Alpha, params);
   2933                    break;
   2934                case TextureEnvParameter::Op2Alpha:
   2935                    ConvertPackedEnum(env.op2Alpha, params);
   2936                    break;
   2937                case TextureEnvParameter::Color:
   2938                    env.color.writeData(params);
   2939                    break;
   2940                case TextureEnvParameter::RgbScale:
   2941                    *params = env.rgbScale;
   2942                    break;
   2943                case TextureEnvParameter::AlphaScale:
   2944                    *params = env.alphaScale;
   2945                    break;
   2946                default:
   2947                    UNREACHABLE();
   2948                    break;
   2949            }
   2950            break;
   2951        case TextureEnvTarget::PointSprite:
   2952            switch (pname)
   2953            {
   2954                case TextureEnvParameter::PointCoordReplace:
   2955                    *params = static_cast<GLfloat>(env.pointSpriteCoordReplace);
   2956                    break;
   2957                default:
   2958                    UNREACHABLE();
   2959                    break;
   2960            }
   2961            break;
   2962        default:
   2963            UNREACHABLE();
   2964            break;
   2965    }
   2966 }
   2967 
   2968 unsigned int GetPointParameterCount(PointParameter pname)
   2969 {
   2970    switch (pname)
   2971    {
   2972        case PointParameter::PointSizeMin:
   2973        case PointParameter::PointSizeMax:
   2974        case PointParameter::PointFadeThresholdSize:
   2975            return 1;
   2976        case PointParameter::PointDistanceAttenuation:
   2977            return 3;
   2978        default:
   2979            return 0;
   2980    }
   2981 }
   2982 
   2983 void SetPointParameter(GLES1State *state, PointParameter pname, const GLfloat *params)
   2984 {
   2985 
   2986    PointParameters &pointParams = state->pointParameters();
   2987 
   2988    switch (pname)
   2989    {
   2990        case PointParameter::PointSizeMin:
   2991            pointParams.pointSizeMin = params[0];
   2992            break;
   2993        case PointParameter::PointSizeMax:
   2994            pointParams.pointSizeMax = params[0];
   2995            break;
   2996        case PointParameter::PointFadeThresholdSize:
   2997            pointParams.pointFadeThresholdSize = params[0];
   2998            break;
   2999        case PointParameter::PointDistanceAttenuation:
   3000            for (unsigned int i = 0; i < 3; i++)
   3001            {
   3002                pointParams.pointDistanceAttenuation[i] = params[i];
   3003            }
   3004            break;
   3005        default:
   3006            UNREACHABLE();
   3007    }
   3008 }
   3009 
   3010 void GetPointParameter(const GLES1State *state, PointParameter pname, GLfloat *params)
   3011 {
   3012    const PointParameters &pointParams = state->pointParameters();
   3013 
   3014    switch (pname)
   3015    {
   3016        case PointParameter::PointSizeMin:
   3017            params[0] = pointParams.pointSizeMin;
   3018            break;
   3019        case PointParameter::PointSizeMax:
   3020            params[0] = pointParams.pointSizeMax;
   3021            break;
   3022        case PointParameter::PointFadeThresholdSize:
   3023            params[0] = pointParams.pointFadeThresholdSize;
   3024            break;
   3025        case PointParameter::PointDistanceAttenuation:
   3026            for (unsigned int i = 0; i < 3; i++)
   3027            {
   3028                params[i] = pointParams.pointDistanceAttenuation[i];
   3029            }
   3030            break;
   3031        default:
   3032            UNREACHABLE();
   3033    }
   3034 }
   3035 
   3036 void SetPointSize(GLES1State *state, GLfloat size)
   3037 {
   3038    PointParameters &params = state->pointParameters();
   3039    params.pointSize        = size;
   3040 }
   3041 
   3042 void GetPointSize(const GLES1State *state, GLfloat *sizeOut)
   3043 {
   3044    const PointParameters &params = state->pointParameters();
   3045    *sizeOut                      = params.pointSize;
   3046 }
   3047 
   3048 unsigned int GetTexParameterCount(GLenum pname)
   3049 {
   3050    switch (pname)
   3051    {
   3052        case GL_TEXTURE_CROP_RECT_OES:
   3053        case GL_TEXTURE_BORDER_COLOR:
   3054            return 4;
   3055        case GL_TEXTURE_MAG_FILTER:
   3056        case GL_TEXTURE_MIN_FILTER:
   3057        case GL_TEXTURE_WRAP_S:
   3058        case GL_TEXTURE_WRAP_T:
   3059        case GL_TEXTURE_USAGE_ANGLE:
   3060        case GL_TEXTURE_MAX_ANISOTROPY_EXT:
   3061        case GL_TEXTURE_IMMUTABLE_FORMAT:
   3062        case GL_TEXTURE_WRAP_R:
   3063        case GL_TEXTURE_IMMUTABLE_LEVELS:
   3064        case GL_TEXTURE_SWIZZLE_R:
   3065        case GL_TEXTURE_SWIZZLE_G:
   3066        case GL_TEXTURE_SWIZZLE_B:
   3067        case GL_TEXTURE_SWIZZLE_A:
   3068        case GL_TEXTURE_BASE_LEVEL:
   3069        case GL_TEXTURE_MAX_LEVEL:
   3070        case GL_TEXTURE_MIN_LOD:
   3071        case GL_TEXTURE_MAX_LOD:
   3072        case GL_TEXTURE_COMPARE_MODE:
   3073        case GL_TEXTURE_COMPARE_FUNC:
   3074        case GL_TEXTURE_SRGB_DECODE_EXT:
   3075        case GL_DEPTH_STENCIL_TEXTURE_MODE:
   3076        case GL_TEXTURE_NATIVE_ID_ANGLE:
   3077        case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
   3078            return 1;
   3079        default:
   3080            return 0;
   3081    }
   3082 }
   3083 
   3084 bool GetQueryParameterInfo(const State &glState,
   3085                           GLenum pname,
   3086                           GLenum *type,
   3087                           unsigned int *numParams)
   3088 {
   3089    const Caps &caps             = glState.getCaps();
   3090    const Extensions &extensions = glState.getExtensions();
   3091    GLint clientMajorVersion     = glState.getClientMajorVersion();
   3092    EGLenum clientType           = glState.getClientType();
   3093 
   3094    // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
   3095    // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
   3096    // to the fact that it is stored internally as a float, and so would require conversion
   3097    // if returned from Context::getIntegerv. Since this conversion is already implemented
   3098    // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
   3099    // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
   3100    // application.
   3101    switch (pname)
   3102    {
   3103        case GL_COMPRESSED_TEXTURE_FORMATS:
   3104        {
   3105            *type      = GL_INT;
   3106            *numParams = static_cast<unsigned int>(caps.compressedTextureFormats.size());
   3107            return true;
   3108        }
   3109        case GL_SHADER_BINARY_FORMATS:
   3110        {
   3111            *type      = GL_INT;
   3112            *numParams = static_cast<unsigned int>(caps.shaderBinaryFormats.size());
   3113            return true;
   3114        }
   3115 
   3116        case GL_MAX_VERTEX_ATTRIBS:
   3117        case GL_MAX_VERTEX_UNIFORM_VECTORS:
   3118        case GL_MAX_VARYING_VECTORS:
   3119        case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
   3120        case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
   3121        case GL_MAX_TEXTURE_IMAGE_UNITS:
   3122        case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
   3123        case GL_MAX_RENDERBUFFER_SIZE:
   3124        case GL_NUM_SHADER_BINARY_FORMATS:
   3125        case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
   3126        case GL_ARRAY_BUFFER_BINDING:
   3127        case GL_FRAMEBUFFER_BINDING:  // GL_FRAMEBUFFER_BINDING now equivalent to
   3128                                      // GL_DRAW_FRAMEBUFFER_BINDING
   3129        case GL_RENDERBUFFER_BINDING:
   3130        case GL_CURRENT_PROGRAM:
   3131        case GL_PACK_ALIGNMENT:
   3132        case GL_UNPACK_ALIGNMENT:
   3133        case GL_GENERATE_MIPMAP_HINT:
   3134        case GL_TEXTURE_FILTERING_HINT_CHROMIUM:
   3135        case GL_RED_BITS:
   3136        case GL_GREEN_BITS:
   3137        case GL_BLUE_BITS:
   3138        case GL_ALPHA_BITS:
   3139        case GL_DEPTH_BITS:
   3140        case GL_STENCIL_BITS:
   3141        case GL_ELEMENT_ARRAY_BUFFER_BINDING:
   3142        case GL_CULL_FACE_MODE:
   3143        case GL_FRONT_FACE:
   3144        case GL_ACTIVE_TEXTURE:
   3145        case GL_STENCIL_FUNC:
   3146        case GL_STENCIL_VALUE_MASK:
   3147        case GL_STENCIL_REF:
   3148        case GL_STENCIL_FAIL:
   3149        case GL_STENCIL_PASS_DEPTH_FAIL:
   3150        case GL_STENCIL_PASS_DEPTH_PASS:
   3151        case GL_STENCIL_BACK_FUNC:
   3152        case GL_STENCIL_BACK_VALUE_MASK:
   3153        case GL_STENCIL_BACK_REF:
   3154        case GL_STENCIL_BACK_FAIL:
   3155        case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
   3156        case GL_STENCIL_BACK_PASS_DEPTH_PASS:
   3157        case GL_DEPTH_FUNC:
   3158        case GL_BLEND_SRC_RGB:
   3159        case GL_BLEND_SRC_ALPHA:
   3160        case GL_BLEND_DST_RGB:
   3161        case GL_BLEND_DST_ALPHA:
   3162        case GL_BLEND_EQUATION_RGB:
   3163        case GL_BLEND_EQUATION_ALPHA:
   3164        case GL_STENCIL_WRITEMASK:
   3165        case GL_STENCIL_BACK_WRITEMASK:
   3166        case GL_STENCIL_CLEAR_VALUE:
   3167        case GL_SUBPIXEL_BITS:
   3168        case GL_MAX_TEXTURE_SIZE:
   3169        case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
   3170        case GL_SAMPLE_BUFFERS:
   3171        case GL_SAMPLES:
   3172        case GL_IMPLEMENTATION_COLOR_READ_TYPE:
   3173        case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
   3174        case GL_TEXTURE_BINDING_2D:
   3175        case GL_TEXTURE_BINDING_CUBE_MAP:
   3176        case GL_RESET_NOTIFICATION_STRATEGY_EXT:
   3177        {
   3178            *type      = GL_INT;
   3179            *numParams = 1;
   3180            return true;
   3181        }
   3182        case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
   3183        {
   3184            if (!extensions.packReverseRowOrderANGLE)
   3185            {
   3186                return false;
   3187            }
   3188            *type      = GL_INT;
   3189            *numParams = 1;
   3190            return true;
   3191        }
   3192        case GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE:
   3193        case GL_TEXTURE_BINDING_RECTANGLE_ANGLE:
   3194        {
   3195            if (!extensions.textureRectangleANGLE)
   3196            {
   3197                return false;
   3198            }
   3199            *type      = GL_INT;
   3200            *numParams = 1;
   3201            return true;
   3202        }
   3203        case GL_MAX_DRAW_BUFFERS_EXT:
   3204        case GL_MAX_COLOR_ATTACHMENTS_EXT:
   3205        {
   3206            if ((clientMajorVersion < 3) && !extensions.drawBuffersEXT)
   3207            {
   3208                return false;
   3209            }
   3210            *type      = GL_INT;
   3211            *numParams = 1;
   3212            return true;
   3213        }
   3214        case GL_MAX_VIEWPORT_DIMS:
   3215        {
   3216            *type      = GL_INT;
   3217            *numParams = 2;
   3218            return true;
   3219        }
   3220        case GL_VIEWPORT:
   3221        case GL_SCISSOR_BOX:
   3222        {
   3223            *type      = GL_INT;
   3224            *numParams = 4;
   3225            return true;
   3226        }
   3227        case GL_SHADER_COMPILER:
   3228        case GL_SAMPLE_COVERAGE_INVERT:
   3229        case GL_DEPTH_WRITEMASK:
   3230        case GL_CULL_FACE:                 // CULL_FACE through DITHER are natural to IsEnabled,
   3231        case GL_POLYGON_OFFSET_FILL:       // but can be retrieved through the Get{Type}v queries.
   3232        case GL_SAMPLE_ALPHA_TO_COVERAGE:  // For this purpose, they are treated here as
   3233                                           // bool-natural
   3234        case GL_SAMPLE_COVERAGE:
   3235        case GL_SCISSOR_TEST:
   3236        case GL_STENCIL_TEST:
   3237        case GL_DEPTH_TEST:
   3238        case GL_BLEND:
   3239        case GL_DITHER:
   3240        case GL_CONTEXT_ROBUST_ACCESS_EXT:
   3241        {
   3242            *type      = GL_BOOL;
   3243            *numParams = 1;
   3244            return true;
   3245        }
   3246        case GL_COLOR_LOGIC_OP:
   3247        {
   3248            if (!extensions.logicOpANGLE)
   3249            {
   3250                return false;
   3251            }
   3252            *type      = GL_BOOL;
   3253            *numParams = 1;
   3254            return true;
   3255        }
   3256        case GL_COLOR_WRITEMASK:
   3257        {
   3258            *type      = GL_BOOL;
   3259            *numParams = 4;
   3260            return true;
   3261        }
   3262        case GL_POLYGON_OFFSET_FACTOR:
   3263        case GL_POLYGON_OFFSET_UNITS:
   3264        case GL_SAMPLE_COVERAGE_VALUE:
   3265        case GL_DEPTH_CLEAR_VALUE:
   3266        case GL_LINE_WIDTH:
   3267        {
   3268            *type      = GL_FLOAT;
   3269            *numParams = 1;
   3270            return true;
   3271        }
   3272        case GL_ALIASED_LINE_WIDTH_RANGE:
   3273        case GL_ALIASED_POINT_SIZE_RANGE:
   3274        case GL_DEPTH_RANGE:
   3275        {
   3276            *type      = GL_FLOAT;
   3277            *numParams = 2;
   3278            return true;
   3279        }
   3280        case GL_COLOR_CLEAR_VALUE:
   3281        case GL_BLEND_COLOR:
   3282        {
   3283            *type      = GL_FLOAT;
   3284            *numParams = 4;
   3285            return true;
   3286        }
   3287        case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
   3288            if (!extensions.textureFilterAnisotropicEXT)
   3289            {
   3290                return false;
   3291            }
   3292            *type      = GL_FLOAT;
   3293            *numParams = 1;
   3294            return true;
   3295        case GL_TIMESTAMP_EXT:
   3296            if (!extensions.disjointTimerQueryEXT)
   3297            {
   3298                return false;
   3299            }
   3300            *type      = GL_INT_64_ANGLEX;
   3301            *numParams = 1;
   3302            return true;
   3303        case GL_GPU_DISJOINT_EXT:
   3304            if (!extensions.disjointTimerQueryEXT)
   3305            {
   3306                return false;
   3307            }
   3308            *type      = GL_INT;
   3309            *numParams = 1;
   3310            return true;
   3311        case GL_COVERAGE_MODULATION_CHROMIUM:
   3312            if (!extensions.framebufferMixedSamplesCHROMIUM)
   3313            {
   3314                return false;
   3315            }
   3316            *type      = GL_INT;
   3317            *numParams = 1;
   3318            return true;
   3319        case GL_TEXTURE_BINDING_EXTERNAL_OES:
   3320            if (!extensions.EGLStreamConsumerExternalNV && !extensions.EGLImageExternalOES)
   3321            {
   3322                return false;
   3323            }
   3324            *type      = GL_INT;
   3325            *numParams = 1;
   3326            return true;
   3327        case GL_MAX_CLIP_DISTANCES_EXT:  // case GL_MAX_CLIP_PLANES
   3328            if (clientMajorVersion < 2)
   3329            {
   3330                break;
   3331            }
   3332            if (!extensions.clipDistanceAPPLE && !extensions.clipCullDistanceEXT)
   3333            {
   3334                // NOTE(hqle): if client version is 1. GL_MAX_CLIP_DISTANCES_EXT is equal
   3335                // to GL_MAX_CLIP_PLANES which is a valid enum.
   3336                return false;
   3337            }
   3338            *type      = GL_INT;
   3339            *numParams = 1;
   3340            return true;
   3341        case GL_MAX_CULL_DISTANCES_EXT:
   3342        case GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES_EXT:
   3343            if (!extensions.clipCullDistanceEXT)
   3344            {
   3345                return false;
   3346            }
   3347            *type      = GL_INT;
   3348            *numParams = 1;
   3349            return true;
   3350        case GL_CLIP_ORIGIN_EXT:
   3351        case GL_CLIP_DEPTH_MODE_EXT:
   3352            if (!extensions.clipControlEXT)
   3353            {
   3354                return false;
   3355            }
   3356            *type      = GL_INT;
   3357            *numParams = 1;
   3358            return true;
   3359        case GL_PRIMITIVE_BOUNDING_BOX:
   3360            if (!extensions.primitiveBoundingBoxAny())
   3361            {
   3362                return false;
   3363            }
   3364            *type      = GL_FLOAT;
   3365            *numParams = 8;
   3366            return true;
   3367        case GL_SHADING_RATE_QCOM:
   3368            if (!extensions.shadingRateQCOM)
   3369            {
   3370                return false;
   3371            }
   3372            *type      = GL_INT;
   3373            *numParams = 1;
   3374            return true;
   3375    }
   3376 
   3377    if (clientType == EGL_OPENGL_API ||
   3378        (clientType == EGL_OPENGL_ES_API && glState.getClientVersion() >= Version(3, 2)))
   3379    {
   3380        switch (pname)
   3381        {
   3382            case GL_CONTEXT_FLAGS:
   3383            {
   3384                *type      = GL_INT;
   3385                *numParams = 1;
   3386                return true;
   3387            }
   3388        }
   3389    }
   3390 
   3391    if (clientType == EGL_OPENGL_API)
   3392    {
   3393        switch (pname)
   3394        {
   3395            case GL_CONTEXT_PROFILE_MASK:
   3396            {
   3397                *type      = GL_INT;
   3398                *numParams = 1;
   3399                return true;
   3400            }
   3401        }
   3402    }
   3403 
   3404    if (extensions.debugKHR)
   3405    {
   3406        switch (pname)
   3407        {
   3408            case GL_DEBUG_LOGGED_MESSAGES:
   3409            case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
   3410            case GL_DEBUG_GROUP_STACK_DEPTH:
   3411            case GL_MAX_DEBUG_MESSAGE_LENGTH:
   3412            case GL_MAX_DEBUG_LOGGED_MESSAGES:
   3413            case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
   3414            case GL_MAX_LABEL_LENGTH:
   3415                *type      = GL_INT;
   3416                *numParams = 1;
   3417                return true;
   3418 
   3419            case GL_DEBUG_OUTPUT_SYNCHRONOUS:
   3420            case GL_DEBUG_OUTPUT:
   3421                *type      = GL_BOOL;
   3422                *numParams = 1;
   3423                return true;
   3424        }
   3425    }
   3426 
   3427    if (extensions.multisampleCompatibilityEXT)
   3428    {
   3429        switch (pname)
   3430        {
   3431            case GL_MULTISAMPLE_EXT:
   3432            case GL_SAMPLE_ALPHA_TO_ONE_EXT:
   3433                *type      = GL_BOOL;
   3434                *numParams = 1;
   3435                return true;
   3436        }
   3437    }
   3438 
   3439    if (extensions.bindGeneratesResourceCHROMIUM)
   3440    {
   3441        switch (pname)
   3442        {
   3443            case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
   3444                *type      = GL_BOOL;
   3445                *numParams = 1;
   3446                return true;
   3447        }
   3448    }
   3449 
   3450    if (extensions.clientArraysANGLE)
   3451    {
   3452        switch (pname)
   3453        {
   3454            case GL_CLIENT_ARRAYS_ANGLE:
   3455                *type      = GL_BOOL;
   3456                *numParams = 1;
   3457                return true;
   3458        }
   3459    }
   3460 
   3461    if (extensions.sRGBWriteControlEXT)
   3462    {
   3463        switch (pname)
   3464        {
   3465            case GL_FRAMEBUFFER_SRGB_EXT:
   3466                *type      = GL_BOOL;
   3467                *numParams = 1;
   3468                return true;
   3469        }
   3470    }
   3471 
   3472    if (extensions.robustResourceInitializationANGLE &&
   3473        pname == GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE)
   3474    {
   3475        *type      = GL_BOOL;
   3476        *numParams = 1;
   3477        return true;
   3478    }
   3479 
   3480    if (extensions.programCacheControlANGLE && pname == GL_PROGRAM_CACHE_ENABLED_ANGLE)
   3481    {
   3482        *type      = GL_BOOL;
   3483        *numParams = 1;
   3484        return true;
   3485    }
   3486 
   3487    if (extensions.parallelShaderCompileKHR && pname == GL_MAX_SHADER_COMPILER_THREADS_KHR)
   3488    {
   3489        *type      = GL_INT;
   3490        *numParams = 1;
   3491        return true;
   3492    }
   3493 
   3494    if (extensions.blendFuncExtendedEXT && pname == GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT)
   3495    {
   3496        *type      = GL_INT;
   3497        *numParams = 1;
   3498        return true;
   3499    }
   3500 
   3501    if (extensions.robustFragmentShaderOutputANGLE &&
   3502        pname == GL_ROBUST_FRAGMENT_SHADER_OUTPUT_ANGLE)
   3503    {
   3504        *type      = GL_BOOL;
   3505        *numParams = 1;
   3506        return true;
   3507    }
   3508 
   3509    // Check for ES3.0+ parameter names which are also exposed as ES2 extensions
   3510    switch (pname)
   3511    {
   3512        // GL_DRAW_FRAMEBUFFER_BINDING equivalent to GL_FRAMEBUFFER_BINDING
   3513        case GL_READ_FRAMEBUFFER_BINDING:
   3514            if ((clientMajorVersion < 3) && !extensions.framebufferBlitAny())
   3515            {
   3516                return false;
   3517            }
   3518            *type      = GL_INT;
   3519            *numParams = 1;
   3520            return true;
   3521 
   3522        case GL_NUM_PROGRAM_BINARY_FORMATS_OES:
   3523            if ((clientMajorVersion < 3) && !extensions.getProgramBinaryOES)
   3524            {
   3525                return false;
   3526            }
   3527            *type      = GL_INT;
   3528            *numParams = 1;
   3529            return true;
   3530 
   3531        case GL_PROGRAM_BINARY_FORMATS_OES:
   3532            if ((clientMajorVersion < 3) && !extensions.getProgramBinaryOES)
   3533            {
   3534                return false;
   3535            }
   3536            *type      = GL_INT;
   3537            *numParams = static_cast<unsigned int>(caps.programBinaryFormats.size());
   3538            return true;
   3539 
   3540        case GL_PACK_ROW_LENGTH:
   3541        case GL_PACK_SKIP_ROWS:
   3542        case GL_PACK_SKIP_PIXELS:
   3543            if ((clientMajorVersion < 3) && !extensions.packSubimageNV)
   3544            {
   3545                return false;
   3546            }
   3547            *type      = GL_INT;
   3548            *numParams = 1;
   3549            return true;
   3550        case GL_UNPACK_ROW_LENGTH:
   3551        case GL_UNPACK_SKIP_ROWS:
   3552        case GL_UNPACK_SKIP_PIXELS:
   3553            if ((clientMajorVersion < 3) && !extensions.unpackSubimageEXT)
   3554            {
   3555                return false;
   3556            }
   3557            *type      = GL_INT;
   3558            *numParams = 1;
   3559            return true;
   3560        case GL_VERTEX_ARRAY_BINDING:
   3561            if ((clientMajorVersion < 3) && !extensions.vertexArrayObjectOES)
   3562            {
   3563                return false;
   3564            }
   3565            *type      = GL_INT;
   3566            *numParams = 1;
   3567            return true;
   3568        case GL_PIXEL_PACK_BUFFER_BINDING:
   3569        case GL_PIXEL_UNPACK_BUFFER_BINDING:
   3570            if ((clientMajorVersion < 3) && !extensions.pixelBufferObjectNV)
   3571            {
   3572                return false;
   3573            }
   3574            *type      = GL_INT;
   3575            *numParams = 1;
   3576            return true;
   3577        case GL_MAX_SAMPLES:
   3578        {
   3579            static_assert(GL_MAX_SAMPLES_ANGLE == GL_MAX_SAMPLES,
   3580                          "GL_MAX_SAMPLES_ANGLE not equal to GL_MAX_SAMPLES");
   3581            if ((clientMajorVersion < 3) && !(extensions.framebufferMultisampleANGLE ||
   3582                                              extensions.multisampledRenderToTextureEXT))
   3583            {
   3584                return false;
   3585            }
   3586            *type      = GL_INT;
   3587            *numParams = 1;
   3588            return true;
   3589 
   3590            case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
   3591                if ((clientMajorVersion < 3) && !extensions.standardDerivativesOES)
   3592                {
   3593                    return false;
   3594                }
   3595                *type      = GL_INT;
   3596                *numParams = 1;
   3597                return true;
   3598        }
   3599        case GL_TEXTURE_BINDING_3D:
   3600            if ((clientMajorVersion < 3) && !extensions.texture3DOES)
   3601            {
   3602                return false;
   3603            }
   3604            *type      = GL_INT;
   3605            *numParams = 1;
   3606            return true;
   3607        case GL_MAX_3D_TEXTURE_SIZE:
   3608            if ((clientMajorVersion < 3) && !extensions.texture3DOES)
   3609            {
   3610                return false;
   3611            }
   3612            *type      = GL_INT;
   3613            *numParams = 1;
   3614            return true;
   3615    }
   3616 
   3617    if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
   3618    {
   3619        if ((glState.getClientVersion() < Version(3, 0)) && !extensions.drawBuffersEXT)
   3620        {
   3621            return false;
   3622        }
   3623        *type      = GL_INT;
   3624        *numParams = 1;
   3625        return true;
   3626    }
   3627 
   3628    if ((extensions.multiview2OVR || extensions.multiviewOVR) && pname == GL_MAX_VIEWS_OVR)
   3629    {
   3630        *type      = GL_INT;
   3631        *numParams = 1;
   3632        return true;
   3633    }
   3634 
   3635    if (extensions.provokingVertexANGLE && pname == GL_PROVOKING_VERTEX)
   3636    {
   3637        *type      = GL_INT;
   3638        *numParams = 1;
   3639        return true;
   3640    }
   3641 
   3642    if (glState.getClientVersion() < Version(2, 0))
   3643    {
   3644        switch (pname)
   3645        {
   3646            case GL_ALPHA_TEST_FUNC:
   3647            case GL_CLIENT_ACTIVE_TEXTURE:
   3648            case GL_MATRIX_MODE:
   3649            case GL_MAX_TEXTURE_UNITS:
   3650            case GL_MAX_MODELVIEW_STACK_DEPTH:
   3651            case GL_MAX_PROJECTION_STACK_DEPTH:
   3652            case GL_MAX_TEXTURE_STACK_DEPTH:
   3653            case GL_MAX_LIGHTS:
   3654            case GL_MAX_CLIP_PLANES:
   3655            case GL_VERTEX_ARRAY_STRIDE:
   3656            case GL_NORMAL_ARRAY_STRIDE:
   3657            case GL_COLOR_ARRAY_STRIDE:
   3658            case GL_TEXTURE_COORD_ARRAY_STRIDE:
   3659            case GL_VERTEX_ARRAY_SIZE:
   3660            case GL_COLOR_ARRAY_SIZE:
   3661            case GL_TEXTURE_COORD_ARRAY_SIZE:
   3662            case GL_VERTEX_ARRAY_TYPE:
   3663            case GL_NORMAL_ARRAY_TYPE:
   3664            case GL_COLOR_ARRAY_TYPE:
   3665            case GL_TEXTURE_COORD_ARRAY_TYPE:
   3666            case GL_VERTEX_ARRAY_BUFFER_BINDING:
   3667            case GL_NORMAL_ARRAY_BUFFER_BINDING:
   3668            case GL_COLOR_ARRAY_BUFFER_BINDING:
   3669            case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:
   3670            case GL_POINT_SIZE_ARRAY_STRIDE_OES:
   3671            case GL_POINT_SIZE_ARRAY_TYPE_OES:
   3672            case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
   3673            case GL_SHADE_MODEL:
   3674            case GL_MODELVIEW_STACK_DEPTH:
   3675            case GL_PROJECTION_STACK_DEPTH:
   3676            case GL_TEXTURE_STACK_DEPTH:
   3677            case GL_LOGIC_OP_MODE:
   3678            case GL_BLEND_SRC:
   3679            case GL_BLEND_DST:
   3680            case GL_PERSPECTIVE_CORRECTION_HINT:
   3681            case GL_POINT_SMOOTH_HINT:
   3682            case GL_LINE_SMOOTH_HINT:
   3683            case GL_FOG_HINT:
   3684                *type      = GL_INT;
   3685                *numParams = 1;
   3686                return true;
   3687            case GL_ALPHA_TEST_REF:
   3688            case GL_FOG_DENSITY:
   3689            case GL_FOG_START:
   3690            case GL_FOG_END:
   3691            case GL_FOG_MODE:
   3692            case GL_POINT_SIZE:
   3693            case GL_POINT_SIZE_MIN:
   3694            case GL_POINT_SIZE_MAX:
   3695            case GL_POINT_FADE_THRESHOLD_SIZE:
   3696                *type      = GL_FLOAT;
   3697                *numParams = 1;
   3698                return true;
   3699            case GL_SMOOTH_POINT_SIZE_RANGE:
   3700            case GL_SMOOTH_LINE_WIDTH_RANGE:
   3701                *type      = GL_FLOAT;
   3702                *numParams = 2;
   3703                return true;
   3704            case GL_CURRENT_COLOR:
   3705            case GL_CURRENT_TEXTURE_COORDS:
   3706            case GL_LIGHT_MODEL_AMBIENT:
   3707            case GL_FOG_COLOR:
   3708                *type      = GL_FLOAT;
   3709                *numParams = 4;
   3710                return true;
   3711            case GL_CURRENT_NORMAL:
   3712            case GL_POINT_DISTANCE_ATTENUATION:
   3713                *type      = GL_FLOAT;
   3714                *numParams = 3;
   3715                return true;
   3716            case GL_MODELVIEW_MATRIX:
   3717            case GL_PROJECTION_MATRIX:
   3718            case GL_TEXTURE_MATRIX:
   3719                *type      = GL_FLOAT;
   3720                *numParams = 16;
   3721                return true;
   3722            case GL_LIGHT_MODEL_TWO_SIDE:
   3723                *type      = GL_BOOL;
   3724                *numParams = 1;
   3725                return true;
   3726        }
   3727    }
   3728 
   3729    if (glState.getClientVersion() < Version(3, 0))
   3730    {
   3731        return false;
   3732    }
   3733 
   3734    // Check for ES3.0+ parameter names
   3735    switch (pname)
   3736    {
   3737        case GL_MAX_UNIFORM_BUFFER_BINDINGS:
   3738        case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
   3739        case GL_UNIFORM_BUFFER_BINDING:
   3740        case GL_TRANSFORM_FEEDBACK_BINDING:
   3741        case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
   3742        case GL_COPY_READ_BUFFER_BINDING:
   3743        case GL_COPY_WRITE_BUFFER_BINDING:
   3744        case GL_SAMPLER_BINDING:
   3745        case GL_READ_BUFFER:
   3746        case GL_TEXTURE_BINDING_3D:
   3747        case GL_TEXTURE_BINDING_2D_ARRAY:
   3748        case GL_MAX_ARRAY_TEXTURE_LAYERS:
   3749        case GL_MAX_VERTEX_UNIFORM_BLOCKS:
   3750        case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
   3751        case GL_MAX_COMBINED_UNIFORM_BLOCKS:
   3752        case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
   3753        case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
   3754        case GL_MAX_VARYING_COMPONENTS:
   3755        case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
   3756        case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
   3757        case GL_MIN_PROGRAM_TEXEL_OFFSET:
   3758        case GL_MAX_PROGRAM_TEXEL_OFFSET:
   3759        case GL_NUM_EXTENSIONS:
   3760        case GL_MAJOR_VERSION:
   3761        case GL_MINOR_VERSION:
   3762        case GL_MAX_ELEMENTS_INDICES:
   3763        case GL_MAX_ELEMENTS_VERTICES:
   3764        case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
   3765        case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
   3766        case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
   3767        case GL_UNPACK_IMAGE_HEIGHT:
   3768        case GL_UNPACK_SKIP_IMAGES:
   3769        case GL_FRAGMENT_INTERPOLATION_OFFSET_BITS_OES:
   3770        {
   3771            *type      = GL_INT;
   3772            *numParams = 1;
   3773            return true;
   3774        }
   3775 
   3776        case GL_MAX_ELEMENT_INDEX:
   3777        case GL_MAX_UNIFORM_BLOCK_SIZE:
   3778        case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
   3779        case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
   3780        case GL_MAX_SERVER_WAIT_TIMEOUT:
   3781        {
   3782            *type      = GL_INT_64_ANGLEX;
   3783            *numParams = 1;
   3784            return true;
   3785        }
   3786 
   3787        case GL_TRANSFORM_FEEDBACK_ACTIVE:
   3788        case GL_TRANSFORM_FEEDBACK_PAUSED:
   3789        case GL_PRIMITIVE_RESTART_FIXED_INDEX:
   3790        case GL_RASTERIZER_DISCARD:
   3791        {
   3792            *type      = GL_BOOL;
   3793            *numParams = 1;
   3794            return true;
   3795        }
   3796 
   3797        case GL_MAX_TEXTURE_LOD_BIAS:
   3798        case GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_OES:
   3799        case GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_OES:
   3800        {
   3801            *type      = GL_FLOAT;
   3802            *numParams = 1;
   3803            return true;
   3804        }
   3805    }
   3806 
   3807    if (extensions.requestExtensionANGLE)
   3808    {
   3809        switch (pname)
   3810        {
   3811            case GL_NUM_REQUESTABLE_EXTENSIONS_ANGLE:
   3812                *type      = GL_INT;
   3813                *numParams = 1;
   3814                return true;
   3815        }
   3816    }
   3817 
   3818    if (extensions.textureMultisampleANGLE)
   3819    {
   3820        switch (pname)
   3821        {
   3822            case GL_MAX_COLOR_TEXTURE_SAMPLES_ANGLE:
   3823            case GL_MAX_INTEGER_SAMPLES_ANGLE:
   3824            case GL_MAX_DEPTH_TEXTURE_SAMPLES_ANGLE:
   3825            case GL_TEXTURE_BINDING_2D_MULTISAMPLE_ANGLE:
   3826            case GL_MAX_SAMPLE_MASK_WORDS:
   3827                *type      = GL_INT;
   3828                *numParams = 1;
   3829                return true;
   3830        }
   3831    }
   3832 
   3833    if (extensions.textureCubeMapArrayAny())
   3834    {
   3835        switch (pname)
   3836        {
   3837            case GL_TEXTURE_BINDING_CUBE_MAP_ARRAY:
   3838                *type      = GL_INT;
   3839                *numParams = 1;
   3840                return true;
   3841        }
   3842    }
   3843 
   3844    if (extensions.textureBufferAny())
   3845    {
   3846        switch (pname)
   3847        {
   3848            case GL_TEXTURE_BUFFER_BINDING:
   3849            case GL_TEXTURE_BINDING_BUFFER:
   3850            case GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
   3851            case GL_MAX_TEXTURE_BUFFER_SIZE:
   3852                *type      = GL_INT;
   3853                *numParams = 1;
   3854                return true;
   3855        }
   3856    }
   3857 
   3858    if (extensions.shaderPixelLocalStorageANGLE)
   3859    {
   3860        switch (pname)
   3861        {
   3862            case GL_MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE:
   3863            case GL_MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE_ANGLE:
   3864            case GL_MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES_ANGLE:
   3865                *type      = GL_INT;
   3866                *numParams = 1;
   3867                return true;
   3868            case GL_PIXEL_LOCAL_STORAGE_ACTIVE_ANGLE:
   3869                *type      = GL_BOOL;
   3870                *numParams = 1;
   3871                return true;
   3872        }
   3873    }
   3874 
   3875    if (glState.getClientVersion() < Version(3, 1))
   3876    {
   3877        return false;
   3878    }
   3879 
   3880    // Check for ES3.1+ parameter names
   3881    switch (pname)
   3882    {
   3883        case GL_ATOMIC_COUNTER_BUFFER_BINDING:
   3884        case GL_DRAW_INDIRECT_BUFFER_BINDING:
   3885        case GL_DISPATCH_INDIRECT_BUFFER_BINDING:
   3886        case GL_MAX_FRAMEBUFFER_WIDTH:
   3887        case GL_MAX_FRAMEBUFFER_HEIGHT:
   3888        case GL_MAX_FRAMEBUFFER_SAMPLES:
   3889        case GL_MAX_SAMPLE_MASK_WORDS:
   3890        case GL_MAX_COLOR_TEXTURE_SAMPLES:
   3891        case GL_MAX_DEPTH_TEXTURE_SAMPLES:
   3892        case GL_MAX_INTEGER_SAMPLES:
   3893        case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
   3894        case GL_MAX_VERTEX_ATTRIB_BINDINGS:
   3895        case GL_MAX_VERTEX_ATTRIB_STRIDE:
   3896        case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
   3897        case GL_MAX_VERTEX_ATOMIC_COUNTERS:
   3898        case GL_MAX_VERTEX_IMAGE_UNIFORMS:
   3899        case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
   3900        case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
   3901        case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
   3902        case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
   3903        case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
   3904        case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
   3905        case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
   3906        case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
   3907        case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
   3908        case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
   3909        case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
   3910        case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
   3911        case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
   3912        case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
   3913        case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
   3914        case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
   3915        case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
   3916        case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
   3917        case GL_MAX_UNIFORM_LOCATIONS:
   3918        case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
   3919        case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
   3920        case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
   3921        case GL_MAX_COMBINED_ATOMIC_COUNTERS:
   3922        case GL_MAX_IMAGE_UNITS:
   3923        case GL_MAX_COMBINED_IMAGE_UNIFORMS:
   3924        case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
   3925        case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
   3926        case GL_SHADER_STORAGE_BUFFER_BINDING:
   3927        case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
   3928        case GL_TEXTURE_BINDING_2D_MULTISAMPLE:
   3929        case GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY:
   3930        case GL_PROGRAM_PIPELINE_BINDING:
   3931            *type      = GL_INT;
   3932            *numParams = 1;
   3933            return true;
   3934        case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
   3935            *type      = GL_INT_64_ANGLEX;
   3936            *numParams = 1;
   3937            return true;
   3938        case GL_SAMPLE_MASK:
   3939        case GL_SAMPLE_SHADING:
   3940            *type      = GL_BOOL;
   3941            *numParams = 1;
   3942            return true;
   3943        case GL_MIN_SAMPLE_SHADING_VALUE:
   3944            *type      = GL_FLOAT;
   3945            *numParams = 1;
   3946            return true;
   3947    }
   3948 
   3949    if (extensions.geometryShaderAny())
   3950    {
   3951        switch (pname)
   3952        {
   3953            case GL_MAX_FRAMEBUFFER_LAYERS_EXT:
   3954            case GL_LAYER_PROVOKING_VERTEX_EXT:
   3955            case GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT:
   3956            case GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT:
   3957            case GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT:
   3958            case GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT:
   3959            case GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT:
   3960            case GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT:
   3961            case GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT:
   3962            case GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT:
   3963            case GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT:
   3964            case GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT:
   3965            case GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT:
   3966            case GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT:
   3967            case GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT:
   3968                *type      = GL_INT;
   3969                *numParams = 1;
   3970                return true;
   3971        }
   3972    }
   3973 
   3974    if (extensions.tessellationShaderEXT)
   3975    {
   3976        switch (pname)
   3977        {
   3978            case GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED:
   3979                *type      = GL_BOOL;
   3980                *numParams = 1;
   3981                return true;
   3982            case GL_PATCH_VERTICES:
   3983            case GL_MAX_PATCH_VERTICES_EXT:
   3984            case GL_MAX_TESS_GEN_LEVEL_EXT:
   3985            case GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS_EXT:
   3986            case GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT:
   3987            case GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS_EXT:
   3988            case GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS_EXT:
   3989            case GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS_EXT:
   3990            case GL_MAX_TESS_PATCH_COMPONENTS_EXT:
   3991            case GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS_EXT:
   3992            case GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS_EXT:
   3993            case GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS_EXT:
   3994            case GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS_EXT:
   3995            case GL_MAX_TESS_CONTROL_INPUT_COMPONENTS_EXT:
   3996            case GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS_EXT:
   3997            case GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS_EXT:
   3998            case GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT:
   3999            case GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS_EXT:
   4000            case GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS_EXT:
   4001            case GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS_EXT:
   4002            case GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS_EXT:
   4003            case GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS_EXT:
   4004            case GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS_EXT:
   4005            case GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS_EXT:
   4006            case GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS_EXT:
   4007                *type      = GL_INT;
   4008                *numParams = 1;
   4009                return true;
   4010        }
   4011    }
   4012 
   4013    return false;
   4014 }
   4015 
   4016 void QueryProgramPipelineiv(const Context *context,
   4017                            ProgramPipeline *programPipeline,
   4018                            GLenum pname,
   4019                            GLint *params)
   4020 {
   4021    if (!params)
   4022    {
   4023        // Can't write the result anywhere, so just return immediately.
   4024        return;
   4025    }
   4026 
   4027    switch (pname)
   4028    {
   4029        case GL_ACTIVE_PROGRAM:
   4030        {
   4031            // the name of the active program object of the program pipeline object is returned in
   4032            // params
   4033            *params = 0;
   4034            if (programPipeline)
   4035            {
   4036                const Program *program = programPipeline->getActiveShaderProgram();
   4037                if (program)
   4038                {
   4039                    *params = program->id().value;
   4040                }
   4041            }
   4042            break;
   4043        }
   4044 
   4045        case GL_VERTEX_SHADER:
   4046        {
   4047            // the name of the current program object for the vertex shader type of the program
   4048            // pipeline object is returned in params
   4049            GetShaderProgramId(programPipeline, ShaderType::Vertex, params);
   4050            break;
   4051        }
   4052 
   4053        case GL_FRAGMENT_SHADER:
   4054        {
   4055            // the name of the current program object for the fragment shader type of the program
   4056            // pipeline object is returned in params
   4057            GetShaderProgramId(programPipeline, ShaderType::Fragment, params);
   4058            break;
   4059        }
   4060 
   4061        case GL_TESS_CONTROL_SHADER:
   4062        {
   4063            // the name of the current program object for the tessellation control shader type of
   4064            // the program pipeline object is returned in params
   4065            GetShaderProgramId(programPipeline, ShaderType::TessControl, params);
   4066            break;
   4067        }
   4068 
   4069        case GL_TESS_EVALUATION_SHADER:
   4070        {
   4071            // the name of the current program object for the tessellation evaluation shader type of
   4072            // the program pipeline object is returned in params
   4073            GetShaderProgramId(programPipeline, ShaderType::TessEvaluation, params);
   4074            break;
   4075        }
   4076 
   4077        case GL_COMPUTE_SHADER:
   4078        {
   4079            // the name of the current program object for the compute shader type of the program
   4080            // pipeline object is returned in params
   4081            GetShaderProgramId(programPipeline, ShaderType::Compute, params);
   4082            break;
   4083        }
   4084 
   4085        case GL_GEOMETRY_SHADER:
   4086        {
   4087            // the name of the current program object for the geometry shader type of the program
   4088            // pipeline object is returned in params
   4089            GetShaderProgramId(programPipeline, ShaderType::Geometry, params);
   4090            break;
   4091        }
   4092 
   4093        case GL_INFO_LOG_LENGTH:
   4094        {
   4095            // the length of the info log, including the null terminator, is returned in params. If
   4096            // there is no info log, zero is returned.
   4097            *params = 0;
   4098            if (programPipeline)
   4099            {
   4100                *params = programPipeline->getExecutable().getInfoLogLength();
   4101            }
   4102            break;
   4103        }
   4104 
   4105        case GL_VALIDATE_STATUS:
   4106        {
   4107            // the validation status of pipeline, as determined by glValidateProgramPipeline, is
   4108            // returned in params
   4109            *params = 0;
   4110            if (programPipeline)
   4111            {
   4112                *params = programPipeline->isValid();
   4113            }
   4114            break;
   4115        }
   4116 
   4117        default:
   4118            break;
   4119    }
   4120 }
   4121 
   4122 }  // namespace gl
   4123 
   4124 namespace egl
   4125 {
   4126 
   4127 void QueryConfigAttrib(const Config *config, EGLint attribute, EGLint *value)
   4128 {
   4129    ASSERT(config != nullptr);
   4130    switch (attribute)
   4131    {
   4132        case EGL_BUFFER_SIZE:
   4133            *value = config->bufferSize;
   4134            break;
   4135        case EGL_ALPHA_SIZE:
   4136            *value = config->alphaSize;
   4137            break;
   4138        case EGL_BLUE_SIZE:
   4139            *value = config->blueSize;
   4140            break;
   4141        case EGL_GREEN_SIZE:
   4142            *value = config->greenSize;
   4143            break;
   4144        case EGL_RED_SIZE:
   4145            *value = config->redSize;
   4146            break;
   4147        case EGL_DEPTH_SIZE:
   4148            *value = config->depthSize;
   4149            break;
   4150        case EGL_STENCIL_SIZE:
   4151            *value = config->stencilSize;
   4152            break;
   4153        case EGL_CONFIG_CAVEAT:
   4154            *value = config->configCaveat;
   4155            break;
   4156        case EGL_CONFIG_ID:
   4157            *value = config->configID;
   4158            break;
   4159        case EGL_LEVEL:
   4160            *value = config->level;
   4161            break;
   4162        case EGL_NATIVE_RENDERABLE:
   4163            *value = config->nativeRenderable;
   4164            break;
   4165        case EGL_NATIVE_VISUAL_ID:
   4166            *value = config->nativeVisualID;
   4167            break;
   4168        case EGL_NATIVE_VISUAL_TYPE:
   4169            *value = config->nativeVisualType;
   4170            break;
   4171        case EGL_SAMPLES:
   4172            *value = config->samples;
   4173            break;
   4174        case EGL_SAMPLE_BUFFERS:
   4175            *value = config->sampleBuffers;
   4176            break;
   4177        case EGL_SURFACE_TYPE:
   4178            *value = config->surfaceType;
   4179            break;
   4180        case EGL_BIND_TO_TEXTURE_TARGET_ANGLE:
   4181            *value = config->bindToTextureTarget;
   4182            break;
   4183        case EGL_TRANSPARENT_TYPE:
   4184            *value = config->transparentType;
   4185            break;
   4186        case EGL_TRANSPARENT_BLUE_VALUE:
   4187            *value = config->transparentBlueValue;
   4188            break;
   4189        case EGL_TRANSPARENT_GREEN_VALUE:
   4190            *value = config->transparentGreenValue;
   4191            break;
   4192        case EGL_TRANSPARENT_RED_VALUE:
   4193            *value = config->transparentRedValue;
   4194            break;
   4195        case EGL_BIND_TO_TEXTURE_RGB:
   4196            *value = config->bindToTextureRGB;
   4197            break;
   4198        case EGL_BIND_TO_TEXTURE_RGBA:
   4199            *value = config->bindToTextureRGBA;
   4200            break;
   4201        case EGL_MIN_SWAP_INTERVAL:
   4202            *value = config->minSwapInterval;
   4203            break;
   4204        case EGL_MAX_SWAP_INTERVAL:
   4205            *value = config->maxSwapInterval;
   4206            break;
   4207        case EGL_LUMINANCE_SIZE:
   4208            *value = config->luminanceSize;
   4209            break;
   4210        case EGL_ALPHA_MASK_SIZE:
   4211            *value = config->alphaMaskSize;
   4212            break;
   4213        case EGL_COLOR_BUFFER_TYPE:
   4214            *value = config->colorBufferType;
   4215            break;
   4216        case EGL_RENDERABLE_TYPE:
   4217            *value = config->renderableType;
   4218            break;
   4219        case EGL_MATCH_NATIVE_PIXMAP:
   4220            *value = false;
   4221            UNIMPLEMENTED();
   4222            break;
   4223        case EGL_CONFORMANT:
   4224            *value = config->conformant;
   4225            break;
   4226        case EGL_MAX_PBUFFER_WIDTH:
   4227            *value = config->maxPBufferWidth;
   4228            break;
   4229        case EGL_MAX_PBUFFER_HEIGHT:
   4230            *value = config->maxPBufferHeight;
   4231            break;
   4232        case EGL_MAX_PBUFFER_PIXELS:
   4233            *value = config->maxPBufferPixels;
   4234            break;
   4235        case EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE:
   4236            *value = config->optimalOrientation;
   4237            break;
   4238        case EGL_COLOR_COMPONENT_TYPE_EXT:
   4239            *value = config->colorComponentType;
   4240            break;
   4241        case EGL_RECORDABLE_ANDROID:
   4242            *value = config->recordable;
   4243            break;
   4244        case EGL_FRAMEBUFFER_TARGET_ANDROID:
   4245            *value = config->framebufferTarget;
   4246            break;
   4247        case EGL_MATCH_FORMAT_KHR:
   4248            *value = config->matchFormat;
   4249            break;
   4250        default:
   4251            UNREACHABLE();
   4252            break;
   4253    }
   4254 }
   4255 
   4256 void QueryContextAttrib(const gl::Context *context, EGLint attribute, EGLint *value)
   4257 {
   4258    switch (attribute)
   4259    {
   4260        case EGL_CONFIG_ID:
   4261            if (context->getConfig() != EGL_NO_CONFIG_KHR)
   4262            {
   4263                *value = context->getConfig()->configID;
   4264            }
   4265            else
   4266            {
   4267                *value = 0;
   4268            }
   4269            break;
   4270        case EGL_CONTEXT_CLIENT_TYPE:
   4271            *value = context->getClientType();
   4272            break;
   4273        case EGL_CONTEXT_CLIENT_VERSION:
   4274            *value = context->getClientMajorVersion();
   4275            break;
   4276        case EGL_RENDER_BUFFER:
   4277            *value = context->getRenderBuffer();
   4278            break;
   4279        case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
   4280            *value = context->isRobustResourceInitEnabled();
   4281            break;
   4282        case EGL_CONTEXT_PRIORITY_LEVEL_IMG:
   4283            *value = static_cast<EGLint>(context->getContextPriority());
   4284            break;
   4285        case EGL_PROTECTED_CONTENT_EXT:
   4286            *value = context->getState().hasProtectedContent();
   4287            break;
   4288        default:
   4289            UNREACHABLE();
   4290            break;
   4291    }
   4292 }
   4293 
   4294 egl::Error QuerySurfaceAttrib(const Display *display,
   4295                              const gl::Context *context,
   4296                              Surface *surface,
   4297                              EGLint attribute,
   4298                              EGLint *value)
   4299 {
   4300    switch (attribute)
   4301    {
   4302        case EGL_GL_COLORSPACE:
   4303            *value = surface->getGLColorspace();
   4304            break;
   4305        case EGL_VG_ALPHA_FORMAT:
   4306            *value = surface->getVGAlphaFormat();
   4307            break;
   4308        case EGL_VG_COLORSPACE:
   4309            *value = surface->getVGColorspace();
   4310            break;
   4311        case EGL_CONFIG_ID:
   4312            *value = surface->getConfig()->configID;
   4313            break;
   4314        case EGL_HEIGHT:
   4315            ANGLE_TRY(surface->getUserHeight(display, value));
   4316            break;
   4317        case EGL_HORIZONTAL_RESOLUTION:
   4318            *value = surface->getHorizontalResolution();
   4319            break;
   4320        case EGL_LARGEST_PBUFFER:
   4321            // The EGL spec states that value is not written if the surface is not a pbuffer
   4322            if (surface->getType() == EGL_PBUFFER_BIT)
   4323            {
   4324                *value = surface->getLargestPbuffer();
   4325            }
   4326            break;
   4327        case EGL_MIPMAP_TEXTURE:
   4328            // The EGL spec states that value is not written if the surface is not a pbuffer
   4329            if (surface->getType() == EGL_PBUFFER_BIT)
   4330            {
   4331                *value = surface->getMipmapTexture();
   4332            }
   4333            break;
   4334        case EGL_MIPMAP_LEVEL:
   4335            // The EGL spec states that value is not written if the surface is not a pbuffer
   4336            if (surface->getType() == EGL_PBUFFER_BIT)
   4337            {
   4338                *value = surface->getMipmapLevel();
   4339            }
   4340            break;
   4341        case EGL_MULTISAMPLE_RESOLVE:
   4342            *value = surface->getMultisampleResolve();
   4343            break;
   4344        case EGL_PIXEL_ASPECT_RATIO:
   4345            *value = surface->getPixelAspectRatio();
   4346            break;
   4347        case EGL_RENDER_BUFFER:
   4348            *value = surface->getRenderBuffer();
   4349            break;
   4350        case EGL_SWAP_BEHAVIOR:
   4351            *value = surface->getSwapBehavior();
   4352            break;
   4353        case EGL_TEXTURE_FORMAT:
   4354            // The EGL spec states that value is not written if the surface is not a pbuffer
   4355            if (surface->getType() == EGL_PBUFFER_BIT)
   4356            {
   4357                *value = ToEGLenum(surface->getTextureFormat());
   4358            }
   4359            break;
   4360        case EGL_TEXTURE_TARGET:
   4361            // The EGL spec states that value is not written if the surface is not a pbuffer
   4362            if (surface->getType() == EGL_PBUFFER_BIT)
   4363            {
   4364                *value = surface->getTextureTarget();
   4365            }
   4366            break;
   4367        case EGL_VERTICAL_RESOLUTION:
   4368            *value = surface->getVerticalResolution();
   4369            break;
   4370        case EGL_WIDTH:
   4371            ANGLE_TRY(surface->getUserWidth(display, value));
   4372            break;
   4373        case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
   4374            *value = surface->isPostSubBufferSupported();
   4375            break;
   4376        case EGL_FIXED_SIZE_ANGLE:
   4377            *value = surface->isFixedSize();
   4378            break;
   4379        case EGL_SURFACE_ORIENTATION_ANGLE:
   4380            *value = surface->getOrientation();
   4381            break;
   4382        case EGL_DIRECT_COMPOSITION_ANGLE:
   4383            *value = surface->directComposition();
   4384            break;
   4385        case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
   4386            *value = surface->isRobustResourceInitEnabled();
   4387            break;
   4388        case EGL_TIMESTAMPS_ANDROID:
   4389            *value = surface->isTimestampsEnabled();
   4390            break;
   4391        case EGL_BUFFER_AGE_EXT:
   4392            ANGLE_TRY(surface->getBufferAge(context, value));
   4393            break;
   4394        case EGL_BITMAP_PITCH_KHR:
   4395            *value = surface->getBitmapPitch();
   4396            break;
   4397        case EGL_BITMAP_ORIGIN_KHR:
   4398            *value = surface->getBitmapOrigin();
   4399            break;
   4400        case EGL_BITMAP_PIXEL_RED_OFFSET_KHR:
   4401            *value = surface->getRedOffset();
   4402            break;
   4403        case EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR:
   4404            *value = surface->getGreenOffset();
   4405            break;
   4406        case EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR:
   4407            *value = surface->getBlueOffset();
   4408            break;
   4409        case EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR:
   4410            *value = surface->getAlphaOffset();
   4411            break;
   4412        case EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR:
   4413            *value = surface->getLuminanceOffset();
   4414            break;
   4415        case EGL_BITMAP_PIXEL_SIZE_KHR:
   4416            *value = surface->getBitmapPixelSize();
   4417            break;
   4418        case EGL_PROTECTED_CONTENT_EXT:
   4419            *value = surface->hasProtectedContent();
   4420            break;
   4421        default:
   4422            UNREACHABLE();
   4423            break;
   4424    }
   4425    return NoError();
   4426 }
   4427 
   4428 egl::Error QuerySurfaceAttrib64KHR(const Display *display,
   4429                                   const gl::Context *context,
   4430                                   const Surface *surface,
   4431                                   EGLint attribute,
   4432                                   EGLAttribKHR *value)
   4433 {
   4434    switch (attribute)
   4435    {
   4436        case EGL_BITMAP_PITCH_KHR:
   4437            *value = static_cast<EGLAttribKHR>(surface->getBitmapPitch());
   4438            break;
   4439        case EGL_BITMAP_ORIGIN_KHR:
   4440            *value = static_cast<EGLAttribKHR>(surface->getBitmapOrigin());
   4441            break;
   4442        case EGL_BITMAP_PIXEL_RED_OFFSET_KHR:
   4443            *value = static_cast<EGLAttribKHR>(surface->getRedOffset());
   4444            break;
   4445        case EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR:
   4446            *value = static_cast<EGLAttribKHR>(surface->getGreenOffset());
   4447            break;
   4448        case EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR:
   4449            *value = static_cast<EGLAttribKHR>(surface->getBlueOffset());
   4450            break;
   4451        case EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR:
   4452            *value = static_cast<EGLAttribKHR>(surface->getAlphaOffset());
   4453            break;
   4454        case EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR:
   4455            *value = static_cast<EGLAttribKHR>(surface->getLuminanceOffset());
   4456            break;
   4457        case EGL_BITMAP_PIXEL_SIZE_KHR:
   4458            *value = static_cast<EGLAttribKHR>(surface->getBitmapPixelSize());
   4459            break;
   4460        case EGL_BITMAP_POINTER_KHR:
   4461            *value = surface->getBitmapPointer();
   4462            break;
   4463        default:
   4464            UNREACHABLE();
   4465            break;
   4466    }
   4467    return NoError();
   4468 }
   4469 
   4470 egl::Error SetSurfaceAttrib(Surface *surface, EGLint attribute, EGLint value)
   4471 {
   4472    switch (attribute)
   4473    {
   4474        case EGL_MIPMAP_LEVEL:
   4475            surface->setMipmapLevel(value);
   4476            break;
   4477        case EGL_MULTISAMPLE_RESOLVE:
   4478            surface->setMultisampleResolve(value);
   4479            break;
   4480        case EGL_SWAP_BEHAVIOR:
   4481            surface->setSwapBehavior(value);
   4482            break;
   4483        case EGL_WIDTH:
   4484            surface->setFixedWidth(value);
   4485            break;
   4486        case EGL_HEIGHT:
   4487            surface->setFixedHeight(value);
   4488            break;
   4489        case EGL_TIMESTAMPS_ANDROID:
   4490            surface->setTimestampsEnabled(value != EGL_FALSE);
   4491            break;
   4492        case EGL_FRONT_BUFFER_AUTO_REFRESH_ANDROID:
   4493            return surface->setAutoRefreshEnabled(value == EGL_TRUE);
   4494        case EGL_RENDER_BUFFER:
   4495            return surface->setRenderBuffer(value);
   4496        default:
   4497            UNREACHABLE();
   4498            break;
   4499    }
   4500    return NoError();
   4501 }
   4502 
   4503 Error GetSyncAttrib(Display *display, Sync *sync, EGLint attribute, EGLint *value)
   4504 {
   4505    switch (attribute)
   4506    {
   4507        case EGL_SYNC_TYPE_KHR:
   4508            *value = sync->getType();
   4509            return NoError();
   4510 
   4511        case EGL_SYNC_STATUS_KHR:
   4512            return sync->getStatus(display, value);
   4513 
   4514        case EGL_SYNC_CONDITION_KHR:
   4515            *value = sync->getCondition();
   4516            return NoError();
   4517 
   4518        default:
   4519            break;
   4520    }
   4521 
   4522    UNREACHABLE();
   4523    return NoError();
   4524 }
   4525 }  // namespace egl