Edit

kc3-lang/angle/src/libANGLE/queryutils.cpp

Branch :

  • Show log

    Commit

  • Author : Jamie Madill
    Date : 2017-04-20 15:46:24
    Hash : 876429b7
    Message : Update gl2.h and update entry points. Some method signatures were updated. Types like GLclampf and GLvoid were replaced with other equivalents. BUG=angleproject:1309 Change-Id: I05e8e2072c5a063d87ad96a855b907424661e680 Reviewed-on: https://chromium-review.googlesource.com/475011 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: Geoff Lang <geofflang@chromium.org>

  • src/libANGLE/queryutils.cpp
  • //
    // Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
    // Use of this source code is governed by a BSD-style license that can be
    // found in the LICENSE file.
    //
    
    // queryutils.cpp: Utilities for querying values from GL objects
    
    #include "libANGLE/queryutils.h"
    
    #include "common/utilities.h"
    
    #include "libANGLE/Buffer.h"
    #include "libANGLE/Config.h"
    #include "libANGLE/Context.h"
    #include "libANGLE/Fence.h"
    #include "libANGLE/Framebuffer.h"
    #include "libANGLE/Program.h"
    #include "libANGLE/Renderbuffer.h"
    #include "libANGLE/Sampler.h"
    #include "libANGLE/Shader.h"
    #include "libANGLE/Texture.h"
    #include "libANGLE/Uniform.h"
    #include "libANGLE/VertexAttribute.h"
    
    namespace gl
    {
    
    namespace
    {
    template <typename ParamType>
    void QueryTexLevelParameterBase(const Texture *texture,
                                    GLenum target,
                                    GLint level,
                                    GLenum pname,
                                    ParamType *params)
    {
        ASSERT(texture != nullptr);
        const InternalFormat *info = texture->getTextureState().getImageDesc(target, level).format.info;
    
        switch (pname)
        {
            case GL_TEXTURE_RED_TYPE:
                *params = ConvertFromGLenum<ParamType>(info->redBits ? info->componentType : GL_NONE);
                break;
            case GL_TEXTURE_GREEN_TYPE:
                *params = ConvertFromGLenum<ParamType>(info->greenBits ? info->componentType : GL_NONE);
                break;
            case GL_TEXTURE_BLUE_TYPE:
                *params = ConvertFromGLenum<ParamType>(info->blueBits ? info->componentType : GL_NONE);
                break;
            case GL_TEXTURE_ALPHA_TYPE:
                *params = ConvertFromGLenum<ParamType>(info->alphaBits ? info->componentType : GL_NONE);
                break;
            case GL_TEXTURE_DEPTH_TYPE:
                *params = ConvertFromGLenum<ParamType>(info->depthBits ? info->componentType : GL_NONE);
                break;
            case GL_TEXTURE_RED_SIZE:
                *params = ConvertFromGLuint<ParamType>(info->redBits);
                break;
            case GL_TEXTURE_GREEN_SIZE:
                *params = ConvertFromGLuint<ParamType>(info->greenBits);
                break;
            case GL_TEXTURE_BLUE_SIZE:
                *params = ConvertFromGLuint<ParamType>(info->blueBits);
                break;
            case GL_TEXTURE_ALPHA_SIZE:
                *params = ConvertFromGLuint<ParamType>(info->alphaBits);
                break;
            case GL_TEXTURE_DEPTH_SIZE:
                *params = ConvertFromGLuint<ParamType>(info->depthBits);
                break;
            case GL_TEXTURE_STENCIL_SIZE:
                *params = ConvertFromGLuint<ParamType>(info->stencilBits);
                break;
            case GL_TEXTURE_SHARED_SIZE:
                *params = ConvertFromGLuint<ParamType>(info->sharedBits);
                break;
            case GL_TEXTURE_INTERNAL_FORMAT:
                *params =
                    ConvertFromGLenum<ParamType>(info->internalFormat ? info->internalFormat : GL_RGBA);
                break;
            case GL_TEXTURE_WIDTH:
                *params =
                    ConvertFromGLint<ParamType>(static_cast<GLint>(texture->getWidth(target, level)));
                break;
            case GL_TEXTURE_HEIGHT:
                *params =
                    ConvertFromGLint<ParamType>(static_cast<GLint>(texture->getHeight(target, level)));
                break;
            case GL_TEXTURE_DEPTH:
                *params =
                    ConvertFromGLint<ParamType>(static_cast<GLint>(texture->getDepth(target, level)));
                break;
            case GL_TEXTURE_SAMPLES:
                *params = ConvertFromGLint<ParamType>(texture->getSamples(target, level));
                break;
            case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS:
                *params =
                    ConvertFromGLboolean<ParamType>(texture->getFixedSampleLocations(target, level));
                break;
            case GL_TEXTURE_COMPRESSED:
                *params = ConvertFromGLboolean<ParamType>(info->compressed);
                break;
            default:
                UNREACHABLE();
                break;
        }
    }
    
    template <typename ParamType>
    void QueryTexParameterBase(const Texture *texture, GLenum pname, ParamType *params)
    {
        ASSERT(texture != nullptr);
    
        switch (pname)
        {
            case GL_TEXTURE_MAG_FILTER:
                *params = ConvertFromGLenum<ParamType>(texture->getMagFilter());
                break;
            case GL_TEXTURE_MIN_FILTER:
                *params = ConvertFromGLenum<ParamType>(texture->getMinFilter());
                break;
            case GL_TEXTURE_WRAP_S:
                *params = ConvertFromGLenum<ParamType>(texture->getWrapS());
                break;
            case GL_TEXTURE_WRAP_T:
                *params = ConvertFromGLenum<ParamType>(texture->getWrapT());
                break;
            case GL_TEXTURE_WRAP_R:
                *params = ConvertFromGLenum<ParamType>(texture->getWrapR());
                break;
            case GL_TEXTURE_IMMUTABLE_FORMAT:
                *params = ConvertFromGLboolean<ParamType>(texture->getImmutableFormat());
                break;
            case GL_TEXTURE_IMMUTABLE_LEVELS:
                *params = ConvertFromGLuint<ParamType>(texture->getImmutableLevels());
                break;
            case GL_TEXTURE_USAGE_ANGLE:
                *params = ConvertFromGLenum<ParamType>(texture->getUsage());
                break;
            case GL_TEXTURE_MAX_ANISOTROPY_EXT:
                *params = ConvertFromGLfloat<ParamType>(texture->getMaxAnisotropy());
                break;
            case GL_TEXTURE_SWIZZLE_R:
                *params = ConvertFromGLenum<ParamType>(texture->getSwizzleRed());
                break;
            case GL_TEXTURE_SWIZZLE_G:
                *params = ConvertFromGLenum<ParamType>(texture->getSwizzleGreen());
                break;
            case GL_TEXTURE_SWIZZLE_B:
                *params = ConvertFromGLenum<ParamType>(texture->getSwizzleBlue());
                break;
            case GL_TEXTURE_SWIZZLE_A:
                *params = ConvertFromGLenum<ParamType>(texture->getSwizzleAlpha());
                break;
            case GL_TEXTURE_BASE_LEVEL:
                *params = ConvertFromGLuint<ParamType>(texture->getBaseLevel());
                break;
            case GL_TEXTURE_MAX_LEVEL:
                *params = ConvertFromGLuint<ParamType>(texture->getMaxLevel());
                break;
            case GL_TEXTURE_MIN_LOD:
                *params = ConvertFromGLfloat<ParamType>(texture->getSamplerState().minLod);
                break;
            case GL_TEXTURE_MAX_LOD:
                *params = ConvertFromGLfloat<ParamType>(texture->getSamplerState().maxLod);
                break;
            case GL_TEXTURE_COMPARE_MODE:
                *params = ConvertFromGLenum<ParamType>(texture->getCompareMode());
                break;
            case GL_TEXTURE_COMPARE_FUNC:
                *params = ConvertFromGLenum<ParamType>(texture->getCompareFunc());
                break;
            case GL_TEXTURE_SRGB_DECODE_EXT:
                *params = ConvertFromGLenum<ParamType>(texture->getSRGBDecode());
                break;
            default:
                UNREACHABLE();
                break;
        }
    }
    
    template <typename ParamType>
    void SetTexParameterBase(Texture *texture, GLenum pname, const ParamType *params)
    {
        ASSERT(texture != nullptr);
    
        switch (pname)
        {
            case GL_TEXTURE_WRAP_S:
                texture->setWrapS(ConvertToGLenum(params[0]));
                break;
            case GL_TEXTURE_WRAP_T:
                texture->setWrapT(ConvertToGLenum(params[0]));
                break;
            case GL_TEXTURE_WRAP_R:
                texture->setWrapR(ConvertToGLenum(params[0]));
                break;
            case GL_TEXTURE_MIN_FILTER:
                texture->setMinFilter(ConvertToGLenum(params[0]));
                break;
            case GL_TEXTURE_MAG_FILTER:
                texture->setMagFilter(ConvertToGLenum(params[0]));
                break;
            case GL_TEXTURE_USAGE_ANGLE:
                texture->setUsage(ConvertToGLenum(params[0]));
                break;
            case GL_TEXTURE_MAX_ANISOTROPY_EXT:
                texture->setMaxAnisotropy(ConvertToGLfloat(params[0]));
                break;
            case GL_TEXTURE_COMPARE_MODE:
                texture->setCompareMode(ConvertToGLenum(params[0]));
                break;
            case GL_TEXTURE_COMPARE_FUNC:
                texture->setCompareFunc(ConvertToGLenum(params[0]));
                break;
            case GL_TEXTURE_SWIZZLE_R:
                texture->setSwizzleRed(ConvertToGLenum(params[0]));
                break;
            case GL_TEXTURE_SWIZZLE_G:
                texture->setSwizzleGreen(ConvertToGLenum(params[0]));
                break;
            case GL_TEXTURE_SWIZZLE_B:
                texture->setSwizzleBlue(ConvertToGLenum(params[0]));
                break;
            case GL_TEXTURE_SWIZZLE_A:
                texture->setSwizzleAlpha(ConvertToGLenum(params[0]));
                break;
            case GL_TEXTURE_BASE_LEVEL:
                texture->setBaseLevel(ConvertToGLuint(params[0]));
                break;
            case GL_TEXTURE_MAX_LEVEL:
                texture->setMaxLevel(ConvertToGLuint(params[0]));
                break;
            case GL_TEXTURE_MIN_LOD:
                texture->setMinLod(ConvertToGLfloat(params[0]));
                break;
            case GL_TEXTURE_MAX_LOD:
                texture->setMaxLod(ConvertToGLfloat(params[0]));
                break;
            case GL_DEPTH_STENCIL_TEXTURE_MODE:
                texture->setDepthStencilTextureMode(ConvertToGLenum(params[0]));
                break;
            case GL_TEXTURE_SRGB_DECODE_EXT:
                texture->setSRGBDecode(ConvertToGLenum(params[0]));
                break;
            default:
                UNREACHABLE();
                break;
        }
    }
    
    template <typename ParamType>
    void QuerySamplerParameterBase(const Sampler *sampler, GLenum pname, ParamType *params)
    {
        switch (pname)
        {
            case GL_TEXTURE_MIN_FILTER:
                *params = ConvertFromGLenum<ParamType>(sampler->getMinFilter());
                break;
            case GL_TEXTURE_MAG_FILTER:
                *params = ConvertFromGLenum<ParamType>(sampler->getMagFilter());
                break;
            case GL_TEXTURE_WRAP_S:
                *params = ConvertFromGLenum<ParamType>(sampler->getWrapS());
                break;
            case GL_TEXTURE_WRAP_T:
                *params = ConvertFromGLenum<ParamType>(sampler->getWrapT());
                break;
            case GL_TEXTURE_WRAP_R:
                *params = ConvertFromGLenum<ParamType>(sampler->getWrapR());
                break;
            case GL_TEXTURE_MAX_ANISOTROPY_EXT:
                *params = ConvertFromGLfloat<ParamType>(sampler->getMaxAnisotropy());
                break;
            case GL_TEXTURE_MIN_LOD:
                *params = ConvertFromGLfloat<ParamType>(sampler->getMinLod());
                break;
            case GL_TEXTURE_MAX_LOD:
                *params = ConvertFromGLfloat<ParamType>(sampler->getMaxLod());
                break;
            case GL_TEXTURE_COMPARE_MODE:
                *params = ConvertFromGLenum<ParamType>(sampler->getCompareMode());
                break;
            case GL_TEXTURE_COMPARE_FUNC:
                *params = ConvertFromGLenum<ParamType>(sampler->getCompareFunc());
                break;
            case GL_TEXTURE_SRGB_DECODE_EXT:
                *params = ConvertFromGLenum<ParamType>(sampler->getSRGBDecode());
                break;
            default:
                UNREACHABLE();
                break;
        }
    }
    
    template <typename ParamType>
    void SetSamplerParameterBase(Sampler *sampler, GLenum pname, const ParamType *params)
    {
        switch (pname)
        {
            case GL_TEXTURE_WRAP_S:
                sampler->setWrapS(ConvertToGLenum(params[0]));
                break;
            case GL_TEXTURE_WRAP_T:
                sampler->setWrapT(ConvertToGLenum(params[0]));
                break;
            case GL_TEXTURE_WRAP_R:
                sampler->setWrapR(ConvertToGLenum(params[0]));
                break;
            case GL_TEXTURE_MIN_FILTER:
                sampler->setMinFilter(ConvertToGLenum(params[0]));
                break;
            case GL_TEXTURE_MAG_FILTER:
                sampler->setMagFilter(ConvertToGLenum(params[0]));
                break;
            case GL_TEXTURE_MAX_ANISOTROPY_EXT:
                sampler->setMaxAnisotropy(ConvertToGLfloat(params[0]));
                break;
            case GL_TEXTURE_COMPARE_MODE:
                sampler->setCompareMode(ConvertToGLenum(params[0]));
                break;
            case GL_TEXTURE_COMPARE_FUNC:
                sampler->setCompareFunc(ConvertToGLenum(params[0]));
                break;
            case GL_TEXTURE_MIN_LOD:
                sampler->setMinLod(ConvertToGLfloat(params[0]));
                break;
            case GL_TEXTURE_MAX_LOD:
                sampler->setMaxLod(ConvertToGLfloat(params[0]));
                break;
            case GL_TEXTURE_SRGB_DECODE_EXT:
                sampler->setSRGBDecode(ConvertToGLenum(params[0]));
                break;
            default:
                UNREACHABLE();
                break;
        }
    }
    
    template <typename ParamType, typename CurrentDataType>
    ParamType ConvertCurrentValue(CurrentDataType currentValue)
    {
        return static_cast<ParamType>(currentValue);
    }
    
    template <>
    GLint ConvertCurrentValue(GLfloat currentValue)
    {
        return iround<GLint>(currentValue);
    }
    
    // Warning: you should ensure binding really matches attrib.bindingIndex before using this function.
    template <typename ParamType, typename CurrentDataType, size_t CurrentValueCount>
    void QueryVertexAttribBase(const VertexAttribute &attrib,
                               const VertexBinding &binding,
                               const CurrentDataType (&currentValueData)[CurrentValueCount],
                               GLenum pname,
                               ParamType *params)
    {
        switch (pname)
        {
            case GL_CURRENT_VERTEX_ATTRIB:
                for (size_t i = 0; i < CurrentValueCount; ++i)
                {
                    params[i] = ConvertCurrentValue<ParamType>(currentValueData[i]);
                }
                break;
            case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
                *params = ConvertFromGLboolean<ParamType>(attrib.enabled);
                break;
            case GL_VERTEX_ATTRIB_ARRAY_SIZE:
                *params = ConvertFromGLuint<ParamType>(attrib.size);
                break;
            case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
                *params = ConvertFromGLuint<ParamType>(attrib.vertexAttribArrayStride);
                break;
            case GL_VERTEX_ATTRIB_ARRAY_TYPE:
                *params = ConvertFromGLenum<ParamType>(attrib.type);
                break;
            case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
                *params = ConvertFromGLboolean<ParamType>(attrib.normalized);
                break;
            case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
                *params = ConvertFromGLuint<ParamType>(binding.buffer.id());
                break;
            case GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
                *params = ConvertFromGLuint<ParamType>(binding.divisor);
                break;
            case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
                *params = ConvertFromGLboolean<ParamType>(attrib.pureInteger);
                break;
            case GL_VERTEX_ATTRIB_BINDING:
                *params = ConvertFromGLuint<ParamType>(attrib.bindingIndex);
                break;
            case GL_VERTEX_ATTRIB_RELATIVE_OFFSET:
                // attrib.relativeOffset should not be negative or greater than max GLint
                ASSERT(attrib.relativeOffset >= 0 &&
                       attrib.relativeOffset <= std::numeric_limits<GLint>::max());
                *params = ConvertFromGLint<ParamType>(static_cast<GLint>(attrib.relativeOffset));
                break;
            default:
                UNREACHABLE();
                break;
        }
    }
    
    template <typename ParamType>
    void QueryBufferParameterBase(const Buffer *buffer, GLenum pname, ParamType *params)
    {
        ASSERT(buffer != nullptr);
    
        switch (pname)
        {
            case GL_BUFFER_USAGE:
                *params = ConvertFromGLenum<ParamType>(buffer->getUsage());
                break;
            case GL_BUFFER_SIZE:
                *params = ConvertFromGLint64<ParamType>(buffer->getSize());
                break;
            case GL_BUFFER_ACCESS_FLAGS:
                *params = ConvertFromGLuint<ParamType>(buffer->getAccessFlags());
                break;
            case GL_BUFFER_ACCESS_OES:
                *params = ConvertFromGLenum<ParamType>(buffer->getAccess());
                break;
            case GL_BUFFER_MAPPED:
                *params = ConvertFromGLboolean<ParamType>(buffer->isMapped());
                break;
            case GL_BUFFER_MAP_OFFSET:
                *params = ConvertFromGLint64<ParamType>(buffer->getMapOffset());
                break;
            case GL_BUFFER_MAP_LENGTH:
                *params = ConvertFromGLint64<ParamType>(buffer->getMapLength());
                break;
            default:
                UNREACHABLE();
                break;
        }
    }
    
    }  // anonymous namespace
    
    void QueryFramebufferAttachmentParameteriv(const Framebuffer *framebuffer,
                                               GLenum attachment,
                                               GLenum pname,
                                               GLint *params)
    {
        ASSERT(framebuffer);
    
        const FramebufferAttachment *attachmentObject = framebuffer->getAttachment(attachment);
        if (attachmentObject == nullptr)
        {
            // ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE
            // is NONE, then querying any other pname will generate INVALID_ENUM.
    
            // ES 3.0.2 spec pg 235 states that if the attachment type is none,
            // GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an
            // INVALID_OPERATION for all other pnames
    
            switch (pname)
            {
                case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
                    *params = GL_NONE;
                    break;
    
                case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
                    *params = 0;
                    break;
    
                default:
                    UNREACHABLE();
                    break;
            }
    
            return;
        }
    
        switch (pname)
        {
            case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
                *params = attachmentObject->type();
                break;
    
            case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
                *params = attachmentObject->id();
                break;
    
            case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
                *params = attachmentObject->mipLevel();
                break;
    
            case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
                *params = attachmentObject->cubeMapFace();
                break;
    
            case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
                *params = attachmentObject->getRedSize();
                break;
    
            case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
                *params = attachmentObject->getGreenSize();
                break;
    
            case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
                *params = attachmentObject->getBlueSize();
                break;
    
            case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
                *params = attachmentObject->getAlphaSize();
                break;
    
            case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
                *params = attachmentObject->getDepthSize();
                break;
    
            case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
                *params = attachmentObject->getStencilSize();
                break;
    
            case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
                *params = attachmentObject->getComponentType();
                break;
    
            case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
                *params = attachmentObject->getColorEncoding();
                break;
    
            case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
                *params = attachmentObject->layer();
                break;
    
            default:
                UNREACHABLE();
                break;
        }
    }
    
    void QueryBufferParameteriv(const Buffer *buffer, GLenum pname, GLint *params)
    {
        QueryBufferParameterBase(buffer, pname, params);
    }
    
    void QueryBufferParameteri64v(const Buffer *buffer, GLenum pname, GLint64 *params)
    {
        QueryBufferParameterBase(buffer, pname, params);
    }
    
    void QueryBufferPointerv(const Buffer *buffer, GLenum pname, void **params)
    {
        switch (pname)
        {
            case GL_BUFFER_MAP_POINTER:
                *params = buffer->getMapPointer();
                break;
    
            default:
                UNREACHABLE();
                break;
        }
    }
    
    void QueryProgramiv(const Program *program, GLenum pname, GLint *params)
    {
        ASSERT(program != nullptr);
    
        switch (pname)
        {
            case GL_DELETE_STATUS:
                *params = program->isFlaggedForDeletion();
                return;
            case GL_LINK_STATUS:
                *params = program->isLinked();
                return;
            case GL_VALIDATE_STATUS:
                *params = program->isValidated();
                return;
            case GL_INFO_LOG_LENGTH:
                *params = program->getInfoLogLength();
                return;
            case GL_ATTACHED_SHADERS:
                *params = program->getAttachedShadersCount();
                return;
            case GL_ACTIVE_ATTRIBUTES:
                *params = program->getActiveAttributeCount();
                return;
            case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
                *params = program->getActiveAttributeMaxLength();
                return;
            case GL_ACTIVE_UNIFORMS:
                *params = program->getActiveUniformCount();
                return;
            case GL_ACTIVE_UNIFORM_MAX_LENGTH:
                *params = program->getActiveUniformMaxLength();
                return;
            case GL_PROGRAM_BINARY_LENGTH_OES:
                *params = program->getBinaryLength();
                return;
            case GL_ACTIVE_UNIFORM_BLOCKS:
                *params = program->getActiveUniformBlockCount();
                return;
            case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH:
                *params = program->getActiveUniformBlockMaxLength();
                break;
            case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
                *params = program->getTransformFeedbackBufferMode();
                break;
            case GL_TRANSFORM_FEEDBACK_VARYINGS:
                *params = program->getTransformFeedbackVaryingCount();
                break;
            case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
                *params = program->getTransformFeedbackVaryingMaxLength();
                break;
            case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
                *params = program->getBinaryRetrievableHint();
                break;
            case GL_PROGRAM_SEPARABLE:
                *params = program->isSeparable();
                break;
            default:
                UNREACHABLE();
                break;
        }
    }
    
    void QueryRenderbufferiv(const Context *context,
                             const Renderbuffer *renderbuffer,
                             GLenum pname,
                             GLint *params)
    {
        ASSERT(renderbuffer != nullptr);
    
        switch (pname)
        {
            case GL_RENDERBUFFER_WIDTH:
                *params = renderbuffer->getWidth();
                break;
            case GL_RENDERBUFFER_HEIGHT:
                *params = renderbuffer->getHeight();
                break;
            case GL_RENDERBUFFER_INTERNAL_FORMAT:
                // Special case the WebGL 1 DEPTH_STENCIL format.
                if (context->isWebGL1() &&
                    renderbuffer->getFormat().info->internalFormat == GL_DEPTH24_STENCIL8)
                {
                    *params = GL_DEPTH_STENCIL;
                }
                else
                {
                    *params = renderbuffer->getFormat().info->internalFormat;
                }
                break;
            case GL_RENDERBUFFER_RED_SIZE:
                *params = renderbuffer->getRedSize();
                break;
            case GL_RENDERBUFFER_GREEN_SIZE:
                *params = renderbuffer->getGreenSize();
                break;
            case GL_RENDERBUFFER_BLUE_SIZE:
                *params = renderbuffer->getBlueSize();
                break;
            case GL_RENDERBUFFER_ALPHA_SIZE:
                *params = renderbuffer->getAlphaSize();
                break;
            case GL_RENDERBUFFER_DEPTH_SIZE:
                *params = renderbuffer->getDepthSize();
                break;
            case GL_RENDERBUFFER_STENCIL_SIZE:
                *params = renderbuffer->getStencilSize();
                break;
            case GL_RENDERBUFFER_SAMPLES_ANGLE:
                *params = renderbuffer->getSamples();
                break;
            default:
                UNREACHABLE();
                break;
        }
    }
    
    void QueryShaderiv(const Shader *shader, GLenum pname, GLint *params)
    {
        ASSERT(shader != nullptr);
    
        switch (pname)
        {
            case GL_SHADER_TYPE:
                *params = shader->getType();
                return;
            case GL_DELETE_STATUS:
                *params = shader->isFlaggedForDeletion();
                return;
            case GL_COMPILE_STATUS:
                *params = shader->isCompiled() ? GL_TRUE : GL_FALSE;
                return;
            case GL_INFO_LOG_LENGTH:
                *params = shader->getInfoLogLength();
                return;
            case GL_SHADER_SOURCE_LENGTH:
                *params = shader->getSourceLength();
                return;
            case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
                *params = shader->getTranslatedSourceWithDebugInfoLength();
                return;
            default:
                UNREACHABLE();
                break;
        }
    }
    
    void QueryTexLevelParameterfv(const Texture *texture,
                                  GLenum target,
                                  GLint level,
                                  GLenum pname,
                                  GLfloat *params)
    {
        QueryTexLevelParameterBase(texture, target, level, pname, params);
    }
    
    void QueryTexLevelParameteriv(const Texture *texture,
                                  GLenum target,
                                  GLint level,
                                  GLenum pname,
                                  GLint *params)
    {
        QueryTexLevelParameterBase(texture, target, level, pname, params);
    }
    
    void QueryTexParameterfv(const Texture *texture, GLenum pname, GLfloat *params)
    {
        QueryTexParameterBase(texture, pname, params);
    }
    
    void QueryTexParameteriv(const Texture *texture, GLenum pname, GLint *params)
    {
        QueryTexParameterBase(texture, pname, params);
    }
    
    void QuerySamplerParameterfv(const Sampler *sampler, GLenum pname, GLfloat *params)
    {
        QuerySamplerParameterBase(sampler, pname, params);
    }
    
    void QuerySamplerParameteriv(const Sampler *sampler, GLenum pname, GLint *params)
    {
        QuerySamplerParameterBase(sampler, pname, params);
    }
    
    void QueryVertexAttribfv(const VertexAttribute &attrib,
                             const VertexBinding &binding,
                             const VertexAttribCurrentValueData &currentValueData,
                             GLenum pname,
                             GLfloat *params)
    {
        QueryVertexAttribBase(attrib, binding, currentValueData.FloatValues, pname, params);
    }
    
    void QueryVertexAttribiv(const VertexAttribute &attrib,
                             const VertexBinding &binding,
                             const VertexAttribCurrentValueData &currentValueData,
                             GLenum pname,
                             GLint *params)
    {
        QueryVertexAttribBase(attrib, binding, currentValueData.FloatValues, pname, params);
    }
    
    void QueryVertexAttribPointerv(const VertexAttribute &attrib, GLenum pname, void **pointer)
    {
        switch (pname)
        {
            case GL_VERTEX_ATTRIB_ARRAY_POINTER:
                *pointer = const_cast<void *>(attrib.pointer);
                break;
    
            default:
                UNREACHABLE();
                break;
        }
    }
    
    void QueryVertexAttribIiv(const VertexAttribute &attrib,
                              const VertexBinding &binding,
                              const VertexAttribCurrentValueData &currentValueData,
                              GLenum pname,
                              GLint *params)
    {
        QueryVertexAttribBase(attrib, binding, currentValueData.IntValues, pname, params);
    }
    
    void QueryVertexAttribIuiv(const VertexAttribute &attrib,
                               const VertexBinding &binding,
                               const VertexAttribCurrentValueData &currentValueData,
                               GLenum pname,
                               GLuint *params)
    {
        QueryVertexAttribBase(attrib, binding, currentValueData.UnsignedIntValues, pname, params);
    }
    
    void QueryActiveUniformBlockiv(const Program *program,
                                   GLuint uniformBlockIndex,
                                   GLenum pname,
                                   GLint *params)
    {
        const UniformBlock &uniformBlock = program->getUniformBlockByIndex(uniformBlockIndex);
        switch (pname)
        {
            case GL_UNIFORM_BLOCK_BINDING:
                *params = ConvertToGLint(program->getUniformBlockBinding(uniformBlockIndex));
                break;
            case GL_UNIFORM_BLOCK_DATA_SIZE:
                *params = ConvertToGLint(uniformBlock.dataSize);
                break;
            case GL_UNIFORM_BLOCK_NAME_LENGTH:
                *params = ConvertToGLint(uniformBlock.nameWithArrayIndex().size() + 1);
                break;
            case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
                *params = ConvertToGLint(uniformBlock.memberUniformIndexes.size());
                break;
            case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
                for (size_t blockMemberIndex = 0;
                     blockMemberIndex < uniformBlock.memberUniformIndexes.size(); blockMemberIndex++)
                {
                    params[blockMemberIndex] =
                        ConvertToGLint(uniformBlock.memberUniformIndexes[blockMemberIndex]);
                }
                break;
            case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
                *params = ConvertToGLint(uniformBlock.vertexStaticUse);
                break;
            case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
                *params = ConvertToGLint(uniformBlock.fragmentStaticUse);
                break;
            default:
                UNREACHABLE();
                break;
        }
    }
    
    void QueryInternalFormativ(const TextureCaps &format, GLenum pname, GLsizei bufSize, GLint *params)
    {
        switch (pname)
        {
            case GL_NUM_SAMPLE_COUNTS:
                if (bufSize != 0)
                {
                    *params = static_cast<GLint>(format.sampleCounts.size());
                }
                break;
    
            case GL_SAMPLES:
            {
                size_t returnCount   = std::min<size_t>(bufSize, format.sampleCounts.size());
                auto sampleReverseIt = format.sampleCounts.rbegin();
                for (size_t sampleIndex = 0; sampleIndex < returnCount; ++sampleIndex)
                {
                    params[sampleIndex] = *sampleReverseIt++;
                }
            }
            break;
    
            default:
                UNREACHABLE();
                break;
        }
    }
    
    void QueryFramebufferParameteriv(const Framebuffer *framebuffer, GLenum pname, GLint *params)
    {
        ASSERT(framebuffer);
    
        switch (pname)
        {
            case GL_FRAMEBUFFER_DEFAULT_WIDTH:
                *params = framebuffer->getDefaultWidth();
                break;
            case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
                *params = framebuffer->getDefaultHeight();
                break;
            case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
                *params = framebuffer->getDefaultSamples();
                break;
            case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
                *params = framebuffer->getDefaultFixedSampleLocations();
                break;
            default:
                UNREACHABLE();
                break;
        }
    }
    
    Error QuerySynciv(const FenceSync *sync,
                      GLenum pname,
                      GLsizei bufSize,
                      GLsizei *length,
                      GLint *values)
    {
        ASSERT(sync);
    
        // All queries return one value, exit early if the buffer can't fit anything.
        if (bufSize < 1)
        {
            if (length != nullptr)
            {
                *length = 0;
            }
            return NoError();
        }
    
        switch (pname)
        {
            case GL_OBJECT_TYPE:
                *values = ConvertToGLint(GL_SYNC_FENCE);
                break;
            case GL_SYNC_CONDITION:
                *values = ConvertToGLint(sync->getCondition());
                break;
            case GL_SYNC_FLAGS:
                *values = ConvertToGLint(sync->getFlags());
                break;
            case GL_SYNC_STATUS:
                ANGLE_TRY(sync->getStatus(values));
                break;
    
            default:
                UNREACHABLE();
                break;
        }
    
        if (length != nullptr)
        {
            *length = 1;
        }
    
        return NoError();
    }
    
    void SetTexParameterf(Texture *texture, GLenum pname, GLfloat param)
    {
        SetTexParameterBase(texture, pname, &param);
    }
    
    void SetTexParameterfv(Texture *texture, GLenum pname, const GLfloat *params)
    {
        SetTexParameterBase(texture, pname, params);
    }
    
    void SetTexParameteri(Texture *texture, GLenum pname, GLint param)
    {
        SetTexParameterBase(texture, pname, &param);
    }
    
    void SetTexParameteriv(Texture *texture, GLenum pname, const GLint *params)
    {
        SetTexParameterBase(texture, pname, params);
    }
    
    void SetSamplerParameterf(Sampler *sampler, GLenum pname, GLfloat param)
    {
        SetSamplerParameterBase(sampler, pname, &param);
    }
    
    void SetSamplerParameterfv(Sampler *sampler, GLenum pname, const GLfloat *params)
    {
        SetSamplerParameterBase(sampler, pname, params);
    }
    
    void SetSamplerParameteri(Sampler *sampler, GLenum pname, GLint param)
    {
        SetSamplerParameterBase(sampler, pname, &param);
    }
    
    void SetSamplerParameteriv(Sampler *sampler, GLenum pname, const GLint *params)
    {
        SetSamplerParameterBase(sampler, pname, params);
    }
    
    void SetFramebufferParameteri(Framebuffer *framebuffer, GLenum pname, GLint param)
    {
        ASSERT(framebuffer);
    
        switch (pname)
        {
            case GL_FRAMEBUFFER_DEFAULT_WIDTH:
                framebuffer->setDefaultWidth(param);
                break;
            case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
                framebuffer->setDefaultHeight(param);
                break;
            case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
                framebuffer->setDefaultSamples(param);
                break;
            case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
                framebuffer->setDefaultFixedSampleLocations(static_cast<GLboolean>(param));
                break;
            default:
                UNREACHABLE();
                break;
        }
    }
    
    void SetProgramParameteri(Program *program, GLenum pname, GLint value)
    {
        ASSERT(program);
    
        switch (pname)
        {
            case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
                program->setBinaryRetrievableHint(value != GL_FALSE);
                break;
            case GL_PROGRAM_SEPARABLE:
                program->setSeparable(value != GL_FALSE);
                break;
            default:
                UNREACHABLE();
                break;
        }
    }
    
    GLuint QueryProgramResourceIndex(const Program *program,
                                     GLenum programInterface,
                                     const GLchar *name)
    {
        switch (programInterface)
        {
            case GL_PROGRAM_INPUT:
                return program->getInputResourceIndex(name);
    
            case GL_PROGRAM_OUTPUT:
                return program->getOutputResourceIndex(name);
    
            // TODO(Jie): more interfaces.
            case GL_UNIFORM:
            case GL_UNIFORM_BLOCK:
            case GL_TRANSFORM_FEEDBACK_VARYING:
            case GL_BUFFER_VARIABLE:
            case GL_SHADER_STORAGE_BLOCK:
                UNIMPLEMENTED();
                return GL_INVALID_INDEX;
    
            default:
                UNREACHABLE();
                return GL_INVALID_INDEX;
        }
    }
    
    void QueryProgramResourceName(const Program *program,
                                  GLenum programInterface,
                                  GLuint index,
                                  GLsizei bufSize,
                                  GLsizei *length,
                                  GLchar *name)
    {
        switch (programInterface)
        {
            case GL_PROGRAM_INPUT:
                program->getInputResourceName(index, bufSize, length, name);
                break;
    
            case GL_PROGRAM_OUTPUT:
                program->getOutputResourceName(index, bufSize, length, name);
                break;
    
            // TODO(Jie): more interfaces.
            case GL_UNIFORM:
            case GL_UNIFORM_BLOCK:
            case GL_TRANSFORM_FEEDBACK_VARYING:
            case GL_BUFFER_VARIABLE:
            case GL_SHADER_STORAGE_BLOCK:
                UNIMPLEMENTED();
                break;
    
            default:
                UNREACHABLE();
        }
    }
    
    }  // namespace gl
    
    namespace egl
    {
    
    void QueryConfigAttrib(const Config *config, EGLint attribute, EGLint *value)
    {
        ASSERT(config != nullptr);
        switch (attribute)
        {
            case EGL_BUFFER_SIZE:
                *value = config->bufferSize;
                break;
            case EGL_ALPHA_SIZE:
                *value = config->alphaSize;
                break;
            case EGL_BLUE_SIZE:
                *value = config->blueSize;
                break;
            case EGL_GREEN_SIZE:
                *value = config->greenSize;
                break;
            case EGL_RED_SIZE:
                *value = config->redSize;
                break;
            case EGL_DEPTH_SIZE:
                *value = config->depthSize;
                break;
            case EGL_STENCIL_SIZE:
                *value = config->stencilSize;
                break;
            case EGL_CONFIG_CAVEAT:
                *value = config->configCaveat;
                break;
            case EGL_CONFIG_ID:
                *value = config->configID;
                break;
            case EGL_LEVEL:
                *value = config->level;
                break;
            case EGL_NATIVE_RENDERABLE:
                *value = config->nativeRenderable;
                break;
            case EGL_NATIVE_VISUAL_ID:
                *value = config->nativeVisualID;
                break;
            case EGL_NATIVE_VISUAL_TYPE:
                *value = config->nativeVisualType;
                break;
            case EGL_SAMPLES:
                *value = config->samples;
                break;
            case EGL_SAMPLE_BUFFERS:
                *value = config->sampleBuffers;
                break;
            case EGL_SURFACE_TYPE:
                *value = config->surfaceType;
                break;
            case EGL_TRANSPARENT_TYPE:
                *value = config->transparentType;
                break;
            case EGL_TRANSPARENT_BLUE_VALUE:
                *value = config->transparentBlueValue;
                break;
            case EGL_TRANSPARENT_GREEN_VALUE:
                *value = config->transparentGreenValue;
                break;
            case EGL_TRANSPARENT_RED_VALUE:
                *value = config->transparentRedValue;
                break;
            case EGL_BIND_TO_TEXTURE_RGB:
                *value = config->bindToTextureRGB;
                break;
            case EGL_BIND_TO_TEXTURE_RGBA:
                *value = config->bindToTextureRGBA;
                break;
            case EGL_MIN_SWAP_INTERVAL:
                *value = config->minSwapInterval;
                break;
            case EGL_MAX_SWAP_INTERVAL:
                *value = config->maxSwapInterval;
                break;
            case EGL_LUMINANCE_SIZE:
                *value = config->luminanceSize;
                break;
            case EGL_ALPHA_MASK_SIZE:
                *value = config->alphaMaskSize;
                break;
            case EGL_COLOR_BUFFER_TYPE:
                *value = config->colorBufferType;
                break;
            case EGL_RENDERABLE_TYPE:
                *value = config->renderableType;
                break;
            case EGL_MATCH_NATIVE_PIXMAP:
                *value = false;
                UNIMPLEMENTED();
                break;
            case EGL_CONFORMANT:
                *value = config->conformant;
                break;
            case EGL_MAX_PBUFFER_WIDTH:
                *value = config->maxPBufferWidth;
                break;
            case EGL_MAX_PBUFFER_HEIGHT:
                *value = config->maxPBufferHeight;
                break;
            case EGL_MAX_PBUFFER_PIXELS:
                *value = config->maxPBufferPixels;
                break;
            case EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE:
                *value = config->optimalOrientation;
                break;
            case EGL_COLOR_COMPONENT_TYPE_EXT:
                *value = config->colorComponentType;
                break;
            default:
                UNREACHABLE();
                break;
        }
    }
    
    }  // namespace egl