// GENERATED FILE - DO NOT EDIT.
// Generated by generate_entry_points.py using data from gl.xml and gl_angle_ext.xml.
//
// Copyright 2020 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.
//
// entry_points_gles_ext_autogen.cpp:
//   Defines the GLES extension entry points.

#include "libGLESv2/entry_points_gles_ext_autogen.h"

#include "common/entry_points_enum_autogen.h"
#include "libANGLE/Context.h"
#include "libANGLE/Context.inl.h"
#include "libANGLE/capture_gles_ext_autogen.h"
#include "libANGLE/entry_points_utils.h"
#include "libANGLE/gl_enum_utils.h"
#include "libANGLE/validationESEXT.h"
#include "libGLESv2/global_state.h"

#include "libANGLE/capture_gles_1_0_autogen.h"
#include "libANGLE/capture_gles_2_0_autogen.h"
#include "libANGLE/capture_gles_3_0_autogen.h"
#include "libANGLE/capture_gles_3_1_autogen.h"
#include "libANGLE/capture_gles_3_2_autogen.h"
#include "libANGLE/validationES1.h"
#include "libANGLE/validationES2.h"
#include "libANGLE/validationES3.h"
#include "libANGLE/validationES31.h"
#include "libANGLE/validationES32.h"

namespace gl
{

// GL_ANGLE_base_vertex_base_instance
void GL_APIENTRY DrawArraysInstancedBaseInstanceANGLE(GLenum mode,
                                                      GLint first,
                                                      GLsizei count,
                                                      GLsizei instanceCount,
                                                      GLuint baseInstance)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::DrawArraysInstancedBaseInstanceANGLE,
          "glDrawArraysInstancedBaseInstanceANGLE",
          "context = %d, mode = %s, first = %d, count = %d, instanceCount = %d, baseInstance = %u",
          CID(context), GLenumToString(GLenumGroup::PrimitiveType, mode), first, count,
          instanceCount, baseInstance);

    if (context)
    {
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateDrawArraysInstancedBaseInstanceANGLE(
                                context, modePacked, first, count, instanceCount, baseInstance));
        if (isCallValid)
        {
            context->drawArraysInstancedBaseInstance(modePacked, first, count, instanceCount,
                                                     baseInstance);
        }
        ANGLE_CAPTURE(DrawArraysInstancedBaseInstanceANGLE, isCallValid, context, modePacked, first,
                      count, instanceCount, baseInstance);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY DrawElementsInstancedBaseVertexBaseInstanceANGLE(GLenum mode,
                                                                  GLsizei count,
                                                                  GLenum type,
                                                                  const GLvoid *indices,
                                                                  GLsizei instanceCounts,
                                                                  GLint baseVertex,
                                                                  GLuint baseInstance)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::DrawElementsInstancedBaseVertexBaseInstanceANGLE,
          "glDrawElementsInstancedBaseVertexBaseInstanceANGLE",
          "context = %d, mode = %s, count = %d, type = %s, indices = 0x%016" PRIxPTR
          ", instanceCounts = %d, baseVertex = %d, baseInstance = %u",
          CID(context), GLenumToString(GLenumGroup::PrimitiveType, mode), count,
          GLenumToString(GLenumGroup::DrawElementsType, type), (uintptr_t)indices, instanceCounts,
          baseVertex, baseInstance);

    if (context)
    {
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        DrawElementsType typePacked                           = FromGL<DrawElementsType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateDrawElementsInstancedBaseVertexBaseInstanceANGLE(
                                              context, modePacked, count, typePacked, indices,
                                              instanceCounts, baseVertex, baseInstance));
        if (isCallValid)
        {
            context->drawElementsInstancedBaseVertexBaseInstance(
                modePacked, count, typePacked, indices, instanceCounts, baseVertex, baseInstance);
        }
        ANGLE_CAPTURE(DrawElementsInstancedBaseVertexBaseInstanceANGLE, isCallValid, context,
                      modePacked, count, typePacked, indices, instanceCounts, baseVertex,
                      baseInstance);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY MultiDrawArraysInstancedBaseInstanceANGLE(GLenum mode,
                                                           const GLint *firsts,
                                                           const GLsizei *counts,
                                                           const GLsizei *instanceCounts,
                                                           const GLuint *baseInstances,
                                                           GLsizei drawcount)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::MultiDrawArraysInstancedBaseInstanceANGLE,
          "glMultiDrawArraysInstancedBaseInstanceANGLE",
          "context = %d, mode = %s, firsts = 0x%016" PRIxPTR ", counts = 0x%016" PRIxPTR
          ", instanceCounts = 0x%016" PRIxPTR ", baseInstances = 0x%016" PRIxPTR ", drawcount = %d",
          CID(context), GLenumToString(GLenumGroup::PrimitiveType, mode), (uintptr_t)firsts,
          (uintptr_t)counts, (uintptr_t)instanceCounts, (uintptr_t)baseInstances, drawcount);

    if (context)
    {
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateMultiDrawArraysInstancedBaseInstanceANGLE(
                 context, modePacked, firsts, counts, instanceCounts, baseInstances, drawcount));
        if (isCallValid)
        {
            context->multiDrawArraysInstancedBaseInstance(modePacked, firsts, counts,
                                                          instanceCounts, baseInstances, drawcount);
        }
        ANGLE_CAPTURE(MultiDrawArraysInstancedBaseInstanceANGLE, isCallValid, context, modePacked,
                      firsts, counts, instanceCounts, baseInstances, drawcount);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY
MultiDrawElementsInstancedBaseVertexBaseInstanceANGLE(GLenum mode,
                                                      const GLsizei *counts,
                                                      GLenum type,
                                                      const GLvoid *const *indices,
                                                      const GLsizei *instanceCounts,
                                                      const GLint *baseVertices,
                                                      const GLuint *baseInstances,
                                                      GLsizei drawcount)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::MultiDrawElementsInstancedBaseVertexBaseInstanceANGLE,
          "glMultiDrawElementsInstancedBaseVertexBaseInstanceANGLE",
          "context = %d, mode = %s, counts = 0x%016" PRIxPTR ", type = %s, indices = 0x%016" PRIxPTR
          ", instanceCounts = 0x%016" PRIxPTR ", baseVertices = 0x%016" PRIxPTR
          ", baseInstances = 0x%016" PRIxPTR ", drawcount = %d",
          CID(context), GLenumToString(GLenumGroup::PrimitiveType, mode), (uintptr_t)counts,
          GLenumToString(GLenumGroup::DrawElementsType, type), (uintptr_t)indices,
          (uintptr_t)instanceCounts, (uintptr_t)baseVertices, (uintptr_t)baseInstances, drawcount);

    if (context)
    {
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        DrawElementsType typePacked                           = FromGL<DrawElementsType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateMultiDrawElementsInstancedBaseVertexBaseInstanceANGLE(
                                context, modePacked, counts, typePacked, indices, instanceCounts,
                                baseVertices, baseInstances, drawcount));
        if (isCallValid)
        {
            context->multiDrawElementsInstancedBaseVertexBaseInstance(
                modePacked, counts, typePacked, indices, instanceCounts, baseVertices,
                baseInstances, drawcount);
        }
        ANGLE_CAPTURE(MultiDrawElementsInstancedBaseVertexBaseInstanceANGLE, isCallValid, context,
                      modePacked, counts, typePacked, indices, instanceCounts, baseVertices,
                      baseInstances, drawcount);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_ANGLE_copy_texture_3d
void GL_APIENTRY CopyTexture3DANGLE(GLuint sourceId,
                                    GLint sourceLevel,
                                    GLenum destTarget,
                                    GLuint destId,
                                    GLint destLevel,
                                    GLint internalFormat,
                                    GLenum destType,
                                    GLboolean unpackFlipY,
                                    GLboolean unpackPremultiplyAlpha,
                                    GLboolean unpackUnmultiplyAlpha)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::CopyTexture3DANGLE, "glCopyTexture3DANGLE",
          "context = %d, sourceId = %u, sourceLevel = %d, destTarget = %s, destId = %u, destLevel "
          "= %d, internalFormat = %d, destType = %s, unpackFlipY = %s, unpackPremultiplyAlpha = "
          "%s, unpackUnmultiplyAlpha = %s",
          CID(context), sourceId, sourceLevel,
          GLenumToString(GLenumGroup::DefaultGroup, destTarget), destId, destLevel, internalFormat,
          GLenumToString(GLenumGroup::DefaultGroup, destType), GLbooleanToString(unpackFlipY),
          GLbooleanToString(unpackPremultiplyAlpha), GLbooleanToString(unpackUnmultiplyAlpha));

    if (context)
    {
        TextureID sourceIdPacked                              = FromGL<TextureID>(sourceId);
        TextureTarget destTargetPacked                        = FromGL<TextureTarget>(destTarget);
        TextureID destIdPacked                                = FromGL<TextureID>(destId);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateCopyTexture3DANGLE(
                                context, sourceIdPacked, sourceLevel, destTargetPacked,
                                destIdPacked, destLevel, internalFormat, destType, unpackFlipY,
                                unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
        if (isCallValid)
        {
            context->copyTexture3D(sourceIdPacked, sourceLevel, destTargetPacked, destIdPacked,
                                   destLevel, internalFormat, destType, unpackFlipY,
                                   unpackPremultiplyAlpha, unpackUnmultiplyAlpha);
        }
        ANGLE_CAPTURE(CopyTexture3DANGLE, isCallValid, context, sourceIdPacked, sourceLevel,
                      destTargetPacked, destIdPacked, destLevel, internalFormat, destType,
                      unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY CopySubTexture3DANGLE(GLuint sourceId,
                                       GLint sourceLevel,
                                       GLenum destTarget,
                                       GLuint destId,
                                       GLint destLevel,
                                       GLint xoffset,
                                       GLint yoffset,
                                       GLint zoffset,
                                       GLint x,
                                       GLint y,
                                       GLint z,
                                       GLint width,
                                       GLint height,
                                       GLint depth,
                                       GLboolean unpackFlipY,
                                       GLboolean unpackPremultiplyAlpha,
                                       GLboolean unpackUnmultiplyAlpha)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::CopySubTexture3DANGLE, "glCopySubTexture3DANGLE",
          "context = %d, sourceId = %u, sourceLevel = %d, destTarget = %s, destId = %u, destLevel "
          "= %d, xoffset = %d, yoffset = %d, zoffset = %d, x = %d, y = %d, z = %d, width = %d, "
          "height = %d, depth = %d, unpackFlipY = %s, unpackPremultiplyAlpha = %s, "
          "unpackUnmultiplyAlpha = %s",
          CID(context), sourceId, sourceLevel,
          GLenumToString(GLenumGroup::DefaultGroup, destTarget), destId, destLevel, xoffset,
          yoffset, zoffset, x, y, z, width, height, depth, GLbooleanToString(unpackFlipY),
          GLbooleanToString(unpackPremultiplyAlpha), GLbooleanToString(unpackUnmultiplyAlpha));

    if (context)
    {
        TextureID sourceIdPacked                              = FromGL<TextureID>(sourceId);
        TextureTarget destTargetPacked                        = FromGL<TextureTarget>(destTarget);
        TextureID destIdPacked                                = FromGL<TextureID>(destId);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateCopySubTexture3DANGLE(context, sourceIdPacked, sourceLevel, destTargetPacked,
                                           destIdPacked, destLevel, xoffset, yoffset, zoffset, x, y,
                                           z, width, height, depth, unpackFlipY,
                                           unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
        if (isCallValid)
        {
            context->copySubTexture3D(sourceIdPacked, sourceLevel, destTargetPacked, destIdPacked,
                                      destLevel, xoffset, yoffset, zoffset, x, y, z, width, height,
                                      depth, unpackFlipY, unpackPremultiplyAlpha,
                                      unpackUnmultiplyAlpha);
        }
        ANGLE_CAPTURE(CopySubTexture3DANGLE, isCallValid, context, sourceIdPacked, sourceLevel,
                      destTargetPacked, destIdPacked, destLevel, xoffset, yoffset, zoffset, x, y, z,
                      width, height, depth, unpackFlipY, unpackPremultiplyAlpha,
                      unpackUnmultiplyAlpha);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_ANGLE_framebuffer_blit
void GL_APIENTRY BlitFramebufferANGLE(GLint srcX0,
                                      GLint srcY0,
                                      GLint srcX1,
                                      GLint srcY1,
                                      GLint dstX0,
                                      GLint dstY0,
                                      GLint dstX1,
                                      GLint dstY1,
                                      GLbitfield mask,
                                      GLenum filter)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::BlitFramebufferANGLE, "glBlitFramebufferANGLE",
          "context = %d, srcX0 = %d, srcY0 = %d, srcX1 = %d, srcY1 = %d, dstX0 = %d, dstY0 = %d, "
          "dstX1 = %d, dstY1 = %d, mask = %s, filter = %s",
          CID(context), srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1,
          GLbitfieldToString(GLenumGroup::ClearBufferMask, mask).c_str(),
          GLenumToString(GLenumGroup::BlitFramebufferFilter, filter));

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateBlitFramebufferANGLE(context, srcX0, srcY0, srcX1, srcY1, dstX0,
                                                         dstY0, dstX1, dstY1, mask, filter));
        if (isCallValid)
        {
            context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask,
                                     filter);
        }
        ANGLE_CAPTURE(BlitFramebufferANGLE, isCallValid, context, srcX0, srcY0, srcX1, srcY1, dstX0,
                      dstY0, dstX1, dstY1, mask, filter);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_ANGLE_framebuffer_multisample
void GL_APIENTRY RenderbufferStorageMultisampleANGLE(GLenum target,
                                                     GLsizei samples,
                                                     GLenum internalformat,
                                                     GLsizei width,
                                                     GLsizei height)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::RenderbufferStorageMultisampleANGLE,
          "glRenderbufferStorageMultisampleANGLE",
          "context = %d, target = %s, samples = %d, internalformat = %s, width = %d, height = %d",
          CID(context), GLenumToString(GLenumGroup::RenderbufferTarget, target), samples,
          GLenumToString(GLenumGroup::InternalFormat, internalformat), width, height);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateRenderbufferStorageMultisampleANGLE(
                                context, target, samples, internalformat, width, height));
        if (isCallValid)
        {
            context->renderbufferStorageMultisample(target, samples, internalformat, width, height);
        }
        ANGLE_CAPTURE(RenderbufferStorageMultisampleANGLE, isCallValid, context, target, samples,
                      internalformat, width, height);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_ANGLE_get_image
void GL_APIENTRY
GetTexImageANGLE(GLenum target, GLint level, GLenum format, GLenum type, void *pixels)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetTexImageANGLE, "glGetTexImageANGLE",
          "context = %d, target = %s, level = %d, format = %s, type = %s, pixels = 0x%016" PRIxPTR
          "",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), level,
          GLenumToString(GLenumGroup::PixelFormat, format),
          GLenumToString(GLenumGroup::PixelType, type), (uintptr_t)pixels);

    if (context)
    {
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetTexImageANGLE(context, targetPacked, level, format, type, pixels));
        if (isCallValid)
        {
            context->getTexImage(targetPacked, level, format, type, pixels);
        }
        ANGLE_CAPTURE(GetTexImageANGLE, isCallValid, context, targetPacked, level, format, type,
                      pixels);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetRenderbufferImageANGLE(GLenum target, GLenum format, GLenum type, void *pixels)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetRenderbufferImageANGLE, "glGetRenderbufferImageANGLE",
          "context = %d, target = %s, format = %s, type = %s, pixels = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::RenderbufferTarget, target),
          GLenumToString(GLenumGroup::PixelFormat, format),
          GLenumToString(GLenumGroup::PixelType, type), (uintptr_t)pixels);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetRenderbufferImageANGLE(context, target, format, type, pixels));
        if (isCallValid)
        {
            context->getRenderbufferImage(target, format, type, pixels);
        }
        ANGLE_CAPTURE(GetRenderbufferImageANGLE, isCallValid, context, target, format, type,
                      pixels);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_ANGLE_get_tex_level_parameter
void GL_APIENTRY GetTexLevelParameterivANGLE(GLenum target,
                                             GLint level,
                                             GLenum pname,
                                             GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetTexLevelParameterivANGLE, "glGetTexLevelParameterivANGLE",
          "context = %d, target = %s, level = %d, pname = %s, params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target), level,
          GLenumToString(GLenumGroup::DefaultGroup, pname), (uintptr_t)params);

    if (context)
    {
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetTexLevelParameterivANGLE(context, targetPacked, level, pname, params));
        if (isCallValid)
        {
            context->getTexLevelParameteriv(targetPacked, level, pname, params);
        }
        ANGLE_CAPTURE(GetTexLevelParameterivANGLE, isCallValid, context, targetPacked, level, pname,
                      params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetTexLevelParameterfvANGLE(GLenum target,
                                             GLint level,
                                             GLenum pname,
                                             GLfloat *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetTexLevelParameterfvANGLE, "glGetTexLevelParameterfvANGLE",
          "context = %d, target = %s, level = %d, pname = %s, params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target), level,
          GLenumToString(GLenumGroup::DefaultGroup, pname), (uintptr_t)params);

    if (context)
    {
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetTexLevelParameterfvANGLE(context, targetPacked, level, pname, params));
        if (isCallValid)
        {
            context->getTexLevelParameterfv(targetPacked, level, pname, params);
        }
        ANGLE_CAPTURE(GetTexLevelParameterfvANGLE, isCallValid, context, targetPacked, level, pname,
                      params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_ANGLE_instanced_arrays
void GL_APIENTRY DrawArraysInstancedANGLE(GLenum mode,
                                          GLint first,
                                          GLsizei count,
                                          GLsizei primcount)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::DrawArraysInstancedANGLE, "glDrawArraysInstancedANGLE",
          "context = %d, mode = %s, first = %d, count = %d, primcount = %d", CID(context),
          GLenumToString(GLenumGroup::PrimitiveType, mode), first, count, primcount);

    if (context)
    {
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateDrawArraysInstancedANGLE(context, modePacked, first, count, primcount));
        if (isCallValid)
        {
            context->drawArraysInstanced(modePacked, first, count, primcount);
        }
        ANGLE_CAPTURE(DrawArraysInstancedANGLE, isCallValid, context, modePacked, first, count,
                      primcount);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY DrawElementsInstancedANGLE(GLenum mode,
                                            GLsizei count,
                                            GLenum type,
                                            const void *indices,
                                            GLsizei primcount)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::DrawElementsInstancedANGLE, "glDrawElementsInstancedANGLE",
          "context = %d, mode = %s, count = %d, type = %s, indices = 0x%016" PRIxPTR
          ", primcount = %d",
          CID(context), GLenumToString(GLenumGroup::PrimitiveType, mode), count,
          GLenumToString(GLenumGroup::PrimitiveType, type), (uintptr_t)indices, primcount);

    if (context)
    {
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        DrawElementsType typePacked                           = FromGL<DrawElementsType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateDrawElementsInstancedANGLE(context, modePacked, count,
                                                               typePacked, indices, primcount));
        if (isCallValid)
        {
            context->drawElementsInstanced(modePacked, count, typePacked, indices, primcount);
        }
        ANGLE_CAPTURE(DrawElementsInstancedANGLE, isCallValid, context, modePacked, count,
                      typePacked, indices, primcount);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY VertexAttribDivisorANGLE(GLuint index, GLuint divisor)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::VertexAttribDivisorANGLE, "glVertexAttribDivisorANGLE",
          "context = %d, index = %u, divisor = %u", CID(context), index, divisor);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateVertexAttribDivisorANGLE(context, index, divisor));
        if (isCallValid)
        {
            context->vertexAttribDivisor(index, divisor);
        }
        ANGLE_CAPTURE(VertexAttribDivisorANGLE, isCallValid, context, index, divisor);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_ANGLE_memory_object_flags
void GL_APIENTRY TexStorageMemFlags2DANGLE(GLenum target,
                                           GLsizei levels,
                                           GLenum internalFormat,
                                           GLsizei width,
                                           GLsizei height,
                                           GLuint memory,
                                           GLuint64 offset,
                                           GLbitfield createFlags,
                                           GLbitfield usageFlags)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::TexStorageMemFlags2DANGLE, "glTexStorageMemFlags2DANGLE",
          "context = %d, target = %s, levels = %d, internalFormat = %s, width = %d, height = %d, "
          "memory = %u, offset = %llu, createFlags = %s, usageFlags = %s",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), levels,
          GLenumToString(GLenumGroup::DefaultGroup, internalFormat), width, height, memory,
          static_cast<unsigned long long>(offset),
          GLbitfieldToString(GLenumGroup::DefaultGroup, createFlags).c_str(),
          GLbitfieldToString(GLenumGroup::DefaultGroup, usageFlags).c_str());

    if (context)
    {
        TextureType targetPacked                              = FromGL<TextureType>(target);
        MemoryObjectID memoryPacked                           = FromGL<MemoryObjectID>(memory);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateTexStorageMemFlags2DANGLE(
                                context, targetPacked, levels, internalFormat, width, height,
                                memoryPacked, offset, createFlags, usageFlags));
        if (isCallValid)
        {
            context->texStorageMemFlags2D(targetPacked, levels, internalFormat, width, height,
                                          memoryPacked, offset, createFlags, usageFlags);
        }
        ANGLE_CAPTURE(TexStorageMemFlags2DANGLE, isCallValid, context, targetPacked, levels,
                      internalFormat, width, height, memoryPacked, offset, createFlags, usageFlags);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TexStorageMemFlags2DMultisampleANGLE(GLenum target,
                                                      GLsizei samples,
                                                      GLenum internalFormat,
                                                      GLsizei width,
                                                      GLsizei height,
                                                      GLboolean fixedSampleLocations,
                                                      GLuint memory,
                                                      GLuint64 offset,
                                                      GLbitfield createFlags,
                                                      GLbitfield usageFlags)
{
    Context *context = GetValidGlobalContext();
    EVENT(
        context, gl::EntryPoint::TexStorageMemFlags2DMultisampleANGLE,
        "glTexStorageMemFlags2DMultisampleANGLE",
        "context = %d, target = %s, samples = %d, internalFormat = %s, width = %d, height = %d, "
        "fixedSampleLocations = %s, memory = %u, offset = %llu, createFlags = %s, usageFlags = %s",
        CID(context), GLenumToString(GLenumGroup::TextureTarget, target), samples,
        GLenumToString(GLenumGroup::DefaultGroup, internalFormat), width, height,
        GLbooleanToString(fixedSampleLocations), memory, static_cast<unsigned long long>(offset),
        GLbitfieldToString(GLenumGroup::DefaultGroup, createFlags).c_str(),
        GLbitfieldToString(GLenumGroup::DefaultGroup, usageFlags).c_str());

    if (context)
    {
        TextureType targetPacked                              = FromGL<TextureType>(target);
        MemoryObjectID memoryPacked                           = FromGL<MemoryObjectID>(memory);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTexStorageMemFlags2DMultisampleANGLE(
                 context, targetPacked, samples, internalFormat, width, height,
                 fixedSampleLocations, memoryPacked, offset, createFlags, usageFlags));
        if (isCallValid)
        {
            context->texStorageMemFlags2DMultisample(targetPacked, samples, internalFormat, width,
                                                     height, fixedSampleLocations, memoryPacked,
                                                     offset, createFlags, usageFlags);
        }
        ANGLE_CAPTURE(TexStorageMemFlags2DMultisampleANGLE, isCallValid, context, targetPacked,
                      samples, internalFormat, width, height, fixedSampleLocations, memoryPacked,
                      offset, createFlags, usageFlags);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TexStorageMemFlags3DANGLE(GLenum target,
                                           GLsizei levels,
                                           GLenum internalFormat,
                                           GLsizei width,
                                           GLsizei height,
                                           GLsizei depth,
                                           GLuint memory,
                                           GLuint64 offset,
                                           GLbitfield createFlags,
                                           GLbitfield usageFlags)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::TexStorageMemFlags3DANGLE, "glTexStorageMemFlags3DANGLE",
          "context = %d, target = %s, levels = %d, internalFormat = %s, width = %d, height = %d, "
          "depth = %d, memory = %u, offset = %llu, createFlags = %s, usageFlags = %s",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), levels,
          GLenumToString(GLenumGroup::DefaultGroup, internalFormat), width, height, depth, memory,
          static_cast<unsigned long long>(offset),
          GLbitfieldToString(GLenumGroup::DefaultGroup, createFlags).c_str(),
          GLbitfieldToString(GLenumGroup::DefaultGroup, usageFlags).c_str());

    if (context)
    {
        TextureType targetPacked                              = FromGL<TextureType>(target);
        MemoryObjectID memoryPacked                           = FromGL<MemoryObjectID>(memory);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateTexStorageMemFlags3DANGLE(
                                context, targetPacked, levels, internalFormat, width, height, depth,
                                memoryPacked, offset, createFlags, usageFlags));
        if (isCallValid)
        {
            context->texStorageMemFlags3D(targetPacked, levels, internalFormat, width, height,
                                          depth, memoryPacked, offset, createFlags, usageFlags);
        }
        ANGLE_CAPTURE(TexStorageMemFlags3DANGLE, isCallValid, context, targetPacked, levels,
                      internalFormat, width, height, depth, memoryPacked, offset, createFlags,
                      usageFlags);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TexStorageMemFlags3DMultisampleANGLE(GLenum target,
                                                      GLsizei samples,
                                                      GLenum internalFormat,
                                                      GLsizei width,
                                                      GLsizei height,
                                                      GLsizei depth,
                                                      GLboolean fixedSampleLocations,
                                                      GLuint memory,
                                                      GLuint64 offset,
                                                      GLbitfield createFlags,
                                                      GLbitfield usageFlags)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::TexStorageMemFlags3DMultisampleANGLE,
          "glTexStorageMemFlags3DMultisampleANGLE",
          "context = %d, target = %s, samples = %d, internalFormat = %s, width = %d, height = %d, "
          "depth = %d, fixedSampleLocations = %s, memory = %u, offset = %llu, createFlags = %s, "
          "usageFlags = %s",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), samples,
          GLenumToString(GLenumGroup::DefaultGroup, internalFormat), width, height, depth,
          GLbooleanToString(fixedSampleLocations), memory, static_cast<unsigned long long>(offset),
          GLbitfieldToString(GLenumGroup::DefaultGroup, createFlags).c_str(),
          GLbitfieldToString(GLenumGroup::DefaultGroup, usageFlags).c_str());

    if (context)
    {
        TextureType targetPacked                              = FromGL<TextureType>(target);
        MemoryObjectID memoryPacked                           = FromGL<MemoryObjectID>(memory);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTexStorageMemFlags3DMultisampleANGLE(
                 context, targetPacked, samples, internalFormat, width, height, depth,
                 fixedSampleLocations, memoryPacked, offset, createFlags, usageFlags));
        if (isCallValid)
        {
            context->texStorageMemFlags3DMultisample(targetPacked, samples, internalFormat, width,
                                                     height, depth, fixedSampleLocations,
                                                     memoryPacked, offset, createFlags, usageFlags);
        }
        ANGLE_CAPTURE(TexStorageMemFlags3DMultisampleANGLE, isCallValid, context, targetPacked,
                      samples, internalFormat, width, height, depth, fixedSampleLocations,
                      memoryPacked, offset, createFlags, usageFlags);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_ANGLE_memory_object_fuchsia
void GL_APIENTRY ImportMemoryZirconHandleANGLE(GLuint memory,
                                               GLuint64 size,
                                               GLenum handleType,
                                               GLuint handle)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::ImportMemoryZirconHandleANGLE, "glImportMemoryZirconHandleANGLE",
          "context = %d, memory = %u, size = %llu, handleType = %s, handle = %u", CID(context),
          memory, static_cast<unsigned long long>(size),
          GLenumToString(GLenumGroup::ExternalHandleType, handleType), handle);

    if (context)
    {
        MemoryObjectID memoryPacked                           = FromGL<MemoryObjectID>(memory);
        HandleType handleTypePacked                           = FromGL<HandleType>(handleType);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateImportMemoryZirconHandleANGLE(context, memoryPacked, size,
                                                                  handleTypePacked, handle));
        if (isCallValid)
        {
            context->importMemoryZirconHandle(memoryPacked, size, handleTypePacked, handle);
        }
        ANGLE_CAPTURE(ImportMemoryZirconHandleANGLE, isCallValid, context, memoryPacked, size,
                      handleTypePacked, handle);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_ANGLE_multi_draw
void GL_APIENTRY MultiDrawArraysANGLE(GLenum mode,
                                      const GLint *firsts,
                                      const GLsizei *counts,
                                      GLsizei drawcount)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::MultiDrawArraysANGLE, "glMultiDrawArraysANGLE",
          "context = %d, mode = %s, firsts = 0x%016" PRIxPTR ", counts = 0x%016" PRIxPTR
          ", drawcount = %d",
          CID(context), GLenumToString(GLenumGroup::PrimitiveType, mode), (uintptr_t)firsts,
          (uintptr_t)counts, drawcount);

    if (context)
    {
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateMultiDrawArraysANGLE(context, modePacked, firsts, counts, drawcount));
        if (isCallValid)
        {
            context->multiDrawArrays(modePacked, firsts, counts, drawcount);
        }
        ANGLE_CAPTURE(MultiDrawArraysANGLE, isCallValid, context, modePacked, firsts, counts,
                      drawcount);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY MultiDrawArraysInstancedANGLE(GLenum mode,
                                               const GLint *firsts,
                                               const GLsizei *counts,
                                               const GLsizei *instanceCounts,
                                               GLsizei drawcount)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::MultiDrawArraysInstancedANGLE, "glMultiDrawArraysInstancedANGLE",
          "context = %d, mode = %s, firsts = 0x%016" PRIxPTR ", counts = 0x%016" PRIxPTR
          ", instanceCounts = 0x%016" PRIxPTR ", drawcount = %d",
          CID(context), GLenumToString(GLenumGroup::PrimitiveType, mode), (uintptr_t)firsts,
          (uintptr_t)counts, (uintptr_t)instanceCounts, drawcount);

    if (context)
    {
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateMultiDrawArraysInstancedANGLE(
                                context, modePacked, firsts, counts, instanceCounts, drawcount));
        if (isCallValid)
        {
            context->multiDrawArraysInstanced(modePacked, firsts, counts, instanceCounts,
                                              drawcount);
        }
        ANGLE_CAPTURE(MultiDrawArraysInstancedANGLE, isCallValid, context, modePacked, firsts,
                      counts, instanceCounts, drawcount);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY MultiDrawElementsANGLE(GLenum mode,
                                        const GLsizei *counts,
                                        GLenum type,
                                        const GLvoid *const *indices,
                                        GLsizei drawcount)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::MultiDrawElementsANGLE, "glMultiDrawElementsANGLE",
          "context = %d, mode = %s, counts = 0x%016" PRIxPTR ", type = %s, indices = 0x%016" PRIxPTR
          ", drawcount = %d",
          CID(context), GLenumToString(GLenumGroup::PrimitiveType, mode), (uintptr_t)counts,
          GLenumToString(GLenumGroup::DrawElementsType, type), (uintptr_t)indices, drawcount);

    if (context)
    {
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        DrawElementsType typePacked                           = FromGL<DrawElementsType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateMultiDrawElementsANGLE(context, modePacked, counts, typePacked,
                                                           indices, drawcount));
        if (isCallValid)
        {
            context->multiDrawElements(modePacked, counts, typePacked, indices, drawcount);
        }
        ANGLE_CAPTURE(MultiDrawElementsANGLE, isCallValid, context, modePacked, counts, typePacked,
                      indices, drawcount);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY MultiDrawElementsInstancedANGLE(GLenum mode,
                                                 const GLsizei *counts,
                                                 GLenum type,
                                                 const GLvoid *const *indices,
                                                 const GLsizei *instanceCounts,
                                                 GLsizei drawcount)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::MultiDrawElementsInstancedANGLE,
          "glMultiDrawElementsInstancedANGLE",
          "context = %d, mode = %s, counts = 0x%016" PRIxPTR ", type = %s, indices = 0x%016" PRIxPTR
          ", instanceCounts = 0x%016" PRIxPTR ", drawcount = %d",
          CID(context), GLenumToString(GLenumGroup::PrimitiveType, mode), (uintptr_t)counts,
          GLenumToString(GLenumGroup::DrawElementsType, type), (uintptr_t)indices,
          (uintptr_t)instanceCounts, drawcount);

    if (context)
    {
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        DrawElementsType typePacked                           = FromGL<DrawElementsType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateMultiDrawElementsInstancedANGLE(context, modePacked, counts, typePacked,
                                                     indices, instanceCounts, drawcount));
        if (isCallValid)
        {
            context->multiDrawElementsInstanced(modePacked, counts, typePacked, indices,
                                                instanceCounts, drawcount);
        }
        ANGLE_CAPTURE(MultiDrawElementsInstancedANGLE, isCallValid, context, modePacked, counts,
                      typePacked, indices, instanceCounts, drawcount);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_ANGLE_program_binary

// GL_ANGLE_provoking_vertex
void GL_APIENTRY ProvokingVertexANGLE(GLenum mode)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::ProvokingVertexANGLE, "glProvokingVertexANGLE",
          "context = %d, mode = %s", CID(context),
          GLenumToString(GLenumGroup::VertexProvokingMode, mode));

    if (context)
    {
        ProvokingVertexConvention modePacked = FromGL<ProvokingVertexConvention>(mode);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateProvokingVertexANGLE(context, modePacked));
        if (isCallValid)
        {
            context->provokingVertex(modePacked);
        }
        ANGLE_CAPTURE(ProvokingVertexANGLE, isCallValid, context, modePacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_ANGLE_request_extension
void GL_APIENTRY RequestExtensionANGLE(const GLchar *name)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::RequestExtensionANGLE, "glRequestExtensionANGLE",
          "context = %d, name = 0x%016" PRIxPTR "", CID(context), (uintptr_t)name);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateRequestExtensionANGLE(context, name));
        if (isCallValid)
        {
            context->requestExtension(name);
        }
        ANGLE_CAPTURE(RequestExtensionANGLE, isCallValid, context, name);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY DisableExtensionANGLE(const GLchar *name)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::DisableExtensionANGLE, "glDisableExtensionANGLE",
          "context = %d, name = 0x%016" PRIxPTR "", CID(context), (uintptr_t)name);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateDisableExtensionANGLE(context, name));
        if (isCallValid)
        {
            context->disableExtension(name);
        }
        ANGLE_CAPTURE(DisableExtensionANGLE, isCallValid, context, name);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_ANGLE_robust_client_memory
void GL_APIENTRY GetBooleanvRobustANGLE(GLenum pname,
                                        GLsizei bufSize,
                                        GLsizei *length,
                                        GLboolean *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetBooleanvRobustANGLE, "glGetBooleanvRobustANGLE",
          "context = %d, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize,
          (uintptr_t)length, (uintptr_t)params);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetBooleanvRobustANGLE(context, pname, bufSize, length, params));
        if (isCallValid)
        {
            context->getBooleanvRobust(pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetBooleanvRobustANGLE, isCallValid, context, pname, bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetBufferParameterivRobustANGLE(GLenum target,
                                                 GLenum pname,
                                                 GLsizei bufSize,
                                                 GLsizei *length,
                                                 GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetBufferParameterivRobustANGLE,
          "glGetBufferParameterivRobustANGLE",
          "context = %d, target = %s, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target),
          GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize, (uintptr_t)length,
          (uintptr_t)params);

    if (context)
    {
        BufferBinding targetPacked                            = FromGL<BufferBinding>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetBufferParameterivRobustANGLE(context, targetPacked, pname,
                                                                    bufSize, length, params));
        if (isCallValid)
        {
            context->getBufferParameterivRobust(targetPacked, pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetBufferParameterivRobustANGLE, isCallValid, context, targetPacked, pname,
                      bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetFloatvRobustANGLE(GLenum pname,
                                      GLsizei bufSize,
                                      GLsizei *length,
                                      GLfloat *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetFloatvRobustANGLE, "glGetFloatvRobustANGLE",
          "context = %d, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize,
          (uintptr_t)length, (uintptr_t)params);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetFloatvRobustANGLE(context, pname, bufSize, length, params));
        if (isCallValid)
        {
            context->getFloatvRobust(pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetFloatvRobustANGLE, isCallValid, context, pname, bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetFramebufferAttachmentParameterivRobustANGLE(GLenum target,
                                                                GLenum attachment,
                                                                GLenum pname,
                                                                GLsizei bufSize,
                                                                GLsizei *length,
                                                                GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetFramebufferAttachmentParameterivRobustANGLE,
          "glGetFramebufferAttachmentParameterivRobustANGLE",
          "context = %d, target = %s, attachment = %s, pname = %s, bufSize = %d, length = "
          "0x%016" PRIxPTR ", params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target),
          GLenumToString(GLenumGroup::DefaultGroup, attachment),
          GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize, (uintptr_t)length,
          (uintptr_t)params);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetFramebufferAttachmentParameterivRobustANGLE(
                                context, target, attachment, pname, bufSize, length, params));
        if (isCallValid)
        {
            context->getFramebufferAttachmentParameterivRobust(target, attachment, pname, bufSize,
                                                               length, params);
        }
        ANGLE_CAPTURE(GetFramebufferAttachmentParameterivRobustANGLE, isCallValid, context, target,
                      attachment, pname, bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetIntegervRobustANGLE(GLenum pname, GLsizei bufSize, GLsizei *length, GLint *data)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetIntegervRobustANGLE, "glGetIntegervRobustANGLE",
          "context = %d, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", data = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize,
          (uintptr_t)length, (uintptr_t)data);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetIntegervRobustANGLE(context, pname, bufSize, length, data));
        if (isCallValid)
        {
            context->getIntegervRobust(pname, bufSize, length, data);
        }
        ANGLE_CAPTURE(GetIntegervRobustANGLE, isCallValid, context, pname, bufSize, length, data);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetProgramivRobustANGLE(GLuint program,
                                         GLenum pname,
                                         GLsizei bufSize,
                                         GLsizei *length,
                                         GLint *params)
{
    Context *context = GetGlobalContext();
    EVENT(context, gl::EntryPoint::GetProgramivRobustANGLE, "glGetProgramivRobustANGLE",
          "context = %d, program = %u, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), program, GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize,
          (uintptr_t)length, (uintptr_t)params);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetProgramivRobustANGLE(context, programPacked, pname, bufSize,
                                                            length, params));
        if (isCallValid)
        {
            context->getProgramivRobust(programPacked, pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetProgramivRobustANGLE, isCallValid, context, programPacked, pname, bufSize,
                      length, params);
    }
    else
    {}
}

void GL_APIENTRY GetRenderbufferParameterivRobustANGLE(GLenum target,
                                                       GLenum pname,
                                                       GLsizei bufSize,
                                                       GLsizei *length,
                                                       GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetRenderbufferParameterivRobustANGLE,
          "glGetRenderbufferParameterivRobustANGLE",
          "context = %d, target = %s, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target),
          GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize, (uintptr_t)length,
          (uintptr_t)params);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetRenderbufferParameterivRobustANGLE(
                                              context, target, pname, bufSize, length, params));
        if (isCallValid)
        {
            context->getRenderbufferParameterivRobust(target, pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetRenderbufferParameterivRobustANGLE, isCallValid, context, target, pname,
                      bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY
GetShaderivRobustANGLE(GLuint shader, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params)
{
    Context *context = GetGlobalContext();
    EVENT(context, gl::EntryPoint::GetShaderivRobustANGLE, "glGetShaderivRobustANGLE",
          "context = %d, shader = %u, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), shader, GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize,
          (uintptr_t)length, (uintptr_t)params);

    if (context)
    {
        ShaderProgramID shaderPacked                          = FromGL<ShaderProgramID>(shader);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetShaderivRobustANGLE(context, shaderPacked, pname, bufSize, length, params));
        if (isCallValid)
        {
            context->getShaderivRobust(shaderPacked, pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetShaderivRobustANGLE, isCallValid, context, shaderPacked, pname, bufSize,
                      length, params);
    }
    else
    {}
}

void GL_APIENTRY GetTexParameterfvRobustANGLE(GLenum target,
                                              GLenum pname,
                                              GLsizei bufSize,
                                              GLsizei *length,
                                              GLfloat *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetTexParameterfvRobustANGLE, "glGetTexParameterfvRobustANGLE",
          "context = %d, target = %s, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target),
          GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize, (uintptr_t)length,
          (uintptr_t)params);

    if (context)
    {
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetTexParameterfvRobustANGLE(context, targetPacked, pname,
                                                                 bufSize, length, params));
        if (isCallValid)
        {
            context->getTexParameterfvRobust(targetPacked, pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetTexParameterfvRobustANGLE, isCallValid, context, targetPacked, pname,
                      bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetTexParameterivRobustANGLE(GLenum target,
                                              GLenum pname,
                                              GLsizei bufSize,
                                              GLsizei *length,
                                              GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetTexParameterivRobustANGLE, "glGetTexParameterivRobustANGLE",
          "context = %d, target = %s, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target),
          GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize, (uintptr_t)length,
          (uintptr_t)params);

    if (context)
    {
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetTexParameterivRobustANGLE(context, targetPacked, pname,
                                                                 bufSize, length, params));
        if (isCallValid)
        {
            context->getTexParameterivRobust(targetPacked, pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetTexParameterivRobustANGLE, isCallValid, context, targetPacked, pname,
                      bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetUniformfvRobustANGLE(GLuint program,
                                         GLint location,
                                         GLsizei bufSize,
                                         GLsizei *length,
                                         GLfloat *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetUniformfvRobustANGLE, "glGetUniformfvRobustANGLE",
          "context = %d, program = %u, location = %d, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), program, location, bufSize, (uintptr_t)length, (uintptr_t)params);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetUniformfvRobustANGLE(context, programPacked, locationPacked,
                                                            bufSize, length, params));
        if (isCallValid)
        {
            context->getUniformfvRobust(programPacked, locationPacked, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetUniformfvRobustANGLE, isCallValid, context, programPacked, locationPacked,
                      bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetUniformivRobustANGLE(GLuint program,
                                         GLint location,
                                         GLsizei bufSize,
                                         GLsizei *length,
                                         GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetUniformivRobustANGLE, "glGetUniformivRobustANGLE",
          "context = %d, program = %u, location = %d, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), program, location, bufSize, (uintptr_t)length, (uintptr_t)params);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetUniformivRobustANGLE(context, programPacked, locationPacked,
                                                            bufSize, length, params));
        if (isCallValid)
        {
            context->getUniformivRobust(programPacked, locationPacked, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetUniformivRobustANGLE, isCallValid, context, programPacked, locationPacked,
                      bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetVertexAttribfvRobustANGLE(GLuint index,
                                              GLenum pname,
                                              GLsizei bufSize,
                                              GLsizei *length,
                                              GLfloat *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetVertexAttribfvRobustANGLE, "glGetVertexAttribfvRobustANGLE",
          "context = %d, index = %u, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), index, GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize,
          (uintptr_t)length, (uintptr_t)params);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetVertexAttribfvRobustANGLE(context, index, pname, bufSize, length, params));
        if (isCallValid)
        {
            context->getVertexAttribfvRobust(index, pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetVertexAttribfvRobustANGLE, isCallValid, context, index, pname, bufSize,
                      length, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetVertexAttribivRobustANGLE(GLuint index,
                                              GLenum pname,
                                              GLsizei bufSize,
                                              GLsizei *length,
                                              GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetVertexAttribivRobustANGLE, "glGetVertexAttribivRobustANGLE",
          "context = %d, index = %u, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), index, GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize,
          (uintptr_t)length, (uintptr_t)params);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetVertexAttribivRobustANGLE(context, index, pname, bufSize, length, params));
        if (isCallValid)
        {
            context->getVertexAttribivRobust(index, pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetVertexAttribivRobustANGLE, isCallValid, context, index, pname, bufSize,
                      length, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetVertexAttribPointervRobustANGLE(GLuint index,
                                                    GLenum pname,
                                                    GLsizei bufSize,
                                                    GLsizei *length,
                                                    void **pointer)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetVertexAttribPointervRobustANGLE,
          "glGetVertexAttribPointervRobustANGLE",
          "context = %d, index = %u, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", pointer = 0x%016" PRIxPTR "",
          CID(context), index, GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize,
          (uintptr_t)length, (uintptr_t)pointer);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetVertexAttribPointervRobustANGLE(
                                              context, index, pname, bufSize, length, pointer));
        if (isCallValid)
        {
            context->getVertexAttribPointervRobust(index, pname, bufSize, length, pointer);
        }
        ANGLE_CAPTURE(GetVertexAttribPointervRobustANGLE, isCallValid, context, index, pname,
                      bufSize, length, pointer);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ReadPixelsRobustANGLE(GLint x,
                                       GLint y,
                                       GLsizei width,
                                       GLsizei height,
                                       GLenum format,
                                       GLenum type,
                                       GLsizei bufSize,
                                       GLsizei *length,
                                       GLsizei *columns,
                                       GLsizei *rows,
                                       void *pixels)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::ReadPixelsRobustANGLE, "glReadPixelsRobustANGLE",
          "context = %d, x = %d, y = %d, width = %d, height = %d, format = %s, type = %s, bufSize "
          "= %d, length = 0x%016" PRIxPTR ", columns = 0x%016" PRIxPTR ", rows = 0x%016" PRIxPTR
          ", pixels = 0x%016" PRIxPTR "",
          CID(context), x, y, width, height, GLenumToString(GLenumGroup::DefaultGroup, format),
          GLenumToString(GLenumGroup::DefaultGroup, type), bufSize, (uintptr_t)length,
          (uintptr_t)columns, (uintptr_t)rows, (uintptr_t)pixels);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateReadPixelsRobustANGLE(context, x, y, width, height, format, type, bufSize,
                                           length, columns, rows, pixels));
        if (isCallValid)
        {
            context->readPixelsRobust(x, y, width, height, format, type, bufSize, length, columns,
                                      rows, pixels);
        }
        ANGLE_CAPTURE(ReadPixelsRobustANGLE, isCallValid, context, x, y, width, height, format,
                      type, bufSize, length, columns, rows, pixels);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TexImage2DRobustANGLE(GLenum target,
                                       GLint level,
                                       GLint internalformat,
                                       GLsizei width,
                                       GLsizei height,
                                       GLint border,
                                       GLenum format,
                                       GLenum type,
                                       GLsizei bufSize,
                                       const void *pixels)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::TexImage2DRobustANGLE, "glTexImage2DRobustANGLE",
          "context = %d, target = %s, level = %d, internalformat = %d, width = %d, height = %d, "
          "border = %d, format = %s, type = %s, bufSize = %d, pixels = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target), level, internalformat,
          width, height, border, GLenumToString(GLenumGroup::DefaultGroup, format),
          GLenumToString(GLenumGroup::DefaultGroup, type), bufSize, (uintptr_t)pixels);

    if (context)
    {
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTexImage2DRobustANGLE(context, targetPacked, level, internalformat, width,
                                           height, border, format, type, bufSize, pixels));
        if (isCallValid)
        {
            context->texImage2DRobust(targetPacked, level, internalformat, width, height, border,
                                      format, type, bufSize, pixels);
        }
        ANGLE_CAPTURE(TexImage2DRobustANGLE, isCallValid, context, targetPacked, level,
                      internalformat, width, height, border, format, type, bufSize, pixels);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TexParameterfvRobustANGLE(GLenum target,
                                           GLenum pname,
                                           GLsizei bufSize,
                                           const GLfloat *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::TexParameterfvRobustANGLE, "glTexParameterfvRobustANGLE",
          "context = %d, target = %s, pname = %s, bufSize = %d, params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target),
          GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize, (uintptr_t)params);

    if (context)
    {
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTexParameterfvRobustANGLE(context, targetPacked, pname, bufSize, params));
        if (isCallValid)
        {
            context->texParameterfvRobust(targetPacked, pname, bufSize, params);
        }
        ANGLE_CAPTURE(TexParameterfvRobustANGLE, isCallValid, context, targetPacked, pname, bufSize,
                      params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TexParameterivRobustANGLE(GLenum target,
                                           GLenum pname,
                                           GLsizei bufSize,
                                           const GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::TexParameterivRobustANGLE, "glTexParameterivRobustANGLE",
          "context = %d, target = %s, pname = %s, bufSize = %d, params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target),
          GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize, (uintptr_t)params);

    if (context)
    {
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTexParameterivRobustANGLE(context, targetPacked, pname, bufSize, params));
        if (isCallValid)
        {
            context->texParameterivRobust(targetPacked, pname, bufSize, params);
        }
        ANGLE_CAPTURE(TexParameterivRobustANGLE, isCallValid, context, targetPacked, pname, bufSize,
                      params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TexSubImage2DRobustANGLE(GLenum target,
                                          GLint level,
                                          GLint xoffset,
                                          GLint yoffset,
                                          GLsizei width,
                                          GLsizei height,
                                          GLenum format,
                                          GLenum type,
                                          GLsizei bufSize,
                                          const void *pixels)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::TexSubImage2DRobustANGLE, "glTexSubImage2DRobustANGLE",
          "context = %d, target = %s, level = %d, xoffset = %d, yoffset = %d, width = %d, height = "
          "%d, format = %s, type = %s, bufSize = %d, pixels = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target), level, xoffset, yoffset,
          width, height, GLenumToString(GLenumGroup::DefaultGroup, format),
          GLenumToString(GLenumGroup::DefaultGroup, type), bufSize, (uintptr_t)pixels);

    if (context)
    {
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTexSubImage2DRobustANGLE(context, targetPacked, level, xoffset, yoffset, width,
                                              height, format, type, bufSize, pixels));
        if (isCallValid)
        {
            context->texSubImage2DRobust(targetPacked, level, xoffset, yoffset, width, height,
                                         format, type, bufSize, pixels);
        }
        ANGLE_CAPTURE(TexSubImage2DRobustANGLE, isCallValid, context, targetPacked, level, xoffset,
                      yoffset, width, height, format, type, bufSize, pixels);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TexImage3DRobustANGLE(GLenum target,
                                       GLint level,
                                       GLint internalformat,
                                       GLsizei width,
                                       GLsizei height,
                                       GLsizei depth,
                                       GLint border,
                                       GLenum format,
                                       GLenum type,
                                       GLsizei bufSize,
                                       const void *pixels)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::TexImage3DRobustANGLE, "glTexImage3DRobustANGLE",
          "context = %d, target = %s, level = %d, internalformat = %d, width = %d, height = %d, "
          "depth = %d, border = %d, format = %s, type = %s, bufSize = %d, pixels = 0x%016" PRIxPTR
          "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target), level, internalformat,
          width, height, depth, border, GLenumToString(GLenumGroup::DefaultGroup, format),
          GLenumToString(GLenumGroup::DefaultGroup, type), bufSize, (uintptr_t)pixels);

    if (context)
    {
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTexImage3DRobustANGLE(context, targetPacked, level, internalformat, width,
                                           height, depth, border, format, type, bufSize, pixels));
        if (isCallValid)
        {
            context->texImage3DRobust(targetPacked, level, internalformat, width, height, depth,
                                      border, format, type, bufSize, pixels);
        }
        ANGLE_CAPTURE(TexImage3DRobustANGLE, isCallValid, context, targetPacked, level,
                      internalformat, width, height, depth, border, format, type, bufSize, pixels);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TexSubImage3DRobustANGLE(GLenum target,
                                          GLint level,
                                          GLint xoffset,
                                          GLint yoffset,
                                          GLint zoffset,
                                          GLsizei width,
                                          GLsizei height,
                                          GLsizei depth,
                                          GLenum format,
                                          GLenum type,
                                          GLsizei bufSize,
                                          const void *pixels)
{
    Context *context = GetValidGlobalContext();
    EVENT(
        context, gl::EntryPoint::TexSubImage3DRobustANGLE, "glTexSubImage3DRobustANGLE",
        "context = %d, target = %s, level = %d, xoffset = %d, yoffset = %d, zoffset = %d, width = "
        "%d, height = %d, depth = %d, format = %s, type = %s, bufSize = %d, pixels = 0x%016" PRIxPTR
        "",
        CID(context), GLenumToString(GLenumGroup::DefaultGroup, target), level, xoffset, yoffset,
        zoffset, width, height, depth, GLenumToString(GLenumGroup::DefaultGroup, format),
        GLenumToString(GLenumGroup::DefaultGroup, type), bufSize, (uintptr_t)pixels);

    if (context)
    {
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateTexSubImage3DRobustANGLE(context, targetPacked, level, xoffset,
                                                             yoffset, zoffset, width, height, depth,
                                                             format, type, bufSize, pixels));
        if (isCallValid)
        {
            context->texSubImage3DRobust(targetPacked, level, xoffset, yoffset, zoffset, width,
                                         height, depth, format, type, bufSize, pixels);
        }
        ANGLE_CAPTURE(TexSubImage3DRobustANGLE, isCallValid, context, targetPacked, level, xoffset,
                      yoffset, zoffset, width, height, depth, format, type, bufSize, pixels);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY CompressedTexImage2DRobustANGLE(GLenum target,
                                                 GLint level,
                                                 GLenum internalformat,
                                                 GLsizei width,
                                                 GLsizei height,
                                                 GLint border,
                                                 GLsizei imageSize,
                                                 GLsizei dataSize,
                                                 const GLvoid *data)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::CompressedTexImage2DRobustANGLE,
          "glCompressedTexImage2DRobustANGLE",
          "context = %d, target = %s, level = %d, internalformat = %s, width = %d, height = %d, "
          "border = %d, imageSize = %d, dataSize = %d, data = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target), level,
          GLenumToString(GLenumGroup::DefaultGroup, internalformat), width, height, border,
          imageSize, dataSize, (uintptr_t)data);

    if (context)
    {
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateCompressedTexImage2DRobustANGLE(
                                              context, targetPacked, level, internalformat, width,
                                              height, border, imageSize, dataSize, data));
        if (isCallValid)
        {
            context->compressedTexImage2DRobust(targetPacked, level, internalformat, width, height,
                                                border, imageSize, dataSize, data);
        }
        ANGLE_CAPTURE(CompressedTexImage2DRobustANGLE, isCallValid, context, targetPacked, level,
                      internalformat, width, height, border, imageSize, dataSize, data);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY CompressedTexSubImage2DRobustANGLE(GLenum target,
                                                    GLint level,
                                                    GLsizei xoffset,
                                                    GLsizei yoffset,
                                                    GLsizei width,
                                                    GLsizei height,
                                                    GLenum format,
                                                    GLsizei imageSize,
                                                    GLsizei dataSize,
                                                    const GLvoid *data)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::CompressedTexSubImage2DRobustANGLE,
          "glCompressedTexSubImage2DRobustANGLE",
          "context = %d, target = %s, level = %d, xoffset = %d, yoffset = %d, width = %d, height = "
          "%d, format = %s, imageSize = %d, dataSize = %d, data = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target), level, xoffset, yoffset,
          width, height, GLenumToString(GLenumGroup::DefaultGroup, format), imageSize, dataSize,
          (uintptr_t)data);

    if (context)
    {
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateCompressedTexSubImage2DRobustANGLE(
                                              context, targetPacked, level, xoffset, yoffset, width,
                                              height, format, imageSize, dataSize, data));
        if (isCallValid)
        {
            context->compressedTexSubImage2DRobust(targetPacked, level, xoffset, yoffset, width,
                                                   height, format, imageSize, dataSize, data);
        }
        ANGLE_CAPTURE(CompressedTexSubImage2DRobustANGLE, isCallValid, context, targetPacked, level,
                      xoffset, yoffset, width, height, format, imageSize, dataSize, data);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY CompressedTexImage3DRobustANGLE(GLenum target,
                                                 GLint level,
                                                 GLenum internalformat,
                                                 GLsizei width,
                                                 GLsizei height,
                                                 GLsizei depth,
                                                 GLint border,
                                                 GLsizei imageSize,
                                                 GLsizei dataSize,
                                                 const GLvoid *data)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::CompressedTexImage3DRobustANGLE,
          "glCompressedTexImage3DRobustANGLE",
          "context = %d, target = %s, level = %d, internalformat = %s, width = %d, height = %d, "
          "depth = %d, border = %d, imageSize = %d, dataSize = %d, data = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target), level,
          GLenumToString(GLenumGroup::DefaultGroup, internalformat), width, height, depth, border,
          imageSize, dataSize, (uintptr_t)data);

    if (context)
    {
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateCompressedTexImage3DRobustANGLE(
                                              context, targetPacked, level, internalformat, width,
                                              height, depth, border, imageSize, dataSize, data));
        if (isCallValid)
        {
            context->compressedTexImage3DRobust(targetPacked, level, internalformat, width, height,
                                                depth, border, imageSize, dataSize, data);
        }
        ANGLE_CAPTURE(CompressedTexImage3DRobustANGLE, isCallValid, context, targetPacked, level,
                      internalformat, width, height, depth, border, imageSize, dataSize, data);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY CompressedTexSubImage3DRobustANGLE(GLenum target,
                                                    GLint level,
                                                    GLint xoffset,
                                                    GLint yoffset,
                                                    GLint zoffset,
                                                    GLsizei width,
                                                    GLsizei height,
                                                    GLsizei depth,
                                                    GLenum format,
                                                    GLsizei imageSize,
                                                    GLsizei dataSize,
                                                    const GLvoid *data)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::CompressedTexSubImage3DRobustANGLE,
          "glCompressedTexSubImage3DRobustANGLE",
          "context = %d, target = %s, level = %d, xoffset = %d, yoffset = %d, zoffset = %d, width "
          "= %d, height = %d, depth = %d, format = %s, imageSize = %d, dataSize = %d, data = "
          "0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target), level, xoffset, yoffset,
          zoffset, width, height, depth, GLenumToString(GLenumGroup::DefaultGroup, format),
          imageSize, dataSize, (uintptr_t)data);

    if (context)
    {
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateCompressedTexSubImage3DRobustANGLE(
                                context, targetPacked, level, xoffset, yoffset, zoffset, width,
                                height, depth, format, imageSize, dataSize, data));
        if (isCallValid)
        {
            context->compressedTexSubImage3DRobust(targetPacked, level, xoffset, yoffset, zoffset,
                                                   width, height, depth, format, imageSize,
                                                   dataSize, data);
        }
        ANGLE_CAPTURE(CompressedTexSubImage3DRobustANGLE, isCallValid, context, targetPacked, level,
                      xoffset, yoffset, zoffset, width, height, depth, format, imageSize, dataSize,
                      data);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY
GetQueryivRobustANGLE(GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetQueryivRobustANGLE, "glGetQueryivRobustANGLE",
          "context = %d, target = %s, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target),
          GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize, (uintptr_t)length,
          (uintptr_t)params);

    if (context)
    {
        QueryType targetPacked                                = FromGL<QueryType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetQueryivRobustANGLE(context, targetPacked, pname, bufSize, length, params));
        if (isCallValid)
        {
            context->getQueryivRobust(targetPacked, pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetQueryivRobustANGLE, isCallValid, context, targetPacked, pname, bufSize,
                      length, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetQueryObjectuivRobustANGLE(GLuint id,
                                              GLenum pname,
                                              GLsizei bufSize,
                                              GLsizei *length,
                                              GLuint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetQueryObjectuivRobustANGLE, "glGetQueryObjectuivRobustANGLE",
          "context = %d, id = %u, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), id, GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize,
          (uintptr_t)length, (uintptr_t)params);

    if (context)
    {
        QueryID idPacked                                      = FromGL<QueryID>(id);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetQueryObjectuivRobustANGLE(
                                              context, idPacked, pname, bufSize, length, params));
        if (isCallValid)
        {
            context->getQueryObjectuivRobust(idPacked, pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetQueryObjectuivRobustANGLE, isCallValid, context, idPacked, pname, bufSize,
                      length, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetBufferPointervRobustANGLE(GLenum target,
                                              GLenum pname,
                                              GLsizei bufSize,
                                              GLsizei *length,
                                              void **params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetBufferPointervRobustANGLE, "glGetBufferPointervRobustANGLE",
          "context = %d, target = %s, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target),
          GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize, (uintptr_t)length,
          (uintptr_t)params);

    if (context)
    {
        BufferBinding targetPacked                            = FromGL<BufferBinding>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetBufferPointervRobustANGLE(context, targetPacked, pname,
                                                                 bufSize, length, params));
        if (isCallValid)
        {
            context->getBufferPointervRobust(targetPacked, pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetBufferPointervRobustANGLE, isCallValid, context, targetPacked, pname,
                      bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY
GetIntegeri_vRobustANGLE(GLenum target, GLuint index, GLsizei bufSize, GLsizei *length, GLint *data)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetIntegeri_vRobustANGLE, "glGetIntegeri_vRobustANGLE",
          "context = %d, target = %s, index = %u, bufSize = %d, length = 0x%016" PRIxPTR
          ", data = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target), index, bufSize,
          (uintptr_t)length, (uintptr_t)data);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetIntegeri_vRobustANGLE(context, target, index, bufSize, length, data));
        if (isCallValid)
        {
            context->getIntegeri_vRobust(target, index, bufSize, length, data);
        }
        ANGLE_CAPTURE(GetIntegeri_vRobustANGLE, isCallValid, context, target, index, bufSize,
                      length, data);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetInternalformativRobustANGLE(GLenum target,
                                                GLenum internalformat,
                                                GLenum pname,
                                                GLsizei bufSize,
                                                GLsizei *length,
                                                GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetInternalformativRobustANGLE,
          "glGetInternalformativRobustANGLE",
          "context = %d, target = %s, internalformat = %s, pname = %s, bufSize = %d, length = "
          "0x%016" PRIxPTR ", params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target),
          GLenumToString(GLenumGroup::DefaultGroup, internalformat),
          GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize, (uintptr_t)length,
          (uintptr_t)params);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetInternalformativRobustANGLE(context, target, internalformat,
                                                                   pname, bufSize, length, params));
        if (isCallValid)
        {
            context->getInternalformativRobust(target, internalformat, pname, bufSize, length,
                                               params);
        }
        ANGLE_CAPTURE(GetInternalformativRobustANGLE, isCallValid, context, target, internalformat,
                      pname, bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetVertexAttribIivRobustANGLE(GLuint index,
                                               GLenum pname,
                                               GLsizei bufSize,
                                               GLsizei *length,
                                               GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetVertexAttribIivRobustANGLE, "glGetVertexAttribIivRobustANGLE",
          "context = %d, index = %u, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), index, GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize,
          (uintptr_t)length, (uintptr_t)params);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetVertexAttribIivRobustANGLE(context, index, pname, bufSize, length, params));
        if (isCallValid)
        {
            context->getVertexAttribIivRobust(index, pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetVertexAttribIivRobustANGLE, isCallValid, context, index, pname, bufSize,
                      length, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetVertexAttribIuivRobustANGLE(GLuint index,
                                                GLenum pname,
                                                GLsizei bufSize,
                                                GLsizei *length,
                                                GLuint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetVertexAttribIuivRobustANGLE,
          "glGetVertexAttribIuivRobustANGLE",
          "context = %d, index = %u, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), index, GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize,
          (uintptr_t)length, (uintptr_t)params);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetVertexAttribIuivRobustANGLE(
                                              context, index, pname, bufSize, length, params));
        if (isCallValid)
        {
            context->getVertexAttribIuivRobust(index, pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetVertexAttribIuivRobustANGLE, isCallValid, context, index, pname, bufSize,
                      length, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetUniformuivRobustANGLE(GLuint program,
                                          GLint location,
                                          GLsizei bufSize,
                                          GLsizei *length,
                                          GLuint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetUniformuivRobustANGLE, "glGetUniformuivRobustANGLE",
          "context = %d, program = %u, location = %d, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), program, location, bufSize, (uintptr_t)length, (uintptr_t)params);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetUniformuivRobustANGLE(context, programPacked, locationPacked,
                                                             bufSize, length, params));
        if (isCallValid)
        {
            context->getUniformuivRobust(programPacked, locationPacked, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetUniformuivRobustANGLE, isCallValid, context, programPacked, locationPacked,
                      bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetActiveUniformBlockivRobustANGLE(GLuint program,
                                                    GLuint uniformBlockIndex,
                                                    GLenum pname,
                                                    GLsizei bufSize,
                                                    GLsizei *length,
                                                    GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetActiveUniformBlockivRobustANGLE,
          "glGetActiveUniformBlockivRobustANGLE",
          "context = %d, program = %u, uniformBlockIndex = %u, pname = %s, bufSize = %d, length = "
          "0x%016" PRIxPTR ", params = 0x%016" PRIxPTR "",
          CID(context), program, uniformBlockIndex,
          GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize, (uintptr_t)length,
          (uintptr_t)params);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetActiveUniformBlockivRobustANGLE(context, programPacked, uniformBlockIndex,
                                                        pname, bufSize, length, params));
        if (isCallValid)
        {
            context->getActiveUniformBlockivRobust(programPacked, uniformBlockIndex, pname, bufSize,
                                                   length, params);
        }
        ANGLE_CAPTURE(GetActiveUniformBlockivRobustANGLE, isCallValid, context, programPacked,
                      uniformBlockIndex, pname, bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetInteger64vRobustANGLE(GLenum pname,
                                          GLsizei bufSize,
                                          GLsizei *length,
                                          GLint64 *data)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetInteger64vRobustANGLE, "glGetInteger64vRobustANGLE",
          "context = %d, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", data = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize,
          (uintptr_t)length, (uintptr_t)data);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetInteger64vRobustANGLE(context, pname, bufSize, length, data));
        if (isCallValid)
        {
            context->getInteger64vRobust(pname, bufSize, length, data);
        }
        ANGLE_CAPTURE(GetInteger64vRobustANGLE, isCallValid, context, pname, bufSize, length, data);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetInteger64i_vRobustANGLE(GLenum target,
                                            GLuint index,
                                            GLsizei bufSize,
                                            GLsizei *length,
                                            GLint64 *data)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetInteger64i_vRobustANGLE, "glGetInteger64i_vRobustANGLE",
          "context = %d, target = %s, index = %u, bufSize = %d, length = 0x%016" PRIxPTR
          ", data = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target), index, bufSize,
          (uintptr_t)length, (uintptr_t)data);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetInteger64i_vRobustANGLE(context, target, index, bufSize, length, data));
        if (isCallValid)
        {
            context->getInteger64i_vRobust(target, index, bufSize, length, data);
        }
        ANGLE_CAPTURE(GetInteger64i_vRobustANGLE, isCallValid, context, target, index, bufSize,
                      length, data);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetBufferParameteri64vRobustANGLE(GLenum target,
                                                   GLenum pname,
                                                   GLsizei bufSize,
                                                   GLsizei *length,
                                                   GLint64 *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetBufferParameteri64vRobustANGLE,
          "glGetBufferParameteri64vRobustANGLE",
          "context = %d, target = %s, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target),
          GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize, (uintptr_t)length,
          (uintptr_t)params);

    if (context)
    {
        BufferBinding targetPacked                            = FromGL<BufferBinding>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetBufferParameteri64vRobustANGLE(context, targetPacked, pname,
                                                                      bufSize, length, params));
        if (isCallValid)
        {
            context->getBufferParameteri64vRobust(targetPacked, pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetBufferParameteri64vRobustANGLE, isCallValid, context, targetPacked, pname,
                      bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY SamplerParameterivRobustANGLE(GLuint sampler,
                                               GLuint pname,
                                               GLsizei bufSize,
                                               const GLint *param)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::SamplerParameterivRobustANGLE, "glSamplerParameterivRobustANGLE",
          "context = %d, sampler = %u, pname = %u, bufSize = %d, param = 0x%016" PRIxPTR "",
          CID(context), sampler, pname, bufSize, (uintptr_t)param);

    if (context)
    {
        SamplerID samplerPacked                               = FromGL<SamplerID>(sampler);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateSamplerParameterivRobustANGLE(context, samplerPacked, pname, bufSize, param));
        if (isCallValid)
        {
            context->samplerParameterivRobust(samplerPacked, pname, bufSize, param);
        }
        ANGLE_CAPTURE(SamplerParameterivRobustANGLE, isCallValid, context, samplerPacked, pname,
                      bufSize, param);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY SamplerParameterfvRobustANGLE(GLuint sampler,
                                               GLenum pname,
                                               GLsizei bufSize,
                                               const GLfloat *param)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::SamplerParameterfvRobustANGLE, "glSamplerParameterfvRobustANGLE",
          "context = %d, sampler = %u, pname = %s, bufSize = %d, param = 0x%016" PRIxPTR "",
          CID(context), sampler, GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize,
          (uintptr_t)param);

    if (context)
    {
        SamplerID samplerPacked                               = FromGL<SamplerID>(sampler);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateSamplerParameterfvRobustANGLE(context, samplerPacked, pname, bufSize, param));
        if (isCallValid)
        {
            context->samplerParameterfvRobust(samplerPacked, pname, bufSize, param);
        }
        ANGLE_CAPTURE(SamplerParameterfvRobustANGLE, isCallValid, context, samplerPacked, pname,
                      bufSize, param);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetSamplerParameterivRobustANGLE(GLuint sampler,
                                                  GLenum pname,
                                                  GLsizei bufSize,
                                                  GLsizei *length,
                                                  GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetSamplerParameterivRobustANGLE,
          "glGetSamplerParameterivRobustANGLE",
          "context = %d, sampler = %u, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), sampler, GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize,
          (uintptr_t)length, (uintptr_t)params);

    if (context)
    {
        SamplerID samplerPacked                               = FromGL<SamplerID>(sampler);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetSamplerParameterivRobustANGLE(context, samplerPacked, pname,
                                                                     bufSize, length, params));
        if (isCallValid)
        {
            context->getSamplerParameterivRobust(samplerPacked, pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetSamplerParameterivRobustANGLE, isCallValid, context, samplerPacked, pname,
                      bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetSamplerParameterfvRobustANGLE(GLuint sampler,
                                                  GLenum pname,
                                                  GLsizei bufSize,
                                                  GLsizei *length,
                                                  GLfloat *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetSamplerParameterfvRobustANGLE,
          "glGetSamplerParameterfvRobustANGLE",
          "context = %d, sampler = %u, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), sampler, GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize,
          (uintptr_t)length, (uintptr_t)params);

    if (context)
    {
        SamplerID samplerPacked                               = FromGL<SamplerID>(sampler);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetSamplerParameterfvRobustANGLE(context, samplerPacked, pname,
                                                                     bufSize, length, params));
        if (isCallValid)
        {
            context->getSamplerParameterfvRobust(samplerPacked, pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetSamplerParameterfvRobustANGLE, isCallValid, context, samplerPacked, pname,
                      bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetFramebufferParameterivRobustANGLE(GLenum target,
                                                      GLenum pname,
                                                      GLsizei bufSize,
                                                      GLsizei *length,
                                                      GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetFramebufferParameterivRobustANGLE,
          "glGetFramebufferParameterivRobustANGLE",
          "context = %d, target = %s, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target),
          GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize, (uintptr_t)length,
          (uintptr_t)params);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetFramebufferParameterivRobustANGLE(
                                              context, target, pname, bufSize, length, params));
        if (isCallValid)
        {
            context->getFramebufferParameterivRobust(target, pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetFramebufferParameterivRobustANGLE, isCallValid, context, target, pname,
                      bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetProgramInterfaceivRobustANGLE(GLuint program,
                                                  GLenum programInterface,
                                                  GLenum pname,
                                                  GLsizei bufSize,
                                                  GLsizei *length,
                                                  GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetProgramInterfaceivRobustANGLE,
          "glGetProgramInterfaceivRobustANGLE",
          "context = %d, program = %u, programInterface = %s, pname = %s, bufSize = %d, length = "
          "0x%016" PRIxPTR ", params = 0x%016" PRIxPTR "",
          CID(context), program, GLenumToString(GLenumGroup::DefaultGroup, programInterface),
          GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize, (uintptr_t)length,
          (uintptr_t)params);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetProgramInterfaceivRobustANGLE(context, programPacked, programInterface,
                                                      pname, bufSize, length, params));
        if (isCallValid)
        {
            context->getProgramInterfaceivRobust(programPacked, programInterface, pname, bufSize,
                                                 length, params);
        }
        ANGLE_CAPTURE(GetProgramInterfaceivRobustANGLE, isCallValid, context, programPacked,
                      programInterface, pname, bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetBooleani_vRobustANGLE(GLenum target,
                                          GLuint index,
                                          GLsizei bufSize,
                                          GLsizei *length,
                                          GLboolean *data)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetBooleani_vRobustANGLE, "glGetBooleani_vRobustANGLE",
          "context = %d, target = %s, index = %u, bufSize = %d, length = 0x%016" PRIxPTR
          ", data = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target), index, bufSize,
          (uintptr_t)length, (uintptr_t)data);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetBooleani_vRobustANGLE(context, target, index, bufSize, length, data));
        if (isCallValid)
        {
            context->getBooleani_vRobust(target, index, bufSize, length, data);
        }
        ANGLE_CAPTURE(GetBooleani_vRobustANGLE, isCallValid, context, target, index, bufSize,
                      length, data);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetMultisamplefvRobustANGLE(GLenum pname,
                                             GLuint index,
                                             GLsizei bufSize,
                                             GLsizei *length,
                                             GLfloat *val)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetMultisamplefvRobustANGLE, "glGetMultisamplefvRobustANGLE",
          "context = %d, pname = %s, index = %u, bufSize = %d, length = 0x%016" PRIxPTR
          ", val = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, pname), index, bufSize,
          (uintptr_t)length, (uintptr_t)val);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetMultisamplefvRobustANGLE(context, pname, index, bufSize, length, val));
        if (isCallValid)
        {
            context->getMultisamplefvRobust(pname, index, bufSize, length, val);
        }
        ANGLE_CAPTURE(GetMultisamplefvRobustANGLE, isCallValid, context, pname, index, bufSize,
                      length, val);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetTexLevelParameterivRobustANGLE(GLenum target,
                                                   GLint level,
                                                   GLenum pname,
                                                   GLsizei bufSize,
                                                   GLsizei *length,
                                                   GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetTexLevelParameterivRobustANGLE,
          "glGetTexLevelParameterivRobustANGLE",
          "context = %d, target = %s, level = %d, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target), level,
          GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize, (uintptr_t)length,
          (uintptr_t)params);

    if (context)
    {
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetTexLevelParameterivRobustANGLE(
                                context, targetPacked, level, pname, bufSize, length, params));
        if (isCallValid)
        {
            context->getTexLevelParameterivRobust(targetPacked, level, pname, bufSize, length,
                                                  params);
        }
        ANGLE_CAPTURE(GetTexLevelParameterivRobustANGLE, isCallValid, context, targetPacked, level,
                      pname, bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetTexLevelParameterfvRobustANGLE(GLenum target,
                                                   GLint level,
                                                   GLenum pname,
                                                   GLsizei bufSize,
                                                   GLsizei *length,
                                                   GLfloat *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetTexLevelParameterfvRobustANGLE,
          "glGetTexLevelParameterfvRobustANGLE",
          "context = %d, target = %s, level = %d, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target), level,
          GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize, (uintptr_t)length,
          (uintptr_t)params);

    if (context)
    {
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetTexLevelParameterfvRobustANGLE(
                                context, targetPacked, level, pname, bufSize, length, params));
        if (isCallValid)
        {
            context->getTexLevelParameterfvRobust(targetPacked, level, pname, bufSize, length,
                                                  params);
        }
        ANGLE_CAPTURE(GetTexLevelParameterfvRobustANGLE, isCallValid, context, targetPacked, level,
                      pname, bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetPointervRobustANGLERobustANGLE(GLenum pname,
                                                   GLsizei bufSize,
                                                   GLsizei *length,
                                                   void **params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetPointervRobustANGLERobustANGLE,
          "glGetPointervRobustANGLERobustANGLE",
          "context = %d, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize,
          (uintptr_t)length, (uintptr_t)params);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetPointervRobustANGLERobustANGLE(context, pname, bufSize, length, params));
        if (isCallValid)
        {
            context->getPointervRobustANGLERobust(pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetPointervRobustANGLERobustANGLE, isCallValid, context, pname, bufSize,
                      length, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ReadnPixelsRobustANGLE(GLint x,
                                        GLint y,
                                        GLsizei width,
                                        GLsizei height,
                                        GLenum format,
                                        GLenum type,
                                        GLsizei bufSize,
                                        GLsizei *length,
                                        GLsizei *columns,
                                        GLsizei *rows,
                                        void *data)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::ReadnPixelsRobustANGLE, "glReadnPixelsRobustANGLE",
          "context = %d, x = %d, y = %d, width = %d, height = %d, format = %s, type = %s, bufSize "
          "= %d, length = 0x%016" PRIxPTR ", columns = 0x%016" PRIxPTR ", rows = 0x%016" PRIxPTR
          ", data = 0x%016" PRIxPTR "",
          CID(context), x, y, width, height, GLenumToString(GLenumGroup::DefaultGroup, format),
          GLenumToString(GLenumGroup::DefaultGroup, type), bufSize, (uintptr_t)length,
          (uintptr_t)columns, (uintptr_t)rows, (uintptr_t)data);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateReadnPixelsRobustANGLE(context, x, y, width, height, format, type, bufSize,
                                            length, columns, rows, data));
        if (isCallValid)
        {
            context->readnPixelsRobust(x, y, width, height, format, type, bufSize, length, columns,
                                       rows, data);
        }
        ANGLE_CAPTURE(ReadnPixelsRobustANGLE, isCallValid, context, x, y, width, height, format,
                      type, bufSize, length, columns, rows, data);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetnUniformfvRobustANGLE(GLuint program,
                                          GLint location,
                                          GLsizei bufSize,
                                          GLsizei *length,
                                          GLfloat *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetnUniformfvRobustANGLE, "glGetnUniformfvRobustANGLE",
          "context = %d, program = %u, location = %d, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), program, location, bufSize, (uintptr_t)length, (uintptr_t)params);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetnUniformfvRobustANGLE(context, programPacked, locationPacked,
                                                             bufSize, length, params));
        if (isCallValid)
        {
            context->getnUniformfvRobust(programPacked, locationPacked, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetnUniformfvRobustANGLE, isCallValid, context, programPacked, locationPacked,
                      bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetnUniformivRobustANGLE(GLuint program,
                                          GLint location,
                                          GLsizei bufSize,
                                          GLsizei *length,
                                          GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetnUniformivRobustANGLE, "glGetnUniformivRobustANGLE",
          "context = %d, program = %u, location = %d, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), program, location, bufSize, (uintptr_t)length, (uintptr_t)params);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetnUniformivRobustANGLE(context, programPacked, locationPacked,
                                                             bufSize, length, params));
        if (isCallValid)
        {
            context->getnUniformivRobust(programPacked, locationPacked, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetnUniformivRobustANGLE, isCallValid, context, programPacked, locationPacked,
                      bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetnUniformuivRobustANGLE(GLuint program,
                                           GLint location,
                                           GLsizei bufSize,
                                           GLsizei *length,
                                           GLuint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetnUniformuivRobustANGLE, "glGetnUniformuivRobustANGLE",
          "context = %d, program = %u, location = %d, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), program, location, bufSize, (uintptr_t)length, (uintptr_t)params);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetnUniformuivRobustANGLE(
                                context, programPacked, locationPacked, bufSize, length, params));
        if (isCallValid)
        {
            context->getnUniformuivRobust(programPacked, locationPacked, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetnUniformuivRobustANGLE, isCallValid, context, programPacked,
                      locationPacked, bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TexParameterIivRobustANGLE(GLenum target,
                                            GLenum pname,
                                            GLsizei bufSize,
                                            const GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::TexParameterIivRobustANGLE, "glTexParameterIivRobustANGLE",
          "context = %d, target = %s, pname = %s, bufSize = %d, params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target),
          GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize, (uintptr_t)params);

    if (context)
    {
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTexParameterIivRobustANGLE(context, targetPacked, pname, bufSize, params));
        if (isCallValid)
        {
            context->texParameterIivRobust(targetPacked, pname, bufSize, params);
        }
        ANGLE_CAPTURE(TexParameterIivRobustANGLE, isCallValid, context, targetPacked, pname,
                      bufSize, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TexParameterIuivRobustANGLE(GLenum target,
                                             GLenum pname,
                                             GLsizei bufSize,
                                             const GLuint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::TexParameterIuivRobustANGLE, "glTexParameterIuivRobustANGLE",
          "context = %d, target = %s, pname = %s, bufSize = %d, params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target),
          GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize, (uintptr_t)params);

    if (context)
    {
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTexParameterIuivRobustANGLE(context, targetPacked, pname, bufSize, params));
        if (isCallValid)
        {
            context->texParameterIuivRobust(targetPacked, pname, bufSize, params);
        }
        ANGLE_CAPTURE(TexParameterIuivRobustANGLE, isCallValid, context, targetPacked, pname,
                      bufSize, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetTexParameterIivRobustANGLE(GLenum target,
                                               GLenum pname,
                                               GLsizei bufSize,
                                               GLsizei *length,
                                               GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetTexParameterIivRobustANGLE, "glGetTexParameterIivRobustANGLE",
          "context = %d, target = %s, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target),
          GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize, (uintptr_t)length,
          (uintptr_t)params);

    if (context)
    {
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetTexParameterIivRobustANGLE(context, targetPacked, pname,
                                                                  bufSize, length, params));
        if (isCallValid)
        {
            context->getTexParameterIivRobust(targetPacked, pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetTexParameterIivRobustANGLE, isCallValid, context, targetPacked, pname,
                      bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetTexParameterIuivRobustANGLE(GLenum target,
                                                GLenum pname,
                                                GLsizei bufSize,
                                                GLsizei *length,
                                                GLuint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetTexParameterIuivRobustANGLE,
          "glGetTexParameterIuivRobustANGLE",
          "context = %d, target = %s, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target),
          GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize, (uintptr_t)length,
          (uintptr_t)params);

    if (context)
    {
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetTexParameterIuivRobustANGLE(context, targetPacked, pname,
                                                                   bufSize, length, params));
        if (isCallValid)
        {
            context->getTexParameterIuivRobust(targetPacked, pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetTexParameterIuivRobustANGLE, isCallValid, context, targetPacked, pname,
                      bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY SamplerParameterIivRobustANGLE(GLuint sampler,
                                                GLenum pname,
                                                GLsizei bufSize,
                                                const GLint *param)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::SamplerParameterIivRobustANGLE,
          "glSamplerParameterIivRobustANGLE",
          "context = %d, sampler = %u, pname = %s, bufSize = %d, param = 0x%016" PRIxPTR "",
          CID(context), sampler, GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize,
          (uintptr_t)param);

    if (context)
    {
        SamplerID samplerPacked                               = FromGL<SamplerID>(sampler);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateSamplerParameterIivRobustANGLE(context, samplerPacked, pname, bufSize, param));
        if (isCallValid)
        {
            context->samplerParameterIivRobust(samplerPacked, pname, bufSize, param);
        }
        ANGLE_CAPTURE(SamplerParameterIivRobustANGLE, isCallValid, context, samplerPacked, pname,
                      bufSize, param);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY SamplerParameterIuivRobustANGLE(GLuint sampler,
                                                 GLenum pname,
                                                 GLsizei bufSize,
                                                 const GLuint *param)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::SamplerParameterIuivRobustANGLE,
          "glSamplerParameterIuivRobustANGLE",
          "context = %d, sampler = %u, pname = %s, bufSize = %d, param = 0x%016" PRIxPTR "",
          CID(context), sampler, GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize,
          (uintptr_t)param);

    if (context)
    {
        SamplerID samplerPacked                               = FromGL<SamplerID>(sampler);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateSamplerParameterIuivRobustANGLE(
                                              context, samplerPacked, pname, bufSize, param));
        if (isCallValid)
        {
            context->samplerParameterIuivRobust(samplerPacked, pname, bufSize, param);
        }
        ANGLE_CAPTURE(SamplerParameterIuivRobustANGLE, isCallValid, context, samplerPacked, pname,
                      bufSize, param);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetSamplerParameterIivRobustANGLE(GLuint sampler,
                                                   GLenum pname,
                                                   GLsizei bufSize,
                                                   GLsizei *length,
                                                   GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetSamplerParameterIivRobustANGLE,
          "glGetSamplerParameterIivRobustANGLE",
          "context = %d, sampler = %u, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), sampler, GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize,
          (uintptr_t)length, (uintptr_t)params);

    if (context)
    {
        SamplerID samplerPacked                               = FromGL<SamplerID>(sampler);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetSamplerParameterIivRobustANGLE(context, samplerPacked, pname,
                                                                      bufSize, length, params));
        if (isCallValid)
        {
            context->getSamplerParameterIivRobust(samplerPacked, pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetSamplerParameterIivRobustANGLE, isCallValid, context, samplerPacked, pname,
                      bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetSamplerParameterIuivRobustANGLE(GLuint sampler,
                                                    GLenum pname,
                                                    GLsizei bufSize,
                                                    GLsizei *length,
                                                    GLuint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetSamplerParameterIuivRobustANGLE,
          "glGetSamplerParameterIuivRobustANGLE",
          "context = %d, sampler = %u, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), sampler, GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize,
          (uintptr_t)length, (uintptr_t)params);

    if (context)
    {
        SamplerID samplerPacked                               = FromGL<SamplerID>(sampler);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetSamplerParameterIuivRobustANGLE(
                                context, samplerPacked, pname, bufSize, length, params));
        if (isCallValid)
        {
            context->getSamplerParameterIuivRobust(samplerPacked, pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetSamplerParameterIuivRobustANGLE, isCallValid, context, samplerPacked,
                      pname, bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetQueryObjectivRobustANGLE(GLuint id,
                                             GLenum pname,
                                             GLsizei bufSize,
                                             GLsizei *length,
                                             GLint *params)
{
    Context *context = GetGlobalContext();
    EVENT(context, gl::EntryPoint::GetQueryObjectivRobustANGLE, "glGetQueryObjectivRobustANGLE",
          "context = %d, id = %u, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), id, GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize,
          (uintptr_t)length, (uintptr_t)params);

    if (context)
    {
        QueryID idPacked                                      = FromGL<QueryID>(id);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetQueryObjectivRobustANGLE(
                                              context, idPacked, pname, bufSize, length, params));
        if (isCallValid)
        {
            context->getQueryObjectivRobust(idPacked, pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetQueryObjectivRobustANGLE, isCallValid, context, idPacked, pname, bufSize,
                      length, params);
    }
    else
    {}
}

void GL_APIENTRY GetQueryObjecti64vRobustANGLE(GLuint id,
                                               GLenum pname,
                                               GLsizei bufSize,
                                               GLsizei *length,
                                               GLint64 *params)
{
    Context *context = GetGlobalContext();
    EVENT(context, gl::EntryPoint::GetQueryObjecti64vRobustANGLE, "glGetQueryObjecti64vRobustANGLE",
          "context = %d, id = %u, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), id, GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize,
          (uintptr_t)length, (uintptr_t)params);

    if (context)
    {
        QueryID idPacked                                      = FromGL<QueryID>(id);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetQueryObjecti64vRobustANGLE(
                                              context, idPacked, pname, bufSize, length, params));
        if (isCallValid)
        {
            context->getQueryObjecti64vRobust(idPacked, pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetQueryObjecti64vRobustANGLE, isCallValid, context, idPacked, pname, bufSize,
                      length, params);
    }
    else
    {}
}

void GL_APIENTRY GetQueryObjectui64vRobustANGLE(GLuint id,
                                                GLenum pname,
                                                GLsizei bufSize,
                                                GLsizei *length,
                                                GLuint64 *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetQueryObjectui64vRobustANGLE,
          "glGetQueryObjectui64vRobustANGLE",
          "context = %d, id = %u, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), id, GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize,
          (uintptr_t)length, (uintptr_t)params);

    if (context)
    {
        QueryID idPacked                                      = FromGL<QueryID>(id);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetQueryObjectui64vRobustANGLE(
                                              context, idPacked, pname, bufSize, length, params));
        if (isCallValid)
        {
            context->getQueryObjectui64vRobust(idPacked, pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetQueryObjectui64vRobustANGLE, isCallValid, context, idPacked, pname,
                      bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_ANGLE_semaphore_fuchsia
void GL_APIENTRY ImportSemaphoreZirconHandleANGLE(GLuint semaphore,
                                                  GLenum handleType,
                                                  GLuint handle)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::ImportSemaphoreZirconHandleANGLE,
          "glImportSemaphoreZirconHandleANGLE",
          "context = %d, semaphore = %u, handleType = %s, handle = %u", CID(context), semaphore,
          GLenumToString(GLenumGroup::ExternalHandleType, handleType), handle);

    if (context)
    {
        SemaphoreID semaphorePacked                           = FromGL<SemaphoreID>(semaphore);
        HandleType handleTypePacked                           = FromGL<HandleType>(handleType);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateImportSemaphoreZirconHandleANGLE(
                                              context, semaphorePacked, handleTypePacked, handle));
        if (isCallValid)
        {
            context->importSemaphoreZirconHandle(semaphorePacked, handleTypePacked, handle);
        }
        ANGLE_CAPTURE(ImportSemaphoreZirconHandleANGLE, isCallValid, context, semaphorePacked,
                      handleTypePacked, handle);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_ANGLE_texture_external_update
void GL_APIENTRY TexImage2DExternalANGLE(GLenum target,
                                         GLint level,
                                         GLint internalformat,
                                         GLsizei width,
                                         GLsizei height,
                                         GLint border,
                                         GLenum format,
                                         GLenum type)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::TexImage2DExternalANGLE, "glTexImage2DExternalANGLE",
          "context = %d, target = %s, level = %d, internalformat = %d, width = %d, height = %d, "
          "border = %d, format = %s, type = %s",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), level, internalformat,
          width, height, border, GLenumToString(GLenumGroup::PixelFormat, format),
          GLenumToString(GLenumGroup::PixelType, type));

    if (context)
    {
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTexImage2DExternalANGLE(context, targetPacked, level, internalformat, width,
                                             height, border, format, type));
        if (isCallValid)
        {
            context->texImage2DExternal(targetPacked, level, internalformat, width, height, border,
                                        format, type);
        }
        ANGLE_CAPTURE(TexImage2DExternalANGLE, isCallValid, context, targetPacked, level,
                      internalformat, width, height, border, format, type);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY InvalidateTextureANGLE(GLenum target)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::InvalidateTextureANGLE, "glInvalidateTextureANGLE",
          "context = %d, target = %s", CID(context),
          GLenumToString(GLenumGroup::TextureTarget, target));

    if (context)
    {
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateInvalidateTextureANGLE(context, targetPacked));
        if (isCallValid)
        {
            context->invalidateTexture(targetPacked);
        }
        ANGLE_CAPTURE(InvalidateTextureANGLE, isCallValid, context, targetPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_ANGLE_texture_multisample
void GL_APIENTRY TexStorage2DMultisampleANGLE(GLenum target,
                                              GLsizei samples,
                                              GLenum internalformat,
                                              GLsizei width,
                                              GLsizei height,
                                              GLboolean fixedsamplelocations)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::TexStorage2DMultisampleANGLE, "glTexStorage2DMultisampleANGLE",
          "context = %d, target = %s, samples = %d, internalformat = %s, width = %d, height = %d, "
          "fixedsamplelocations = %s",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target), samples,
          GLenumToString(GLenumGroup::DefaultGroup, internalformat), width, height,
          GLbooleanToString(fixedsamplelocations));

    if (context)
    {
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTexStorage2DMultisampleANGLE(context, targetPacked, samples, internalformat,
                                                  width, height, fixedsamplelocations));
        if (isCallValid)
        {
            context->texStorage2DMultisample(targetPacked, samples, internalformat, width, height,
                                             fixedsamplelocations);
        }
        ANGLE_CAPTURE(TexStorage2DMultisampleANGLE, isCallValid, context, targetPacked, samples,
                      internalformat, width, height, fixedsamplelocations);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetMultisamplefvANGLE(GLenum pname, GLuint index, GLfloat *val)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetMultisamplefvANGLE, "glGetMultisamplefvANGLE",
          "context = %d, pname = %s, index = %u, val = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::DefaultGroup, pname), index, (uintptr_t)val);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetMultisamplefvANGLE(context, pname, index, val));
        if (isCallValid)
        {
            context->getMultisamplefv(pname, index, val);
        }
        ANGLE_CAPTURE(GetMultisamplefvANGLE, isCallValid, context, pname, index, val);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY SampleMaskiANGLE(GLuint maskNumber, GLbitfield mask)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::SampleMaskiANGLE, "glSampleMaskiANGLE",
          "context = %d, maskNumber = %u, mask = %s", CID(context), maskNumber,
          GLbitfieldToString(GLenumGroup::DefaultGroup, mask).c_str());

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateSampleMaskiANGLE(context, maskNumber, mask));
        if (isCallValid)
        {
            context->sampleMaski(maskNumber, mask);
        }
        ANGLE_CAPTURE(SampleMaskiANGLE, isCallValid, context, maskNumber, mask);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GetTexLevelParameterfvANGLE is already defined.

// GetTexLevelParameterivANGLE is already defined.

// GL_ANGLE_translated_shader_source
void GL_APIENTRY GetTranslatedShaderSourceANGLE(GLuint shader,
                                                GLsizei bufsize,
                                                GLsizei *length,
                                                GLchar *source)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetTranslatedShaderSourceANGLE,
          "glGetTranslatedShaderSourceANGLE",
          "context = %d, shader = %u, bufsize = %d, length = 0x%016" PRIxPTR
          ", source = 0x%016" PRIxPTR "",
          CID(context), shader, bufsize, (uintptr_t)length, (uintptr_t)source);

    if (context)
    {
        ShaderProgramID shaderPacked                          = FromGL<ShaderProgramID>(shader);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetTranslatedShaderSourceANGLE(
                                              context, shaderPacked, bufsize, length, source));
        if (isCallValid)
        {
            context->getTranslatedShaderSource(shaderPacked, bufsize, length, source);
        }
        ANGLE_CAPTURE(GetTranslatedShaderSourceANGLE, isCallValid, context, shaderPacked, bufsize,
                      length, source);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_CHROMIUM_bind_uniform_location
void GL_APIENTRY BindUniformLocationCHROMIUM(GLuint program, GLint location, const GLchar *name)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::BindUniformLocationCHROMIUM, "glBindUniformLocationCHROMIUM",
          "context = %d, program = %u, location = %d, name = 0x%016" PRIxPTR "", CID(context),
          program, location, (uintptr_t)name);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateBindUniformLocationCHROMIUM(context, programPacked, locationPacked, name));
        if (isCallValid)
        {
            context->bindUniformLocation(programPacked, locationPacked, name);
        }
        ANGLE_CAPTURE(BindUniformLocationCHROMIUM, isCallValid, context, programPacked,
                      locationPacked, name);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_CHROMIUM_copy_compressed_texture
void GL_APIENTRY CompressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::CompressedCopyTextureCHROMIUM, "glCompressedCopyTextureCHROMIUM",
          "context = %d, sourceId = %u, destId = %u", CID(context), sourceId, destId);

    if (context)
    {
        TextureID sourceIdPacked                              = FromGL<TextureID>(sourceId);
        TextureID destIdPacked                                = FromGL<TextureID>(destId);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateCompressedCopyTextureCHROMIUM(context, sourceIdPacked, destIdPacked));
        if (isCallValid)
        {
            context->compressedCopyTexture(sourceIdPacked, destIdPacked);
        }
        ANGLE_CAPTURE(CompressedCopyTextureCHROMIUM, isCallValid, context, sourceIdPacked,
                      destIdPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_CHROMIUM_copy_texture
void GL_APIENTRY CopyTextureCHROMIUM(GLuint sourceId,
                                     GLint sourceLevel,
                                     GLenum destTarget,
                                     GLuint destId,
                                     GLint destLevel,
                                     GLint internalFormat,
                                     GLenum destType,
                                     GLboolean unpackFlipY,
                                     GLboolean unpackPremultiplyAlpha,
                                     GLboolean unpackUnmultiplyAlpha)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::CopyTextureCHROMIUM, "glCopyTextureCHROMIUM",
          "context = %d, sourceId = %u, sourceLevel = %d, destTarget = %s, destId = %u, destLevel "
          "= %d, internalFormat = %d, destType = %s, unpackFlipY = %s, unpackPremultiplyAlpha = "
          "%s, unpackUnmultiplyAlpha = %s",
          CID(context), sourceId, sourceLevel,
          GLenumToString(GLenumGroup::DefaultGroup, destTarget), destId, destLevel, internalFormat,
          GLenumToString(GLenumGroup::DefaultGroup, destType), GLbooleanToString(unpackFlipY),
          GLbooleanToString(unpackPremultiplyAlpha), GLbooleanToString(unpackUnmultiplyAlpha));

    if (context)
    {
        TextureID sourceIdPacked                              = FromGL<TextureID>(sourceId);
        TextureTarget destTargetPacked                        = FromGL<TextureTarget>(destTarget);
        TextureID destIdPacked                                = FromGL<TextureID>(destId);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateCopyTextureCHROMIUM(
                                context, sourceIdPacked, sourceLevel, destTargetPacked,
                                destIdPacked, destLevel, internalFormat, destType, unpackFlipY,
                                unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
        if (isCallValid)
        {
            context->copyTexture(sourceIdPacked, sourceLevel, destTargetPacked, destIdPacked,
                                 destLevel, internalFormat, destType, unpackFlipY,
                                 unpackPremultiplyAlpha, unpackUnmultiplyAlpha);
        }
        ANGLE_CAPTURE(CopyTextureCHROMIUM, isCallValid, context, sourceIdPacked, sourceLevel,
                      destTargetPacked, destIdPacked, destLevel, internalFormat, destType,
                      unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY CopySubTextureCHROMIUM(GLuint sourceId,
                                        GLint sourceLevel,
                                        GLenum destTarget,
                                        GLuint destId,
                                        GLint destLevel,
                                        GLint xoffset,
                                        GLint yoffset,
                                        GLint x,
                                        GLint y,
                                        GLint width,
                                        GLint height,
                                        GLboolean unpackFlipY,
                                        GLboolean unpackPremultiplyAlpha,
                                        GLboolean unpackUnmultiplyAlpha)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::CopySubTextureCHROMIUM, "glCopySubTextureCHROMIUM",
          "context = %d, sourceId = %u, sourceLevel = %d, destTarget = %s, destId = %u, destLevel "
          "= %d, xoffset = %d, yoffset = %d, x = %d, y = %d, width = %d, height = %d, unpackFlipY "
          "= %s, unpackPremultiplyAlpha = %s, unpackUnmultiplyAlpha = %s",
          CID(context), sourceId, sourceLevel,
          GLenumToString(GLenumGroup::DefaultGroup, destTarget), destId, destLevel, xoffset,
          yoffset, x, y, width, height, GLbooleanToString(unpackFlipY),
          GLbooleanToString(unpackPremultiplyAlpha), GLbooleanToString(unpackUnmultiplyAlpha));

    if (context)
    {
        TextureID sourceIdPacked                              = FromGL<TextureID>(sourceId);
        TextureTarget destTargetPacked                        = FromGL<TextureTarget>(destTarget);
        TextureID destIdPacked                                = FromGL<TextureID>(destId);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateCopySubTextureCHROMIUM(
                                context, sourceIdPacked, sourceLevel, destTargetPacked,
                                destIdPacked, destLevel, xoffset, yoffset, x, y, width, height,
                                unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
        if (isCallValid)
        {
            context->copySubTexture(sourceIdPacked, sourceLevel, destTargetPacked, destIdPacked,
                                    destLevel, xoffset, yoffset, x, y, width, height, unpackFlipY,
                                    unpackPremultiplyAlpha, unpackUnmultiplyAlpha);
        }
        ANGLE_CAPTURE(CopySubTextureCHROMIUM, isCallValid, context, sourceIdPacked, sourceLevel,
                      destTargetPacked, destIdPacked, destLevel, xoffset, yoffset, x, y, width,
                      height, unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_CHROMIUM_framebuffer_mixed_samples
void GL_APIENTRY CoverageModulationCHROMIUM(GLenum components)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::CoverageModulationCHROMIUM, "glCoverageModulationCHROMIUM",
          "context = %d, components = %s", CID(context),
          GLenumToString(GLenumGroup::DefaultGroup, components));

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateCoverageModulationCHROMIUM(context, components));
        if (isCallValid)
        {
            context->coverageModulation(components);
        }
        ANGLE_CAPTURE(CoverageModulationCHROMIUM, isCallValid, context, components);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_CHROMIUM_lose_context
void GL_APIENTRY LoseContextCHROMIUM(GLenum current, GLenum other)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::LoseContextCHROMIUM, "glLoseContextCHROMIUM",
          "context = %d, current = %s, other = %s", CID(context),
          GLenumToString(GLenumGroup::GraphicsResetStatus, current),
          GLenumToString(GLenumGroup::GraphicsResetStatus, other));

    if (context)
    {
        GraphicsResetStatus currentPacked = FromGL<GraphicsResetStatus>(current);
        GraphicsResetStatus otherPacked   = FromGL<GraphicsResetStatus>(other);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateLoseContextCHROMIUM(context, currentPacked, otherPacked));
        if (isCallValid)
        {
            context->loseContext(currentPacked, otherPacked);
        }
        ANGLE_CAPTURE(LoseContextCHROMIUM, isCallValid, context, currentPacked, otherPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_EXT_EGL_image_array

// GL_EXT_blend_func_extended
void GL_APIENTRY BindFragDataLocationEXT(GLuint program, GLuint color, const GLchar *name)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::BindFragDataLocationEXT, "glBindFragDataLocationEXT",
          "context = %d, program = %u, color = %u, name = 0x%016" PRIxPTR "", CID(context), program,
          color, (uintptr_t)name);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateBindFragDataLocationEXT(context, programPacked, color, name));
        if (isCallValid)
        {
            context->bindFragDataLocation(programPacked, color, name);
        }
        ANGLE_CAPTURE(BindFragDataLocationEXT, isCallValid, context, programPacked, color, name);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY BindFragDataLocationIndexedEXT(GLuint program,
                                                GLuint colorNumber,
                                                GLuint index,
                                                const GLchar *name)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::BindFragDataLocationIndexedEXT,
          "glBindFragDataLocationIndexedEXT",
          "context = %d, program = %u, colorNumber = %u, index = %u, name = 0x%016" PRIxPTR "",
          CID(context), program, colorNumber, index, (uintptr_t)name);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateBindFragDataLocationIndexedEXT(
                                              context, programPacked, colorNumber, index, name));
        if (isCallValid)
        {
            context->bindFragDataLocationIndexed(programPacked, colorNumber, index, name);
        }
        ANGLE_CAPTURE(BindFragDataLocationIndexedEXT, isCallValid, context, programPacked,
                      colorNumber, index, name);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

GLint GL_APIENTRY GetFragDataIndexEXT(GLuint program, const GLchar *name)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetFragDataIndexEXT, "glGetFragDataIndexEXT",
          "context = %d, program = %u, name = 0x%016" PRIxPTR "", CID(context), program,
          (uintptr_t)name);

    GLint returnValue;
    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetFragDataIndexEXT(context, programPacked, name));
        if (isCallValid)
        {
            returnValue = context->getFragDataIndex(programPacked, name);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::GetFragDataIndexEXT, GLint>();
        }
        ANGLE_CAPTURE(GetFragDataIndexEXT, isCallValid, context, programPacked, name, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
        returnValue = GetDefaultReturnValue<EntryPoint::GetFragDataIndexEXT, GLint>();
    }
    return returnValue;
}

GLint GL_APIENTRY GetProgramResourceLocationIndexEXT(GLuint program,
                                                     GLenum programInterface,
                                                     const GLchar *name)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetProgramResourceLocationIndexEXT,
          "glGetProgramResourceLocationIndexEXT",
          "context = %d, program = %u, programInterface = %s, name = 0x%016" PRIxPTR "",
          CID(context), program, GLenumToString(GLenumGroup::ProgramInterface, programInterface),
          (uintptr_t)name);

    GLint returnValue;
    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetProgramResourceLocationIndexEXT(
                                              context, programPacked, programInterface, name));
        if (isCallValid)
        {
            returnValue =
                context->getProgramResourceLocationIndex(programPacked, programInterface, name);
        }
        else
        {
            returnValue =
                GetDefaultReturnValue<EntryPoint::GetProgramResourceLocationIndexEXT, GLint>();
        }
        ANGLE_CAPTURE(GetProgramResourceLocationIndexEXT, isCallValid, context, programPacked,
                      programInterface, name, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
        returnValue =
            GetDefaultReturnValue<EntryPoint::GetProgramResourceLocationIndexEXT, GLint>();
    }
    return returnValue;
}

// GL_EXT_buffer_storage
void GL_APIENTRY BufferStorageEXT(GLenum target,
                                  GLsizeiptr size,
                                  const void *data,
                                  GLbitfield flags)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::BufferStorageEXT, "glBufferStorageEXT",
          "context = %d, target = %s, size = %llu, data = 0x%016" PRIxPTR ", flags = %s",
          CID(context), GLenumToString(GLenumGroup::BufferStorageTarget, target),
          static_cast<unsigned long long>(size), (uintptr_t)data,
          GLbitfieldToString(GLenumGroup::MapBufferUsageMask, flags).c_str());

    if (context)
    {
        BufferBinding targetPacked                            = FromGL<BufferBinding>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateBufferStorageEXT(context, targetPacked, size, data, flags));
        if (isCallValid)
        {
            context->bufferStorage(targetPacked, size, data, flags);
        }
        ANGLE_CAPTURE(BufferStorageEXT, isCallValid, context, targetPacked, size, data, flags);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_EXT_copy_image
void GL_APIENTRY CopyImageSubDataEXT(GLuint srcName,
                                     GLenum srcTarget,
                                     GLint srcLevel,
                                     GLint srcX,
                                     GLint srcY,
                                     GLint srcZ,
                                     GLuint dstName,
                                     GLenum dstTarget,
                                     GLint dstLevel,
                                     GLint dstX,
                                     GLint dstY,
                                     GLint dstZ,
                                     GLsizei srcWidth,
                                     GLsizei srcHeight,
                                     GLsizei srcDepth)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::CopyImageSubDataEXT, "glCopyImageSubDataEXT",
          "context = %d, srcName = %u, srcTarget = %s, srcLevel = %d, srcX = %d, srcY = %d, srcZ = "
          "%d, dstName = %u, dstTarget = %s, dstLevel = %d, dstX = %d, dstY = %d, dstZ = %d, "
          "srcWidth = %d, srcHeight = %d, srcDepth = %d",
          CID(context), srcName, GLenumToString(GLenumGroup::CopyBufferSubDataTarget, srcTarget),
          srcLevel, srcX, srcY, srcZ, dstName,
          GLenumToString(GLenumGroup::CopyBufferSubDataTarget, dstTarget), dstLevel, dstX, dstY,
          dstZ, srcWidth, srcHeight, srcDepth);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateCopyImageSubDataEXT(context, srcName, srcTarget, srcLevel, srcX, srcY, srcZ,
                                         dstName, dstTarget, dstLevel, dstX, dstY, dstZ, srcWidth,
                                         srcHeight, srcDepth));
        if (isCallValid)
        {
            context->copyImageSubData(srcName, srcTarget, srcLevel, srcX, srcY, srcZ, dstName,
                                      dstTarget, dstLevel, dstX, dstY, dstZ, srcWidth, srcHeight,
                                      srcDepth);
        }
        ANGLE_CAPTURE(CopyImageSubDataEXT, isCallValid, context, srcName, srcTarget, srcLevel, srcX,
                      srcY, srcZ, dstName, dstTarget, dstLevel, dstX, dstY, dstZ, srcWidth,
                      srcHeight, srcDepth);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_EXT_debug_marker
void GL_APIENTRY InsertEventMarkerEXT(GLsizei length, const GLchar *marker)
{
    Context *context = GetValidGlobalContext();
    // Don't run the EVENT() macro on the EXT_debug_marker entry points.
    // It can interfere with the debug events being set by the caller.
    // EVENT(context, gl::EntryPoint::InsertEventMarkerEXT, "glInsertEventMarkerEXT", "context = %d,
    // length = %d, marker = 0x%016" PRIxPTR "", CID(context), length, (uintptr_t)marker);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateInsertEventMarkerEXT(context, length, marker));
        if (isCallValid)
        {
            context->insertEventMarker(length, marker);
        }
        ANGLE_CAPTURE(InsertEventMarkerEXT, isCallValid, context, length, marker);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY PopGroupMarkerEXT()
{
    Context *context = GetValidGlobalContext();
    // Don't run the EVENT() macro on the EXT_debug_marker entry points.
    // It can interfere with the debug events being set by the caller.
    // EVENT(context, gl::EntryPoint::PopGroupMarkerEXT, "glPopGroupMarkerEXT", "context = %d",
    // CID(context));

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidatePopGroupMarkerEXT(context));
        if (isCallValid)
        {
            context->popGroupMarker();
        }
        ANGLE_CAPTURE(PopGroupMarkerEXT, isCallValid, context);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY PushGroupMarkerEXT(GLsizei length, const GLchar *marker)
{
    Context *context = GetValidGlobalContext();
    // Don't run the EVENT() macro on the EXT_debug_marker entry points.
    // It can interfere with the debug events being set by the caller.
    // EVENT(context, gl::EntryPoint::PushGroupMarkerEXT, "glPushGroupMarkerEXT", "context = %d,
    // length = %d, marker = 0x%016" PRIxPTR "", CID(context), length, (uintptr_t)marker);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidatePushGroupMarkerEXT(context, length, marker));
        if (isCallValid)
        {
            context->pushGroupMarker(length, marker);
        }
        ANGLE_CAPTURE(PushGroupMarkerEXT, isCallValid, context, length, marker);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_EXT_discard_framebuffer
void GL_APIENTRY DiscardFramebufferEXT(GLenum target,
                                       GLsizei numAttachments,
                                       const GLenum *attachments)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::DiscardFramebufferEXT, "glDiscardFramebufferEXT",
          "context = %d, target = %s, numAttachments = %d, attachments = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target), numAttachments,
          (uintptr_t)attachments);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateDiscardFramebufferEXT(context, target, numAttachments, attachments));
        if (isCallValid)
        {
            context->discardFramebuffer(target, numAttachments, attachments);
        }
        ANGLE_CAPTURE(DiscardFramebufferEXT, isCallValid, context, target, numAttachments,
                      attachments);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_EXT_disjoint_timer_query
void GL_APIENTRY BeginQueryEXT(GLenum target, GLuint id)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::BeginQueryEXT, "glBeginQueryEXT",
          "context = %d, target = %s, id = %u", CID(context),
          GLenumToString(GLenumGroup::QueryTarget, target), id);

    if (context)
    {
        QueryType targetPacked                                = FromGL<QueryType>(target);
        QueryID idPacked                                      = FromGL<QueryID>(id);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateBeginQueryEXT(context, targetPacked, idPacked));
        if (isCallValid)
        {
            context->beginQuery(targetPacked, idPacked);
        }
        ANGLE_CAPTURE(BeginQueryEXT, isCallValid, context, targetPacked, idPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY DeleteQueriesEXT(GLsizei n, const GLuint *ids)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::DeleteQueriesEXT, "glDeleteQueriesEXT",
          "context = %d, n = %d, ids = 0x%016" PRIxPTR "", CID(context), n, (uintptr_t)ids);

    if (context)
    {
        const QueryID *idsPacked                              = FromGL<const QueryID *>(ids);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateDeleteQueriesEXT(context, n, idsPacked));
        if (isCallValid)
        {
            context->deleteQueries(n, idsPacked);
        }
        ANGLE_CAPTURE(DeleteQueriesEXT, isCallValid, context, n, idsPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY EndQueryEXT(GLenum target)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::EndQueryEXT, "glEndQueryEXT", "context = %d, target = %s",
          CID(context), GLenumToString(GLenumGroup::QueryTarget, target));

    if (context)
    {
        QueryType targetPacked                                = FromGL<QueryType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateEndQueryEXT(context, targetPacked));
        if (isCallValid)
        {
            context->endQuery(targetPacked);
        }
        ANGLE_CAPTURE(EndQueryEXT, isCallValid, context, targetPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GenQueriesEXT(GLsizei n, GLuint *ids)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GenQueriesEXT, "glGenQueriesEXT",
          "context = %d, n = %d, ids = 0x%016" PRIxPTR "", CID(context), n, (uintptr_t)ids);

    if (context)
    {
        QueryID *idsPacked                                    = FromGL<QueryID *>(ids);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGenQueriesEXT(context, n, idsPacked));
        if (isCallValid)
        {
            context->genQueries(n, idsPacked);
        }
        ANGLE_CAPTURE(GenQueriesEXT, isCallValid, context, n, idsPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetInteger64vEXT(GLenum pname, GLint64 *data)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetInteger64vEXT, "glGetInteger64vEXT",
          "context = %d, pname = %s, data = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::GetPName, pname), (uintptr_t)data);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetInteger64vEXT(context, pname, data));
        if (isCallValid)
        {
            context->getInteger64v(pname, data);
        }
        ANGLE_CAPTURE(GetInteger64vEXT, isCallValid, context, pname, data);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetQueryObjecti64vEXT(GLuint id, GLenum pname, GLint64 *params)
{
    Context *context = GetGlobalContext();
    EVENT(context, gl::EntryPoint::GetQueryObjecti64vEXT, "glGetQueryObjecti64vEXT",
          "context = %d, id = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context), id,
          GLenumToString(GLenumGroup::QueryObjectParameterName, pname), (uintptr_t)params);

    if (context)
    {
        QueryID idPacked                                      = FromGL<QueryID>(id);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetQueryObjecti64vEXT(context, idPacked, pname, params));
        if (isCallValid)
        {
            context->getQueryObjecti64v(idPacked, pname, params);
        }
        ANGLE_CAPTURE(GetQueryObjecti64vEXT, isCallValid, context, idPacked, pname, params);
    }
    else
    {}
}

void GL_APIENTRY GetQueryObjectivEXT(GLuint id, GLenum pname, GLint *params)
{
    Context *context = GetGlobalContext();
    EVENT(context, gl::EntryPoint::GetQueryObjectivEXT, "glGetQueryObjectivEXT",
          "context = %d, id = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context), id,
          GLenumToString(GLenumGroup::QueryObjectParameterName, pname), (uintptr_t)params);

    if (context)
    {
        QueryID idPacked                                      = FromGL<QueryID>(id);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetQueryObjectivEXT(context, idPacked, pname, params));
        if (isCallValid)
        {
            context->getQueryObjectiv(idPacked, pname, params);
        }
        ANGLE_CAPTURE(GetQueryObjectivEXT, isCallValid, context, idPacked, pname, params);
    }
    else
    {}
}

void GL_APIENTRY GetQueryObjectui64vEXT(GLuint id, GLenum pname, GLuint64 *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetQueryObjectui64vEXT, "glGetQueryObjectui64vEXT",
          "context = %d, id = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context), id,
          GLenumToString(GLenumGroup::QueryObjectParameterName, pname), (uintptr_t)params);

    if (context)
    {
        QueryID idPacked                                      = FromGL<QueryID>(id);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetQueryObjectui64vEXT(context, idPacked, pname, params));
        if (isCallValid)
        {
            context->getQueryObjectui64v(idPacked, pname, params);
        }
        ANGLE_CAPTURE(GetQueryObjectui64vEXT, isCallValid, context, idPacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetQueryObjectuivEXT, "glGetQueryObjectuivEXT",
          "context = %d, id = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context), id,
          GLenumToString(GLenumGroup::QueryObjectParameterName, pname), (uintptr_t)params);

    if (context)
    {
        QueryID idPacked                                      = FromGL<QueryID>(id);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetQueryObjectuivEXT(context, idPacked, pname, params));
        if (isCallValid)
        {
            context->getQueryObjectuiv(idPacked, pname, params);
        }
        ANGLE_CAPTURE(GetQueryObjectuivEXT, isCallValid, context, idPacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetQueryivEXT(GLenum target, GLenum pname, GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetQueryivEXT, "glGetQueryivEXT",
          "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::QueryTarget, target),
          GLenumToString(GLenumGroup::QueryParameterName, pname), (uintptr_t)params);

    if (context)
    {
        QueryType targetPacked                                = FromGL<QueryType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetQueryivEXT(context, targetPacked, pname, params));
        if (isCallValid)
        {
            context->getQueryiv(targetPacked, pname, params);
        }
        ANGLE_CAPTURE(GetQueryivEXT, isCallValid, context, targetPacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

GLboolean GL_APIENTRY IsQueryEXT(GLuint id)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::IsQueryEXT, "glIsQueryEXT", "context = %d, id = %u",
          CID(context), id);

    GLboolean returnValue;
    if (context)
    {
        QueryID idPacked                                      = FromGL<QueryID>(id);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateIsQueryEXT(context, idPacked));
        if (isCallValid)
        {
            returnValue = context->isQuery(idPacked);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::IsQueryEXT, GLboolean>();
        }
        ANGLE_CAPTURE(IsQueryEXT, isCallValid, context, idPacked, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
        returnValue = GetDefaultReturnValue<EntryPoint::IsQueryEXT, GLboolean>();
    }
    return returnValue;
}

void GL_APIENTRY QueryCounterEXT(GLuint id, GLenum target)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::QueryCounterEXT, "glQueryCounterEXT",
          "context = %d, id = %u, target = %s", CID(context), id,
          GLenumToString(GLenumGroup::QueryTarget, target));

    if (context)
    {
        QueryID idPacked                                      = FromGL<QueryID>(id);
        QueryType targetPacked                                = FromGL<QueryType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateQueryCounterEXT(context, idPacked, targetPacked));
        if (isCallValid)
        {
            context->queryCounter(idPacked, targetPacked);
        }
        ANGLE_CAPTURE(QueryCounterEXT, isCallValid, context, idPacked, targetPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_EXT_draw_buffers
void GL_APIENTRY DrawBuffersEXT(GLsizei n, const GLenum *bufs)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::DrawBuffersEXT, "glDrawBuffersEXT",
          "context = %d, n = %d, bufs = 0x%016" PRIxPTR "", CID(context), n, (uintptr_t)bufs);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateDrawBuffersEXT(context, n, bufs));
        if (isCallValid)
        {
            context->drawBuffers(n, bufs);
        }
        ANGLE_CAPTURE(DrawBuffersEXT, isCallValid, context, n, bufs);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_EXT_draw_buffers_indexed
void GL_APIENTRY BlendEquationSeparateiEXT(GLuint buf, GLenum modeRGB, GLenum modeAlpha)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::BlendEquationSeparateiEXT, "glBlendEquationSeparateiEXT",
          "context = %d, buf = %u, modeRGB = %s, modeAlpha = %s", CID(context), buf,
          GLenumToString(GLenumGroup::BlendEquationModeEXT, modeRGB),
          GLenumToString(GLenumGroup::BlendEquationModeEXT, modeAlpha));

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateBlendEquationSeparateiEXT(context, buf, modeRGB, modeAlpha));
        if (isCallValid)
        {
            context->blendEquationSeparatei(buf, modeRGB, modeAlpha);
        }
        ANGLE_CAPTURE(BlendEquationSeparateiEXT, isCallValid, context, buf, modeRGB, modeAlpha);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY BlendEquationiEXT(GLuint buf, GLenum mode)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::BlendEquationiEXT, "glBlendEquationiEXT",
          "context = %d, buf = %u, mode = %s", CID(context), buf,
          GLenumToString(GLenumGroup::BlendEquationModeEXT, mode));

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateBlendEquationiEXT(context, buf, mode));
        if (isCallValid)
        {
            context->blendEquationi(buf, mode);
        }
        ANGLE_CAPTURE(BlendEquationiEXT, isCallValid, context, buf, mode);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY
BlendFuncSeparateiEXT(GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::BlendFuncSeparateiEXT, "glBlendFuncSeparateiEXT",
          "context = %d, buf = %u, srcRGB = %s, dstRGB = %s, srcAlpha = %s, dstAlpha = %s",
          CID(context), buf, GLenumToString(GLenumGroup::BlendingFactor, srcRGB),
          GLenumToString(GLenumGroup::BlendingFactor, dstRGB),
          GLenumToString(GLenumGroup::BlendingFactor, srcAlpha),
          GLenumToString(GLenumGroup::BlendingFactor, dstAlpha));

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateBlendFuncSeparateiEXT(context, buf, srcRGB, dstRGB, srcAlpha, dstAlpha));
        if (isCallValid)
        {
            context->blendFuncSeparatei(buf, srcRGB, dstRGB, srcAlpha, dstAlpha);
        }
        ANGLE_CAPTURE(BlendFuncSeparateiEXT, isCallValid, context, buf, srcRGB, dstRGB, srcAlpha,
                      dstAlpha);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY BlendFunciEXT(GLuint buf, GLenum src, GLenum dst)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::BlendFunciEXT, "glBlendFunciEXT",
          "context = %d, buf = %u, src = %s, dst = %s", CID(context), buf,
          GLenumToString(GLenumGroup::BlendingFactor, src),
          GLenumToString(GLenumGroup::BlendingFactor, dst));

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateBlendFunciEXT(context, buf, src, dst));
        if (isCallValid)
        {
            context->blendFunci(buf, src, dst);
        }
        ANGLE_CAPTURE(BlendFunciEXT, isCallValid, context, buf, src, dst);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ColorMaskiEXT(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::ColorMaskiEXT, "glColorMaskiEXT",
          "context = %d, index = %u, r = %s, g = %s, b = %s, a = %s", CID(context), index,
          GLbooleanToString(r), GLbooleanToString(g), GLbooleanToString(b), GLbooleanToString(a));

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateColorMaskiEXT(context, index, r, g, b, a));
        if (isCallValid)
        {
            context->colorMaski(index, r, g, b, a);
        }
        ANGLE_CAPTURE(ColorMaskiEXT, isCallValid, context, index, r, g, b, a);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY DisableiEXT(GLenum target, GLuint index)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::DisableiEXT, "glDisableiEXT",
          "context = %d, target = %s, index = %u", CID(context),
          GLenumToString(GLenumGroup::EnableCap, target), index);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateDisableiEXT(context, target, index));
        if (isCallValid)
        {
            context->disablei(target, index);
        }
        ANGLE_CAPTURE(DisableiEXT, isCallValid, context, target, index);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY EnableiEXT(GLenum target, GLuint index)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::EnableiEXT, "glEnableiEXT",
          "context = %d, target = %s, index = %u", CID(context),
          GLenumToString(GLenumGroup::EnableCap, target), index);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateEnableiEXT(context, target, index));
        if (isCallValid)
        {
            context->enablei(target, index);
        }
        ANGLE_CAPTURE(EnableiEXT, isCallValid, context, target, index);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

GLboolean GL_APIENTRY IsEnablediEXT(GLenum target, GLuint index)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::IsEnablediEXT, "glIsEnablediEXT",
          "context = %d, target = %s, index = %u", CID(context),
          GLenumToString(GLenumGroup::EnableCap, target), index);

    GLboolean returnValue;
    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateIsEnablediEXT(context, target, index));
        if (isCallValid)
        {
            returnValue = context->isEnabledi(target, index);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::IsEnablediEXT, GLboolean>();
        }
        ANGLE_CAPTURE(IsEnablediEXT, isCallValid, context, target, index, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
        returnValue = GetDefaultReturnValue<EntryPoint::IsEnablediEXT, GLboolean>();
    }
    return returnValue;
}

// GL_EXT_draw_elements_base_vertex
void GL_APIENTRY DrawElementsBaseVertexEXT(GLenum mode,
                                           GLsizei count,
                                           GLenum type,
                                           const void *indices,
                                           GLint basevertex)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::DrawElementsBaseVertexEXT, "glDrawElementsBaseVertexEXT",
          "context = %d, mode = %s, count = %d, type = %s, indices = 0x%016" PRIxPTR
          ", basevertex = %d",
          CID(context), GLenumToString(GLenumGroup::PrimitiveType, mode), count,
          GLenumToString(GLenumGroup::DrawElementsType, type), (uintptr_t)indices, basevertex);

    if (context)
    {
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        DrawElementsType typePacked                           = FromGL<DrawElementsType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateDrawElementsBaseVertexEXT(context, modePacked, count,
                                                              typePacked, indices, basevertex));
        if (isCallValid)
        {
            context->drawElementsBaseVertex(modePacked, count, typePacked, indices, basevertex);
        }
        ANGLE_CAPTURE(DrawElementsBaseVertexEXT, isCallValid, context, modePacked, count,
                      typePacked, indices, basevertex);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY DrawElementsInstancedBaseVertexEXT(GLenum mode,
                                                    GLsizei count,
                                                    GLenum type,
                                                    const void *indices,
                                                    GLsizei instancecount,
                                                    GLint basevertex)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::DrawElementsInstancedBaseVertexEXT,
          "glDrawElementsInstancedBaseVertexEXT",
          "context = %d, mode = %s, count = %d, type = %s, indices = 0x%016" PRIxPTR
          ", instancecount = %d, basevertex = %d",
          CID(context), GLenumToString(GLenumGroup::PrimitiveType, mode), count,
          GLenumToString(GLenumGroup::DrawElementsType, type), (uintptr_t)indices, instancecount,
          basevertex);

    if (context)
    {
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        DrawElementsType typePacked                           = FromGL<DrawElementsType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateDrawElementsInstancedBaseVertexEXT(
                                                             context, modePacked, count, typePacked,
                                                             indices, instancecount, basevertex));
        if (isCallValid)
        {
            context->drawElementsInstancedBaseVertex(modePacked, count, typePacked, indices,
                                                     instancecount, basevertex);
        }
        ANGLE_CAPTURE(DrawElementsInstancedBaseVertexEXT, isCallValid, context, modePacked, count,
                      typePacked, indices, instancecount, basevertex);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY DrawRangeElementsBaseVertexEXT(GLenum mode,
                                                GLuint start,
                                                GLuint end,
                                                GLsizei count,
                                                GLenum type,
                                                const void *indices,
                                                GLint basevertex)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::DrawRangeElementsBaseVertexEXT,
          "glDrawRangeElementsBaseVertexEXT",
          "context = %d, mode = %s, start = %u, end = %u, count = %d, type = %s, indices = "
          "0x%016" PRIxPTR ", basevertex = %d",
          CID(context), GLenumToString(GLenumGroup::PrimitiveType, mode), start, end, count,
          GLenumToString(GLenumGroup::DrawElementsType, type), (uintptr_t)indices, basevertex);

    if (context)
    {
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        DrawElementsType typePacked                           = FromGL<DrawElementsType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateDrawRangeElementsBaseVertexEXT(
                                                             context, modePacked, start, end, count,
                                                             typePacked, indices, basevertex));
        if (isCallValid)
        {
            context->drawRangeElementsBaseVertex(modePacked, start, end, count, typePacked, indices,
                                                 basevertex);
        }
        ANGLE_CAPTURE(DrawRangeElementsBaseVertexEXT, isCallValid, context, modePacked, start, end,
                      count, typePacked, indices, basevertex);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY MultiDrawElementsBaseVertexEXT(GLenum mode,
                                                const GLsizei *count,
                                                GLenum type,
                                                const void *const *indices,
                                                GLsizei primcount,
                                                const GLint *basevertex)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::MultiDrawElementsBaseVertexEXT,
          "glMultiDrawElementsBaseVertexEXT",
          "context = %d, mode = %s, count = 0x%016" PRIxPTR ", type = %s, indices = 0x%016" PRIxPTR
          ", primcount = %d, basevertex = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::PrimitiveType, mode), (uintptr_t)count,
          GLenumToString(GLenumGroup::DrawElementsType, type), (uintptr_t)indices, primcount,
          (uintptr_t)basevertex);

    if (context)
    {
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        DrawElementsType typePacked                           = FromGL<DrawElementsType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateMultiDrawElementsBaseVertexEXT(
                                                             context, modePacked, count, typePacked,
                                                             indices, primcount, basevertex));
        if (isCallValid)
        {
            context->multiDrawElementsBaseVertex(modePacked, count, typePacked, indices, primcount,
                                                 basevertex);
        }
        ANGLE_CAPTURE(MultiDrawElementsBaseVertexEXT, isCallValid, context, modePacked, count,
                      typePacked, indices, primcount, basevertex);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_EXT_external_buffer
void GL_APIENTRY BufferStorageExternalEXT(GLenum target,
                                          GLintptr offset,
                                          GLsizeiptr size,
                                          GLeglClientBufferEXT clientBuffer,
                                          GLbitfield flags)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::BufferStorageExternalEXT, "glBufferStorageExternalEXT",
          "context = %d, target = %s, offset = %llu, size = %llu, clientBuffer = 0x%016" PRIxPTR
          ", flags = %s",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target),
          static_cast<unsigned long long>(offset), static_cast<unsigned long long>(size),
          (uintptr_t)clientBuffer,
          GLbitfieldToString(GLenumGroup::MapBufferUsageMask, flags).c_str());

    if (context)
    {
        BufferBinding targetPacked                            = FromGL<BufferBinding>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateBufferStorageExternalEXT(context, targetPacked, offset, size,
                                                             clientBuffer, flags));
        if (isCallValid)
        {
            context->bufferStorageExternal(targetPacked, offset, size, clientBuffer, flags);
        }
        ANGLE_CAPTURE(BufferStorageExternalEXT, isCallValid, context, targetPacked, offset, size,
                      clientBuffer, flags);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY NamedBufferStorageExternalEXT(GLuint buffer,
                                               GLintptr offset,
                                               GLsizeiptr size,
                                               GLeglClientBufferEXT clientBuffer,
                                               GLbitfield flags)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::NamedBufferStorageExternalEXT, "glNamedBufferStorageExternalEXT",
          "context = %d, buffer = %u, offset = %llu, size = %llu, clientBuffer = 0x%016" PRIxPTR
          ", flags = %s",
          CID(context), buffer, static_cast<unsigned long long>(offset),
          static_cast<unsigned long long>(size), (uintptr_t)clientBuffer,
          GLbitfieldToString(GLenumGroup::MapBufferUsageMask, flags).c_str());

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateNamedBufferStorageExternalEXT(
                                              context, buffer, offset, size, clientBuffer, flags));
        if (isCallValid)
        {
            context->namedBufferStorageExternal(buffer, offset, size, clientBuffer, flags);
        }
        ANGLE_CAPTURE(NamedBufferStorageExternalEXT, isCallValid, context, buffer, offset, size,
                      clientBuffer, flags);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_EXT_geometry_shader
void GL_APIENTRY FramebufferTextureEXT(GLenum target,
                                       GLenum attachment,
                                       GLuint texture,
                                       GLint level)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::FramebufferTextureEXT, "glFramebufferTextureEXT",
          "context = %d, target = %s, attachment = %s, texture = %u, level = %d", CID(context),
          GLenumToString(GLenumGroup::FramebufferTarget, target),
          GLenumToString(GLenumGroup::FramebufferAttachment, attachment), texture, level);

    if (context)
    {
        TextureID texturePacked                               = FromGL<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateFramebufferTextureEXT(context, target, attachment, texturePacked, level));
        if (isCallValid)
        {
            context->framebufferTexture(target, attachment, texturePacked, level);
        }
        ANGLE_CAPTURE(FramebufferTextureEXT, isCallValid, context, target, attachment,
                      texturePacked, level);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_EXT_instanced_arrays
void GL_APIENTRY DrawArraysInstancedEXT(GLenum mode, GLint start, GLsizei count, GLsizei primcount)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::DrawArraysInstancedEXT, "glDrawArraysInstancedEXT",
          "context = %d, mode = %s, start = %d, count = %d, primcount = %d", CID(context),
          GLenumToString(GLenumGroup::PrimitiveType, mode), start, count, primcount);

    if (context)
    {
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateDrawArraysInstancedEXT(context, modePacked, start, count, primcount));
        if (isCallValid)
        {
            context->drawArraysInstanced(modePacked, start, count, primcount);
        }
        ANGLE_CAPTURE(DrawArraysInstancedEXT, isCallValid, context, modePacked, start, count,
                      primcount);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY DrawElementsInstancedEXT(GLenum mode,
                                          GLsizei count,
                                          GLenum type,
                                          const void *indices,
                                          GLsizei primcount)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::DrawElementsInstancedEXT, "glDrawElementsInstancedEXT",
          "context = %d, mode = %s, count = %d, type = %s, indices = 0x%016" PRIxPTR
          ", primcount = %d",
          CID(context), GLenumToString(GLenumGroup::PrimitiveType, mode), count,
          GLenumToString(GLenumGroup::DrawElementsType, type), (uintptr_t)indices, primcount);

    if (context)
    {
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        DrawElementsType typePacked                           = FromGL<DrawElementsType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateDrawElementsInstancedEXT(context, modePacked, count, typePacked,
                                                             indices, primcount));
        if (isCallValid)
        {
            context->drawElementsInstanced(modePacked, count, typePacked, indices, primcount);
        }
        ANGLE_CAPTURE(DrawElementsInstancedEXT, isCallValid, context, modePacked, count, typePacked,
                      indices, primcount);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY VertexAttribDivisorEXT(GLuint index, GLuint divisor)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::VertexAttribDivisorEXT, "glVertexAttribDivisorEXT",
          "context = %d, index = %u, divisor = %u", CID(context), index, divisor);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateVertexAttribDivisorEXT(context, index, divisor));
        if (isCallValid)
        {
            context->vertexAttribDivisor(index, divisor);
        }
        ANGLE_CAPTURE(VertexAttribDivisorEXT, isCallValid, context, index, divisor);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_EXT_map_buffer_range
void GL_APIENTRY FlushMappedBufferRangeEXT(GLenum target, GLintptr offset, GLsizeiptr length)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::FlushMappedBufferRangeEXT, "glFlushMappedBufferRangeEXT",
          "context = %d, target = %s, offset = %llu, length = %llu", CID(context),
          GLenumToString(GLenumGroup::BufferTargetARB, target),
          static_cast<unsigned long long>(offset), static_cast<unsigned long long>(length));

    if (context)
    {
        BufferBinding targetPacked                            = FromGL<BufferBinding>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateFlushMappedBufferRangeEXT(context, targetPacked, offset, length));
        if (isCallValid)
        {
            context->flushMappedBufferRange(targetPacked, offset, length);
        }
        ANGLE_CAPTURE(FlushMappedBufferRangeEXT, isCallValid, context, targetPacked, offset,
                      length);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void *GL_APIENTRY MapBufferRangeEXT(GLenum target,
                                    GLintptr offset,
                                    GLsizeiptr length,
                                    GLbitfield access)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::MapBufferRangeEXT, "glMapBufferRangeEXT",
          "context = %d, target = %s, offset = %llu, length = %llu, access = %s", CID(context),
          GLenumToString(GLenumGroup::BufferTargetARB, target),
          static_cast<unsigned long long>(offset), static_cast<unsigned long long>(length),
          GLbitfieldToString(GLenumGroup::BufferAccessMask, access).c_str());

    void *returnValue;
    if (context)
    {
        BufferBinding targetPacked                            = FromGL<BufferBinding>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateMapBufferRangeEXT(context, targetPacked, offset, length, access));
        if (isCallValid)
        {
            returnValue = context->mapBufferRange(targetPacked, offset, length, access);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::MapBufferRangeEXT, void *>();
        }
        ANGLE_CAPTURE(MapBufferRangeEXT, isCallValid, context, targetPacked, offset, length, access,
                      returnValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
        returnValue = GetDefaultReturnValue<EntryPoint::MapBufferRangeEXT, void *>();
    }
    return returnValue;
}

// GL_EXT_memory_object
void GL_APIENTRY BufferStorageMemEXT(GLenum target, GLsizeiptr size, GLuint memory, GLuint64 offset)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::BufferStorageMemEXT, "glBufferStorageMemEXT",
          "context = %d, target = %s, size = %llu, memory = %u, offset = %llu", CID(context),
          GLenumToString(GLenumGroup::BufferTargetARB, target),
          static_cast<unsigned long long>(size), memory, static_cast<unsigned long long>(offset));

    if (context)
    {
        TextureType targetPacked                              = FromGL<TextureType>(target);
        MemoryObjectID memoryPacked                           = FromGL<MemoryObjectID>(memory);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateBufferStorageMemEXT(context, targetPacked, size, memoryPacked, offset));
        if (isCallValid)
        {
            context->bufferStorageMem(targetPacked, size, memoryPacked, offset);
        }
        ANGLE_CAPTURE(BufferStorageMemEXT, isCallValid, context, targetPacked, size, memoryPacked,
                      offset);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY CreateMemoryObjectsEXT(GLsizei n, GLuint *memoryObjects)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::CreateMemoryObjectsEXT, "glCreateMemoryObjectsEXT",
          "context = %d, n = %d, memoryObjects = 0x%016" PRIxPTR "", CID(context), n,
          (uintptr_t)memoryObjects);

    if (context)
    {
        MemoryObjectID *memoryObjectsPacked = FromGL<MemoryObjectID *>(memoryObjects);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateCreateMemoryObjectsEXT(context, n, memoryObjectsPacked));
        if (isCallValid)
        {
            context->createMemoryObjects(n, memoryObjectsPacked);
        }
        ANGLE_CAPTURE(CreateMemoryObjectsEXT, isCallValid, context, n, memoryObjectsPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY DeleteMemoryObjectsEXT(GLsizei n, const GLuint *memoryObjects)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::DeleteMemoryObjectsEXT, "glDeleteMemoryObjectsEXT",
          "context = %d, n = %d, memoryObjects = 0x%016" PRIxPTR "", CID(context), n,
          (uintptr_t)memoryObjects);

    if (context)
    {
        const MemoryObjectID *memoryObjectsPacked = FromGL<const MemoryObjectID *>(memoryObjects);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateDeleteMemoryObjectsEXT(context, n, memoryObjectsPacked));
        if (isCallValid)
        {
            context->deleteMemoryObjects(n, memoryObjectsPacked);
        }
        ANGLE_CAPTURE(DeleteMemoryObjectsEXT, isCallValid, context, n, memoryObjectsPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetMemoryObjectParameterivEXT(GLuint memoryObject, GLenum pname, GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetMemoryObjectParameterivEXT, "glGetMemoryObjectParameterivEXT",
          "context = %d, memoryObject = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          memoryObject, GLenumToString(GLenumGroup::MemoryObjectParameterName, pname),
          (uintptr_t)params);

    if (context)
    {
        MemoryObjectID memoryObjectPacked = FromGL<MemoryObjectID>(memoryObject);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetMemoryObjectParameterivEXT(context, memoryObjectPacked, pname, params));
        if (isCallValid)
        {
            context->getMemoryObjectParameteriv(memoryObjectPacked, pname, params);
        }
        ANGLE_CAPTURE(GetMemoryObjectParameterivEXT, isCallValid, context, memoryObjectPacked,
                      pname, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetUnsignedBytevEXT(GLenum pname, GLubyte *data)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetUnsignedBytevEXT, "glGetUnsignedBytevEXT",
          "context = %d, pname = %s, data = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::GetPName, pname), (uintptr_t)data);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetUnsignedBytevEXT(context, pname, data));
        if (isCallValid)
        {
            context->getUnsignedBytev(pname, data);
        }
        ANGLE_CAPTURE(GetUnsignedBytevEXT, isCallValid, context, pname, data);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetUnsignedBytei_vEXT(GLenum target, GLuint index, GLubyte *data)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetUnsignedBytei_vEXT, "glGetUnsignedBytei_vEXT",
          "context = %d, target = %s, index = %u, data = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::DefaultGroup, target), index, (uintptr_t)data);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetUnsignedBytei_vEXT(context, target, index, data));
        if (isCallValid)
        {
            context->getUnsignedBytei_v(target, index, data);
        }
        ANGLE_CAPTURE(GetUnsignedBytei_vEXT, isCallValid, context, target, index, data);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

GLboolean GL_APIENTRY IsMemoryObjectEXT(GLuint memoryObject)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::IsMemoryObjectEXT, "glIsMemoryObjectEXT",
          "context = %d, memoryObject = %u", CID(context), memoryObject);

    GLboolean returnValue;
    if (context)
    {
        MemoryObjectID memoryObjectPacked = FromGL<MemoryObjectID>(memoryObject);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateIsMemoryObjectEXT(context, memoryObjectPacked));
        if (isCallValid)
        {
            returnValue = context->isMemoryObject(memoryObjectPacked);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::IsMemoryObjectEXT, GLboolean>();
        }
        ANGLE_CAPTURE(IsMemoryObjectEXT, isCallValid, context, memoryObjectPacked, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
        returnValue = GetDefaultReturnValue<EntryPoint::IsMemoryObjectEXT, GLboolean>();
    }
    return returnValue;
}

void GL_APIENTRY MemoryObjectParameterivEXT(GLuint memoryObject, GLenum pname, const GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::MemoryObjectParameterivEXT, "glMemoryObjectParameterivEXT",
          "context = %d, memoryObject = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          memoryObject, GLenumToString(GLenumGroup::MemoryObjectParameterName, pname),
          (uintptr_t)params);

    if (context)
    {
        MemoryObjectID memoryObjectPacked = FromGL<MemoryObjectID>(memoryObject);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateMemoryObjectParameterivEXT(context, memoryObjectPacked, pname, params));
        if (isCallValid)
        {
            context->memoryObjectParameteriv(memoryObjectPacked, pname, params);
        }
        ANGLE_CAPTURE(MemoryObjectParameterivEXT, isCallValid, context, memoryObjectPacked, pname,
                      params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TexStorageMem2DEXT(GLenum target,
                                    GLsizei levels,
                                    GLenum internalFormat,
                                    GLsizei width,
                                    GLsizei height,
                                    GLuint memory,
                                    GLuint64 offset)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::TexStorageMem2DEXT, "glTexStorageMem2DEXT",
          "context = %d, target = %s, levels = %d, internalFormat = %s, width = %d, height = %d, "
          "memory = %u, offset = %llu",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), levels,
          GLenumToString(GLenumGroup::DefaultGroup, internalFormat), width, height, memory,
          static_cast<unsigned long long>(offset));

    if (context)
    {
        TextureType targetPacked                              = FromGL<TextureType>(target);
        MemoryObjectID memoryPacked                           = FromGL<MemoryObjectID>(memory);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTexStorageMem2DEXT(context, targetPacked, levels, internalFormat, width,
                                        height, memoryPacked, offset));
        if (isCallValid)
        {
            context->texStorageMem2D(targetPacked, levels, internalFormat, width, height,
                                     memoryPacked, offset);
        }
        ANGLE_CAPTURE(TexStorageMem2DEXT, isCallValid, context, targetPacked, levels,
                      internalFormat, width, height, memoryPacked, offset);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TexStorageMem2DMultisampleEXT(GLenum target,
                                               GLsizei samples,
                                               GLenum internalFormat,
                                               GLsizei width,
                                               GLsizei height,
                                               GLboolean fixedSampleLocations,
                                               GLuint memory,
                                               GLuint64 offset)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::TexStorageMem2DMultisampleEXT, "glTexStorageMem2DMultisampleEXT",
          "context = %d, target = %s, samples = %d, internalFormat = %s, width = %d, height = %d, "
          "fixedSampleLocations = %s, memory = %u, offset = %llu",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), samples,
          GLenumToString(GLenumGroup::DefaultGroup, internalFormat), width, height,
          GLbooleanToString(fixedSampleLocations), memory, static_cast<unsigned long long>(offset));

    if (context)
    {
        TextureType targetPacked                              = FromGL<TextureType>(target);
        MemoryObjectID memoryPacked                           = FromGL<MemoryObjectID>(memory);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateTexStorageMem2DMultisampleEXT(
                                              context, targetPacked, samples, internalFormat, width,
                                              height, fixedSampleLocations, memoryPacked, offset));
        if (isCallValid)
        {
            context->texStorageMem2DMultisample(targetPacked, samples, internalFormat, width,
                                                height, fixedSampleLocations, memoryPacked, offset);
        }
        ANGLE_CAPTURE(TexStorageMem2DMultisampleEXT, isCallValid, context, targetPacked, samples,
                      internalFormat, width, height, fixedSampleLocations, memoryPacked, offset);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TexStorageMem3DEXT(GLenum target,
                                    GLsizei levels,
                                    GLenum internalFormat,
                                    GLsizei width,
                                    GLsizei height,
                                    GLsizei depth,
                                    GLuint memory,
                                    GLuint64 offset)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::TexStorageMem3DEXT, "glTexStorageMem3DEXT",
          "context = %d, target = %s, levels = %d, internalFormat = %s, width = %d, height = %d, "
          "depth = %d, memory = %u, offset = %llu",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), levels,
          GLenumToString(GLenumGroup::DefaultGroup, internalFormat), width, height, depth, memory,
          static_cast<unsigned long long>(offset));

    if (context)
    {
        TextureType targetPacked                              = FromGL<TextureType>(target);
        MemoryObjectID memoryPacked                           = FromGL<MemoryObjectID>(memory);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTexStorageMem3DEXT(context, targetPacked, levels, internalFormat, width,
                                        height, depth, memoryPacked, offset));
        if (isCallValid)
        {
            context->texStorageMem3D(targetPacked, levels, internalFormat, width, height, depth,
                                     memoryPacked, offset);
        }
        ANGLE_CAPTURE(TexStorageMem3DEXT, isCallValid, context, targetPacked, levels,
                      internalFormat, width, height, depth, memoryPacked, offset);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TexStorageMem3DMultisampleEXT(GLenum target,
                                               GLsizei samples,
                                               GLenum internalFormat,
                                               GLsizei width,
                                               GLsizei height,
                                               GLsizei depth,
                                               GLboolean fixedSampleLocations,
                                               GLuint memory,
                                               GLuint64 offset)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::TexStorageMem3DMultisampleEXT, "glTexStorageMem3DMultisampleEXT",
          "context = %d, target = %s, samples = %d, internalFormat = %s, width = %d, height = %d, "
          "depth = %d, fixedSampleLocations = %s, memory = %u, offset = %llu",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), samples,
          GLenumToString(GLenumGroup::DefaultGroup, internalFormat), width, height, depth,
          GLbooleanToString(fixedSampleLocations), memory, static_cast<unsigned long long>(offset));

    if (context)
    {
        TextureType targetPacked                              = FromGL<TextureType>(target);
        MemoryObjectID memoryPacked                           = FromGL<MemoryObjectID>(memory);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateTexStorageMem3DMultisampleEXT(
                                context, targetPacked, samples, internalFormat, width, height,
                                depth, fixedSampleLocations, memoryPacked, offset));
        if (isCallValid)
        {
            context->texStorageMem3DMultisample(targetPacked, samples, internalFormat, width,
                                                height, depth, fixedSampleLocations, memoryPacked,
                                                offset);
        }
        ANGLE_CAPTURE(TexStorageMem3DMultisampleEXT, isCallValid, context, targetPacked, samples,
                      internalFormat, width, height, depth, fixedSampleLocations, memoryPacked,
                      offset);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_EXT_memory_object_fd
void GL_APIENTRY ImportMemoryFdEXT(GLuint memory, GLuint64 size, GLenum handleType, GLint fd)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::ImportMemoryFdEXT, "glImportMemoryFdEXT",
          "context = %d, memory = %u, size = %llu, handleType = %s, fd = %d", CID(context), memory,
          static_cast<unsigned long long>(size),
          GLenumToString(GLenumGroup::ExternalHandleType, handleType), fd);

    if (context)
    {
        MemoryObjectID memoryPacked                           = FromGL<MemoryObjectID>(memory);
        HandleType handleTypePacked                           = FromGL<HandleType>(handleType);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateImportMemoryFdEXT(context, memoryPacked, size, handleTypePacked, fd));
        if (isCallValid)
        {
            context->importMemoryFd(memoryPacked, size, handleTypePacked, fd);
        }
        ANGLE_CAPTURE(ImportMemoryFdEXT, isCallValid, context, memoryPacked, size, handleTypePacked,
                      fd);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_EXT_multisampled_render_to_texture
void GL_APIENTRY FramebufferTexture2DMultisampleEXT(GLenum target,
                                                    GLenum attachment,
                                                    GLenum textarget,
                                                    GLuint texture,
                                                    GLint level,
                                                    GLsizei samples)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::FramebufferTexture2DMultisampleEXT,
          "glFramebufferTexture2DMultisampleEXT",
          "context = %d, target = %s, attachment = %s, textarget = %s, texture = %u, level = %d, "
          "samples = %d",
          CID(context), GLenumToString(GLenumGroup::FramebufferTarget, target),
          GLenumToString(GLenumGroup::FramebufferAttachment, attachment),
          GLenumToString(GLenumGroup::TextureTarget, textarget), texture, level, samples);

    if (context)
    {
        TextureTarget textargetPacked                         = FromGL<TextureTarget>(textarget);
        TextureID texturePacked                               = FromGL<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateFramebufferTexture2DMultisampleEXT(
                 context, target, attachment, textargetPacked, texturePacked, level, samples));
        if (isCallValid)
        {
            context->framebufferTexture2DMultisample(target, attachment, textargetPacked,
                                                     texturePacked, level, samples);
        }
        ANGLE_CAPTURE(FramebufferTexture2DMultisampleEXT, isCallValid, context, target, attachment,
                      textargetPacked, texturePacked, level, samples);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY RenderbufferStorageMultisampleEXT(GLenum target,
                                                   GLsizei samples,
                                                   GLenum internalformat,
                                                   GLsizei width,
                                                   GLsizei height)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::RenderbufferStorageMultisampleEXT,
          "glRenderbufferStorageMultisampleEXT",
          "context = %d, target = %s, samples = %d, internalformat = %s, width = %d, height = %d",
          CID(context), GLenumToString(GLenumGroup::RenderbufferTarget, target), samples,
          GLenumToString(GLenumGroup::InternalFormat, internalformat), width, height);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateRenderbufferStorageMultisampleEXT(
                                context, target, samples, internalformat, width, height));
        if (isCallValid)
        {
            context->renderbufferStorageMultisampleEXT(target, samples, internalformat, width,
                                                       height);
        }
        ANGLE_CAPTURE(RenderbufferStorageMultisampleEXT, isCallValid, context, target, samples,
                      internalformat, width, height);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_EXT_occlusion_query_boolean
// BeginQueryEXT is already defined.

// DeleteQueriesEXT is already defined.

// EndQueryEXT is already defined.

// GenQueriesEXT is already defined.

// GetQueryObjectuivEXT is already defined.

// GetQueryivEXT is already defined.

// IsQueryEXT is already defined.

// GL_EXT_read_format_bgra

// GL_EXT_robustness
GLenum GL_APIENTRY GetGraphicsResetStatusEXT()
{
    Context *context = GetGlobalContext();
    EVENT(context, gl::EntryPoint::GetGraphicsResetStatusEXT, "glGetGraphicsResetStatusEXT",
          "context = %d", CID(context));

    GLenum returnValue;
    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetGraphicsResetStatusEXT(context));
        if (isCallValid)
        {
            returnValue = context->getGraphicsResetStatus();
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::GetGraphicsResetStatusEXT, GLenum>();
        }
        ANGLE_CAPTURE(GetGraphicsResetStatusEXT, isCallValid, context, returnValue);
    }
    else
    {

        returnValue = GetDefaultReturnValue<EntryPoint::GetGraphicsResetStatusEXT, GLenum>();
    }
    return returnValue;
}

void GL_APIENTRY GetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetnUniformfvEXT, "glGetnUniformfvEXT",
          "context = %d, program = %u, location = %d, bufSize = %d, params = 0x%016" PRIxPTR "",
          CID(context), program, location, bufSize, (uintptr_t)params);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetnUniformfvEXT(context, programPacked, locationPacked, bufSize, params));
        if (isCallValid)
        {
            context->getnUniformfv(programPacked, locationPacked, bufSize, params);
        }
        ANGLE_CAPTURE(GetnUniformfvEXT, isCallValid, context, programPacked, locationPacked,
                      bufSize, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetnUniformivEXT, "glGetnUniformivEXT",
          "context = %d, program = %u, location = %d, bufSize = %d, params = 0x%016" PRIxPTR "",
          CID(context), program, location, bufSize, (uintptr_t)params);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetnUniformivEXT(context, programPacked, locationPacked, bufSize, params));
        if (isCallValid)
        {
            context->getnUniformiv(programPacked, locationPacked, bufSize, params);
        }
        ANGLE_CAPTURE(GetnUniformivEXT, isCallValid, context, programPacked, locationPacked,
                      bufSize, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ReadnPixelsEXT(GLint x,
                                GLint y,
                                GLsizei width,
                                GLsizei height,
                                GLenum format,
                                GLenum type,
                                GLsizei bufSize,
                                void *data)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::ReadnPixelsEXT, "glReadnPixelsEXT",
          "context = %d, x = %d, y = %d, width = %d, height = %d, format = %s, type = %s, bufSize "
          "= %d, data = 0x%016" PRIxPTR "",
          CID(context), x, y, width, height, GLenumToString(GLenumGroup::PixelFormat, format),
          GLenumToString(GLenumGroup::PixelType, type), bufSize, (uintptr_t)data);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateReadnPixelsEXT(context, x, y, width, height, format, type, bufSize, data));
        if (isCallValid)
        {
            context->readnPixels(x, y, width, height, format, type, bufSize, data);
        }
        ANGLE_CAPTURE(ReadnPixelsEXT, isCallValid, context, x, y, width, height, format, type,
                      bufSize, data);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_EXT_sRGB

// GL_EXT_semaphore
void GL_APIENTRY DeleteSemaphoresEXT(GLsizei n, const GLuint *semaphores)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::DeleteSemaphoresEXT, "glDeleteSemaphoresEXT",
          "context = %d, n = %d, semaphores = 0x%016" PRIxPTR "", CID(context), n,
          (uintptr_t)semaphores);

    if (context)
    {
        const SemaphoreID *semaphoresPacked = FromGL<const SemaphoreID *>(semaphores);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateDeleteSemaphoresEXT(context, n, semaphoresPacked));
        if (isCallValid)
        {
            context->deleteSemaphores(n, semaphoresPacked);
        }
        ANGLE_CAPTURE(DeleteSemaphoresEXT, isCallValid, context, n, semaphoresPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GenSemaphoresEXT(GLsizei n, GLuint *semaphores)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GenSemaphoresEXT, "glGenSemaphoresEXT",
          "context = %d, n = %d, semaphores = 0x%016" PRIxPTR "", CID(context), n,
          (uintptr_t)semaphores);

    if (context)
    {
        SemaphoreID *semaphoresPacked                         = FromGL<SemaphoreID *>(semaphores);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGenSemaphoresEXT(context, n, semaphoresPacked));
        if (isCallValid)
        {
            context->genSemaphores(n, semaphoresPacked);
        }
        ANGLE_CAPTURE(GenSemaphoresEXT, isCallValid, context, n, semaphoresPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetSemaphoreParameterui64vEXT(GLuint semaphore, GLenum pname, GLuint64 *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetSemaphoreParameterui64vEXT, "glGetSemaphoreParameterui64vEXT",
          "context = %d, semaphore = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          semaphore, GLenumToString(GLenumGroup::SemaphoreParameterName, pname), (uintptr_t)params);

    if (context)
    {
        SemaphoreID semaphorePacked                           = FromGL<SemaphoreID>(semaphore);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetSemaphoreParameterui64vEXT(context, semaphorePacked, pname, params));
        if (isCallValid)
        {
            context->getSemaphoreParameterui64v(semaphorePacked, pname, params);
        }
        ANGLE_CAPTURE(GetSemaphoreParameterui64vEXT, isCallValid, context, semaphorePacked, pname,
                      params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

GLboolean GL_APIENTRY IsSemaphoreEXT(GLuint semaphore)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::IsSemaphoreEXT, "glIsSemaphoreEXT",
          "context = %d, semaphore = %u", CID(context), semaphore);

    GLboolean returnValue;
    if (context)
    {
        SemaphoreID semaphorePacked                           = FromGL<SemaphoreID>(semaphore);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateIsSemaphoreEXT(context, semaphorePacked));
        if (isCallValid)
        {
            returnValue = context->isSemaphore(semaphorePacked);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::IsSemaphoreEXT, GLboolean>();
        }
        ANGLE_CAPTURE(IsSemaphoreEXT, isCallValid, context, semaphorePacked, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
        returnValue = GetDefaultReturnValue<EntryPoint::IsSemaphoreEXT, GLboolean>();
    }
    return returnValue;
}

void GL_APIENTRY SemaphoreParameterui64vEXT(GLuint semaphore, GLenum pname, const GLuint64 *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::SemaphoreParameterui64vEXT, "glSemaphoreParameterui64vEXT",
          "context = %d, semaphore = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          semaphore, GLenumToString(GLenumGroup::SemaphoreParameterName, pname), (uintptr_t)params);

    if (context)
    {
        SemaphoreID semaphorePacked                           = FromGL<SemaphoreID>(semaphore);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateSemaphoreParameterui64vEXT(context, semaphorePacked, pname, params));
        if (isCallValid)
        {
            context->semaphoreParameterui64v(semaphorePacked, pname, params);
        }
        ANGLE_CAPTURE(SemaphoreParameterui64vEXT, isCallValid, context, semaphorePacked, pname,
                      params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY SignalSemaphoreEXT(GLuint semaphore,
                                    GLuint numBufferBarriers,
                                    const GLuint *buffers,
                                    GLuint numTextureBarriers,
                                    const GLuint *textures,
                                    const GLenum *dstLayouts)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::SignalSemaphoreEXT, "glSignalSemaphoreEXT",
          "context = %d, semaphore = %u, numBufferBarriers = %u, buffers = 0x%016" PRIxPTR
          ", numTextureBarriers = %u, textures = 0x%016" PRIxPTR ", dstLayouts = 0x%016" PRIxPTR "",
          CID(context), semaphore, numBufferBarriers, (uintptr_t)buffers, numTextureBarriers,
          (uintptr_t)textures, (uintptr_t)dstLayouts);

    if (context)
    {
        SemaphoreID semaphorePacked                           = FromGL<SemaphoreID>(semaphore);
        const BufferID *buffersPacked                         = FromGL<const BufferID *>(buffers);
        const TextureID *texturesPacked                       = FromGL<const TextureID *>(textures);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateSignalSemaphoreEXT(context, semaphorePacked, numBufferBarriers, buffersPacked,
                                        numTextureBarriers, texturesPacked, dstLayouts));
        if (isCallValid)
        {
            context->signalSemaphore(semaphorePacked, numBufferBarriers, buffersPacked,
                                     numTextureBarriers, texturesPacked, dstLayouts);
        }
        ANGLE_CAPTURE(SignalSemaphoreEXT, isCallValid, context, semaphorePacked, numBufferBarriers,
                      buffersPacked, numTextureBarriers, texturesPacked, dstLayouts);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY WaitSemaphoreEXT(GLuint semaphore,
                                  GLuint numBufferBarriers,
                                  const GLuint *buffers,
                                  GLuint numTextureBarriers,
                                  const GLuint *textures,
                                  const GLenum *srcLayouts)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::WaitSemaphoreEXT, "glWaitSemaphoreEXT",
          "context = %d, semaphore = %u, numBufferBarriers = %u, buffers = 0x%016" PRIxPTR
          ", numTextureBarriers = %u, textures = 0x%016" PRIxPTR ", srcLayouts = 0x%016" PRIxPTR "",
          CID(context), semaphore, numBufferBarriers, (uintptr_t)buffers, numTextureBarriers,
          (uintptr_t)textures, (uintptr_t)srcLayouts);

    if (context)
    {
        SemaphoreID semaphorePacked                           = FromGL<SemaphoreID>(semaphore);
        const BufferID *buffersPacked                         = FromGL<const BufferID *>(buffers);
        const TextureID *texturesPacked                       = FromGL<const TextureID *>(textures);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateWaitSemaphoreEXT(context, semaphorePacked, numBufferBarriers, buffersPacked,
                                      numTextureBarriers, texturesPacked, srcLayouts));
        if (isCallValid)
        {
            context->waitSemaphore(semaphorePacked, numBufferBarriers, buffersPacked,
                                   numTextureBarriers, texturesPacked, srcLayouts);
        }
        ANGLE_CAPTURE(WaitSemaphoreEXT, isCallValid, context, semaphorePacked, numBufferBarriers,
                      buffersPacked, numTextureBarriers, texturesPacked, srcLayouts);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GetUnsignedBytei_vEXT is already defined.

// GetUnsignedBytevEXT is already defined.

// GL_EXT_semaphore_fd
void GL_APIENTRY ImportSemaphoreFdEXT(GLuint semaphore, GLenum handleType, GLint fd)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::ImportSemaphoreFdEXT, "glImportSemaphoreFdEXT",
          "context = %d, semaphore = %u, handleType = %s, fd = %d", CID(context), semaphore,
          GLenumToString(GLenumGroup::ExternalHandleType, handleType), fd);

    if (context)
    {
        SemaphoreID semaphorePacked                           = FromGL<SemaphoreID>(semaphore);
        HandleType handleTypePacked                           = FromGL<HandleType>(handleType);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateImportSemaphoreFdEXT(context, semaphorePacked, handleTypePacked, fd));
        if (isCallValid)
        {
            context->importSemaphoreFd(semaphorePacked, handleTypePacked, fd);
        }
        ANGLE_CAPTURE(ImportSemaphoreFdEXT, isCallValid, context, semaphorePacked, handleTypePacked,
                      fd);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_EXT_texture_buffer
void GL_APIENTRY TexBufferEXT(GLenum target, GLenum internalformat, GLuint buffer)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::TexBufferEXT, "glTexBufferEXT",
          "context = %d, target = %s, internalformat = %s, buffer = %u", CID(context),
          GLenumToString(GLenumGroup::TextureTarget, target),
          GLenumToString(GLenumGroup::InternalFormat, internalformat), buffer);

    if (context)
    {
        TextureType targetPacked                              = FromGL<TextureType>(target);
        BufferID bufferPacked                                 = FromGL<BufferID>(buffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTexBufferEXT(context, targetPacked, internalformat, bufferPacked));
        if (isCallValid)
        {
            context->texBuffer(targetPacked, internalformat, bufferPacked);
        }
        ANGLE_CAPTURE(TexBufferEXT, isCallValid, context, targetPacked, internalformat,
                      bufferPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TexBufferRangeEXT(GLenum target,
                                   GLenum internalformat,
                                   GLuint buffer,
                                   GLintptr offset,
                                   GLsizeiptr size)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::TexBufferRangeEXT, "glTexBufferRangeEXT",
          "context = %d, target = %s, internalformat = %s, buffer = %u, offset = %llu, size = %llu",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target),
          GLenumToString(GLenumGroup::InternalFormat, internalformat), buffer,
          static_cast<unsigned long long>(offset), static_cast<unsigned long long>(size));

    if (context)
    {
        TextureType targetPacked                              = FromGL<TextureType>(target);
        BufferID bufferPacked                                 = FromGL<BufferID>(buffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateTexBufferRangeEXT(context, targetPacked, internalformat,
                                                      bufferPacked, offset, size));
        if (isCallValid)
        {
            context->texBufferRange(targetPacked, internalformat, bufferPacked, offset, size);
        }
        ANGLE_CAPTURE(TexBufferRangeEXT, isCallValid, context, targetPacked, internalformat,
                      bufferPacked, offset, size);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_EXT_texture_compression_bptc

// GL_EXT_texture_compression_dxt1

// GL_EXT_texture_compression_rgtc

// GL_EXT_texture_compression_s3tc

// GL_EXT_texture_compression_s3tc_srgb

// GL_EXT_texture_cube_map_array

// GL_EXT_texture_filter_anisotropic

// GL_EXT_texture_format_BGRA8888

// GL_EXT_texture_sRGB_R8

// GL_EXT_texture_storage
void GL_APIENTRY TexStorage1DEXT(GLenum target,
                                 GLsizei levels,
                                 GLenum internalformat,
                                 GLsizei width)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::TexStorage1DEXT, "glTexStorage1DEXT",
          "context = %d, target = %s, levels = %d, internalformat = %s, width = %d", CID(context),
          GLenumToString(GLenumGroup::TextureTarget, target), levels,
          GLenumToString(GLenumGroup::InternalFormat, internalformat), width);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTexStorage1DEXT(context, target, levels, internalformat, width));
        if (isCallValid)
        {
            context->texStorage1D(target, levels, internalformat, width);
        }
        ANGLE_CAPTURE(TexStorage1DEXT, isCallValid, context, target, levels, internalformat, width);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY
TexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::TexStorage2DEXT, "glTexStorage2DEXT",
          "context = %d, target = %s, levels = %d, internalformat = %s, width = %d, height = %d",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), levels,
          GLenumToString(GLenumGroup::InternalFormat, internalformat), width, height);

    if (context)
    {
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTexStorage2DEXT(context, targetPacked, levels, internalformat, width, height));
        if (isCallValid)
        {
            context->texStorage2D(targetPacked, levels, internalformat, width, height);
        }
        ANGLE_CAPTURE(TexStorage2DEXT, isCallValid, context, targetPacked, levels, internalformat,
                      width, height);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TexStorage3DEXT(GLenum target,
                                 GLsizei levels,
                                 GLenum internalformat,
                                 GLsizei width,
                                 GLsizei height,
                                 GLsizei depth)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::TexStorage3DEXT, "glTexStorage3DEXT",
          "context = %d, target = %s, levels = %d, internalformat = %s, width = %d, height = %d, "
          "depth = %d",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), levels,
          GLenumToString(GLenumGroup::InternalFormat, internalformat), width, height, depth);

    if (context)
    {
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateTexStorage3DEXT(context, targetPacked, levels, internalformat,
                                                    width, height, depth));
        if (isCallValid)
        {
            context->texStorage3D(targetPacked, levels, internalformat, width, height, depth);
        }
        ANGLE_CAPTURE(TexStorage3DEXT, isCallValid, context, targetPacked, levels, internalformat,
                      width, height, depth);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_KHR_debug
void GL_APIENTRY DebugMessageCallbackKHR(GLDEBUGPROCKHR callback, const void *userParam)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::DebugMessageCallbackKHR, "glDebugMessageCallbackKHR",
          "context = %d, callback = 0x%016" PRIxPTR ", userParam = 0x%016" PRIxPTR "", CID(context),
          (uintptr_t)callback, (uintptr_t)userParam);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateDebugMessageCallbackKHR(context, callback, userParam));
        if (isCallValid)
        {
            context->debugMessageCallback(callback, userParam);
        }
        ANGLE_CAPTURE(DebugMessageCallbackKHR, isCallValid, context, callback, userParam);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY DebugMessageControlKHR(GLenum source,
                                        GLenum type,
                                        GLenum severity,
                                        GLsizei count,
                                        const GLuint *ids,
                                        GLboolean enabled)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::DebugMessageControlKHR, "glDebugMessageControlKHR",
          "context = %d, source = %s, type = %s, severity = %s, count = %d, ids = 0x%016" PRIxPTR
          ", enabled = %s",
          CID(context), GLenumToString(GLenumGroup::DebugSource, source),
          GLenumToString(GLenumGroup::DebugType, type),
          GLenumToString(GLenumGroup::DebugSeverity, severity), count, (uintptr_t)ids,
          GLbooleanToString(enabled));

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateDebugMessageControlKHR(context, source, type, severity, count, ids, enabled));
        if (isCallValid)
        {
            context->debugMessageControl(source, type, severity, count, ids, enabled);
        }
        ANGLE_CAPTURE(DebugMessageControlKHR, isCallValid, context, source, type, severity, count,
                      ids, enabled);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY DebugMessageInsertKHR(GLenum source,
                                       GLenum type,
                                       GLuint id,
                                       GLenum severity,
                                       GLsizei length,
                                       const GLchar *buf)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::DebugMessageInsertKHR, "glDebugMessageInsertKHR",
          "context = %d, source = %s, type = %s, id = %u, severity = %s, length = %d, buf = "
          "0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DebugSource, source),
          GLenumToString(GLenumGroup::DebugType, type), id,
          GLenumToString(GLenumGroup::DebugSeverity, severity), length, (uintptr_t)buf);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateDebugMessageInsertKHR(context, source, type, id, severity, length, buf));
        if (isCallValid)
        {
            context->debugMessageInsert(source, type, id, severity, length, buf);
        }
        ANGLE_CAPTURE(DebugMessageInsertKHR, isCallValid, context, source, type, id, severity,
                      length, buf);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

GLuint GL_APIENTRY GetDebugMessageLogKHR(GLuint count,
                                         GLsizei bufSize,
                                         GLenum *sources,
                                         GLenum *types,
                                         GLuint *ids,
                                         GLenum *severities,
                                         GLsizei *lengths,
                                         GLchar *messageLog)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetDebugMessageLogKHR, "glGetDebugMessageLogKHR",
          "context = %d, count = %u, bufSize = %d, sources = 0x%016" PRIxPTR
          ", types = 0x%016" PRIxPTR ", ids = 0x%016" PRIxPTR ", severities = 0x%016" PRIxPTR
          ", lengths = 0x%016" PRIxPTR ", messageLog = 0x%016" PRIxPTR "",
          CID(context), count, bufSize, (uintptr_t)sources, (uintptr_t)types, (uintptr_t)ids,
          (uintptr_t)severities, (uintptr_t)lengths, (uintptr_t)messageLog);

    GLuint returnValue;
    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetDebugMessageLogKHR(context, count, bufSize, sources, types,
                                                          ids, severities, lengths, messageLog));
        if (isCallValid)
        {
            returnValue = context->getDebugMessageLog(count, bufSize, sources, types, ids,
                                                      severities, lengths, messageLog);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::GetDebugMessageLogKHR, GLuint>();
        }
        ANGLE_CAPTURE(GetDebugMessageLogKHR, isCallValid, context, count, bufSize, sources, types,
                      ids, severities, lengths, messageLog, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
        returnValue = GetDefaultReturnValue<EntryPoint::GetDebugMessageLogKHR, GLuint>();
    }
    return returnValue;
}

void GL_APIENTRY
GetObjectLabelKHR(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetObjectLabelKHR, "glGetObjectLabelKHR",
          "context = %d, identifier = %s, name = %u, bufSize = %d, length = 0x%016" PRIxPTR
          ", label = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, identifier), name, bufSize,
          (uintptr_t)length, (uintptr_t)label);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetObjectLabelKHR(context, identifier, name, bufSize, length, label));
        if (isCallValid)
        {
            context->getObjectLabel(identifier, name, bufSize, length, label);
        }
        ANGLE_CAPTURE(GetObjectLabelKHR, isCallValid, context, identifier, name, bufSize, length,
                      label);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetObjectPtrLabelKHR(const void *ptr,
                                      GLsizei bufSize,
                                      GLsizei *length,
                                      GLchar *label)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetObjectPtrLabelKHR, "glGetObjectPtrLabelKHR",
          "context = %d, ptr = 0x%016" PRIxPTR ", bufSize = %d, length = 0x%016" PRIxPTR
          ", label = 0x%016" PRIxPTR "",
          CID(context), (uintptr_t)ptr, bufSize, (uintptr_t)length, (uintptr_t)label);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetObjectPtrLabelKHR(context, ptr, bufSize, length, label));
        if (isCallValid)
        {
            context->getObjectPtrLabel(ptr, bufSize, length, label);
        }
        ANGLE_CAPTURE(GetObjectPtrLabelKHR, isCallValid, context, ptr, bufSize, length, label);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetPointervKHR(GLenum pname, void **params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetPointervKHR, "glGetPointervKHR",
          "context = %d, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::DefaultGroup, pname), (uintptr_t)params);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetPointervKHR(context, pname, params));
        if (isCallValid)
        {
            context->getPointerv(pname, params);
        }
        ANGLE_CAPTURE(GetPointervKHR, isCallValid, context, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ObjectLabelKHR(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::ObjectLabelKHR, "glObjectLabelKHR",
          "context = %d, identifier = %s, name = %u, length = %d, label = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::ObjectIdentifier, identifier), name, length,
          (uintptr_t)label);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateObjectLabelKHR(context, identifier, name, length, label));
        if (isCallValid)
        {
            context->objectLabel(identifier, name, length, label);
        }
        ANGLE_CAPTURE(ObjectLabelKHR, isCallValid, context, identifier, name, length, label);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ObjectPtrLabelKHR(const void *ptr, GLsizei length, const GLchar *label)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::ObjectPtrLabelKHR, "glObjectPtrLabelKHR",
          "context = %d, ptr = 0x%016" PRIxPTR ", length = %d, label = 0x%016" PRIxPTR "",
          CID(context), (uintptr_t)ptr, length, (uintptr_t)label);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateObjectPtrLabelKHR(context, ptr, length, label));
        if (isCallValid)
        {
            context->objectPtrLabel(ptr, length, label);
        }
        ANGLE_CAPTURE(ObjectPtrLabelKHR, isCallValid, context, ptr, length, label);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY PopDebugGroupKHR()
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::PopDebugGroupKHR, "glPopDebugGroupKHR", "context = %d",
          CID(context));

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidatePopDebugGroupKHR(context));
        if (isCallValid)
        {
            context->popDebugGroup();
        }
        ANGLE_CAPTURE(PopDebugGroupKHR, isCallValid, context);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY PushDebugGroupKHR(GLenum source, GLuint id, GLsizei length, const GLchar *message)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::PushDebugGroupKHR, "glPushDebugGroupKHR",
          "context = %d, source = %s, id = %u, length = %d, message = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DebugSource, source), id, length,
          (uintptr_t)message);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidatePushDebugGroupKHR(context, source, id, length, message));
        if (isCallValid)
        {
            context->pushDebugGroup(source, id, length, message);
        }
        ANGLE_CAPTURE(PushDebugGroupKHR, isCallValid, context, source, id, length, message);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_KHR_parallel_shader_compile
void GL_APIENTRY MaxShaderCompilerThreadsKHR(GLuint count)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::MaxShaderCompilerThreadsKHR, "glMaxShaderCompilerThreadsKHR",
          "context = %d, count = %u", CID(context), count);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateMaxShaderCompilerThreadsKHR(context, count));
        if (isCallValid)
        {
            context->maxShaderCompilerThreads(count);
        }
        ANGLE_CAPTURE(MaxShaderCompilerThreadsKHR, isCallValid, context, count);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_NV_fence
void GL_APIENTRY DeleteFencesNV(GLsizei n, const GLuint *fences)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::DeleteFencesNV, "glDeleteFencesNV",
          "context = %d, n = %d, fences = 0x%016" PRIxPTR "", CID(context), n, (uintptr_t)fences);

    if (context)
    {
        const FenceNVID *fencesPacked                         = FromGL<const FenceNVID *>(fences);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateDeleteFencesNV(context, n, fencesPacked));
        if (isCallValid)
        {
            context->deleteFencesNV(n, fencesPacked);
        }
        ANGLE_CAPTURE(DeleteFencesNV, isCallValid, context, n, fencesPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY FinishFenceNV(GLuint fence)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::FinishFenceNV, "glFinishFenceNV", "context = %d, fence = %u",
          CID(context), fence);

    if (context)
    {
        FenceNVID fencePacked                                 = FromGL<FenceNVID>(fence);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateFinishFenceNV(context, fencePacked));
        if (isCallValid)
        {
            context->finishFenceNV(fencePacked);
        }
        ANGLE_CAPTURE(FinishFenceNV, isCallValid, context, fencePacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GenFencesNV(GLsizei n, GLuint *fences)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GenFencesNV, "glGenFencesNV",
          "context = %d, n = %d, fences = 0x%016" PRIxPTR "", CID(context), n, (uintptr_t)fences);

    if (context)
    {
        FenceNVID *fencesPacked                               = FromGL<FenceNVID *>(fences);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGenFencesNV(context, n, fencesPacked));
        if (isCallValid)
        {
            context->genFencesNV(n, fencesPacked);
        }
        ANGLE_CAPTURE(GenFencesNV, isCallValid, context, n, fencesPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetFenceivNV(GLuint fence, GLenum pname, GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetFenceivNV, "glGetFenceivNV",
          "context = %d, fence = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context), fence,
          GLenumToString(GLenumGroup::DefaultGroup, pname), (uintptr_t)params);

    if (context)
    {
        FenceNVID fencePacked                                 = FromGL<FenceNVID>(fence);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetFenceivNV(context, fencePacked, pname, params));
        if (isCallValid)
        {
            context->getFenceivNV(fencePacked, pname, params);
        }
        ANGLE_CAPTURE(GetFenceivNV, isCallValid, context, fencePacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

GLboolean GL_APIENTRY IsFenceNV(GLuint fence)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::IsFenceNV, "glIsFenceNV", "context = %d, fence = %u",
          CID(context), fence);

    GLboolean returnValue;
    if (context)
    {
        FenceNVID fencePacked                                 = FromGL<FenceNVID>(fence);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateIsFenceNV(context, fencePacked));
        if (isCallValid)
        {
            returnValue = context->isFenceNV(fencePacked);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::IsFenceNV, GLboolean>();
        }
        ANGLE_CAPTURE(IsFenceNV, isCallValid, context, fencePacked, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
        returnValue = GetDefaultReturnValue<EntryPoint::IsFenceNV, GLboolean>();
    }
    return returnValue;
}

void GL_APIENTRY SetFenceNV(GLuint fence, GLenum condition)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::SetFenceNV, "glSetFenceNV",
          "context = %d, fence = %u, condition = %s", CID(context), fence,
          GLenumToString(GLenumGroup::DefaultGroup, condition));

    if (context)
    {
        FenceNVID fencePacked                                 = FromGL<FenceNVID>(fence);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateSetFenceNV(context, fencePacked, condition));
        if (isCallValid)
        {
            context->setFenceNV(fencePacked, condition);
        }
        ANGLE_CAPTURE(SetFenceNV, isCallValid, context, fencePacked, condition);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

GLboolean GL_APIENTRY TestFenceNV(GLuint fence)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::TestFenceNV, "glTestFenceNV", "context = %d, fence = %u",
          CID(context), fence);

    GLboolean returnValue;
    if (context)
    {
        FenceNVID fencePacked                                 = FromGL<FenceNVID>(fence);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateTestFenceNV(context, fencePacked));
        if (isCallValid)
        {
            returnValue = context->testFenceNV(fencePacked);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::TestFenceNV, GLboolean>();
        }
        ANGLE_CAPTURE(TestFenceNV, isCallValid, context, fencePacked, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
        returnValue = GetDefaultReturnValue<EntryPoint::TestFenceNV, GLboolean>();
    }
    return returnValue;
}

// GL_OES_EGL_image
void GL_APIENTRY EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::EGLImageTargetRenderbufferStorageOES,
          "glEGLImageTargetRenderbufferStorageOES",
          "context = %d, target = %s, image = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::DefaultGroup, target), (uintptr_t)image);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateEGLImageTargetRenderbufferStorageOES(context, target, image));
        if (isCallValid)
        {
            context->eGLImageTargetRenderbufferStorage(target, image);
        }
        ANGLE_CAPTURE(EGLImageTargetRenderbufferStorageOES, isCallValid, context, target, image);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY EGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::EGLImageTargetTexture2DOES, "glEGLImageTargetTexture2DOES",
          "context = %d, target = %s, image = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::DefaultGroup, target), (uintptr_t)image);

    if (context)
    {
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateEGLImageTargetTexture2DOES(context, targetPacked, image));
        if (isCallValid)
        {
            context->eGLImageTargetTexture2D(targetPacked, image);
        }
        ANGLE_CAPTURE(EGLImageTargetTexture2DOES, isCallValid, context, targetPacked, image);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_OES_compressed_ETC1_RGB8_texture

// GL_OES_copy_image
void GL_APIENTRY CopyImageSubDataOES(GLuint srcName,
                                     GLenum srcTarget,
                                     GLint srcLevel,
                                     GLint srcX,
                                     GLint srcY,
                                     GLint srcZ,
                                     GLuint dstName,
                                     GLenum dstTarget,
                                     GLint dstLevel,
                                     GLint dstX,
                                     GLint dstY,
                                     GLint dstZ,
                                     GLsizei srcWidth,
                                     GLsizei srcHeight,
                                     GLsizei srcDepth)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::CopyImageSubDataOES, "glCopyImageSubDataOES",
          "context = %d, srcName = %u, srcTarget = %s, srcLevel = %d, srcX = %d, srcY = %d, srcZ = "
          "%d, dstName = %u, dstTarget = %s, dstLevel = %d, dstX = %d, dstY = %d, dstZ = %d, "
          "srcWidth = %d, srcHeight = %d, srcDepth = %d",
          CID(context), srcName, GLenumToString(GLenumGroup::CopyBufferSubDataTarget, srcTarget),
          srcLevel, srcX, srcY, srcZ, dstName,
          GLenumToString(GLenumGroup::CopyBufferSubDataTarget, dstTarget), dstLevel, dstX, dstY,
          dstZ, srcWidth, srcHeight, srcDepth);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateCopyImageSubDataOES(context, srcName, srcTarget, srcLevel, srcX, srcY, srcZ,
                                         dstName, dstTarget, dstLevel, dstX, dstY, dstZ, srcWidth,
                                         srcHeight, srcDepth));
        if (isCallValid)
        {
            context->copyImageSubData(srcName, srcTarget, srcLevel, srcX, srcY, srcZ, dstName,
                                      dstTarget, dstLevel, dstX, dstY, dstZ, srcWidth, srcHeight,
                                      srcDepth);
        }
        ANGLE_CAPTURE(CopyImageSubDataOES, isCallValid, context, srcName, srcTarget, srcLevel, srcX,
                      srcY, srcZ, dstName, dstTarget, dstLevel, dstX, dstY, dstZ, srcWidth,
                      srcHeight, srcDepth);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_OES_depth32

// GL_OES_draw_buffers_indexed
void GL_APIENTRY BlendEquationSeparateiOES(GLuint buf, GLenum modeRGB, GLenum modeAlpha)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::BlendEquationSeparateiOES, "glBlendEquationSeparateiOES",
          "context = %d, buf = %u, modeRGB = %s, modeAlpha = %s", CID(context), buf,
          GLenumToString(GLenumGroup::BlendEquationModeEXT, modeRGB),
          GLenumToString(GLenumGroup::BlendEquationModeEXT, modeAlpha));

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateBlendEquationSeparateiOES(context, buf, modeRGB, modeAlpha));
        if (isCallValid)
        {
            context->blendEquationSeparatei(buf, modeRGB, modeAlpha);
        }
        ANGLE_CAPTURE(BlendEquationSeparateiOES, isCallValid, context, buf, modeRGB, modeAlpha);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY BlendEquationiOES(GLuint buf, GLenum mode)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::BlendEquationiOES, "glBlendEquationiOES",
          "context = %d, buf = %u, mode = %s", CID(context), buf,
          GLenumToString(GLenumGroup::BlendEquationModeEXT, mode));

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateBlendEquationiOES(context, buf, mode));
        if (isCallValid)
        {
            context->blendEquationi(buf, mode);
        }
        ANGLE_CAPTURE(BlendEquationiOES, isCallValid, context, buf, mode);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY
BlendFuncSeparateiOES(GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::BlendFuncSeparateiOES, "glBlendFuncSeparateiOES",
          "context = %d, buf = %u, srcRGB = %s, dstRGB = %s, srcAlpha = %s, dstAlpha = %s",
          CID(context), buf, GLenumToString(GLenumGroup::BlendingFactor, srcRGB),
          GLenumToString(GLenumGroup::BlendingFactor, dstRGB),
          GLenumToString(GLenumGroup::BlendingFactor, srcAlpha),
          GLenumToString(GLenumGroup::BlendingFactor, dstAlpha));

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateBlendFuncSeparateiOES(context, buf, srcRGB, dstRGB, srcAlpha, dstAlpha));
        if (isCallValid)
        {
            context->blendFuncSeparatei(buf, srcRGB, dstRGB, srcAlpha, dstAlpha);
        }
        ANGLE_CAPTURE(BlendFuncSeparateiOES, isCallValid, context, buf, srcRGB, dstRGB, srcAlpha,
                      dstAlpha);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY BlendFunciOES(GLuint buf, GLenum src, GLenum dst)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::BlendFunciOES, "glBlendFunciOES",
          "context = %d, buf = %u, src = %s, dst = %s", CID(context), buf,
          GLenumToString(GLenumGroup::BlendingFactor, src),
          GLenumToString(GLenumGroup::BlendingFactor, dst));

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateBlendFunciOES(context, buf, src, dst));
        if (isCallValid)
        {
            context->blendFunci(buf, src, dst);
        }
        ANGLE_CAPTURE(BlendFunciOES, isCallValid, context, buf, src, dst);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ColorMaskiOES(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::ColorMaskiOES, "glColorMaskiOES",
          "context = %d, index = %u, r = %s, g = %s, b = %s, a = %s", CID(context), index,
          GLbooleanToString(r), GLbooleanToString(g), GLbooleanToString(b), GLbooleanToString(a));

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateColorMaskiOES(context, index, r, g, b, a));
        if (isCallValid)
        {
            context->colorMaski(index, r, g, b, a);
        }
        ANGLE_CAPTURE(ColorMaskiOES, isCallValid, context, index, r, g, b, a);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY DisableiOES(GLenum target, GLuint index)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::DisableiOES, "glDisableiOES",
          "context = %d, target = %s, index = %u", CID(context),
          GLenumToString(GLenumGroup::EnableCap, target), index);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateDisableiOES(context, target, index));
        if (isCallValid)
        {
            context->disablei(target, index);
        }
        ANGLE_CAPTURE(DisableiOES, isCallValid, context, target, index);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY EnableiOES(GLenum target, GLuint index)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::EnableiOES, "glEnableiOES",
          "context = %d, target = %s, index = %u", CID(context),
          GLenumToString(GLenumGroup::EnableCap, target), index);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateEnableiOES(context, target, index));
        if (isCallValid)
        {
            context->enablei(target, index);
        }
        ANGLE_CAPTURE(EnableiOES, isCallValid, context, target, index);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

GLboolean GL_APIENTRY IsEnablediOES(GLenum target, GLuint index)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::IsEnablediOES, "glIsEnablediOES",
          "context = %d, target = %s, index = %u", CID(context),
          GLenumToString(GLenumGroup::EnableCap, target), index);

    GLboolean returnValue;
    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateIsEnablediOES(context, target, index));
        if (isCallValid)
        {
            returnValue = context->isEnabledi(target, index);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::IsEnablediOES, GLboolean>();
        }
        ANGLE_CAPTURE(IsEnablediOES, isCallValid, context, target, index, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
        returnValue = GetDefaultReturnValue<EntryPoint::IsEnablediOES, GLboolean>();
    }
    return returnValue;
}

// GL_OES_draw_elements_base_vertex
void GL_APIENTRY DrawElementsBaseVertexOES(GLenum mode,
                                           GLsizei count,
                                           GLenum type,
                                           const void *indices,
                                           GLint basevertex)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::DrawElementsBaseVertexOES, "glDrawElementsBaseVertexOES",
          "context = %d, mode = %s, count = %d, type = %s, indices = 0x%016" PRIxPTR
          ", basevertex = %d",
          CID(context), GLenumToString(GLenumGroup::PrimitiveType, mode), count,
          GLenumToString(GLenumGroup::DrawElementsType, type), (uintptr_t)indices, basevertex);

    if (context)
    {
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        DrawElementsType typePacked                           = FromGL<DrawElementsType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateDrawElementsBaseVertexOES(context, modePacked, count,
                                                              typePacked, indices, basevertex));
        if (isCallValid)
        {
            context->drawElementsBaseVertex(modePacked, count, typePacked, indices, basevertex);
        }
        ANGLE_CAPTURE(DrawElementsBaseVertexOES, isCallValid, context, modePacked, count,
                      typePacked, indices, basevertex);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY DrawElementsInstancedBaseVertexOES(GLenum mode,
                                                    GLsizei count,
                                                    GLenum type,
                                                    const void *indices,
                                                    GLsizei instancecount,
                                                    GLint basevertex)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::DrawElementsInstancedBaseVertexOES,
          "glDrawElementsInstancedBaseVertexOES",
          "context = %d, mode = %s, count = %d, type = %s, indices = 0x%016" PRIxPTR
          ", instancecount = %d, basevertex = %d",
          CID(context), GLenumToString(GLenumGroup::PrimitiveType, mode), count,
          GLenumToString(GLenumGroup::DrawElementsType, type), (uintptr_t)indices, instancecount,
          basevertex);

    if (context)
    {
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        DrawElementsType typePacked                           = FromGL<DrawElementsType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateDrawElementsInstancedBaseVertexOES(
                                                             context, modePacked, count, typePacked,
                                                             indices, instancecount, basevertex));
        if (isCallValid)
        {
            context->drawElementsInstancedBaseVertex(modePacked, count, typePacked, indices,
                                                     instancecount, basevertex);
        }
        ANGLE_CAPTURE(DrawElementsInstancedBaseVertexOES, isCallValid, context, modePacked, count,
                      typePacked, indices, instancecount, basevertex);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY DrawRangeElementsBaseVertexOES(GLenum mode,
                                                GLuint start,
                                                GLuint end,
                                                GLsizei count,
                                                GLenum type,
                                                const void *indices,
                                                GLint basevertex)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::DrawRangeElementsBaseVertexOES,
          "glDrawRangeElementsBaseVertexOES",
          "context = %d, mode = %s, start = %u, end = %u, count = %d, type = %s, indices = "
          "0x%016" PRIxPTR ", basevertex = %d",
          CID(context), GLenumToString(GLenumGroup::PrimitiveType, mode), start, end, count,
          GLenumToString(GLenumGroup::DrawElementsType, type), (uintptr_t)indices, basevertex);

    if (context)
    {
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        DrawElementsType typePacked                           = FromGL<DrawElementsType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateDrawRangeElementsBaseVertexOES(
                                                             context, modePacked, start, end, count,
                                                             typePacked, indices, basevertex));
        if (isCallValid)
        {
            context->drawRangeElementsBaseVertex(modePacked, start, end, count, typePacked, indices,
                                                 basevertex);
        }
        ANGLE_CAPTURE(DrawRangeElementsBaseVertexOES, isCallValid, context, modePacked, start, end,
                      count, typePacked, indices, basevertex);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// MultiDrawElementsBaseVertexEXT is already defined.

// GL_OES_draw_texture
void GL_APIENTRY DrawTexfOES(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::DrawTexfOES, "glDrawTexfOES",
          "context = %d, x = %f, y = %f, z = %f, width = %f, height = %f", CID(context), x, y, z,
          width, height);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateDrawTexfOES(context, x, y, z, width, height));
        if (isCallValid)
        {
            context->drawTexf(x, y, z, width, height);
        }
        ANGLE_CAPTURE(DrawTexfOES, isCallValid, context, x, y, z, width, height);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY DrawTexfvOES(const GLfloat *coords)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::DrawTexfvOES, "glDrawTexfvOES",
          "context = %d, coords = 0x%016" PRIxPTR "", CID(context), (uintptr_t)coords);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateDrawTexfvOES(context, coords));
        if (isCallValid)
        {
            context->drawTexfv(coords);
        }
        ANGLE_CAPTURE(DrawTexfvOES, isCallValid, context, coords);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY DrawTexiOES(GLint x, GLint y, GLint z, GLint width, GLint height)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::DrawTexiOES, "glDrawTexiOES",
          "context = %d, x = %d, y = %d, z = %d, width = %d, height = %d", CID(context), x, y, z,
          width, height);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateDrawTexiOES(context, x, y, z, width, height));
        if (isCallValid)
        {
            context->drawTexi(x, y, z, width, height);
        }
        ANGLE_CAPTURE(DrawTexiOES, isCallValid, context, x, y, z, width, height);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY DrawTexivOES(const GLint *coords)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::DrawTexivOES, "glDrawTexivOES",
          "context = %d, coords = 0x%016" PRIxPTR "", CID(context), (uintptr_t)coords);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateDrawTexivOES(context, coords));
        if (isCallValid)
        {
            context->drawTexiv(coords);
        }
        ANGLE_CAPTURE(DrawTexivOES, isCallValid, context, coords);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY DrawTexsOES(GLshort x, GLshort y, GLshort z, GLshort width, GLshort height)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::DrawTexsOES, "glDrawTexsOES",
          "context = %d, x = %d, y = %d, z = %d, width = %d, height = %d", CID(context), x, y, z,
          width, height);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateDrawTexsOES(context, x, y, z, width, height));
        if (isCallValid)
        {
            context->drawTexs(x, y, z, width, height);
        }
        ANGLE_CAPTURE(DrawTexsOES, isCallValid, context, x, y, z, width, height);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY DrawTexsvOES(const GLshort *coords)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::DrawTexsvOES, "glDrawTexsvOES",
          "context = %d, coords = 0x%016" PRIxPTR "", CID(context), (uintptr_t)coords);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateDrawTexsvOES(context, coords));
        if (isCallValid)
        {
            context->drawTexsv(coords);
        }
        ANGLE_CAPTURE(DrawTexsvOES, isCallValid, context, coords);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY DrawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::DrawTexxOES, "glDrawTexxOES",
          "context = %d, x = 0x%X, y = 0x%X, z = 0x%X, width = 0x%X, height = 0x%X", CID(context),
          x, y, z, width, height);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateDrawTexxOES(context, x, y, z, width, height));
        if (isCallValid)
        {
            context->drawTexx(x, y, z, width, height);
        }
        ANGLE_CAPTURE(DrawTexxOES, isCallValid, context, x, y, z, width, height);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY DrawTexxvOES(const GLfixed *coords)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::DrawTexxvOES, "glDrawTexxvOES",
          "context = %d, coords = 0x%016" PRIxPTR "", CID(context), (uintptr_t)coords);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateDrawTexxvOES(context, coords));
        if (isCallValid)
        {
            context->drawTexxv(coords);
        }
        ANGLE_CAPTURE(DrawTexxvOES, isCallValid, context, coords);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_OES_framebuffer_object
void GL_APIENTRY BindFramebufferOES(GLenum target, GLuint framebuffer)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::BindFramebufferOES, "glBindFramebufferOES",
          "context = %d, target = %s, framebuffer = %u", CID(context),
          GLenumToString(GLenumGroup::FramebufferTarget, target), framebuffer);

    if (context)
    {
        FramebufferID framebufferPacked                       = FromGL<FramebufferID>(framebuffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateBindFramebufferOES(context, target, framebufferPacked));
        if (isCallValid)
        {
            context->bindFramebuffer(target, framebufferPacked);
        }
        ANGLE_CAPTURE(BindFramebufferOES, isCallValid, context, target, framebufferPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY BindRenderbufferOES(GLenum target, GLuint renderbuffer)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::BindRenderbufferOES, "glBindRenderbufferOES",
          "context = %d, target = %s, renderbuffer = %u", CID(context),
          GLenumToString(GLenumGroup::RenderbufferTarget, target), renderbuffer);

    if (context)
    {
        RenderbufferID renderbufferPacked = FromGL<RenderbufferID>(renderbuffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateBindRenderbufferOES(context, target, renderbufferPacked));
        if (isCallValid)
        {
            context->bindRenderbuffer(target, renderbufferPacked);
        }
        ANGLE_CAPTURE(BindRenderbufferOES, isCallValid, context, target, renderbufferPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

GLenum GL_APIENTRY CheckFramebufferStatusOES(GLenum target)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::CheckFramebufferStatusOES, "glCheckFramebufferStatusOES",
          "context = %d, target = %s", CID(context),
          GLenumToString(GLenumGroup::FramebufferTarget, target));

    GLenum returnValue;
    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateCheckFramebufferStatusOES(context, target));
        if (isCallValid)
        {
            returnValue = context->checkFramebufferStatus(target);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::CheckFramebufferStatusOES, GLenum>();
        }
        ANGLE_CAPTURE(CheckFramebufferStatusOES, isCallValid, context, target, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
        returnValue = GetDefaultReturnValue<EntryPoint::CheckFramebufferStatusOES, GLenum>();
    }
    return returnValue;
}

void GL_APIENTRY DeleteFramebuffersOES(GLsizei n, const GLuint *framebuffers)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::DeleteFramebuffersOES, "glDeleteFramebuffersOES",
          "context = %d, n = %d, framebuffers = 0x%016" PRIxPTR "", CID(context), n,
          (uintptr_t)framebuffers);

    if (context)
    {
        const FramebufferID *framebuffersPacked = FromGL<const FramebufferID *>(framebuffers);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateDeleteFramebuffersOES(context, n, framebuffersPacked));
        if (isCallValid)
        {
            context->deleteFramebuffers(n, framebuffersPacked);
        }
        ANGLE_CAPTURE(DeleteFramebuffersOES, isCallValid, context, n, framebuffersPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY DeleteRenderbuffersOES(GLsizei n, const GLuint *renderbuffers)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::DeleteRenderbuffersOES, "glDeleteRenderbuffersOES",
          "context = %d, n = %d, renderbuffers = 0x%016" PRIxPTR "", CID(context), n,
          (uintptr_t)renderbuffers);

    if (context)
    {
        const RenderbufferID *renderbuffersPacked = FromGL<const RenderbufferID *>(renderbuffers);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateDeleteRenderbuffersOES(context, n, renderbuffersPacked));
        if (isCallValid)
        {
            context->deleteRenderbuffers(n, renderbuffersPacked);
        }
        ANGLE_CAPTURE(DeleteRenderbuffersOES, isCallValid, context, n, renderbuffersPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY FramebufferRenderbufferOES(GLenum target,
                                            GLenum attachment,
                                            GLenum renderbuffertarget,
                                            GLuint renderbuffer)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::FramebufferRenderbufferOES, "glFramebufferRenderbufferOES",
          "context = %d, target = %s, attachment = %s, renderbuffertarget = %s, renderbuffer = %u",
          CID(context), GLenumToString(GLenumGroup::FramebufferTarget, target),
          GLenumToString(GLenumGroup::FramebufferAttachment, attachment),
          GLenumToString(GLenumGroup::RenderbufferTarget, renderbuffertarget), renderbuffer);

    if (context)
    {
        RenderbufferID renderbufferPacked = FromGL<RenderbufferID>(renderbuffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateFramebufferRenderbufferOES(context, target, attachment, renderbuffertarget,
                                                renderbufferPacked));
        if (isCallValid)
        {
            context->framebufferRenderbuffer(target, attachment, renderbuffertarget,
                                             renderbufferPacked);
        }
        ANGLE_CAPTURE(FramebufferRenderbufferOES, isCallValid, context, target, attachment,
                      renderbuffertarget, renderbufferPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY FramebufferTexture2DOES(GLenum target,
                                         GLenum attachment,
                                         GLenum textarget,
                                         GLuint texture,
                                         GLint level)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::FramebufferTexture2DOES, "glFramebufferTexture2DOES",
          "context = %d, target = %s, attachment = %s, textarget = %s, texture = %u, level = %d",
          CID(context), GLenumToString(GLenumGroup::FramebufferTarget, target),
          GLenumToString(GLenumGroup::FramebufferAttachment, attachment),
          GLenumToString(GLenumGroup::TextureTarget, textarget), texture, level);

    if (context)
    {
        TextureTarget textargetPacked                         = FromGL<TextureTarget>(textarget);
        TextureID texturePacked                               = FromGL<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateFramebufferTexture2DOES(context, target, attachment,
                                                            textargetPacked, texturePacked, level));
        if (isCallValid)
        {
            context->framebufferTexture2D(target, attachment, textargetPacked, texturePacked,
                                          level);
        }
        ANGLE_CAPTURE(FramebufferTexture2DOES, isCallValid, context, target, attachment,
                      textargetPacked, texturePacked, level);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GenFramebuffersOES(GLsizei n, GLuint *framebuffers)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GenFramebuffersOES, "glGenFramebuffersOES",
          "context = %d, n = %d, framebuffers = 0x%016" PRIxPTR "", CID(context), n,
          (uintptr_t)framebuffers);

    if (context)
    {
        FramebufferID *framebuffersPacked = FromGL<FramebufferID *>(framebuffers);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGenFramebuffersOES(context, n, framebuffersPacked));
        if (isCallValid)
        {
            context->genFramebuffers(n, framebuffersPacked);
        }
        ANGLE_CAPTURE(GenFramebuffersOES, isCallValid, context, n, framebuffersPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GenRenderbuffersOES(GLsizei n, GLuint *renderbuffers)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GenRenderbuffersOES, "glGenRenderbuffersOES",
          "context = %d, n = %d, renderbuffers = 0x%016" PRIxPTR "", CID(context), n,
          (uintptr_t)renderbuffers);

    if (context)
    {
        RenderbufferID *renderbuffersPacked = FromGL<RenderbufferID *>(renderbuffers);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGenRenderbuffersOES(context, n, renderbuffersPacked));
        if (isCallValid)
        {
            context->genRenderbuffers(n, renderbuffersPacked);
        }
        ANGLE_CAPTURE(GenRenderbuffersOES, isCallValid, context, n, renderbuffersPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GenerateMipmapOES(GLenum target)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GenerateMipmapOES, "glGenerateMipmapOES",
          "context = %d, target = %s", CID(context),
          GLenumToString(GLenumGroup::TextureTarget, target));

    if (context)
    {
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGenerateMipmapOES(context, targetPacked));
        if (isCallValid)
        {
            context->generateMipmap(targetPacked);
        }
        ANGLE_CAPTURE(GenerateMipmapOES, isCallValid, context, targetPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetFramebufferAttachmentParameterivOES(GLenum target,
                                                        GLenum attachment,
                                                        GLenum pname,
                                                        GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetFramebufferAttachmentParameterivOES,
          "glGetFramebufferAttachmentParameterivOES",
          "context = %d, target = %s, attachment = %s, pname = %s, params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::FramebufferTarget, target),
          GLenumToString(GLenumGroup::FramebufferAttachment, attachment),
          GLenumToString(GLenumGroup::FramebufferAttachmentParameterName, pname),
          (uintptr_t)params);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetFramebufferAttachmentParameterivOES(
                                              context, target, attachment, pname, params));
        if (isCallValid)
        {
            context->getFramebufferAttachmentParameteriv(target, attachment, pname, params);
        }
        ANGLE_CAPTURE(GetFramebufferAttachmentParameterivOES, isCallValid, context, target,
                      attachment, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetRenderbufferParameterivOES, "glGetRenderbufferParameterivOES",
          "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::RenderbufferTarget, target),
          GLenumToString(GLenumGroup::RenderbufferParameterName, pname), (uintptr_t)params);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetRenderbufferParameterivOES(context, target, pname, params));
        if (isCallValid)
        {
            context->getRenderbufferParameteriv(target, pname, params);
        }
        ANGLE_CAPTURE(GetRenderbufferParameterivOES, isCallValid, context, target, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

GLboolean GL_APIENTRY IsFramebufferOES(GLuint framebuffer)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::IsFramebufferOES, "glIsFramebufferOES",
          "context = %d, framebuffer = %u", CID(context), framebuffer);

    GLboolean returnValue;
    if (context)
    {
        FramebufferID framebufferPacked                       = FromGL<FramebufferID>(framebuffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateIsFramebufferOES(context, framebufferPacked));
        if (isCallValid)
        {
            returnValue = context->isFramebuffer(framebufferPacked);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::IsFramebufferOES, GLboolean>();
        }
        ANGLE_CAPTURE(IsFramebufferOES, isCallValid, context, framebufferPacked, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
        returnValue = GetDefaultReturnValue<EntryPoint::IsFramebufferOES, GLboolean>();
    }
    return returnValue;
}

GLboolean GL_APIENTRY IsRenderbufferOES(GLuint renderbuffer)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::IsRenderbufferOES, "glIsRenderbufferOES",
          "context = %d, renderbuffer = %u", CID(context), renderbuffer);

    GLboolean returnValue;
    if (context)
    {
        RenderbufferID renderbufferPacked = FromGL<RenderbufferID>(renderbuffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateIsRenderbufferOES(context, renderbufferPacked));
        if (isCallValid)
        {
            returnValue = context->isRenderbuffer(renderbufferPacked);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::IsRenderbufferOES, GLboolean>();
        }
        ANGLE_CAPTURE(IsRenderbufferOES, isCallValid, context, renderbufferPacked, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
        returnValue = GetDefaultReturnValue<EntryPoint::IsRenderbufferOES, GLboolean>();
    }
    return returnValue;
}

void GL_APIENTRY RenderbufferStorageOES(GLenum target,
                                        GLenum internalformat,
                                        GLsizei width,
                                        GLsizei height)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::RenderbufferStorageOES, "glRenderbufferStorageOES",
          "context = %d, target = %s, internalformat = %s, width = %d, height = %d", CID(context),
          GLenumToString(GLenumGroup::RenderbufferTarget, target),
          GLenumToString(GLenumGroup::InternalFormat, internalformat), width, height);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateRenderbufferStorageOES(context, target, internalformat, width, height));
        if (isCallValid)
        {
            context->renderbufferStorage(target, internalformat, width, height);
        }
        ANGLE_CAPTURE(RenderbufferStorageOES, isCallValid, context, target, internalformat, width,
                      height);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_OES_get_program_binary
void GL_APIENTRY GetProgramBinaryOES(GLuint program,
                                     GLsizei bufSize,
                                     GLsizei *length,
                                     GLenum *binaryFormat,
                                     void *binary)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetProgramBinaryOES, "glGetProgramBinaryOES",
          "context = %d, program = %u, bufSize = %d, length = 0x%016" PRIxPTR
          ", binaryFormat = 0x%016" PRIxPTR ", binary = 0x%016" PRIxPTR "",
          CID(context), program, bufSize, (uintptr_t)length, (uintptr_t)binaryFormat,
          (uintptr_t)binary);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetProgramBinaryOES(context, programPacked, bufSize, length,
                                                        binaryFormat, binary));
        if (isCallValid)
        {
            context->getProgramBinary(programPacked, bufSize, length, binaryFormat, binary);
        }
        ANGLE_CAPTURE(GetProgramBinaryOES, isCallValid, context, programPacked, bufSize, length,
                      binaryFormat, binary);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramBinaryOES(GLuint program,
                                  GLenum binaryFormat,
                                  const void *binary,
                                  GLint length)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::ProgramBinaryOES, "glProgramBinaryOES",
          "context = %d, program = %u, binaryFormat = %s, binary = 0x%016" PRIxPTR ", length = %d",
          CID(context), program, GLenumToString(GLenumGroup::DefaultGroup, binaryFormat),
          (uintptr_t)binary, length);

    if (context)
    {
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramBinaryOES(context, programPacked, binaryFormat, binary, length));
        if (isCallValid)
        {
            context->programBinary(programPacked, binaryFormat, binary, length);
        }
        ANGLE_CAPTURE(ProgramBinaryOES, isCallValid, context, programPacked, binaryFormat, binary,
                      length);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_OES_mapbuffer
void GL_APIENTRY GetBufferPointervOES(GLenum target, GLenum pname, void **params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetBufferPointervOES, "glGetBufferPointervOES",
          "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::BufferTargetARB, target),
          GLenumToString(GLenumGroup::DefaultGroup, pname), (uintptr_t)params);

    if (context)
    {
        BufferBinding targetPacked                            = FromGL<BufferBinding>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetBufferPointervOES(context, targetPacked, pname, params));
        if (isCallValid)
        {
            context->getBufferPointerv(targetPacked, pname, params);
        }
        ANGLE_CAPTURE(GetBufferPointervOES, isCallValid, context, targetPacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void *GL_APIENTRY MapBufferOES(GLenum target, GLenum access)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::MapBufferOES, "glMapBufferOES",
          "context = %d, target = %s, access = %s", CID(context),
          GLenumToString(GLenumGroup::BufferTargetARB, target),
          GLenumToString(GLenumGroup::BufferAccessARB, access));

    void *returnValue;
    if (context)
    {
        BufferBinding targetPacked                            = FromGL<BufferBinding>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateMapBufferOES(context, targetPacked, access));
        if (isCallValid)
        {
            returnValue = context->mapBuffer(targetPacked, access);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::MapBufferOES, void *>();
        }
        ANGLE_CAPTURE(MapBufferOES, isCallValid, context, targetPacked, access, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
        returnValue = GetDefaultReturnValue<EntryPoint::MapBufferOES, void *>();
    }
    return returnValue;
}

GLboolean GL_APIENTRY UnmapBufferOES(GLenum target)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::UnmapBufferOES, "glUnmapBufferOES", "context = %d, target = %s",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target));

    GLboolean returnValue;
    if (context)
    {
        BufferBinding targetPacked                            = FromGL<BufferBinding>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateUnmapBufferOES(context, targetPacked));
        if (isCallValid)
        {
            returnValue = context->unmapBuffer(targetPacked);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::UnmapBufferOES, GLboolean>();
        }
        ANGLE_CAPTURE(UnmapBufferOES, isCallValid, context, targetPacked, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
        returnValue = GetDefaultReturnValue<EntryPoint::UnmapBufferOES, GLboolean>();
    }
    return returnValue;
}

// GL_OES_matrix_palette
void GL_APIENTRY CurrentPaletteMatrixOES(GLuint matrixpaletteindex)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::CurrentPaletteMatrixOES, "glCurrentPaletteMatrixOES",
          "context = %d, matrixpaletteindex = %u", CID(context), matrixpaletteindex);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateCurrentPaletteMatrixOES(context, matrixpaletteindex));
        if (isCallValid)
        {
            context->currentPaletteMatrix(matrixpaletteindex);
        }
        ANGLE_CAPTURE(CurrentPaletteMatrixOES, isCallValid, context, matrixpaletteindex);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY LoadPaletteFromModelViewMatrixOES()
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::LoadPaletteFromModelViewMatrixOES,
          "glLoadPaletteFromModelViewMatrixOES", "context = %d", CID(context));

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateLoadPaletteFromModelViewMatrixOES(context));
        if (isCallValid)
        {
            context->loadPaletteFromModelViewMatrix();
        }
        ANGLE_CAPTURE(LoadPaletteFromModelViewMatrixOES, isCallValid, context);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY MatrixIndexPointerOES(GLint size, GLenum type, GLsizei stride, const void *pointer)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::MatrixIndexPointerOES, "glMatrixIndexPointerOES",
          "context = %d, size = %d, type = %s, stride = %d, pointer = 0x%016" PRIxPTR "",
          CID(context), size, GLenumToString(GLenumGroup::DefaultGroup, type), stride,
          (uintptr_t)pointer);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateMatrixIndexPointerOES(context, size, type, stride, pointer));
        if (isCallValid)
        {
            context->matrixIndexPointer(size, type, stride, pointer);
        }
        ANGLE_CAPTURE(MatrixIndexPointerOES, isCallValid, context, size, type, stride, pointer);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY WeightPointerOES(GLint size, GLenum type, GLsizei stride, const void *pointer)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::WeightPointerOES, "glWeightPointerOES",
          "context = %d, size = %d, type = %s, stride = %d, pointer = 0x%016" PRIxPTR "",
          CID(context), size, GLenumToString(GLenumGroup::DefaultGroup, type), stride,
          (uintptr_t)pointer);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateWeightPointerOES(context, size, type, stride, pointer));
        if (isCallValid)
        {
            context->weightPointer(size, type, stride, pointer);
        }
        ANGLE_CAPTURE(WeightPointerOES, isCallValid, context, size, type, stride, pointer);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_OES_point_size_array
void GL_APIENTRY PointSizePointerOES(GLenum type, GLsizei stride, const void *pointer)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::PointSizePointerOES, "glPointSizePointerOES",
          "context = %d, type = %s, stride = %d, pointer = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::DefaultGroup, type), stride, (uintptr_t)pointer);

    if (context)
    {
        VertexAttribType typePacked                           = FromGL<VertexAttribType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidatePointSizePointerOES(context, typePacked, stride, pointer));
        if (isCallValid)
        {
            context->pointSizePointer(typePacked, stride, pointer);
        }
        ANGLE_CAPTURE(PointSizePointerOES, isCallValid, context, typePacked, stride, pointer);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_OES_query_matrix
GLbitfield GL_APIENTRY QueryMatrixxOES(GLfixed *mantissa, GLint *exponent)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::QueryMatrixxOES, "glQueryMatrixxOES",
          "context = %d, mantissa = 0x%016" PRIxPTR ", exponent = 0x%016" PRIxPTR "", CID(context),
          (uintptr_t)mantissa, (uintptr_t)exponent);

    GLbitfield returnValue;
    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateQueryMatrixxOES(context, mantissa, exponent));
        if (isCallValid)
        {
            returnValue = context->queryMatrixx(mantissa, exponent);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::QueryMatrixxOES, GLbitfield>();
        }
        ANGLE_CAPTURE(QueryMatrixxOES, isCallValid, context, mantissa, exponent, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
        returnValue = GetDefaultReturnValue<EntryPoint::QueryMatrixxOES, GLbitfield>();
    }
    return returnValue;
}

// GL_OES_sample_shading
void GL_APIENTRY MinSampleShadingOES(GLfloat value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::MinSampleShadingOES, "glMinSampleShadingOES",
          "context = %d, value = %f", CID(context), value);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateMinSampleShadingOES(context, value));
        if (isCallValid)
        {
            context->minSampleShading(value);
        }
        ANGLE_CAPTURE(MinSampleShadingOES, isCallValid, context, value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_OES_texture_3D
void GL_APIENTRY CompressedTexImage3DOES(GLenum target,
                                         GLint level,
                                         GLenum internalformat,
                                         GLsizei width,
                                         GLsizei height,
                                         GLsizei depth,
                                         GLint border,
                                         GLsizei imageSize,
                                         const void *data)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::CompressedTexImage3DOES, "glCompressedTexImage3DOES",
          "context = %d, target = %s, level = %d, internalformat = %s, width = %d, height = %d, "
          "depth = %d, border = %d, imageSize = %d, data = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), level,
          GLenumToString(GLenumGroup::InternalFormat, internalformat), width, height, depth, border,
          imageSize, (uintptr_t)data);

    if (context)
    {
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateCompressedTexImage3DOES(context, targetPacked, level, internalformat, width,
                                             height, depth, border, imageSize, data));
        if (isCallValid)
        {
            context->compressedTexImage3D(targetPacked, level, internalformat, width, height, depth,
                                          border, imageSize, data);
        }
        ANGLE_CAPTURE(CompressedTexImage3DOES, isCallValid, context, targetPacked, level,
                      internalformat, width, height, depth, border, imageSize, data);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY CompressedTexSubImage3DOES(GLenum target,
                                            GLint level,
                                            GLint xoffset,
                                            GLint yoffset,
                                            GLint zoffset,
                                            GLsizei width,
                                            GLsizei height,
                                            GLsizei depth,
                                            GLenum format,
                                            GLsizei imageSize,
                                            const void *data)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::CompressedTexSubImage3DOES, "glCompressedTexSubImage3DOES",
          "context = %d, target = %s, level = %d, xoffset = %d, yoffset = %d, zoffset = %d, width "
          "= %d, height = %d, depth = %d, format = %s, imageSize = %d, data = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), level, xoffset, yoffset,
          zoffset, width, height, depth, GLenumToString(GLenumGroup::PixelFormat, format),
          imageSize, (uintptr_t)data);

    if (context)
    {
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateCompressedTexSubImage3DOES(
                                context, targetPacked, level, xoffset, yoffset, zoffset, width,
                                height, depth, format, imageSize, data));
        if (isCallValid)
        {
            context->compressedTexSubImage3D(targetPacked, level, xoffset, yoffset, zoffset, width,
                                             height, depth, format, imageSize, data);
        }
        ANGLE_CAPTURE(CompressedTexSubImage3DOES, isCallValid, context, targetPacked, level,
                      xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY CopyTexSubImage3DOES(GLenum target,
                                      GLint level,
                                      GLint xoffset,
                                      GLint yoffset,
                                      GLint zoffset,
                                      GLint x,
                                      GLint y,
                                      GLsizei width,
                                      GLsizei height)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::CopyTexSubImage3DOES, "glCopyTexSubImage3DOES",
          "context = %d, target = %s, level = %d, xoffset = %d, yoffset = %d, zoffset = %d, x = "
          "%d, y = %d, width = %d, height = %d",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target), level, xoffset, yoffset,
          zoffset, x, y, width, height);

    if (context)
    {
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateCopyTexSubImage3DOES(context, targetPacked, level, xoffset,
                                                         yoffset, zoffset, x, y, width, height));
        if (isCallValid)
        {
            context->copyTexSubImage3D(targetPacked, level, xoffset, yoffset, zoffset, x, y, width,
                                       height);
        }
        ANGLE_CAPTURE(CopyTexSubImage3DOES, isCallValid, context, targetPacked, level, xoffset,
                      yoffset, zoffset, x, y, width, height);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY FramebufferTexture3DOES(GLenum target,
                                         GLenum attachment,
                                         GLenum textarget,
                                         GLuint texture,
                                         GLint level,
                                         GLint zoffset)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::FramebufferTexture3DOES, "glFramebufferTexture3DOES",
          "context = %d, target = %s, attachment = %s, textarget = %s, texture = %u, level = %d, "
          "zoffset = %d",
          CID(context), GLenumToString(GLenumGroup::FramebufferTarget, target),
          GLenumToString(GLenumGroup::FramebufferAttachment, attachment),
          GLenumToString(GLenumGroup::TextureTarget, textarget), texture, level, zoffset);

    if (context)
    {
        TextureTarget textargetPacked                         = FromGL<TextureTarget>(textarget);
        TextureID texturePacked                               = FromGL<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateFramebufferTexture3DOES(context, target, attachment, textargetPacked,
                                             texturePacked, level, zoffset));
        if (isCallValid)
        {
            context->framebufferTexture3D(target, attachment, textargetPacked, texturePacked, level,
                                          zoffset);
        }
        ANGLE_CAPTURE(FramebufferTexture3DOES, isCallValid, context, target, attachment,
                      textargetPacked, texturePacked, level, zoffset);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TexImage3DOES(GLenum target,
                               GLint level,
                               GLenum internalformat,
                               GLsizei width,
                               GLsizei height,
                               GLsizei depth,
                               GLint border,
                               GLenum format,
                               GLenum type,
                               const void *pixels)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::TexImage3DOES, "glTexImage3DOES",
          "context = %d, target = %s, level = %d, internalformat = %s, width = %d, height = %d, "
          "depth = %d, border = %d, format = %s, type = %s, pixels = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), level,
          GLenumToString(GLenumGroup::InternalFormat, internalformat), width, height, depth, border,
          GLenumToString(GLenumGroup::PixelFormat, format),
          GLenumToString(GLenumGroup::PixelType, type), (uintptr_t)pixels);

    if (context)
    {
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTexImage3DOES(context, targetPacked, level, internalformat, width, height,
                                   depth, border, format, type, pixels));
        if (isCallValid)
        {
            context->texImage3D(targetPacked, level, internalformat, width, height, depth, border,
                                format, type, pixels);
        }
        ANGLE_CAPTURE(TexImage3DOES, isCallValid, context, targetPacked, level, internalformat,
                      width, height, depth, border, format, type, pixels);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TexSubImage3DOES(GLenum target,
                                  GLint level,
                                  GLint xoffset,
                                  GLint yoffset,
                                  GLint zoffset,
                                  GLsizei width,
                                  GLsizei height,
                                  GLsizei depth,
                                  GLenum format,
                                  GLenum type,
                                  const void *pixels)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::TexSubImage3DOES, "glTexSubImage3DOES",
          "context = %d, target = %s, level = %d, xoffset = %d, yoffset = %d, zoffset = %d, width "
          "= %d, height = %d, depth = %d, format = %s, type = %s, pixels = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), level, xoffset, yoffset,
          zoffset, width, height, depth, GLenumToString(GLenumGroup::PixelFormat, format),
          GLenumToString(GLenumGroup::PixelType, type), (uintptr_t)pixels);

    if (context)
    {
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTexSubImage3DOES(context, targetPacked, level, xoffset, yoffset, zoffset,
                                      width, height, depth, format, type, pixels));
        if (isCallValid)
        {
            context->texSubImage3D(targetPacked, level, xoffset, yoffset, zoffset, width, height,
                                   depth, format, type, pixels);
        }
        ANGLE_CAPTURE(TexSubImage3DOES, isCallValid, context, targetPacked, level, xoffset, yoffset,
                      zoffset, width, height, depth, format, type, pixels);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_OES_texture_border_clamp
void GL_APIENTRY GetSamplerParameterIivOES(GLuint sampler, GLenum pname, GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetSamplerParameterIivOES, "glGetSamplerParameterIivOES",
          "context = %d, sampler = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          sampler, GLenumToString(GLenumGroup::SamplerParameterName, pname), (uintptr_t)params);

    if (context)
    {
        SamplerID samplerPacked                               = FromGL<SamplerID>(sampler);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetSamplerParameterIivOES(context, samplerPacked, pname, params));
        if (isCallValid)
        {
            context->getSamplerParameterIiv(samplerPacked, pname, params);
        }
        ANGLE_CAPTURE(GetSamplerParameterIivOES, isCallValid, context, samplerPacked, pname,
                      params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetSamplerParameterIuivOES(GLuint sampler, GLenum pname, GLuint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetSamplerParameterIuivOES, "glGetSamplerParameterIuivOES",
          "context = %d, sampler = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          sampler, GLenumToString(GLenumGroup::SamplerParameterName, pname), (uintptr_t)params);

    if (context)
    {
        SamplerID samplerPacked                               = FromGL<SamplerID>(sampler);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetSamplerParameterIuivOES(context, samplerPacked, pname, params));
        if (isCallValid)
        {
            context->getSamplerParameterIuiv(samplerPacked, pname, params);
        }
        ANGLE_CAPTURE(GetSamplerParameterIuivOES, isCallValid, context, samplerPacked, pname,
                      params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetTexParameterIivOES(GLenum target, GLenum pname, GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetTexParameterIivOES, "glGetTexParameterIivOES",
          "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::TextureTarget, target),
          GLenumToString(GLenumGroup::GetTextureParameter, pname), (uintptr_t)params);

    if (context)
    {
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetTexParameterIivOES(context, targetPacked, pname, params));
        if (isCallValid)
        {
            context->getTexParameterIiv(targetPacked, pname, params);
        }
        ANGLE_CAPTURE(GetTexParameterIivOES, isCallValid, context, targetPacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetTexParameterIuivOES(GLenum target, GLenum pname, GLuint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetTexParameterIuivOES, "glGetTexParameterIuivOES",
          "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::TextureTarget, target),
          GLenumToString(GLenumGroup::GetTextureParameter, pname), (uintptr_t)params);

    if (context)
    {
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetTexParameterIuivOES(context, targetPacked, pname, params));
        if (isCallValid)
        {
            context->getTexParameterIuiv(targetPacked, pname, params);
        }
        ANGLE_CAPTURE(GetTexParameterIuivOES, isCallValid, context, targetPacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY SamplerParameterIivOES(GLuint sampler, GLenum pname, const GLint *param)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::SamplerParameterIivOES, "glSamplerParameterIivOES",
          "context = %d, sampler = %u, pname = %s, param = 0x%016" PRIxPTR "", CID(context),
          sampler, GLenumToString(GLenumGroup::SamplerParameterName, pname), (uintptr_t)param);

    if (context)
    {
        SamplerID samplerPacked                               = FromGL<SamplerID>(sampler);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateSamplerParameterIivOES(context, samplerPacked, pname, param));
        if (isCallValid)
        {
            context->samplerParameterIiv(samplerPacked, pname, param);
        }
        ANGLE_CAPTURE(SamplerParameterIivOES, isCallValid, context, samplerPacked, pname, param);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY SamplerParameterIuivOES(GLuint sampler, GLenum pname, const GLuint *param)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::SamplerParameterIuivOES, "glSamplerParameterIuivOES",
          "context = %d, sampler = %u, pname = %s, param = 0x%016" PRIxPTR "", CID(context),
          sampler, GLenumToString(GLenumGroup::SamplerParameterName, pname), (uintptr_t)param);

    if (context)
    {
        SamplerID samplerPacked                               = FromGL<SamplerID>(sampler);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateSamplerParameterIuivOES(context, samplerPacked, pname, param));
        if (isCallValid)
        {
            context->samplerParameterIuiv(samplerPacked, pname, param);
        }
        ANGLE_CAPTURE(SamplerParameterIuivOES, isCallValid, context, samplerPacked, pname, param);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TexParameterIivOES(GLenum target, GLenum pname, const GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::TexParameterIivOES, "glTexParameterIivOES",
          "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::TextureTarget, target),
          GLenumToString(GLenumGroup::TextureParameterName, pname), (uintptr_t)params);

    if (context)
    {
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateTexParameterIivOES(context, targetPacked, pname, params));
        if (isCallValid)
        {
            context->texParameterIiv(targetPacked, pname, params);
        }
        ANGLE_CAPTURE(TexParameterIivOES, isCallValid, context, targetPacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TexParameterIuivOES(GLenum target, GLenum pname, const GLuint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::TexParameterIuivOES, "glTexParameterIuivOES",
          "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::TextureTarget, target),
          GLenumToString(GLenumGroup::TextureParameterName, pname), (uintptr_t)params);

    if (context)
    {
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateTexParameterIuivOES(context, targetPacked, pname, params));
        if (isCallValid)
        {
            context->texParameterIuiv(targetPacked, pname, params);
        }
        ANGLE_CAPTURE(TexParameterIuivOES, isCallValid, context, targetPacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_OES_texture_buffer
void GL_APIENTRY TexBufferOES(GLenum target, GLenum internalformat, GLuint buffer)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::TexBufferOES, "glTexBufferOES",
          "context = %d, target = %s, internalformat = %s, buffer = %u", CID(context),
          GLenumToString(GLenumGroup::TextureTarget, target),
          GLenumToString(GLenumGroup::InternalFormat, internalformat), buffer);

    if (context)
    {
        TextureType targetPacked                              = FromGL<TextureType>(target);
        BufferID bufferPacked                                 = FromGL<BufferID>(buffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTexBufferOES(context, targetPacked, internalformat, bufferPacked));
        if (isCallValid)
        {
            context->texBuffer(targetPacked, internalformat, bufferPacked);
        }
        ANGLE_CAPTURE(TexBufferOES, isCallValid, context, targetPacked, internalformat,
                      bufferPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TexBufferRangeOES(GLenum target,
                                   GLenum internalformat,
                                   GLuint buffer,
                                   GLintptr offset,
                                   GLsizeiptr size)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::TexBufferRangeOES, "glTexBufferRangeOES",
          "context = %d, target = %s, internalformat = %s, buffer = %u, offset = %llu, size = %llu",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target),
          GLenumToString(GLenumGroup::InternalFormat, internalformat), buffer,
          static_cast<unsigned long long>(offset), static_cast<unsigned long long>(size));

    if (context)
    {
        TextureType targetPacked                              = FromGL<TextureType>(target);
        BufferID bufferPacked                                 = FromGL<BufferID>(buffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateTexBufferRangeOES(context, targetPacked, internalformat,
                                                      bufferPacked, offset, size));
        if (isCallValid)
        {
            context->texBufferRange(targetPacked, internalformat, bufferPacked, offset, size);
        }
        ANGLE_CAPTURE(TexBufferRangeOES, isCallValid, context, targetPacked, internalformat,
                      bufferPacked, offset, size);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_OES_texture_cube_map
void GL_APIENTRY GetTexGenfvOES(GLenum coord, GLenum pname, GLfloat *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetTexGenfvOES, "glGetTexGenfvOES",
          "context = %d, coord = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::TextureCoordName, coord),
          GLenumToString(GLenumGroup::TextureGenParameter, pname), (uintptr_t)params);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetTexGenfvOES(context, coord, pname, params));
        if (isCallValid)
        {
            context->getTexGenfv(coord, pname, params);
        }
        ANGLE_CAPTURE(GetTexGenfvOES, isCallValid, context, coord, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetTexGenivOES(GLenum coord, GLenum pname, GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetTexGenivOES, "glGetTexGenivOES",
          "context = %d, coord = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::TextureCoordName, coord),
          GLenumToString(GLenumGroup::TextureGenParameter, pname), (uintptr_t)params);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetTexGenivOES(context, coord, pname, params));
        if (isCallValid)
        {
            context->getTexGeniv(coord, pname, params);
        }
        ANGLE_CAPTURE(GetTexGenivOES, isCallValid, context, coord, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetTexGenxvOES(GLenum coord, GLenum pname, GLfixed *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GetTexGenxvOES, "glGetTexGenxvOES",
          "context = %d, coord = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::TextureCoordName, coord),
          GLenumToString(GLenumGroup::TextureGenParameter, pname), (uintptr_t)params);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetTexGenxvOES(context, coord, pname, params));
        if (isCallValid)
        {
            context->getTexGenxv(coord, pname, params);
        }
        ANGLE_CAPTURE(GetTexGenxvOES, isCallValid, context, coord, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TexGenfOES(GLenum coord, GLenum pname, GLfloat param)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::TexGenfOES, "glTexGenfOES",
          "context = %d, coord = %s, pname = %s, param = %f", CID(context),
          GLenumToString(GLenumGroup::TextureCoordName, coord),
          GLenumToString(GLenumGroup::TextureGenParameter, pname), param);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateTexGenfOES(context, coord, pname, param));
        if (isCallValid)
        {
            context->texGenf(coord, pname, param);
        }
        ANGLE_CAPTURE(TexGenfOES, isCallValid, context, coord, pname, param);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TexGenfvOES(GLenum coord, GLenum pname, const GLfloat *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::TexGenfvOES, "glTexGenfvOES",
          "context = %d, coord = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::TextureCoordName, coord),
          GLenumToString(GLenumGroup::TextureGenParameter, pname), (uintptr_t)params);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateTexGenfvOES(context, coord, pname, params));
        if (isCallValid)
        {
            context->texGenfv(coord, pname, params);
        }
        ANGLE_CAPTURE(TexGenfvOES, isCallValid, context, coord, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TexGeniOES(GLenum coord, GLenum pname, GLint param)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::TexGeniOES, "glTexGeniOES",
          "context = %d, coord = %s, pname = %s, param = %d", CID(context),
          GLenumToString(GLenumGroup::TextureCoordName, coord),
          GLenumToString(GLenumGroup::TextureGenParameter, pname), param);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateTexGeniOES(context, coord, pname, param));
        if (isCallValid)
        {
            context->texGeni(coord, pname, param);
        }
        ANGLE_CAPTURE(TexGeniOES, isCallValid, context, coord, pname, param);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TexGenivOES(GLenum coord, GLenum pname, const GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::TexGenivOES, "glTexGenivOES",
          "context = %d, coord = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::TextureCoordName, coord),
          GLenumToString(GLenumGroup::TextureGenParameter, pname), (uintptr_t)params);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateTexGenivOES(context, coord, pname, params));
        if (isCallValid)
        {
            context->texGeniv(coord, pname, params);
        }
        ANGLE_CAPTURE(TexGenivOES, isCallValid, context, coord, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TexGenxOES(GLenum coord, GLenum pname, GLfixed param)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::TexGenxOES, "glTexGenxOES",
          "context = %d, coord = %s, pname = %s, param = 0x%X", CID(context),
          GLenumToString(GLenumGroup::TextureCoordName, coord),
          GLenumToString(GLenumGroup::TextureGenParameter, pname), param);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateTexGenxOES(context, coord, pname, param));
        if (isCallValid)
        {
            context->texGenx(coord, pname, param);
        }
        ANGLE_CAPTURE(TexGenxOES, isCallValid, context, coord, pname, param);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TexGenxvOES(GLenum coord, GLenum pname, const GLfixed *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::TexGenxvOES, "glTexGenxvOES",
          "context = %d, coord = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::TextureCoordName, coord),
          GLenumToString(GLenumGroup::TextureGenParameter, pname), (uintptr_t)params);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateTexGenxvOES(context, coord, pname, params));
        if (isCallValid)
        {
            context->texGenxv(coord, pname, params);
        }
        ANGLE_CAPTURE(TexGenxvOES, isCallValid, context, coord, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_OES_texture_cube_map_array

// GL_OES_texture_half_float

// GL_OES_texture_stencil8

// GL_OES_texture_storage_multisample_2d_array
void GL_APIENTRY TexStorage3DMultisampleOES(GLenum target,
                                            GLsizei samples,
                                            GLenum internalformat,
                                            GLsizei width,
                                            GLsizei height,
                                            GLsizei depth,
                                            GLboolean fixedsamplelocations)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::TexStorage3DMultisampleOES, "glTexStorage3DMultisampleOES",
          "context = %d, target = %s, samples = %d, internalformat = %s, width = %d, height = %d, "
          "depth = %d, fixedsamplelocations = %s",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), samples,
          GLenumToString(GLenumGroup::InternalFormat, internalformat), width, height, depth,
          GLbooleanToString(fixedsamplelocations));

    if (context)
    {
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTexStorage3DMultisampleOES(context, targetPacked, samples, internalformat,
                                                width, height, depth, fixedsamplelocations));
        if (isCallValid)
        {
            context->texStorage3DMultisample(targetPacked, samples, internalformat, width, height,
                                             depth, fixedsamplelocations);
        }
        ANGLE_CAPTURE(TexStorage3DMultisampleOES, isCallValid, context, targetPacked, samples,
                      internalformat, width, height, depth, fixedsamplelocations);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_OES_vertex_array_object
void GL_APIENTRY BindVertexArrayOES(GLuint array)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::BindVertexArrayOES, "glBindVertexArrayOES",
          "context = %d, array = %u", CID(context), array);

    if (context)
    {
        VertexArrayID arrayPacked                             = FromGL<VertexArrayID>(array);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateBindVertexArrayOES(context, arrayPacked));
        if (isCallValid)
        {
            context->bindVertexArray(arrayPacked);
        }
        ANGLE_CAPTURE(BindVertexArrayOES, isCallValid, context, arrayPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY DeleteVertexArraysOES(GLsizei n, const GLuint *arrays)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::DeleteVertexArraysOES, "glDeleteVertexArraysOES",
          "context = %d, n = %d, arrays = 0x%016" PRIxPTR "", CID(context), n, (uintptr_t)arrays);

    if (context)
    {
        const VertexArrayID *arraysPacked = FromGL<const VertexArrayID *>(arrays);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateDeleteVertexArraysOES(context, n, arraysPacked));
        if (isCallValid)
        {
            context->deleteVertexArrays(n, arraysPacked);
        }
        ANGLE_CAPTURE(DeleteVertexArraysOES, isCallValid, context, n, arraysPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GenVertexArraysOES(GLsizei n, GLuint *arrays)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::GenVertexArraysOES, "glGenVertexArraysOES",
          "context = %d, n = %d, arrays = 0x%016" PRIxPTR "", CID(context), n, (uintptr_t)arrays);

    if (context)
    {
        VertexArrayID *arraysPacked                           = FromGL<VertexArrayID *>(arrays);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGenVertexArraysOES(context, n, arraysPacked));
        if (isCallValid)
        {
            context->genVertexArrays(n, arraysPacked);
        }
        ANGLE_CAPTURE(GenVertexArraysOES, isCallValid, context, n, arraysPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

GLboolean GL_APIENTRY IsVertexArrayOES(GLuint array)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::IsVertexArrayOES, "glIsVertexArrayOES",
          "context = %d, array = %u", CID(context), array);

    GLboolean returnValue;
    if (context)
    {
        VertexArrayID arrayPacked                             = FromGL<VertexArrayID>(array);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateIsVertexArrayOES(context, arrayPacked));
        if (isCallValid)
        {
            returnValue = context->isVertexArray(arrayPacked);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::IsVertexArrayOES, GLboolean>();
        }
        ANGLE_CAPTURE(IsVertexArrayOES, isCallValid, context, arrayPacked, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
        returnValue = GetDefaultReturnValue<EntryPoint::IsVertexArrayOES, GLboolean>();
    }
    return returnValue;
}

// GL_OVR_multiview
void GL_APIENTRY FramebufferTextureMultiviewOVR(GLenum target,
                                                GLenum attachment,
                                                GLuint texture,
                                                GLint level,
                                                GLint baseViewIndex,
                                                GLsizei numViews)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::FramebufferTextureMultiviewOVR,
          "glFramebufferTextureMultiviewOVR",
          "context = %d, target = %s, attachment = %s, texture = %u, level = %d, baseViewIndex = "
          "%d, numViews = %d",
          CID(context), GLenumToString(GLenumGroup::FramebufferTarget, target),
          GLenumToString(GLenumGroup::FramebufferAttachment, attachment), texture, level,
          baseViewIndex, numViews);

    if (context)
    {
        TextureID texturePacked                               = FromGL<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateFramebufferTextureMultiviewOVR(context, target, attachment, texturePacked,
                                                    level, baseViewIndex, numViews));
        if (isCallValid)
        {
            context->framebufferTextureMultiview(target, attachment, texturePacked, level,
                                                 baseViewIndex, numViews);
        }
        ANGLE_CAPTURE(FramebufferTextureMultiviewOVR, isCallValid, context, target, attachment,
                      texturePacked, level, baseViewIndex, numViews);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL_OVR_multiview2

// EGL_ANGLE_explicit_context
void GL_APIENTRY ActiveShaderProgramContextANGLE(GLeglContext ctx, GLuint pipeline, GLuint program)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ActiveShaderProgram, "glActiveShaderProgram",
          "context = %d, pipeline = %u, program = %u", CID(context), pipeline, program);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ProgramPipelineID pipelinePacked                      = FromGL<ProgramPipelineID>(pipeline);
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateActiveShaderProgram(context, pipelinePacked, programPacked));
        if (isCallValid)
        {
            context->activeShaderProgram(pipelinePacked, programPacked);
        }
        ANGLE_CAPTURE(ActiveShaderProgram, isCallValid, context, pipelinePacked, programPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ActiveTextureContextANGLE(GLeglContext ctx, GLenum texture)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ActiveTexture, "glActiveTexture", "context = %d, texture = %s",
          CID(context), GLenumToString(GLenumGroup::TextureUnit, texture));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateActiveTexture(context, texture));
        if (isCallValid)
        {
            context->activeTexture(texture);
        }
        ANGLE_CAPTURE(ActiveTexture, isCallValid, context, texture);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY AlphaFuncContextANGLE(GLeglContext ctx, GLenum func, GLfloat ref)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::AlphaFunc, "glAlphaFunc", "context = %d, func = %s, ref = %f",
          CID(context), GLenumToString(GLenumGroup::AlphaFunction, func), ref);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        AlphaTestFunc funcPacked                              = FromGL<AlphaTestFunc>(func);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateAlphaFunc(context, funcPacked, ref));
        if (isCallValid)
        {
            context->alphaFunc(funcPacked, ref);
        }
        ANGLE_CAPTURE(AlphaFunc, isCallValid, context, funcPacked, ref);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY AlphaFuncxContextANGLE(GLeglContext ctx, GLenum func, GLfixed ref)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::AlphaFuncx, "glAlphaFuncx",
          "context = %d, func = %s, ref = 0x%X", CID(context),
          GLenumToString(GLenumGroup::AlphaFunction, func), ref);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        AlphaTestFunc funcPacked                              = FromGL<AlphaTestFunc>(func);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateAlphaFuncx(context, funcPacked, ref));
        if (isCallValid)
        {
            context->alphaFuncx(funcPacked, ref);
        }
        ANGLE_CAPTURE(AlphaFuncx, isCallValid, context, funcPacked, ref);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY AttachShaderContextANGLE(GLeglContext ctx, GLuint program, GLuint shader)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::AttachShader, "glAttachShader",
          "context = %d, program = %u, shader = %u", CID(context), program, shader);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        ShaderProgramID shaderPacked                          = FromGL<ShaderProgramID>(shader);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateAttachShader(context, programPacked, shaderPacked));
        if (isCallValid)
        {
            context->attachShader(programPacked, shaderPacked);
        }
        ANGLE_CAPTURE(AttachShader, isCallValid, context, programPacked, shaderPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY BeginQueryContextANGLE(GLeglContext ctx, GLenum target, GLuint id)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::BeginQuery, "glBeginQuery", "context = %d, target = %s, id = %u",
          CID(context), GLenumToString(GLenumGroup::QueryTarget, target), id);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        QueryType targetPacked                                = FromGL<QueryType>(target);
        QueryID idPacked                                      = FromGL<QueryID>(id);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateBeginQuery(context, targetPacked, idPacked));
        if (isCallValid)
        {
            context->beginQuery(targetPacked, idPacked);
        }
        ANGLE_CAPTURE(BeginQuery, isCallValid, context, targetPacked, idPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY BeginQueryEXTContextANGLE(GLeglContext ctx, GLenum target, GLuint id)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::BeginQueryEXT, "glBeginQueryEXT",
          "context = %d, target = %s, id = %u", CID(context),
          GLenumToString(GLenumGroup::QueryTarget, target), id);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        QueryType targetPacked                                = FromGL<QueryType>(target);
        QueryID idPacked                                      = FromGL<QueryID>(id);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateBeginQueryEXT(context, targetPacked, idPacked));
        if (isCallValid)
        {
            context->beginQuery(targetPacked, idPacked);
        }
        ANGLE_CAPTURE(BeginQueryEXT, isCallValid, context, targetPacked, idPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY BeginTransformFeedbackContextANGLE(GLeglContext ctx, GLenum primitiveMode)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::BeginTransformFeedback, "glBeginTransformFeedback",
          "context = %d, primitiveMode = %s", CID(context),
          GLenumToString(GLenumGroup::PrimitiveType, primitiveMode));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        PrimitiveMode primitiveModePacked = FromGL<PrimitiveMode>(primitiveMode);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateBeginTransformFeedback(context, primitiveModePacked));
        if (isCallValid)
        {
            context->beginTransformFeedback(primitiveModePacked);
        }
        ANGLE_CAPTURE(BeginTransformFeedback, isCallValid, context, primitiveModePacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY BindAttribLocationContextANGLE(GLeglContext ctx,
                                                GLuint program,
                                                GLuint index,
                                                const GLchar *name)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::BindAttribLocation, "glBindAttribLocation",
          "context = %d, program = %u, index = %u, name = 0x%016" PRIxPTR "", CID(context), program,
          index, (uintptr_t)name);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateBindAttribLocation(context, programPacked, index, name));
        if (isCallValid)
        {
            context->bindAttribLocation(programPacked, index, name);
        }
        ANGLE_CAPTURE(BindAttribLocation, isCallValid, context, programPacked, index, name);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY BindBufferContextANGLE(GLeglContext ctx, GLenum target, GLuint buffer)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::BindBuffer, "glBindBuffer",
          "context = %d, target = %s, buffer = %u", CID(context),
          GLenumToString(GLenumGroup::BufferTargetARB, target), buffer);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        BufferBinding targetPacked                            = FromGL<BufferBinding>(target);
        BufferID bufferPacked                                 = FromGL<BufferID>(buffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateBindBuffer(context, targetPacked, bufferPacked));
        if (isCallValid)
        {
            context->bindBuffer(targetPacked, bufferPacked);
        }
        ANGLE_CAPTURE(BindBuffer, isCallValid, context, targetPacked, bufferPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY BindBufferBaseContextANGLE(GLeglContext ctx,
                                            GLenum target,
                                            GLuint index,
                                            GLuint buffer)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::BindBufferBase, "glBindBufferBase",
          "context = %d, target = %s, index = %u, buffer = %u", CID(context),
          GLenumToString(GLenumGroup::BufferTargetARB, target), index, buffer);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        BufferBinding targetPacked                            = FromGL<BufferBinding>(target);
        BufferID bufferPacked                                 = FromGL<BufferID>(buffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateBindBufferBase(context, targetPacked, index, bufferPacked));
        if (isCallValid)
        {
            context->bindBufferBase(targetPacked, index, bufferPacked);
        }
        ANGLE_CAPTURE(BindBufferBase, isCallValid, context, targetPacked, index, bufferPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY BindBufferRangeContextANGLE(GLeglContext ctx,
                                             GLenum target,
                                             GLuint index,
                                             GLuint buffer,
                                             GLintptr offset,
                                             GLsizeiptr size)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::BindBufferRange, "glBindBufferRange",
          "context = %d, target = %s, index = %u, buffer = %u, offset = %llu, size = %llu",
          CID(context), GLenumToString(GLenumGroup::BufferTargetARB, target), index, buffer,
          static_cast<unsigned long long>(offset), static_cast<unsigned long long>(size));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        BufferBinding targetPacked                            = FromGL<BufferBinding>(target);
        BufferID bufferPacked                                 = FromGL<BufferID>(buffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateBindBufferRange(context, targetPacked, index, bufferPacked, offset, size));
        if (isCallValid)
        {
            context->bindBufferRange(targetPacked, index, bufferPacked, offset, size);
        }
        ANGLE_CAPTURE(BindBufferRange, isCallValid, context, targetPacked, index, bufferPacked,
                      offset, size);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY BindFragDataLocationEXTContextANGLE(GLeglContext ctx,
                                                     GLuint program,
                                                     GLuint color,
                                                     const GLchar *name)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::BindFragDataLocationEXT, "glBindFragDataLocationEXT",
          "context = %d, program = %u, color = %u, name = 0x%016" PRIxPTR "", CID(context), program,
          color, (uintptr_t)name);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateBindFragDataLocationEXT(context, programPacked, color, name));
        if (isCallValid)
        {
            context->bindFragDataLocation(programPacked, color, name);
        }
        ANGLE_CAPTURE(BindFragDataLocationEXT, isCallValid, context, programPacked, color, name);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY BindFragDataLocationIndexedEXTContextANGLE(GLeglContext ctx,
                                                            GLuint program,
                                                            GLuint colorNumber,
                                                            GLuint index,
                                                            const GLchar *name)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::BindFragDataLocationIndexedEXT,
          "glBindFragDataLocationIndexedEXT",
          "context = %d, program = %u, colorNumber = %u, index = %u, name = 0x%016" PRIxPTR "",
          CID(context), program, colorNumber, index, (uintptr_t)name);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateBindFragDataLocationIndexedEXT(
                                              context, programPacked, colorNumber, index, name));
        if (isCallValid)
        {
            context->bindFragDataLocationIndexed(programPacked, colorNumber, index, name);
        }
        ANGLE_CAPTURE(BindFragDataLocationIndexedEXT, isCallValid, context, programPacked,
                      colorNumber, index, name);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY BindFramebufferContextANGLE(GLeglContext ctx, GLenum target, GLuint framebuffer)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::BindFramebuffer, "glBindFramebuffer",
          "context = %d, target = %s, framebuffer = %u", CID(context),
          GLenumToString(GLenumGroup::FramebufferTarget, target), framebuffer);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        FramebufferID framebufferPacked                       = FromGL<FramebufferID>(framebuffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateBindFramebuffer(context, target, framebufferPacked));
        if (isCallValid)
        {
            context->bindFramebuffer(target, framebufferPacked);
        }
        ANGLE_CAPTURE(BindFramebuffer, isCallValid, context, target, framebufferPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY BindFramebufferOESContextANGLE(GLeglContext ctx, GLenum target, GLuint framebuffer)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::BindFramebufferOES, "glBindFramebufferOES",
          "context = %d, target = %s, framebuffer = %u", CID(context),
          GLenumToString(GLenumGroup::FramebufferTarget, target), framebuffer);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        FramebufferID framebufferPacked                       = FromGL<FramebufferID>(framebuffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateBindFramebufferOES(context, target, framebufferPacked));
        if (isCallValid)
        {
            context->bindFramebuffer(target, framebufferPacked);
        }
        ANGLE_CAPTURE(BindFramebufferOES, isCallValid, context, target, framebufferPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY BindImageTextureContextANGLE(GLeglContext ctx,
                                              GLuint unit,
                                              GLuint texture,
                                              GLint level,
                                              GLboolean layered,
                                              GLint layer,
                                              GLenum access,
                                              GLenum format)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::BindImageTexture, "glBindImageTexture",
          "context = %d, unit = %u, texture = %u, level = %d, layered = %s, layer = %d, access = "
          "%s, format = %s",
          CID(context), unit, texture, level, GLbooleanToString(layered), layer,
          GLenumToString(GLenumGroup::BufferAccessARB, access),
          GLenumToString(GLenumGroup::InternalFormat, format));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureID texturePacked                               = FromGL<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateBindImageTexture(context, unit, texturePacked, level, layered,
                                                     layer, access, format));
        if (isCallValid)
        {
            context->bindImageTexture(unit, texturePacked, level, layered, layer, access, format);
        }
        ANGLE_CAPTURE(BindImageTexture, isCallValid, context, unit, texturePacked, level, layered,
                      layer, access, format);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY BindProgramPipelineContextANGLE(GLeglContext ctx, GLuint pipeline)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::BindProgramPipeline, "glBindProgramPipeline",
          "context = %d, pipeline = %u", CID(context), pipeline);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ProgramPipelineID pipelinePacked                      = FromGL<ProgramPipelineID>(pipeline);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateBindProgramPipeline(context, pipelinePacked));
        if (isCallValid)
        {
            context->bindProgramPipeline(pipelinePacked);
        }
        ANGLE_CAPTURE(BindProgramPipeline, isCallValid, context, pipelinePacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY BindRenderbufferContextANGLE(GLeglContext ctx, GLenum target, GLuint renderbuffer)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::BindRenderbuffer, "glBindRenderbuffer",
          "context = %d, target = %s, renderbuffer = %u", CID(context),
          GLenumToString(GLenumGroup::RenderbufferTarget, target), renderbuffer);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        RenderbufferID renderbufferPacked = FromGL<RenderbufferID>(renderbuffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateBindRenderbuffer(context, target, renderbufferPacked));
        if (isCallValid)
        {
            context->bindRenderbuffer(target, renderbufferPacked);
        }
        ANGLE_CAPTURE(BindRenderbuffer, isCallValid, context, target, renderbufferPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY BindRenderbufferOESContextANGLE(GLeglContext ctx,
                                                 GLenum target,
                                                 GLuint renderbuffer)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::BindRenderbufferOES, "glBindRenderbufferOES",
          "context = %d, target = %s, renderbuffer = %u", CID(context),
          GLenumToString(GLenumGroup::RenderbufferTarget, target), renderbuffer);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        RenderbufferID renderbufferPacked = FromGL<RenderbufferID>(renderbuffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateBindRenderbufferOES(context, target, renderbufferPacked));
        if (isCallValid)
        {
            context->bindRenderbuffer(target, renderbufferPacked);
        }
        ANGLE_CAPTURE(BindRenderbufferOES, isCallValid, context, target, renderbufferPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY BindSamplerContextANGLE(GLeglContext ctx, GLuint unit, GLuint sampler)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::BindSampler, "glBindSampler",
          "context = %d, unit = %u, sampler = %u", CID(context), unit, sampler);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        SamplerID samplerPacked                               = FromGL<SamplerID>(sampler);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateBindSampler(context, unit, samplerPacked));
        if (isCallValid)
        {
            context->bindSampler(unit, samplerPacked);
        }
        ANGLE_CAPTURE(BindSampler, isCallValid, context, unit, samplerPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY BindTextureContextANGLE(GLeglContext ctx, GLenum target, GLuint texture)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::BindTexture, "glBindTexture",
          "context = %d, target = %s, texture = %u", CID(context),
          GLenumToString(GLenumGroup::TextureTarget, target), texture);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        TextureID texturePacked                               = FromGL<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateBindTexture(context, targetPacked, texturePacked));
        if (isCallValid)
        {
            context->bindTexture(targetPacked, texturePacked);
        }
        ANGLE_CAPTURE(BindTexture, isCallValid, context, targetPacked, texturePacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY BindTransformFeedbackContextANGLE(GLeglContext ctx, GLenum target, GLuint id)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::BindTransformFeedback, "glBindTransformFeedback",
          "context = %d, target = %s, id = %u", CID(context),
          GLenumToString(GLenumGroup::BindTransformFeedbackTarget, target), id);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TransformFeedbackID idPacked                          = FromGL<TransformFeedbackID>(id);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateBindTransformFeedback(context, target, idPacked));
        if (isCallValid)
        {
            context->bindTransformFeedback(target, idPacked);
        }
        ANGLE_CAPTURE(BindTransformFeedback, isCallValid, context, target, idPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY BindVertexArrayContextANGLE(GLeglContext ctx, GLuint array)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::BindVertexArray, "glBindVertexArray", "context = %d, array = %u",
          CID(context), array);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        VertexArrayID arrayPacked                             = FromGL<VertexArrayID>(array);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateBindVertexArray(context, arrayPacked));
        if (isCallValid)
        {
            context->bindVertexArray(arrayPacked);
        }
        ANGLE_CAPTURE(BindVertexArray, isCallValid, context, arrayPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY BindVertexArrayOESContextANGLE(GLeglContext ctx, GLuint array)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::BindVertexArrayOES, "glBindVertexArrayOES",
          "context = %d, array = %u", CID(context), array);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        VertexArrayID arrayPacked                             = FromGL<VertexArrayID>(array);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateBindVertexArrayOES(context, arrayPacked));
        if (isCallValid)
        {
            context->bindVertexArray(arrayPacked);
        }
        ANGLE_CAPTURE(BindVertexArrayOES, isCallValid, context, arrayPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY BindVertexBufferContextANGLE(GLeglContext ctx,
                                              GLuint bindingindex,
                                              GLuint buffer,
                                              GLintptr offset,
                                              GLsizei stride)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::BindVertexBuffer, "glBindVertexBuffer",
          "context = %d, bindingindex = %u, buffer = %u, offset = %llu, stride = %d", CID(context),
          bindingindex, buffer, static_cast<unsigned long long>(offset), stride);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        BufferID bufferPacked                                 = FromGL<BufferID>(buffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateBindVertexBuffer(context, bindingindex, bufferPacked, offset, stride));
        if (isCallValid)
        {
            context->bindVertexBuffer(bindingindex, bufferPacked, offset, stride);
        }
        ANGLE_CAPTURE(BindVertexBuffer, isCallValid, context, bindingindex, bufferPacked, offset,
                      stride);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY BlendBarrierContextANGLE(GLeglContext ctx)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::BlendBarrier, "glBlendBarrier", "context = %d", CID(context));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateBlendBarrier(context));
        if (isCallValid)
        {
            context->blendBarrier();
        }
        ANGLE_CAPTURE(BlendBarrier, isCallValid, context);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY
BlendColorContextANGLE(GLeglContext ctx, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::BlendColor, "glBlendColor",
          "context = %d, red = %f, green = %f, blue = %f, alpha = %f", CID(context), red, green,
          blue, alpha);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateBlendColor(context, red, green, blue, alpha));
        if (isCallValid)
        {
            context->blendColor(red, green, blue, alpha);
        }
        ANGLE_CAPTURE(BlendColor, isCallValid, context, red, green, blue, alpha);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY BlendEquationContextANGLE(GLeglContext ctx, GLenum mode)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::BlendEquation, "glBlendEquation", "context = %d, mode = %s",
          CID(context), GLenumToString(GLenumGroup::BlendEquationModeEXT, mode));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateBlendEquation(context, mode));
        if (isCallValid)
        {
            context->blendEquation(mode);
        }
        ANGLE_CAPTURE(BlendEquation, isCallValid, context, mode);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY BlendEquationSeparateContextANGLE(GLeglContext ctx,
                                                   GLenum modeRGB,
                                                   GLenum modeAlpha)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::BlendEquationSeparate, "glBlendEquationSeparate",
          "context = %d, modeRGB = %s, modeAlpha = %s", CID(context),
          GLenumToString(GLenumGroup::BlendEquationModeEXT, modeRGB),
          GLenumToString(GLenumGroup::BlendEquationModeEXT, modeAlpha));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateBlendEquationSeparate(context, modeRGB, modeAlpha));
        if (isCallValid)
        {
            context->blendEquationSeparate(modeRGB, modeAlpha);
        }
        ANGLE_CAPTURE(BlendEquationSeparate, isCallValid, context, modeRGB, modeAlpha);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY BlendEquationSeparateiContextANGLE(GLeglContext ctx,
                                                    GLuint buf,
                                                    GLenum modeRGB,
                                                    GLenum modeAlpha)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::BlendEquationSeparatei, "glBlendEquationSeparatei",
          "context = %d, buf = %u, modeRGB = %s, modeAlpha = %s", CID(context), buf,
          GLenumToString(GLenumGroup::BlendEquationModeEXT, modeRGB),
          GLenumToString(GLenumGroup::BlendEquationModeEXT, modeAlpha));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateBlendEquationSeparatei(context, buf, modeRGB, modeAlpha));
        if (isCallValid)
        {
            context->blendEquationSeparatei(buf, modeRGB, modeAlpha);
        }
        ANGLE_CAPTURE(BlendEquationSeparatei, isCallValid, context, buf, modeRGB, modeAlpha);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY BlendEquationSeparateiEXTContextANGLE(GLeglContext ctx,
                                                       GLuint buf,
                                                       GLenum modeRGB,
                                                       GLenum modeAlpha)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::BlendEquationSeparateiEXT, "glBlendEquationSeparateiEXT",
          "context = %d, buf = %u, modeRGB = %s, modeAlpha = %s", CID(context), buf,
          GLenumToString(GLenumGroup::BlendEquationModeEXT, modeRGB),
          GLenumToString(GLenumGroup::BlendEquationModeEXT, modeAlpha));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateBlendEquationSeparateiEXT(context, buf, modeRGB, modeAlpha));
        if (isCallValid)
        {
            context->blendEquationSeparatei(buf, modeRGB, modeAlpha);
        }
        ANGLE_CAPTURE(BlendEquationSeparateiEXT, isCallValid, context, buf, modeRGB, modeAlpha);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY BlendEquationSeparateiOESContextANGLE(GLeglContext ctx,
                                                       GLuint buf,
                                                       GLenum modeRGB,
                                                       GLenum modeAlpha)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::BlendEquationSeparateiOES, "glBlendEquationSeparateiOES",
          "context = %d, buf = %u, modeRGB = %s, modeAlpha = %s", CID(context), buf,
          GLenumToString(GLenumGroup::BlendEquationModeEXT, modeRGB),
          GLenumToString(GLenumGroup::BlendEquationModeEXT, modeAlpha));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateBlendEquationSeparateiOES(context, buf, modeRGB, modeAlpha));
        if (isCallValid)
        {
            context->blendEquationSeparatei(buf, modeRGB, modeAlpha);
        }
        ANGLE_CAPTURE(BlendEquationSeparateiOES, isCallValid, context, buf, modeRGB, modeAlpha);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY BlendEquationiContextANGLE(GLeglContext ctx, GLuint buf, GLenum mode)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::BlendEquationi, "glBlendEquationi",
          "context = %d, buf = %u, mode = %s", CID(context), buf,
          GLenumToString(GLenumGroup::BlendEquationModeEXT, mode));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateBlendEquationi(context, buf, mode));
        if (isCallValid)
        {
            context->blendEquationi(buf, mode);
        }
        ANGLE_CAPTURE(BlendEquationi, isCallValid, context, buf, mode);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY BlendEquationiEXTContextANGLE(GLeglContext ctx, GLuint buf, GLenum mode)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::BlendEquationiEXT, "glBlendEquationiEXT",
          "context = %d, buf = %u, mode = %s", CID(context), buf,
          GLenumToString(GLenumGroup::BlendEquationModeEXT, mode));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateBlendEquationiEXT(context, buf, mode));
        if (isCallValid)
        {
            context->blendEquationi(buf, mode);
        }
        ANGLE_CAPTURE(BlendEquationiEXT, isCallValid, context, buf, mode);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY BlendEquationiOESContextANGLE(GLeglContext ctx, GLuint buf, GLenum mode)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::BlendEquationiOES, "glBlendEquationiOES",
          "context = %d, buf = %u, mode = %s", CID(context), buf,
          GLenumToString(GLenumGroup::BlendEquationModeEXT, mode));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateBlendEquationiOES(context, buf, mode));
        if (isCallValid)
        {
            context->blendEquationi(buf, mode);
        }
        ANGLE_CAPTURE(BlendEquationiOES, isCallValid, context, buf, mode);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY BlendFuncContextANGLE(GLeglContext ctx, GLenum sfactor, GLenum dfactor)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::BlendFunc, "glBlendFunc",
          "context = %d, sfactor = %s, dfactor = %s", CID(context),
          GLenumToString(GLenumGroup::BlendingFactor, sfactor),
          GLenumToString(GLenumGroup::BlendingFactor, dfactor));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateBlendFunc(context, sfactor, dfactor));
        if (isCallValid)
        {
            context->blendFunc(sfactor, dfactor);
        }
        ANGLE_CAPTURE(BlendFunc, isCallValid, context, sfactor, dfactor);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY BlendFuncSeparateContextANGLE(GLeglContext ctx,
                                               GLenum sfactorRGB,
                                               GLenum dfactorRGB,
                                               GLenum sfactorAlpha,
                                               GLenum dfactorAlpha)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::BlendFuncSeparate, "glBlendFuncSeparate",
          "context = %d, sfactorRGB = %s, dfactorRGB = %s, sfactorAlpha = %s, dfactorAlpha = %s",
          CID(context), GLenumToString(GLenumGroup::BlendingFactor, sfactorRGB),
          GLenumToString(GLenumGroup::BlendingFactor, dfactorRGB),
          GLenumToString(GLenumGroup::BlendingFactor, sfactorAlpha),
          GLenumToString(GLenumGroup::BlendingFactor, dfactorAlpha));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateBlendFuncSeparate(context, sfactorRGB, dfactorRGB,
                                                                    sfactorAlpha, dfactorAlpha));
        if (isCallValid)
        {
            context->blendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha);
        }
        ANGLE_CAPTURE(BlendFuncSeparate, isCallValid, context, sfactorRGB, dfactorRGB, sfactorAlpha,
                      dfactorAlpha);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY BlendFuncSeparateiContextANGLE(GLeglContext ctx,
                                                GLuint buf,
                                                GLenum srcRGB,
                                                GLenum dstRGB,
                                                GLenum srcAlpha,
                                                GLenum dstAlpha)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::BlendFuncSeparatei, "glBlendFuncSeparatei",
          "context = %d, buf = %u, srcRGB = %s, dstRGB = %s, srcAlpha = %s, dstAlpha = %s",
          CID(context), buf, GLenumToString(GLenumGroup::BlendingFactor, srcRGB),
          GLenumToString(GLenumGroup::BlendingFactor, dstRGB),
          GLenumToString(GLenumGroup::BlendingFactor, srcAlpha),
          GLenumToString(GLenumGroup::BlendingFactor, dstAlpha));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateBlendFuncSeparatei(context, buf, srcRGB, dstRGB, srcAlpha, dstAlpha));
        if (isCallValid)
        {
            context->blendFuncSeparatei(buf, srcRGB, dstRGB, srcAlpha, dstAlpha);
        }
        ANGLE_CAPTURE(BlendFuncSeparatei, isCallValid, context, buf, srcRGB, dstRGB, srcAlpha,
                      dstAlpha);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY BlendFuncSeparateiEXTContextANGLE(GLeglContext ctx,
                                                   GLuint buf,
                                                   GLenum srcRGB,
                                                   GLenum dstRGB,
                                                   GLenum srcAlpha,
                                                   GLenum dstAlpha)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::BlendFuncSeparateiEXT, "glBlendFuncSeparateiEXT",
          "context = %d, buf = %u, srcRGB = %s, dstRGB = %s, srcAlpha = %s, dstAlpha = %s",
          CID(context), buf, GLenumToString(GLenumGroup::BlendingFactor, srcRGB),
          GLenumToString(GLenumGroup::BlendingFactor, dstRGB),
          GLenumToString(GLenumGroup::BlendingFactor, srcAlpha),
          GLenumToString(GLenumGroup::BlendingFactor, dstAlpha));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateBlendFuncSeparateiEXT(context, buf, srcRGB, dstRGB, srcAlpha, dstAlpha));
        if (isCallValid)
        {
            context->blendFuncSeparatei(buf, srcRGB, dstRGB, srcAlpha, dstAlpha);
        }
        ANGLE_CAPTURE(BlendFuncSeparateiEXT, isCallValid, context, buf, srcRGB, dstRGB, srcAlpha,
                      dstAlpha);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY BlendFuncSeparateiOESContextANGLE(GLeglContext ctx,
                                                   GLuint buf,
                                                   GLenum srcRGB,
                                                   GLenum dstRGB,
                                                   GLenum srcAlpha,
                                                   GLenum dstAlpha)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::BlendFuncSeparateiOES, "glBlendFuncSeparateiOES",
          "context = %d, buf = %u, srcRGB = %s, dstRGB = %s, srcAlpha = %s, dstAlpha = %s",
          CID(context), buf, GLenumToString(GLenumGroup::BlendingFactor, srcRGB),
          GLenumToString(GLenumGroup::BlendingFactor, dstRGB),
          GLenumToString(GLenumGroup::BlendingFactor, srcAlpha),
          GLenumToString(GLenumGroup::BlendingFactor, dstAlpha));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateBlendFuncSeparateiOES(context, buf, srcRGB, dstRGB, srcAlpha, dstAlpha));
        if (isCallValid)
        {
            context->blendFuncSeparatei(buf, srcRGB, dstRGB, srcAlpha, dstAlpha);
        }
        ANGLE_CAPTURE(BlendFuncSeparateiOES, isCallValid, context, buf, srcRGB, dstRGB, srcAlpha,
                      dstAlpha);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY BlendFunciContextANGLE(GLeglContext ctx, GLuint buf, GLenum src, GLenum dst)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::BlendFunci, "glBlendFunci",
          "context = %d, buf = %u, src = %s, dst = %s", CID(context), buf,
          GLenumToString(GLenumGroup::BlendingFactor, src),
          GLenumToString(GLenumGroup::BlendingFactor, dst));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateBlendFunci(context, buf, src, dst));
        if (isCallValid)
        {
            context->blendFunci(buf, src, dst);
        }
        ANGLE_CAPTURE(BlendFunci, isCallValid, context, buf, src, dst);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY BlendFunciEXTContextANGLE(GLeglContext ctx, GLuint buf, GLenum src, GLenum dst)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::BlendFunciEXT, "glBlendFunciEXT",
          "context = %d, buf = %u, src = %s, dst = %s", CID(context), buf,
          GLenumToString(GLenumGroup::BlendingFactor, src),
          GLenumToString(GLenumGroup::BlendingFactor, dst));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateBlendFunciEXT(context, buf, src, dst));
        if (isCallValid)
        {
            context->blendFunci(buf, src, dst);
        }
        ANGLE_CAPTURE(BlendFunciEXT, isCallValid, context, buf, src, dst);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY BlendFunciOESContextANGLE(GLeglContext ctx, GLuint buf, GLenum src, GLenum dst)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::BlendFunciOES, "glBlendFunciOES",
          "context = %d, buf = %u, src = %s, dst = %s", CID(context), buf,
          GLenumToString(GLenumGroup::BlendingFactor, src),
          GLenumToString(GLenumGroup::BlendingFactor, dst));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateBlendFunciOES(context, buf, src, dst));
        if (isCallValid)
        {
            context->blendFunci(buf, src, dst);
        }
        ANGLE_CAPTURE(BlendFunciOES, isCallValid, context, buf, src, dst);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY BlitFramebufferContextANGLE(GLeglContext ctx,
                                             GLint srcX0,
                                             GLint srcY0,
                                             GLint srcX1,
                                             GLint srcY1,
                                             GLint dstX0,
                                             GLint dstY0,
                                             GLint dstX1,
                                             GLint dstY1,
                                             GLbitfield mask,
                                             GLenum filter)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::BlitFramebuffer, "glBlitFramebuffer",
          "context = %d, srcX0 = %d, srcY0 = %d, srcX1 = %d, srcY1 = %d, dstX0 = %d, dstY0 = %d, "
          "dstX1 = %d, dstY1 = %d, mask = %s, filter = %s",
          CID(context), srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1,
          GLbitfieldToString(GLenumGroup::ClearBufferMask, mask).c_str(),
          GLenumToString(GLenumGroup::BlitFramebufferFilter, filter));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateBlitFramebuffer(context, srcX0, srcY0, srcX1, srcY1, dstX0,
                                                    dstY0, dstX1, dstY1, mask, filter));
        if (isCallValid)
        {
            context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask,
                                     filter);
        }
        ANGLE_CAPTURE(BlitFramebuffer, isCallValid, context, srcX0, srcY0, srcX1, srcY1, dstX0,
                      dstY0, dstX1, dstY1, mask, filter);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY BlitFramebufferANGLEContextANGLE(GLeglContext ctx,
                                                  GLint srcX0,
                                                  GLint srcY0,
                                                  GLint srcX1,
                                                  GLint srcY1,
                                                  GLint dstX0,
                                                  GLint dstY0,
                                                  GLint dstX1,
                                                  GLint dstY1,
                                                  GLbitfield mask,
                                                  GLenum filter)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::BlitFramebufferANGLE, "glBlitFramebufferANGLE",
          "context = %d, srcX0 = %d, srcY0 = %d, srcX1 = %d, srcY1 = %d, dstX0 = %d, dstY0 = %d, "
          "dstX1 = %d, dstY1 = %d, mask = %s, filter = %s",
          CID(context), srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1,
          GLbitfieldToString(GLenumGroup::ClearBufferMask, mask).c_str(),
          GLenumToString(GLenumGroup::BlitFramebufferFilter, filter));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateBlitFramebufferANGLE(context, srcX0, srcY0, srcX1, srcY1, dstX0,
                                                         dstY0, dstX1, dstY1, mask, filter));
        if (isCallValid)
        {
            context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask,
                                     filter);
        }
        ANGLE_CAPTURE(BlitFramebufferANGLE, isCallValid, context, srcX0, srcY0, srcX1, srcY1, dstX0,
                      dstY0, dstX1, dstY1, mask, filter);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY BufferDataContextANGLE(GLeglContext ctx,
                                        GLenum target,
                                        GLsizeiptr size,
                                        const void *data,
                                        GLenum usage)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::BufferData, "glBufferData",
          "context = %d, target = %s, size = %llu, data = 0x%016" PRIxPTR ", usage = %s",
          CID(context), GLenumToString(GLenumGroup::BufferTargetARB, target),
          static_cast<unsigned long long>(size), (uintptr_t)data,
          GLenumToString(GLenumGroup::BufferUsageARB, usage));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        BufferBinding targetPacked                            = FromGL<BufferBinding>(target);
        BufferUsage usagePacked                               = FromGL<BufferUsage>(usage);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateBufferData(context, targetPacked, size, data, usagePacked));
        if (isCallValid)
        {
            context->bufferData(targetPacked, size, data, usagePacked);
        }
        ANGLE_CAPTURE(BufferData, isCallValid, context, targetPacked, size, data, usagePacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY BufferStorageEXTContextANGLE(GLeglContext ctx,
                                              GLenum target,
                                              GLsizeiptr size,
                                              const void *data,
                                              GLbitfield flags)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::BufferStorageEXT, "glBufferStorageEXT",
          "context = %d, target = %s, size = %llu, data = 0x%016" PRIxPTR ", flags = %s",
          CID(context), GLenumToString(GLenumGroup::BufferStorageTarget, target),
          static_cast<unsigned long long>(size), (uintptr_t)data,
          GLbitfieldToString(GLenumGroup::MapBufferUsageMask, flags).c_str());

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        BufferBinding targetPacked                            = FromGL<BufferBinding>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateBufferStorageEXT(context, targetPacked, size, data, flags));
        if (isCallValid)
        {
            context->bufferStorage(targetPacked, size, data, flags);
        }
        ANGLE_CAPTURE(BufferStorageEXT, isCallValid, context, targetPacked, size, data, flags);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY BufferStorageExternalEXTContextANGLE(GLeglContext ctx,
                                                      GLenum target,
                                                      GLintptr offset,
                                                      GLsizeiptr size,
                                                      GLeglClientBufferEXT clientBuffer,
                                                      GLbitfield flags)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::BufferStorageExternalEXT, "glBufferStorageExternalEXT",
          "context = %d, target = %s, offset = %llu, size = %llu, clientBuffer = 0x%016" PRIxPTR
          ", flags = %s",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target),
          static_cast<unsigned long long>(offset), static_cast<unsigned long long>(size),
          (uintptr_t)clientBuffer,
          GLbitfieldToString(GLenumGroup::MapBufferUsageMask, flags).c_str());

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        BufferBinding targetPacked                            = FromGL<BufferBinding>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateBufferStorageExternalEXT(context, targetPacked, offset, size,
                                                             clientBuffer, flags));
        if (isCallValid)
        {
            context->bufferStorageExternal(targetPacked, offset, size, clientBuffer, flags);
        }
        ANGLE_CAPTURE(BufferStorageExternalEXT, isCallValid, context, targetPacked, offset, size,
                      clientBuffer, flags);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY BufferStorageMemEXTContextANGLE(GLeglContext ctx,
                                                 GLenum target,
                                                 GLsizeiptr size,
                                                 GLuint memory,
                                                 GLuint64 offset)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::BufferStorageMemEXT, "glBufferStorageMemEXT",
          "context = %d, target = %s, size = %llu, memory = %u, offset = %llu", CID(context),
          GLenumToString(GLenumGroup::BufferTargetARB, target),
          static_cast<unsigned long long>(size), memory, static_cast<unsigned long long>(offset));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        MemoryObjectID memoryPacked                           = FromGL<MemoryObjectID>(memory);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateBufferStorageMemEXT(context, targetPacked, size, memoryPacked, offset));
        if (isCallValid)
        {
            context->bufferStorageMem(targetPacked, size, memoryPacked, offset);
        }
        ANGLE_CAPTURE(BufferStorageMemEXT, isCallValid, context, targetPacked, size, memoryPacked,
                      offset);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY BufferSubDataContextANGLE(GLeglContext ctx,
                                           GLenum target,
                                           GLintptr offset,
                                           GLsizeiptr size,
                                           const void *data)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::BufferSubData, "glBufferSubData",
          "context = %d, target = %s, offset = %llu, size = %llu, data = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::BufferTargetARB, target),
          static_cast<unsigned long long>(offset), static_cast<unsigned long long>(size),
          (uintptr_t)data);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        BufferBinding targetPacked                            = FromGL<BufferBinding>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateBufferSubData(context, targetPacked, offset, size, data));
        if (isCallValid)
        {
            context->bufferSubData(targetPacked, offset, size, data);
        }
        ANGLE_CAPTURE(BufferSubData, isCallValid, context, targetPacked, offset, size, data);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

GLenum GL_APIENTRY CheckFramebufferStatusContextANGLE(GLeglContext ctx, GLenum target)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::CheckFramebufferStatus, "glCheckFramebufferStatus",
          "context = %d, target = %s", CID(context),
          GLenumToString(GLenumGroup::FramebufferTarget, target));

    GLenum returnValue;
    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateCheckFramebufferStatus(context, target));
        if (isCallValid)
        {
            returnValue = context->checkFramebufferStatus(target);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::CheckFramebufferStatus, GLenum>();
        }
        ANGLE_CAPTURE(CheckFramebufferStatus, isCallValid, context, target, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
        returnValue = GetDefaultReturnValue<EntryPoint::CheckFramebufferStatus, GLenum>();
    }
    return returnValue;
}

GLenum GL_APIENTRY CheckFramebufferStatusOESContextANGLE(GLeglContext ctx, GLenum target)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::CheckFramebufferStatusOES, "glCheckFramebufferStatusOES",
          "context = %d, target = %s", CID(context),
          GLenumToString(GLenumGroup::FramebufferTarget, target));

    GLenum returnValue;
    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateCheckFramebufferStatusOES(context, target));
        if (isCallValid)
        {
            returnValue = context->checkFramebufferStatus(target);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::CheckFramebufferStatusOES, GLenum>();
        }
        ANGLE_CAPTURE(CheckFramebufferStatusOES, isCallValid, context, target, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
        returnValue = GetDefaultReturnValue<EntryPoint::CheckFramebufferStatusOES, GLenum>();
    }
    return returnValue;
}

void GL_APIENTRY ClearContextANGLE(GLeglContext ctx, GLbitfield mask)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Clear, "glClear", "context = %d, mask = %s", CID(context),
          GLbitfieldToString(GLenumGroup::ClearBufferMask, mask).c_str());

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateClear(context, mask));
        if (isCallValid)
        {
            context->clear(mask);
        }
        ANGLE_CAPTURE(Clear, isCallValid, context, mask);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ClearBufferfiContextANGLE(GLeglContext ctx,
                                           GLenum buffer,
                                           GLint drawbuffer,
                                           GLfloat depth,
                                           GLint stencil)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ClearBufferfi, "glClearBufferfi",
          "context = %d, buffer = %s, drawbuffer = %d, depth = %f, stencil = %d", CID(context),
          GLenumToString(GLenumGroup::Buffer, buffer), drawbuffer, depth, stencil);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateClearBufferfi(context, buffer, drawbuffer, depth, stencil));
        if (isCallValid)
        {
            context->clearBufferfi(buffer, drawbuffer, depth, stencil);
        }
        ANGLE_CAPTURE(ClearBufferfi, isCallValid, context, buffer, drawbuffer, depth, stencil);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ClearBufferfvContextANGLE(GLeglContext ctx,
                                           GLenum buffer,
                                           GLint drawbuffer,
                                           const GLfloat *value)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ClearBufferfv, "glClearBufferfv",
          "context = %d, buffer = %s, drawbuffer = %d, value = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::Buffer, buffer), drawbuffer, (uintptr_t)value);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateClearBufferfv(context, buffer, drawbuffer, value));
        if (isCallValid)
        {
            context->clearBufferfv(buffer, drawbuffer, value);
        }
        ANGLE_CAPTURE(ClearBufferfv, isCallValid, context, buffer, drawbuffer, value);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ClearBufferivContextANGLE(GLeglContext ctx,
                                           GLenum buffer,
                                           GLint drawbuffer,
                                           const GLint *value)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ClearBufferiv, "glClearBufferiv",
          "context = %d, buffer = %s, drawbuffer = %d, value = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::Buffer, buffer), drawbuffer, (uintptr_t)value);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateClearBufferiv(context, buffer, drawbuffer, value));
        if (isCallValid)
        {
            context->clearBufferiv(buffer, drawbuffer, value);
        }
        ANGLE_CAPTURE(ClearBufferiv, isCallValid, context, buffer, drawbuffer, value);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ClearBufferuivContextANGLE(GLeglContext ctx,
                                            GLenum buffer,
                                            GLint drawbuffer,
                                            const GLuint *value)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ClearBufferuiv, "glClearBufferuiv",
          "context = %d, buffer = %s, drawbuffer = %d, value = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::Buffer, buffer), drawbuffer, (uintptr_t)value);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateClearBufferuiv(context, buffer, drawbuffer, value));
        if (isCallValid)
        {
            context->clearBufferuiv(buffer, drawbuffer, value);
        }
        ANGLE_CAPTURE(ClearBufferuiv, isCallValid, context, buffer, drawbuffer, value);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY
ClearColorContextANGLE(GLeglContext ctx, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ClearColor, "glClearColor",
          "context = %d, red = %f, green = %f, blue = %f, alpha = %f", CID(context), red, green,
          blue, alpha);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateClearColor(context, red, green, blue, alpha));
        if (isCallValid)
        {
            context->clearColor(red, green, blue, alpha);
        }
        ANGLE_CAPTURE(ClearColor, isCallValid, context, red, green, blue, alpha);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY
ClearColorxContextANGLE(GLeglContext ctx, GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ClearColorx, "glClearColorx",
          "context = %d, red = 0x%X, green = 0x%X, blue = 0x%X, alpha = 0x%X", CID(context), red,
          green, blue, alpha);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateClearColorx(context, red, green, blue, alpha));
        if (isCallValid)
        {
            context->clearColorx(red, green, blue, alpha);
        }
        ANGLE_CAPTURE(ClearColorx, isCallValid, context, red, green, blue, alpha);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ClearDepthfContextANGLE(GLeglContext ctx, GLfloat d)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ClearDepthf, "glClearDepthf", "context = %d, d = %f",
          CID(context), d);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateClearDepthf(context, d));
        if (isCallValid)
        {
            context->clearDepthf(d);
        }
        ANGLE_CAPTURE(ClearDepthf, isCallValid, context, d);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ClearDepthxContextANGLE(GLeglContext ctx, GLfixed depth)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ClearDepthx, "glClearDepthx", "context = %d, depth = 0x%X",
          CID(context), depth);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateClearDepthx(context, depth));
        if (isCallValid)
        {
            context->clearDepthx(depth);
        }
        ANGLE_CAPTURE(ClearDepthx, isCallValid, context, depth);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ClearStencilContextANGLE(GLeglContext ctx, GLint s)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ClearStencil, "glClearStencil", "context = %d, s = %d",
          CID(context), s);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateClearStencil(context, s));
        if (isCallValid)
        {
            context->clearStencil(s);
        }
        ANGLE_CAPTURE(ClearStencil, isCallValid, context, s);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ClientActiveTextureContextANGLE(GLeglContext ctx, GLenum texture)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ClientActiveTexture, "glClientActiveTexture",
          "context = %d, texture = %s", CID(context),
          GLenumToString(GLenumGroup::TextureUnit, texture));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateClientActiveTexture(context, texture));
        if (isCallValid)
        {
            context->clientActiveTexture(texture);
        }
        ANGLE_CAPTURE(ClientActiveTexture, isCallValid, context, texture);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

GLenum GL_APIENTRY ClientWaitSyncContextANGLE(GLeglContext ctx,
                                              GLsync sync,
                                              GLbitfield flags,
                                              GLuint64 timeout)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ClientWaitSync, "glClientWaitSync",
          "context = %d, sync = 0x%016" PRIxPTR ", flags = %s, timeout = %llu", CID(context),
          (uintptr_t)sync, GLbitfieldToString(GLenumGroup::SyncObjectMask, flags).c_str(),
          static_cast<unsigned long long>(timeout));

    GLenum returnValue;
    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateClientWaitSync(context, sync, flags, timeout));
        if (isCallValid)
        {
            returnValue = context->clientWaitSync(sync, flags, timeout);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::ClientWaitSync, GLenum>();
        }
        ANGLE_CAPTURE(ClientWaitSync, isCallValid, context, sync, flags, timeout, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
        returnValue = GetDefaultReturnValue<EntryPoint::ClientWaitSync, GLenum>();
    }
    return returnValue;
}

void GL_APIENTRY ClipPlanefContextANGLE(GLeglContext ctx, GLenum p, const GLfloat *eqn)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ClipPlanef, "glClipPlanef",
          "context = %d, p = %s, eqn = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::ClipPlaneName, p), (uintptr_t)eqn);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateClipPlanef(context, p, eqn));
        if (isCallValid)
        {
            context->clipPlanef(p, eqn);
        }
        ANGLE_CAPTURE(ClipPlanef, isCallValid, context, p, eqn);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ClipPlanexContextANGLE(GLeglContext ctx, GLenum plane, const GLfixed *equation)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ClipPlanex, "glClipPlanex",
          "context = %d, plane = %s, equation = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::ClipPlaneName, plane), (uintptr_t)equation);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateClipPlanex(context, plane, equation));
        if (isCallValid)
        {
            context->clipPlanex(plane, equation);
        }
        ANGLE_CAPTURE(ClipPlanex, isCallValid, context, plane, equation);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY
Color4fContextANGLE(GLeglContext ctx, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Color4f, "glColor4f",
          "context = %d, red = %f, green = %f, blue = %f, alpha = %f", CID(context), red, green,
          blue, alpha);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateColor4f(context, red, green, blue, alpha));
        if (isCallValid)
        {
            context->color4f(red, green, blue, alpha);
        }
        ANGLE_CAPTURE(Color4f, isCallValid, context, red, green, blue, alpha);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY
Color4ubContextANGLE(GLeglContext ctx, GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Color4ub, "glColor4ub",
          "context = %d, red = %d, green = %d, blue = %d, alpha = %d", CID(context), red, green,
          blue, alpha);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateColor4ub(context, red, green, blue, alpha));
        if (isCallValid)
        {
            context->color4ub(red, green, blue, alpha);
        }
        ANGLE_CAPTURE(Color4ub, isCallValid, context, red, green, blue, alpha);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY
Color4xContextANGLE(GLeglContext ctx, GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Color4x, "glColor4x",
          "context = %d, red = 0x%X, green = 0x%X, blue = 0x%X, alpha = 0x%X", CID(context), red,
          green, blue, alpha);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateColor4x(context, red, green, blue, alpha));
        if (isCallValid)
        {
            context->color4x(red, green, blue, alpha);
        }
        ANGLE_CAPTURE(Color4x, isCallValid, context, red, green, blue, alpha);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ColorMaskContextANGLE(GLeglContext ctx,
                                       GLboolean red,
                                       GLboolean green,
                                       GLboolean blue,
                                       GLboolean alpha)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ColorMask, "glColorMask",
          "context = %d, red = %s, green = %s, blue = %s, alpha = %s", CID(context),
          GLbooleanToString(red), GLbooleanToString(green), GLbooleanToString(blue),
          GLbooleanToString(alpha));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateColorMask(context, red, green, blue, alpha));
        if (isCallValid)
        {
            context->colorMask(red, green, blue, alpha);
        }
        ANGLE_CAPTURE(ColorMask, isCallValid, context, red, green, blue, alpha);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ColorMaskiContextANGLE(GLeglContext ctx,
                                        GLuint index,
                                        GLboolean r,
                                        GLboolean g,
                                        GLboolean b,
                                        GLboolean a)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ColorMaski, "glColorMaski",
          "context = %d, index = %u, r = %s, g = %s, b = %s, a = %s", CID(context), index,
          GLbooleanToString(r), GLbooleanToString(g), GLbooleanToString(b), GLbooleanToString(a));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateColorMaski(context, index, r, g, b, a));
        if (isCallValid)
        {
            context->colorMaski(index, r, g, b, a);
        }
        ANGLE_CAPTURE(ColorMaski, isCallValid, context, index, r, g, b, a);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ColorMaskiEXTContextANGLE(GLeglContext ctx,
                                           GLuint index,
                                           GLboolean r,
                                           GLboolean g,
                                           GLboolean b,
                                           GLboolean a)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ColorMaskiEXT, "glColorMaskiEXT",
          "context = %d, index = %u, r = %s, g = %s, b = %s, a = %s", CID(context), index,
          GLbooleanToString(r), GLbooleanToString(g), GLbooleanToString(b), GLbooleanToString(a));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateColorMaskiEXT(context, index, r, g, b, a));
        if (isCallValid)
        {
            context->colorMaski(index, r, g, b, a);
        }
        ANGLE_CAPTURE(ColorMaskiEXT, isCallValid, context, index, r, g, b, a);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ColorMaskiOESContextANGLE(GLeglContext ctx,
                                           GLuint index,
                                           GLboolean r,
                                           GLboolean g,
                                           GLboolean b,
                                           GLboolean a)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ColorMaskiOES, "glColorMaskiOES",
          "context = %d, index = %u, r = %s, g = %s, b = %s, a = %s", CID(context), index,
          GLbooleanToString(r), GLbooleanToString(g), GLbooleanToString(b), GLbooleanToString(a));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateColorMaskiOES(context, index, r, g, b, a));
        if (isCallValid)
        {
            context->colorMaski(index, r, g, b, a);
        }
        ANGLE_CAPTURE(ColorMaskiOES, isCallValid, context, index, r, g, b, a);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ColorPointerContextANGLE(GLeglContext ctx,
                                          GLint size,
                                          GLenum type,
                                          GLsizei stride,
                                          const void *pointer)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ColorPointer, "glColorPointer",
          "context = %d, size = %d, type = %s, stride = %d, pointer = 0x%016" PRIxPTR "",
          CID(context), size, GLenumToString(GLenumGroup::ColorPointerType, type), stride,
          (uintptr_t)pointer);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        VertexAttribType typePacked                           = FromGL<VertexAttribType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateColorPointer(context, size, typePacked, stride, pointer));
        if (isCallValid)
        {
            context->colorPointer(size, typePacked, stride, pointer);
        }
        ANGLE_CAPTURE(ColorPointer, isCallValid, context, size, typePacked, stride, pointer);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY CompileShaderContextANGLE(GLeglContext ctx, GLuint shader)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::CompileShader, "glCompileShader", "context = %d, shader = %u",
          CID(context), shader);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID shaderPacked                          = FromGL<ShaderProgramID>(shader);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateCompileShader(context, shaderPacked));
        if (isCallValid)
        {
            context->compileShader(shaderPacked);
        }
        ANGLE_CAPTURE(CompileShader, isCallValid, context, shaderPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY CompressedTexImage2DContextANGLE(GLeglContext ctx,
                                                  GLenum target,
                                                  GLint level,
                                                  GLenum internalformat,
                                                  GLsizei width,
                                                  GLsizei height,
                                                  GLint border,
                                                  GLsizei imageSize,
                                                  const void *data)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::CompressedTexImage2D, "glCompressedTexImage2D",
          "context = %d, target = %s, level = %d, internalformat = %s, width = %d, height = %d, "
          "border = %d, imageSize = %d, data = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), level,
          GLenumToString(GLenumGroup::InternalFormat, internalformat), width, height, border,
          imageSize, (uintptr_t)data);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateCompressedTexImage2D(context, targetPacked, level, internalformat, width,
                                          height, border, imageSize, data));
        if (isCallValid)
        {
            context->compressedTexImage2D(targetPacked, level, internalformat, width, height,
                                          border, imageSize, data);
        }
        ANGLE_CAPTURE(CompressedTexImage2D, isCallValid, context, targetPacked, level,
                      internalformat, width, height, border, imageSize, data);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY CompressedTexImage3DContextANGLE(GLeglContext ctx,
                                                  GLenum target,
                                                  GLint level,
                                                  GLenum internalformat,
                                                  GLsizei width,
                                                  GLsizei height,
                                                  GLsizei depth,
                                                  GLint border,
                                                  GLsizei imageSize,
                                                  const void *data)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::CompressedTexImage3D, "glCompressedTexImage3D",
          "context = %d, target = %s, level = %d, internalformat = %s, width = %d, height = %d, "
          "depth = %d, border = %d, imageSize = %d, data = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), level,
          GLenumToString(GLenumGroup::InternalFormat, internalformat), width, height, depth, border,
          imageSize, (uintptr_t)data);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateCompressedTexImage3D(context, targetPacked, level, internalformat, width,
                                          height, depth, border, imageSize, data));
        if (isCallValid)
        {
            context->compressedTexImage3D(targetPacked, level, internalformat, width, height, depth,
                                          border, imageSize, data);
        }
        ANGLE_CAPTURE(CompressedTexImage3D, isCallValid, context, targetPacked, level,
                      internalformat, width, height, depth, border, imageSize, data);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY CompressedTexImage3DOESContextANGLE(GLeglContext ctx,
                                                     GLenum target,
                                                     GLint level,
                                                     GLenum internalformat,
                                                     GLsizei width,
                                                     GLsizei height,
                                                     GLsizei depth,
                                                     GLint border,
                                                     GLsizei imageSize,
                                                     const void *data)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::CompressedTexImage3DOES, "glCompressedTexImage3DOES",
          "context = %d, target = %s, level = %d, internalformat = %s, width = %d, height = %d, "
          "depth = %d, border = %d, imageSize = %d, data = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), level,
          GLenumToString(GLenumGroup::InternalFormat, internalformat), width, height, depth, border,
          imageSize, (uintptr_t)data);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateCompressedTexImage3DOES(context, targetPacked, level, internalformat, width,
                                             height, depth, border, imageSize, data));
        if (isCallValid)
        {
            context->compressedTexImage3D(targetPacked, level, internalformat, width, height, depth,
                                          border, imageSize, data);
        }
        ANGLE_CAPTURE(CompressedTexImage3DOES, isCallValid, context, targetPacked, level,
                      internalformat, width, height, depth, border, imageSize, data);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY CompressedTexSubImage2DContextANGLE(GLeglContext ctx,
                                                     GLenum target,
                                                     GLint level,
                                                     GLint xoffset,
                                                     GLint yoffset,
                                                     GLsizei width,
                                                     GLsizei height,
                                                     GLenum format,
                                                     GLsizei imageSize,
                                                     const void *data)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::CompressedTexSubImage2D, "glCompressedTexSubImage2D",
          "context = %d, target = %s, level = %d, xoffset = %d, yoffset = %d, width = %d, height = "
          "%d, format = %s, imageSize = %d, data = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), level, xoffset, yoffset,
          width, height, GLenumToString(GLenumGroup::PixelFormat, format), imageSize,
          (uintptr_t)data);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateCompressedTexSubImage2D(context, targetPacked, level, xoffset, yoffset, width,
                                             height, format, imageSize, data));
        if (isCallValid)
        {
            context->compressedTexSubImage2D(targetPacked, level, xoffset, yoffset, width, height,
                                             format, imageSize, data);
        }
        ANGLE_CAPTURE(CompressedTexSubImage2D, isCallValid, context, targetPacked, level, xoffset,
                      yoffset, width, height, format, imageSize, data);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY CompressedTexSubImage3DContextANGLE(GLeglContext ctx,
                                                     GLenum target,
                                                     GLint level,
                                                     GLint xoffset,
                                                     GLint yoffset,
                                                     GLint zoffset,
                                                     GLsizei width,
                                                     GLsizei height,
                                                     GLsizei depth,
                                                     GLenum format,
                                                     GLsizei imageSize,
                                                     const void *data)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::CompressedTexSubImage3D, "glCompressedTexSubImage3D",
          "context = %d, target = %s, level = %d, xoffset = %d, yoffset = %d, zoffset = %d, width "
          "= %d, height = %d, depth = %d, format = %s, imageSize = %d, data = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), level, xoffset, yoffset,
          zoffset, width, height, depth, GLenumToString(GLenumGroup::PixelFormat, format),
          imageSize, (uintptr_t)data);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateCompressedTexSubImage3D(context, targetPacked, level, xoffset,
                                                            yoffset, zoffset, width, height, depth,
                                                            format, imageSize, data));
        if (isCallValid)
        {
            context->compressedTexSubImage3D(targetPacked, level, xoffset, yoffset, zoffset, width,
                                             height, depth, format, imageSize, data);
        }
        ANGLE_CAPTURE(CompressedTexSubImage3D, isCallValid, context, targetPacked, level, xoffset,
                      yoffset, zoffset, width, height, depth, format, imageSize, data);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY CompressedTexSubImage3DOESContextANGLE(GLeglContext ctx,
                                                        GLenum target,
                                                        GLint level,
                                                        GLint xoffset,
                                                        GLint yoffset,
                                                        GLint zoffset,
                                                        GLsizei width,
                                                        GLsizei height,
                                                        GLsizei depth,
                                                        GLenum format,
                                                        GLsizei imageSize,
                                                        const void *data)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::CompressedTexSubImage3DOES, "glCompressedTexSubImage3DOES",
          "context = %d, target = %s, level = %d, xoffset = %d, yoffset = %d, zoffset = %d, width "
          "= %d, height = %d, depth = %d, format = %s, imageSize = %d, data = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), level, xoffset, yoffset,
          zoffset, width, height, depth, GLenumToString(GLenumGroup::PixelFormat, format),
          imageSize, (uintptr_t)data);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateCompressedTexSubImage3DOES(
                                context, targetPacked, level, xoffset, yoffset, zoffset, width,
                                height, depth, format, imageSize, data));
        if (isCallValid)
        {
            context->compressedTexSubImage3D(targetPacked, level, xoffset, yoffset, zoffset, width,
                                             height, depth, format, imageSize, data);
        }
        ANGLE_CAPTURE(CompressedTexSubImage3DOES, isCallValid, context, targetPacked, level,
                      xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY CopyBufferSubDataContextANGLE(GLeglContext ctx,
                                               GLenum readTarget,
                                               GLenum writeTarget,
                                               GLintptr readOffset,
                                               GLintptr writeOffset,
                                               GLsizeiptr size)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::CopyBufferSubData, "glCopyBufferSubData",
          "context = %d, readTarget = %s, writeTarget = %s, readOffset = %llu, writeOffset = %llu, "
          "size = %llu",
          CID(context), GLenumToString(GLenumGroup::CopyBufferSubDataTarget, readTarget),
          GLenumToString(GLenumGroup::CopyBufferSubDataTarget, writeTarget),
          static_cast<unsigned long long>(readOffset), static_cast<unsigned long long>(writeOffset),
          static_cast<unsigned long long>(size));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        BufferBinding readTargetPacked                        = FromGL<BufferBinding>(readTarget);
        BufferBinding writeTargetPacked                       = FromGL<BufferBinding>(writeTarget);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateCopyBufferSubData(context, readTargetPacked, writeTargetPacked,
                                                      readOffset, writeOffset, size));
        if (isCallValid)
        {
            context->copyBufferSubData(readTargetPacked, writeTargetPacked, readOffset, writeOffset,
                                       size);
        }
        ANGLE_CAPTURE(CopyBufferSubData, isCallValid, context, readTargetPacked, writeTargetPacked,
                      readOffset, writeOffset, size);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY CopyImageSubDataContextANGLE(GLeglContext ctx,
                                              GLuint srcName,
                                              GLenum srcTarget,
                                              GLint srcLevel,
                                              GLint srcX,
                                              GLint srcY,
                                              GLint srcZ,
                                              GLuint dstName,
                                              GLenum dstTarget,
                                              GLint dstLevel,
                                              GLint dstX,
                                              GLint dstY,
                                              GLint dstZ,
                                              GLsizei srcWidth,
                                              GLsizei srcHeight,
                                              GLsizei srcDepth)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::CopyImageSubData, "glCopyImageSubData",
          "context = %d, srcName = %u, srcTarget = %s, srcLevel = %d, srcX = %d, srcY = %d, srcZ = "
          "%d, dstName = %u, dstTarget = %s, dstLevel = %d, dstX = %d, dstY = %d, dstZ = %d, "
          "srcWidth = %d, srcHeight = %d, srcDepth = %d",
          CID(context), srcName, GLenumToString(GLenumGroup::CopyBufferSubDataTarget, srcTarget),
          srcLevel, srcX, srcY, srcZ, dstName,
          GLenumToString(GLenumGroup::CopyBufferSubDataTarget, dstTarget), dstLevel, dstX, dstY,
          dstZ, srcWidth, srcHeight, srcDepth);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateCopyImageSubData(context, srcName, srcTarget, srcLevel, srcX,
                                                     srcY, srcZ, dstName, dstTarget, dstLevel, dstX,
                                                     dstY, dstZ, srcWidth, srcHeight, srcDepth));
        if (isCallValid)
        {
            context->copyImageSubData(srcName, srcTarget, srcLevel, srcX, srcY, srcZ, dstName,
                                      dstTarget, dstLevel, dstX, dstY, dstZ, srcWidth, srcHeight,
                                      srcDepth);
        }
        ANGLE_CAPTURE(CopyImageSubData, isCallValid, context, srcName, srcTarget, srcLevel, srcX,
                      srcY, srcZ, dstName, dstTarget, dstLevel, dstX, dstY, dstZ, srcWidth,
                      srcHeight, srcDepth);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY CopyImageSubDataEXTContextANGLE(GLeglContext ctx,
                                                 GLuint srcName,
                                                 GLenum srcTarget,
                                                 GLint srcLevel,
                                                 GLint srcX,
                                                 GLint srcY,
                                                 GLint srcZ,
                                                 GLuint dstName,
                                                 GLenum dstTarget,
                                                 GLint dstLevel,
                                                 GLint dstX,
                                                 GLint dstY,
                                                 GLint dstZ,
                                                 GLsizei srcWidth,
                                                 GLsizei srcHeight,
                                                 GLsizei srcDepth)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::CopyImageSubDataEXT, "glCopyImageSubDataEXT",
          "context = %d, srcName = %u, srcTarget = %s, srcLevel = %d, srcX = %d, srcY = %d, srcZ = "
          "%d, dstName = %u, dstTarget = %s, dstLevel = %d, dstX = %d, dstY = %d, dstZ = %d, "
          "srcWidth = %d, srcHeight = %d, srcDepth = %d",
          CID(context), srcName, GLenumToString(GLenumGroup::CopyBufferSubDataTarget, srcTarget),
          srcLevel, srcX, srcY, srcZ, dstName,
          GLenumToString(GLenumGroup::CopyBufferSubDataTarget, dstTarget), dstLevel, dstX, dstY,
          dstZ, srcWidth, srcHeight, srcDepth);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateCopyImageSubDataEXT(context, srcName, srcTarget, srcLevel, srcX, srcY, srcZ,
                                         dstName, dstTarget, dstLevel, dstX, dstY, dstZ, srcWidth,
                                         srcHeight, srcDepth));
        if (isCallValid)
        {
            context->copyImageSubData(srcName, srcTarget, srcLevel, srcX, srcY, srcZ, dstName,
                                      dstTarget, dstLevel, dstX, dstY, dstZ, srcWidth, srcHeight,
                                      srcDepth);
        }
        ANGLE_CAPTURE(CopyImageSubDataEXT, isCallValid, context, srcName, srcTarget, srcLevel, srcX,
                      srcY, srcZ, dstName, dstTarget, dstLevel, dstX, dstY, dstZ, srcWidth,
                      srcHeight, srcDepth);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY CopyImageSubDataOESContextANGLE(GLeglContext ctx,
                                                 GLuint srcName,
                                                 GLenum srcTarget,
                                                 GLint srcLevel,
                                                 GLint srcX,
                                                 GLint srcY,
                                                 GLint srcZ,
                                                 GLuint dstName,
                                                 GLenum dstTarget,
                                                 GLint dstLevel,
                                                 GLint dstX,
                                                 GLint dstY,
                                                 GLint dstZ,
                                                 GLsizei srcWidth,
                                                 GLsizei srcHeight,
                                                 GLsizei srcDepth)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::CopyImageSubDataOES, "glCopyImageSubDataOES",
          "context = %d, srcName = %u, srcTarget = %s, srcLevel = %d, srcX = %d, srcY = %d, srcZ = "
          "%d, dstName = %u, dstTarget = %s, dstLevel = %d, dstX = %d, dstY = %d, dstZ = %d, "
          "srcWidth = %d, srcHeight = %d, srcDepth = %d",
          CID(context), srcName, GLenumToString(GLenumGroup::CopyBufferSubDataTarget, srcTarget),
          srcLevel, srcX, srcY, srcZ, dstName,
          GLenumToString(GLenumGroup::CopyBufferSubDataTarget, dstTarget), dstLevel, dstX, dstY,
          dstZ, srcWidth, srcHeight, srcDepth);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateCopyImageSubDataOES(context, srcName, srcTarget, srcLevel, srcX, srcY, srcZ,
                                         dstName, dstTarget, dstLevel, dstX, dstY, dstZ, srcWidth,
                                         srcHeight, srcDepth));
        if (isCallValid)
        {
            context->copyImageSubData(srcName, srcTarget, srcLevel, srcX, srcY, srcZ, dstName,
                                      dstTarget, dstLevel, dstX, dstY, dstZ, srcWidth, srcHeight,
                                      srcDepth);
        }
        ANGLE_CAPTURE(CopyImageSubDataOES, isCallValid, context, srcName, srcTarget, srcLevel, srcX,
                      srcY, srcZ, dstName, dstTarget, dstLevel, dstX, dstY, dstZ, srcWidth,
                      srcHeight, srcDepth);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY CopyTexImage2DContextANGLE(GLeglContext ctx,
                                            GLenum target,
                                            GLint level,
                                            GLenum internalformat,
                                            GLint x,
                                            GLint y,
                                            GLsizei width,
                                            GLsizei height,
                                            GLint border)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::CopyTexImage2D, "glCopyTexImage2D",
          "context = %d, target = %s, level = %d, internalformat = %s, x = %d, y = %d, width = %d, "
          "height = %d, border = %d",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), level,
          GLenumToString(GLenumGroup::InternalFormat, internalformat), x, y, width, height, border);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateCopyTexImage2D(context, targetPacked, level, internalformat, x,
                                                   y, width, height, border));
        if (isCallValid)
        {
            context->copyTexImage2D(targetPacked, level, internalformat, x, y, width, height,
                                    border);
        }
        ANGLE_CAPTURE(CopyTexImage2D, isCallValid, context, targetPacked, level, internalformat, x,
                      y, width, height, border);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY CopyTexSubImage2DContextANGLE(GLeglContext ctx,
                                               GLenum target,
                                               GLint level,
                                               GLint xoffset,
                                               GLint yoffset,
                                               GLint x,
                                               GLint y,
                                               GLsizei width,
                                               GLsizei height)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::CopyTexSubImage2D, "glCopyTexSubImage2D",
          "context = %d, target = %s, level = %d, xoffset = %d, yoffset = %d, x = %d, y = %d, "
          "width = %d, height = %d",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), level, xoffset, yoffset,
          x, y, width, height);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateCopyTexSubImage2D(context, targetPacked, level, xoffset,
                                                      yoffset, x, y, width, height));
        if (isCallValid)
        {
            context->copyTexSubImage2D(targetPacked, level, xoffset, yoffset, x, y, width, height);
        }
        ANGLE_CAPTURE(CopyTexSubImage2D, isCallValid, context, targetPacked, level, xoffset,
                      yoffset, x, y, width, height);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY CopyTexSubImage3DContextANGLE(GLeglContext ctx,
                                               GLenum target,
                                               GLint level,
                                               GLint xoffset,
                                               GLint yoffset,
                                               GLint zoffset,
                                               GLint x,
                                               GLint y,
                                               GLsizei width,
                                               GLsizei height)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::CopyTexSubImage3D, "glCopyTexSubImage3D",
          "context = %d, target = %s, level = %d, xoffset = %d, yoffset = %d, zoffset = %d, x = "
          "%d, y = %d, width = %d, height = %d",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), level, xoffset, yoffset,
          zoffset, x, y, width, height);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateCopyTexSubImage3D(context, targetPacked, level, xoffset,
                                                      yoffset, zoffset, x, y, width, height));
        if (isCallValid)
        {
            context->copyTexSubImage3D(targetPacked, level, xoffset, yoffset, zoffset, x, y, width,
                                       height);
        }
        ANGLE_CAPTURE(CopyTexSubImage3D, isCallValid, context, targetPacked, level, xoffset,
                      yoffset, zoffset, x, y, width, height);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY CopyTexSubImage3DOESContextANGLE(GLeglContext ctx,
                                                  GLenum target,
                                                  GLint level,
                                                  GLint xoffset,
                                                  GLint yoffset,
                                                  GLint zoffset,
                                                  GLint x,
                                                  GLint y,
                                                  GLsizei width,
                                                  GLsizei height)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::CopyTexSubImage3DOES, "glCopyTexSubImage3DOES",
          "context = %d, target = %s, level = %d, xoffset = %d, yoffset = %d, zoffset = %d, x = "
          "%d, y = %d, width = %d, height = %d",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target), level, xoffset, yoffset,
          zoffset, x, y, width, height);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateCopyTexSubImage3DOES(context, targetPacked, level, xoffset,
                                                         yoffset, zoffset, x, y, width, height));
        if (isCallValid)
        {
            context->copyTexSubImage3D(targetPacked, level, xoffset, yoffset, zoffset, x, y, width,
                                       height);
        }
        ANGLE_CAPTURE(CopyTexSubImage3DOES, isCallValid, context, targetPacked, level, xoffset,
                      yoffset, zoffset, x, y, width, height);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY CreateMemoryObjectsEXTContextANGLE(GLeglContext ctx,
                                                    GLsizei n,
                                                    GLuint *memoryObjects)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::CreateMemoryObjectsEXT, "glCreateMemoryObjectsEXT",
          "context = %d, n = %d, memoryObjects = 0x%016" PRIxPTR "", CID(context), n,
          (uintptr_t)memoryObjects);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        MemoryObjectID *memoryObjectsPacked = FromGL<MemoryObjectID *>(memoryObjects);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateCreateMemoryObjectsEXT(context, n, memoryObjectsPacked));
        if (isCallValid)
        {
            context->createMemoryObjects(n, memoryObjectsPacked);
        }
        ANGLE_CAPTURE(CreateMemoryObjectsEXT, isCallValid, context, n, memoryObjectsPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

GLuint GL_APIENTRY CreateProgramContextANGLE(GLeglContext ctx)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::CreateProgram, "glCreateProgram", "context = %d", CID(context));

    GLuint returnValue;
    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateCreateProgram(context));
        if (isCallValid)
        {
            returnValue = context->createProgram();
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::CreateProgram, GLuint>();
        }
        ANGLE_CAPTURE(CreateProgram, isCallValid, context, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
        returnValue = GetDefaultReturnValue<EntryPoint::CreateProgram, GLuint>();
    }
    return returnValue;
}

GLuint GL_APIENTRY CreateShaderContextANGLE(GLeglContext ctx, GLenum type)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::CreateShader, "glCreateShader", "context = %d, type = %s",
          CID(context), GLenumToString(GLenumGroup::ShaderType, type));

    GLuint returnValue;
    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderType typePacked                                 = FromGL<ShaderType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateCreateShader(context, typePacked));
        if (isCallValid)
        {
            returnValue = context->createShader(typePacked);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::CreateShader, GLuint>();
        }
        ANGLE_CAPTURE(CreateShader, isCallValid, context, typePacked, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
        returnValue = GetDefaultReturnValue<EntryPoint::CreateShader, GLuint>();
    }
    return returnValue;
}

GLuint GL_APIENTRY CreateShaderProgramvContextANGLE(GLeglContext ctx,
                                                    GLenum type,
                                                    GLsizei count,
                                                    const GLchar *const *strings)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::CreateShaderProgramv, "glCreateShaderProgramv",
          "context = %d, type = %s, count = %d, strings = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::ShaderType, type), count, (uintptr_t)strings);

    GLuint returnValue;
    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderType typePacked                                 = FromGL<ShaderType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateCreateShaderProgramv(context, typePacked, count, strings));
        if (isCallValid)
        {
            returnValue = context->createShaderProgramv(typePacked, count, strings);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::CreateShaderProgramv, GLuint>();
        }
        ANGLE_CAPTURE(CreateShaderProgramv, isCallValid, context, typePacked, count, strings,
                      returnValue);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
        returnValue = GetDefaultReturnValue<EntryPoint::CreateShaderProgramv, GLuint>();
    }
    return returnValue;
}

void GL_APIENTRY CullFaceContextANGLE(GLeglContext ctx, GLenum mode)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::CullFace, "glCullFace", "context = %d, mode = %s", CID(context),
          GLenumToString(GLenumGroup::CullFaceMode, mode));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        CullFaceMode modePacked                               = FromGL<CullFaceMode>(mode);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateCullFace(context, modePacked));
        if (isCallValid)
        {
            context->cullFace(modePacked);
        }
        ANGLE_CAPTURE(CullFace, isCallValid, context, modePacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY CurrentPaletteMatrixOESContextANGLE(GLeglContext ctx, GLuint matrixpaletteindex)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::CurrentPaletteMatrixOES, "glCurrentPaletteMatrixOES",
          "context = %d, matrixpaletteindex = %u", CID(context), matrixpaletteindex);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateCurrentPaletteMatrixOES(context, matrixpaletteindex));
        if (isCallValid)
        {
            context->currentPaletteMatrix(matrixpaletteindex);
        }
        ANGLE_CAPTURE(CurrentPaletteMatrixOES, isCallValid, context, matrixpaletteindex);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DebugMessageCallbackContextANGLE(GLeglContext ctx,
                                                  GLDEBUGPROC callback,
                                                  const void *userParam)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DebugMessageCallback, "glDebugMessageCallback",
          "context = %d, callback = 0x%016" PRIxPTR ", userParam = 0x%016" PRIxPTR "", CID(context),
          (uintptr_t)callback, (uintptr_t)userParam);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateDebugMessageCallback(context, callback, userParam));
        if (isCallValid)
        {
            context->debugMessageCallback(callback, userParam);
        }
        ANGLE_CAPTURE(DebugMessageCallback, isCallValid, context, callback, userParam);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DebugMessageCallbackKHRContextANGLE(GLeglContext ctx,
                                                     GLDEBUGPROCKHR callback,
                                                     const void *userParam)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DebugMessageCallbackKHR, "glDebugMessageCallbackKHR",
          "context = %d, callback = 0x%016" PRIxPTR ", userParam = 0x%016" PRIxPTR "", CID(context),
          (uintptr_t)callback, (uintptr_t)userParam);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateDebugMessageCallbackKHR(context, callback, userParam));
        if (isCallValid)
        {
            context->debugMessageCallback(callback, userParam);
        }
        ANGLE_CAPTURE(DebugMessageCallbackKHR, isCallValid, context, callback, userParam);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DebugMessageControlContextANGLE(GLeglContext ctx,
                                                 GLenum source,
                                                 GLenum type,
                                                 GLenum severity,
                                                 GLsizei count,
                                                 const GLuint *ids,
                                                 GLboolean enabled)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DebugMessageControl, "glDebugMessageControl",
          "context = %d, source = %s, type = %s, severity = %s, count = %d, ids = 0x%016" PRIxPTR
          ", enabled = %s",
          CID(context), GLenumToString(GLenumGroup::DebugSource, source),
          GLenumToString(GLenumGroup::DebugType, type),
          GLenumToString(GLenumGroup::DebugSeverity, severity), count, (uintptr_t)ids,
          GLbooleanToString(enabled));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateDebugMessageControl(context, source, type, severity, count, ids, enabled));
        if (isCallValid)
        {
            context->debugMessageControl(source, type, severity, count, ids, enabled);
        }
        ANGLE_CAPTURE(DebugMessageControl, isCallValid, context, source, type, severity, count, ids,
                      enabled);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DebugMessageControlKHRContextANGLE(GLeglContext ctx,
                                                    GLenum source,
                                                    GLenum type,
                                                    GLenum severity,
                                                    GLsizei count,
                                                    const GLuint *ids,
                                                    GLboolean enabled)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DebugMessageControlKHR, "glDebugMessageControlKHR",
          "context = %d, source = %s, type = %s, severity = %s, count = %d, ids = 0x%016" PRIxPTR
          ", enabled = %s",
          CID(context), GLenumToString(GLenumGroup::DebugSource, source),
          GLenumToString(GLenumGroup::DebugType, type),
          GLenumToString(GLenumGroup::DebugSeverity, severity), count, (uintptr_t)ids,
          GLbooleanToString(enabled));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateDebugMessageControlKHR(context, source, type, severity, count, ids, enabled));
        if (isCallValid)
        {
            context->debugMessageControl(source, type, severity, count, ids, enabled);
        }
        ANGLE_CAPTURE(DebugMessageControlKHR, isCallValid, context, source, type, severity, count,
                      ids, enabled);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DebugMessageInsertContextANGLE(GLeglContext ctx,
                                                GLenum source,
                                                GLenum type,
                                                GLuint id,
                                                GLenum severity,
                                                GLsizei length,
                                                const GLchar *buf)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DebugMessageInsert, "glDebugMessageInsert",
          "context = %d, source = %s, type = %s, id = %u, severity = %s, length = %d, buf = "
          "0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DebugSource, source),
          GLenumToString(GLenumGroup::DebugType, type), id,
          GLenumToString(GLenumGroup::DebugSeverity, severity), length, (uintptr_t)buf);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateDebugMessageInsert(context, source, type, id, severity, length, buf));
        if (isCallValid)
        {
            context->debugMessageInsert(source, type, id, severity, length, buf);
        }
        ANGLE_CAPTURE(DebugMessageInsert, isCallValid, context, source, type, id, severity, length,
                      buf);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DebugMessageInsertKHRContextANGLE(GLeglContext ctx,
                                                   GLenum source,
                                                   GLenum type,
                                                   GLuint id,
                                                   GLenum severity,
                                                   GLsizei length,
                                                   const GLchar *buf)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DebugMessageInsertKHR, "glDebugMessageInsertKHR",
          "context = %d, source = %s, type = %s, id = %u, severity = %s, length = %d, buf = "
          "0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DebugSource, source),
          GLenumToString(GLenumGroup::DebugType, type), id,
          GLenumToString(GLenumGroup::DebugSeverity, severity), length, (uintptr_t)buf);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateDebugMessageInsertKHR(context, source, type, id, severity, length, buf));
        if (isCallValid)
        {
            context->debugMessageInsert(source, type, id, severity, length, buf);
        }
        ANGLE_CAPTURE(DebugMessageInsertKHR, isCallValid, context, source, type, id, severity,
                      length, buf);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DeleteBuffersContextANGLE(GLeglContext ctx, GLsizei n, const GLuint *buffers)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DeleteBuffers, "glDeleteBuffers",
          "context = %d, n = %d, buffers = 0x%016" PRIxPTR "", CID(context), n, (uintptr_t)buffers);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        const BufferID *buffersPacked                         = FromGL<const BufferID *>(buffers);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateDeleteBuffers(context, n, buffersPacked));
        if (isCallValid)
        {
            context->deleteBuffers(n, buffersPacked);
        }
        ANGLE_CAPTURE(DeleteBuffers, isCallValid, context, n, buffersPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DeleteFencesNVContextANGLE(GLeglContext ctx, GLsizei n, const GLuint *fences)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DeleteFencesNV, "glDeleteFencesNV",
          "context = %d, n = %d, fences = 0x%016" PRIxPTR "", CID(context), n, (uintptr_t)fences);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        const FenceNVID *fencesPacked                         = FromGL<const FenceNVID *>(fences);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateDeleteFencesNV(context, n, fencesPacked));
        if (isCallValid)
        {
            context->deleteFencesNV(n, fencesPacked);
        }
        ANGLE_CAPTURE(DeleteFencesNV, isCallValid, context, n, fencesPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DeleteFramebuffersContextANGLE(GLeglContext ctx,
                                                GLsizei n,
                                                const GLuint *framebuffers)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DeleteFramebuffers, "glDeleteFramebuffers",
          "context = %d, n = %d, framebuffers = 0x%016" PRIxPTR "", CID(context), n,
          (uintptr_t)framebuffers);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        const FramebufferID *framebuffersPacked = FromGL<const FramebufferID *>(framebuffers);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateDeleteFramebuffers(context, n, framebuffersPacked));
        if (isCallValid)
        {
            context->deleteFramebuffers(n, framebuffersPacked);
        }
        ANGLE_CAPTURE(DeleteFramebuffers, isCallValid, context, n, framebuffersPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DeleteFramebuffersOESContextANGLE(GLeglContext ctx,
                                                   GLsizei n,
                                                   const GLuint *framebuffers)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DeleteFramebuffersOES, "glDeleteFramebuffersOES",
          "context = %d, n = %d, framebuffers = 0x%016" PRIxPTR "", CID(context), n,
          (uintptr_t)framebuffers);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        const FramebufferID *framebuffersPacked = FromGL<const FramebufferID *>(framebuffers);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateDeleteFramebuffersOES(context, n, framebuffersPacked));
        if (isCallValid)
        {
            context->deleteFramebuffers(n, framebuffersPacked);
        }
        ANGLE_CAPTURE(DeleteFramebuffersOES, isCallValid, context, n, framebuffersPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DeleteMemoryObjectsEXTContextANGLE(GLeglContext ctx,
                                                    GLsizei n,
                                                    const GLuint *memoryObjects)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DeleteMemoryObjectsEXT, "glDeleteMemoryObjectsEXT",
          "context = %d, n = %d, memoryObjects = 0x%016" PRIxPTR "", CID(context), n,
          (uintptr_t)memoryObjects);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        const MemoryObjectID *memoryObjectsPacked = FromGL<const MemoryObjectID *>(memoryObjects);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateDeleteMemoryObjectsEXT(context, n, memoryObjectsPacked));
        if (isCallValid)
        {
            context->deleteMemoryObjects(n, memoryObjectsPacked);
        }
        ANGLE_CAPTURE(DeleteMemoryObjectsEXT, isCallValid, context, n, memoryObjectsPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DeleteProgramContextANGLE(GLeglContext ctx, GLuint program)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DeleteProgram, "glDeleteProgram", "context = %d, program = %u",
          CID(context), program);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateDeleteProgram(context, programPacked));
        if (isCallValid)
        {
            context->deleteProgram(programPacked);
        }
        ANGLE_CAPTURE(DeleteProgram, isCallValid, context, programPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DeleteProgramPipelinesContextANGLE(GLeglContext ctx,
                                                    GLsizei n,
                                                    const GLuint *pipelines)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DeleteProgramPipelines, "glDeleteProgramPipelines",
          "context = %d, n = %d, pipelines = 0x%016" PRIxPTR "", CID(context), n,
          (uintptr_t)pipelines);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        const ProgramPipelineID *pipelinesPacked = FromGL<const ProgramPipelineID *>(pipelines);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateDeleteProgramPipelines(context, n, pipelinesPacked));
        if (isCallValid)
        {
            context->deleteProgramPipelines(n, pipelinesPacked);
        }
        ANGLE_CAPTURE(DeleteProgramPipelines, isCallValid, context, n, pipelinesPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DeleteQueriesContextANGLE(GLeglContext ctx, GLsizei n, const GLuint *ids)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DeleteQueries, "glDeleteQueries",
          "context = %d, n = %d, ids = 0x%016" PRIxPTR "", CID(context), n, (uintptr_t)ids);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        const QueryID *idsPacked                              = FromGL<const QueryID *>(ids);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateDeleteQueries(context, n, idsPacked));
        if (isCallValid)
        {
            context->deleteQueries(n, idsPacked);
        }
        ANGLE_CAPTURE(DeleteQueries, isCallValid, context, n, idsPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DeleteQueriesEXTContextANGLE(GLeglContext ctx, GLsizei n, const GLuint *ids)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DeleteQueriesEXT, "glDeleteQueriesEXT",
          "context = %d, n = %d, ids = 0x%016" PRIxPTR "", CID(context), n, (uintptr_t)ids);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        const QueryID *idsPacked                              = FromGL<const QueryID *>(ids);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateDeleteQueriesEXT(context, n, idsPacked));
        if (isCallValid)
        {
            context->deleteQueries(n, idsPacked);
        }
        ANGLE_CAPTURE(DeleteQueriesEXT, isCallValid, context, n, idsPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DeleteRenderbuffersContextANGLE(GLeglContext ctx,
                                                 GLsizei n,
                                                 const GLuint *renderbuffers)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DeleteRenderbuffers, "glDeleteRenderbuffers",
          "context = %d, n = %d, renderbuffers = 0x%016" PRIxPTR "", CID(context), n,
          (uintptr_t)renderbuffers);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        const RenderbufferID *renderbuffersPacked = FromGL<const RenderbufferID *>(renderbuffers);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateDeleteRenderbuffers(context, n, renderbuffersPacked));
        if (isCallValid)
        {
            context->deleteRenderbuffers(n, renderbuffersPacked);
        }
        ANGLE_CAPTURE(DeleteRenderbuffers, isCallValid, context, n, renderbuffersPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DeleteRenderbuffersOESContextANGLE(GLeglContext ctx,
                                                    GLsizei n,
                                                    const GLuint *renderbuffers)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DeleteRenderbuffersOES, "glDeleteRenderbuffersOES",
          "context = %d, n = %d, renderbuffers = 0x%016" PRIxPTR "", CID(context), n,
          (uintptr_t)renderbuffers);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        const RenderbufferID *renderbuffersPacked = FromGL<const RenderbufferID *>(renderbuffers);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateDeleteRenderbuffersOES(context, n, renderbuffersPacked));
        if (isCallValid)
        {
            context->deleteRenderbuffers(n, renderbuffersPacked);
        }
        ANGLE_CAPTURE(DeleteRenderbuffersOES, isCallValid, context, n, renderbuffersPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DeleteSamplersContextANGLE(GLeglContext ctx, GLsizei count, const GLuint *samplers)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DeleteSamplers, "glDeleteSamplers",
          "context = %d, count = %d, samplers = 0x%016" PRIxPTR "", CID(context), count,
          (uintptr_t)samplers);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        const SamplerID *samplersPacked                       = FromGL<const SamplerID *>(samplers);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateDeleteSamplers(context, count, samplersPacked));
        if (isCallValid)
        {
            context->deleteSamplers(count, samplersPacked);
        }
        ANGLE_CAPTURE(DeleteSamplers, isCallValid, context, count, samplersPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DeleteSemaphoresEXTContextANGLE(GLeglContext ctx,
                                                 GLsizei n,
                                                 const GLuint *semaphores)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DeleteSemaphoresEXT, "glDeleteSemaphoresEXT",
          "context = %d, n = %d, semaphores = 0x%016" PRIxPTR "", CID(context), n,
          (uintptr_t)semaphores);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        const SemaphoreID *semaphoresPacked = FromGL<const SemaphoreID *>(semaphores);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateDeleteSemaphoresEXT(context, n, semaphoresPacked));
        if (isCallValid)
        {
            context->deleteSemaphores(n, semaphoresPacked);
        }
        ANGLE_CAPTURE(DeleteSemaphoresEXT, isCallValid, context, n, semaphoresPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DeleteShaderContextANGLE(GLeglContext ctx, GLuint shader)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DeleteShader, "glDeleteShader", "context = %d, shader = %u",
          CID(context), shader);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID shaderPacked                          = FromGL<ShaderProgramID>(shader);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateDeleteShader(context, shaderPacked));
        if (isCallValid)
        {
            context->deleteShader(shaderPacked);
        }
        ANGLE_CAPTURE(DeleteShader, isCallValid, context, shaderPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DeleteSyncContextANGLE(GLeglContext ctx, GLsync sync)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DeleteSync, "glDeleteSync",
          "context = %d, sync = 0x%016" PRIxPTR "", CID(context), (uintptr_t)sync);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateDeleteSync(context, sync));
        if (isCallValid)
        {
            context->deleteSync(sync);
        }
        ANGLE_CAPTURE(DeleteSync, isCallValid, context, sync);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DeleteTexturesContextANGLE(GLeglContext ctx, GLsizei n, const GLuint *textures)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DeleteTextures, "glDeleteTextures",
          "context = %d, n = %d, textures = 0x%016" PRIxPTR "", CID(context), n,
          (uintptr_t)textures);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        const TextureID *texturesPacked                       = FromGL<const TextureID *>(textures);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateDeleteTextures(context, n, texturesPacked));
        if (isCallValid)
        {
            context->deleteTextures(n, texturesPacked);
        }
        ANGLE_CAPTURE(DeleteTextures, isCallValid, context, n, texturesPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DeleteTransformFeedbacksContextANGLE(GLeglContext ctx,
                                                      GLsizei n,
                                                      const GLuint *ids)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DeleteTransformFeedbacks, "glDeleteTransformFeedbacks",
          "context = %d, n = %d, ids = 0x%016" PRIxPTR "", CID(context), n, (uintptr_t)ids);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        const TransformFeedbackID *idsPacked = FromGL<const TransformFeedbackID *>(ids);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateDeleteTransformFeedbacks(context, n, idsPacked));
        if (isCallValid)
        {
            context->deleteTransformFeedbacks(n, idsPacked);
        }
        ANGLE_CAPTURE(DeleteTransformFeedbacks, isCallValid, context, n, idsPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DeleteVertexArraysContextANGLE(GLeglContext ctx, GLsizei n, const GLuint *arrays)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DeleteVertexArrays, "glDeleteVertexArrays",
          "context = %d, n = %d, arrays = 0x%016" PRIxPTR "", CID(context), n, (uintptr_t)arrays);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        const VertexArrayID *arraysPacked = FromGL<const VertexArrayID *>(arrays);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateDeleteVertexArrays(context, n, arraysPacked));
        if (isCallValid)
        {
            context->deleteVertexArrays(n, arraysPacked);
        }
        ANGLE_CAPTURE(DeleteVertexArrays, isCallValid, context, n, arraysPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DeleteVertexArraysOESContextANGLE(GLeglContext ctx,
                                                   GLsizei n,
                                                   const GLuint *arrays)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DeleteVertexArraysOES, "glDeleteVertexArraysOES",
          "context = %d, n = %d, arrays = 0x%016" PRIxPTR "", CID(context), n, (uintptr_t)arrays);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        const VertexArrayID *arraysPacked = FromGL<const VertexArrayID *>(arrays);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateDeleteVertexArraysOES(context, n, arraysPacked));
        if (isCallValid)
        {
            context->deleteVertexArrays(n, arraysPacked);
        }
        ANGLE_CAPTURE(DeleteVertexArraysOES, isCallValid, context, n, arraysPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DepthFuncContextANGLE(GLeglContext ctx, GLenum func)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DepthFunc, "glDepthFunc", "context = %d, func = %s",
          CID(context), GLenumToString(GLenumGroup::DepthFunction, func));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateDepthFunc(context, func));
        if (isCallValid)
        {
            context->depthFunc(func);
        }
        ANGLE_CAPTURE(DepthFunc, isCallValid, context, func);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DepthMaskContextANGLE(GLeglContext ctx, GLboolean flag)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DepthMask, "glDepthMask", "context = %d, flag = %s",
          CID(context), GLbooleanToString(flag));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateDepthMask(context, flag));
        if (isCallValid)
        {
            context->depthMask(flag);
        }
        ANGLE_CAPTURE(DepthMask, isCallValid, context, flag);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DepthRangefContextANGLE(GLeglContext ctx, GLfloat n, GLfloat f)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DepthRangef, "glDepthRangef", "context = %d, n = %f, f = %f",
          CID(context), n, f);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateDepthRangef(context, n, f));
        if (isCallValid)
        {
            context->depthRangef(n, f);
        }
        ANGLE_CAPTURE(DepthRangef, isCallValid, context, n, f);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DepthRangexContextANGLE(GLeglContext ctx, GLfixed n, GLfixed f)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DepthRangex, "glDepthRangex", "context = %d, n = 0x%X, f = 0x%X",
          CID(context), n, f);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateDepthRangex(context, n, f));
        if (isCallValid)
        {
            context->depthRangex(n, f);
        }
        ANGLE_CAPTURE(DepthRangex, isCallValid, context, n, f);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DetachShaderContextANGLE(GLeglContext ctx, GLuint program, GLuint shader)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DetachShader, "glDetachShader",
          "context = %d, program = %u, shader = %u", CID(context), program, shader);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        ShaderProgramID shaderPacked                          = FromGL<ShaderProgramID>(shader);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateDetachShader(context, programPacked, shaderPacked));
        if (isCallValid)
        {
            context->detachShader(programPacked, shaderPacked);
        }
        ANGLE_CAPTURE(DetachShader, isCallValid, context, programPacked, shaderPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DisableContextANGLE(GLeglContext ctx, GLenum cap)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Disable, "glDisable", "context = %d, cap = %s", CID(context),
          GLenumToString(GLenumGroup::EnableCap, cap));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateDisable(context, cap));
        if (isCallValid)
        {
            context->disable(cap);
        }
        ANGLE_CAPTURE(Disable, isCallValid, context, cap);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DisableClientStateContextANGLE(GLeglContext ctx, GLenum array)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DisableClientState, "glDisableClientState",
          "context = %d, array = %s", CID(context), GLenumToString(GLenumGroup::EnableCap, array));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ClientVertexArrayType arrayPacked = FromGL<ClientVertexArrayType>(array);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateDisableClientState(context, arrayPacked));
        if (isCallValid)
        {
            context->disableClientState(arrayPacked);
        }
        ANGLE_CAPTURE(DisableClientState, isCallValid, context, arrayPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DisableVertexAttribArrayContextANGLE(GLeglContext ctx, GLuint index)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DisableVertexAttribArray, "glDisableVertexAttribArray",
          "context = %d, index = %u", CID(context), index);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateDisableVertexAttribArray(context, index));
        if (isCallValid)
        {
            context->disableVertexAttribArray(index);
        }
        ANGLE_CAPTURE(DisableVertexAttribArray, isCallValid, context, index);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DisableiContextANGLE(GLeglContext ctx, GLenum target, GLuint index)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Disablei, "glDisablei", "context = %d, target = %s, index = %u",
          CID(context), GLenumToString(GLenumGroup::EnableCap, target), index);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateDisablei(context, target, index));
        if (isCallValid)
        {
            context->disablei(target, index);
        }
        ANGLE_CAPTURE(Disablei, isCallValid, context, target, index);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DisableiEXTContextANGLE(GLeglContext ctx, GLenum target, GLuint index)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DisableiEXT, "glDisableiEXT",
          "context = %d, target = %s, index = %u", CID(context),
          GLenumToString(GLenumGroup::EnableCap, target), index);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateDisableiEXT(context, target, index));
        if (isCallValid)
        {
            context->disablei(target, index);
        }
        ANGLE_CAPTURE(DisableiEXT, isCallValid, context, target, index);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DisableiOESContextANGLE(GLeglContext ctx, GLenum target, GLuint index)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DisableiOES, "glDisableiOES",
          "context = %d, target = %s, index = %u", CID(context),
          GLenumToString(GLenumGroup::EnableCap, target), index);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateDisableiOES(context, target, index));
        if (isCallValid)
        {
            context->disablei(target, index);
        }
        ANGLE_CAPTURE(DisableiOES, isCallValid, context, target, index);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DiscardFramebufferEXTContextANGLE(GLeglContext ctx,
                                                   GLenum target,
                                                   GLsizei numAttachments,
                                                   const GLenum *attachments)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DiscardFramebufferEXT, "glDiscardFramebufferEXT",
          "context = %d, target = %s, numAttachments = %d, attachments = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target), numAttachments,
          (uintptr_t)attachments);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateDiscardFramebufferEXT(context, target, numAttachments, attachments));
        if (isCallValid)
        {
            context->discardFramebuffer(target, numAttachments, attachments);
        }
        ANGLE_CAPTURE(DiscardFramebufferEXT, isCallValid, context, target, numAttachments,
                      attachments);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DispatchComputeContextANGLE(GLeglContext ctx,
                                             GLuint num_groups_x,
                                             GLuint num_groups_y,
                                             GLuint num_groups_z)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DispatchCompute, "glDispatchCompute",
          "context = %d, num_groups_x = %u, num_groups_y = %u, num_groups_z = %u", CID(context),
          num_groups_x, num_groups_y, num_groups_z);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateDispatchCompute(context, num_groups_x, num_groups_y, num_groups_z));
        if (isCallValid)
        {
            context->dispatchCompute(num_groups_x, num_groups_y, num_groups_z);
        }
        ANGLE_CAPTURE(DispatchCompute, isCallValid, context, num_groups_x, num_groups_y,
                      num_groups_z);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DispatchComputeIndirectContextANGLE(GLeglContext ctx, GLintptr indirect)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DispatchComputeIndirect, "glDispatchComputeIndirect",
          "context = %d, indirect = %llu", CID(context), static_cast<unsigned long long>(indirect));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateDispatchComputeIndirect(context, indirect));
        if (isCallValid)
        {
            context->dispatchComputeIndirect(indirect);
        }
        ANGLE_CAPTURE(DispatchComputeIndirect, isCallValid, context, indirect);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DrawArraysContextANGLE(GLeglContext ctx, GLenum mode, GLint first, GLsizei count)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DrawArrays, "glDrawArrays",
          "context = %d, mode = %s, first = %d, count = %d", CID(context),
          GLenumToString(GLenumGroup::PrimitiveType, mode), first, count);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateDrawArrays(context, modePacked, first, count));
        if (isCallValid)
        {
            context->drawArrays(modePacked, first, count);
        }
        ANGLE_CAPTURE(DrawArrays, isCallValid, context, modePacked, first, count);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DrawArraysIndirectContextANGLE(GLeglContext ctx, GLenum mode, const void *indirect)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DrawArraysIndirect, "glDrawArraysIndirect",
          "context = %d, mode = %s, indirect = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::PrimitiveType, mode), (uintptr_t)indirect);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateDrawArraysIndirect(context, modePacked, indirect));
        if (isCallValid)
        {
            context->drawArraysIndirect(modePacked, indirect);
        }
        ANGLE_CAPTURE(DrawArraysIndirect, isCallValid, context, modePacked, indirect);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DrawArraysInstancedContextANGLE(GLeglContext ctx,
                                                 GLenum mode,
                                                 GLint first,
                                                 GLsizei count,
                                                 GLsizei instancecount)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DrawArraysInstanced, "glDrawArraysInstanced",
          "context = %d, mode = %s, first = %d, count = %d, instancecount = %d", CID(context),
          GLenumToString(GLenumGroup::PrimitiveType, mode), first, count, instancecount);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateDrawArraysInstanced(context, modePacked, first, count, instancecount));
        if (isCallValid)
        {
            context->drawArraysInstanced(modePacked, first, count, instancecount);
        }
        ANGLE_CAPTURE(DrawArraysInstanced, isCallValid, context, modePacked, first, count,
                      instancecount);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DrawArraysInstancedANGLEContextANGLE(GLeglContext ctx,
                                                      GLenum mode,
                                                      GLint first,
                                                      GLsizei count,
                                                      GLsizei primcount)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DrawArraysInstancedANGLE, "glDrawArraysInstancedANGLE",
          "context = %d, mode = %s, first = %d, count = %d, primcount = %d", CID(context),
          GLenumToString(GLenumGroup::PrimitiveType, mode), first, count, primcount);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateDrawArraysInstancedANGLE(context, modePacked, first, count, primcount));
        if (isCallValid)
        {
            context->drawArraysInstanced(modePacked, first, count, primcount);
        }
        ANGLE_CAPTURE(DrawArraysInstancedANGLE, isCallValid, context, modePacked, first, count,
                      primcount);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DrawArraysInstancedEXTContextANGLE(GLeglContext ctx,
                                                    GLenum mode,
                                                    GLint start,
                                                    GLsizei count,
                                                    GLsizei primcount)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DrawArraysInstancedEXT, "glDrawArraysInstancedEXT",
          "context = %d, mode = %s, start = %d, count = %d, primcount = %d", CID(context),
          GLenumToString(GLenumGroup::PrimitiveType, mode), start, count, primcount);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateDrawArraysInstancedEXT(context, modePacked, start, count, primcount));
        if (isCallValid)
        {
            context->drawArraysInstanced(modePacked, start, count, primcount);
        }
        ANGLE_CAPTURE(DrawArraysInstancedEXT, isCallValid, context, modePacked, start, count,
                      primcount);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DrawBuffersContextANGLE(GLeglContext ctx, GLsizei n, const GLenum *bufs)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DrawBuffers, "glDrawBuffers",
          "context = %d, n = %d, bufs = 0x%016" PRIxPTR "", CID(context), n, (uintptr_t)bufs);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateDrawBuffers(context, n, bufs));
        if (isCallValid)
        {
            context->drawBuffers(n, bufs);
        }
        ANGLE_CAPTURE(DrawBuffers, isCallValid, context, n, bufs);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DrawBuffersEXTContextANGLE(GLeglContext ctx, GLsizei n, const GLenum *bufs)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DrawBuffersEXT, "glDrawBuffersEXT",
          "context = %d, n = %d, bufs = 0x%016" PRIxPTR "", CID(context), n, (uintptr_t)bufs);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateDrawBuffersEXT(context, n, bufs));
        if (isCallValid)
        {
            context->drawBuffers(n, bufs);
        }
        ANGLE_CAPTURE(DrawBuffersEXT, isCallValid, context, n, bufs);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DrawElementsContextANGLE(GLeglContext ctx,
                                          GLenum mode,
                                          GLsizei count,
                                          GLenum type,
                                          const void *indices)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DrawElements, "glDrawElements",
          "context = %d, mode = %s, count = %d, type = %s, indices = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::PrimitiveType, mode), count,
          GLenumToString(GLenumGroup::DrawElementsType, type), (uintptr_t)indices);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        DrawElementsType typePacked                           = FromGL<DrawElementsType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateDrawElements(context, modePacked, count, typePacked, indices));
        if (isCallValid)
        {
            context->drawElements(modePacked, count, typePacked, indices);
        }
        ANGLE_CAPTURE(DrawElements, isCallValid, context, modePacked, count, typePacked, indices);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DrawElementsBaseVertexContextANGLE(GLeglContext ctx,
                                                    GLenum mode,
                                                    GLsizei count,
                                                    GLenum type,
                                                    const void *indices,
                                                    GLint basevertex)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DrawElementsBaseVertex, "glDrawElementsBaseVertex",
          "context = %d, mode = %s, count = %d, type = %s, indices = 0x%016" PRIxPTR
          ", basevertex = %d",
          CID(context), GLenumToString(GLenumGroup::PrimitiveType, mode), count,
          GLenumToString(GLenumGroup::DrawElementsType, type), (uintptr_t)indices, basevertex);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        DrawElementsType typePacked                           = FromGL<DrawElementsType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateDrawElementsBaseVertex(context, modePacked, count, typePacked,
                                                           indices, basevertex));
        if (isCallValid)
        {
            context->drawElementsBaseVertex(modePacked, count, typePacked, indices, basevertex);
        }
        ANGLE_CAPTURE(DrawElementsBaseVertex, isCallValid, context, modePacked, count, typePacked,
                      indices, basevertex);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DrawElementsBaseVertexEXTContextANGLE(GLeglContext ctx,
                                                       GLenum mode,
                                                       GLsizei count,
                                                       GLenum type,
                                                       const void *indices,
                                                       GLint basevertex)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DrawElementsBaseVertexEXT, "glDrawElementsBaseVertexEXT",
          "context = %d, mode = %s, count = %d, type = %s, indices = 0x%016" PRIxPTR
          ", basevertex = %d",
          CID(context), GLenumToString(GLenumGroup::PrimitiveType, mode), count,
          GLenumToString(GLenumGroup::DrawElementsType, type), (uintptr_t)indices, basevertex);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        DrawElementsType typePacked                           = FromGL<DrawElementsType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateDrawElementsBaseVertexEXT(context, modePacked, count,
                                                              typePacked, indices, basevertex));
        if (isCallValid)
        {
            context->drawElementsBaseVertex(modePacked, count, typePacked, indices, basevertex);
        }
        ANGLE_CAPTURE(DrawElementsBaseVertexEXT, isCallValid, context, modePacked, count,
                      typePacked, indices, basevertex);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DrawElementsBaseVertexOESContextANGLE(GLeglContext ctx,
                                                       GLenum mode,
                                                       GLsizei count,
                                                       GLenum type,
                                                       const void *indices,
                                                       GLint basevertex)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DrawElementsBaseVertexOES, "glDrawElementsBaseVertexOES",
          "context = %d, mode = %s, count = %d, type = %s, indices = 0x%016" PRIxPTR
          ", basevertex = %d",
          CID(context), GLenumToString(GLenumGroup::PrimitiveType, mode), count,
          GLenumToString(GLenumGroup::DrawElementsType, type), (uintptr_t)indices, basevertex);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        DrawElementsType typePacked                           = FromGL<DrawElementsType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateDrawElementsBaseVertexOES(context, modePacked, count,
                                                              typePacked, indices, basevertex));
        if (isCallValid)
        {
            context->drawElementsBaseVertex(modePacked, count, typePacked, indices, basevertex);
        }
        ANGLE_CAPTURE(DrawElementsBaseVertexOES, isCallValid, context, modePacked, count,
                      typePacked, indices, basevertex);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DrawElementsIndirectContextANGLE(GLeglContext ctx,
                                                  GLenum mode,
                                                  GLenum type,
                                                  const void *indirect)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DrawElementsIndirect, "glDrawElementsIndirect",
          "context = %d, mode = %s, type = %s, indirect = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::PrimitiveType, mode),
          GLenumToString(GLenumGroup::DrawElementsType, type), (uintptr_t)indirect);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        DrawElementsType typePacked                           = FromGL<DrawElementsType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateDrawElementsIndirect(context, modePacked, typePacked, indirect));
        if (isCallValid)
        {
            context->drawElementsIndirect(modePacked, typePacked, indirect);
        }
        ANGLE_CAPTURE(DrawElementsIndirect, isCallValid, context, modePacked, typePacked, indirect);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DrawElementsInstancedContextANGLE(GLeglContext ctx,
                                                   GLenum mode,
                                                   GLsizei count,
                                                   GLenum type,
                                                   const void *indices,
                                                   GLsizei instancecount)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DrawElementsInstanced, "glDrawElementsInstanced",
          "context = %d, mode = %s, count = %d, type = %s, indices = 0x%016" PRIxPTR
          ", instancecount = %d",
          CID(context), GLenumToString(GLenumGroup::PrimitiveType, mode), count,
          GLenumToString(GLenumGroup::DrawElementsType, type), (uintptr_t)indices, instancecount);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        DrawElementsType typePacked                           = FromGL<DrawElementsType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateDrawElementsInstanced(context, modePacked, count, typePacked,
                                                          indices, instancecount));
        if (isCallValid)
        {
            context->drawElementsInstanced(modePacked, count, typePacked, indices, instancecount);
        }
        ANGLE_CAPTURE(DrawElementsInstanced, isCallValid, context, modePacked, count, typePacked,
                      indices, instancecount);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DrawElementsInstancedANGLEContextANGLE(GLeglContext ctx,
                                                        GLenum mode,
                                                        GLsizei count,
                                                        GLenum type,
                                                        const void *indices,
                                                        GLsizei primcount)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DrawElementsInstancedANGLE, "glDrawElementsInstancedANGLE",
          "context = %d, mode = %s, count = %d, type = %s, indices = 0x%016" PRIxPTR
          ", primcount = %d",
          CID(context), GLenumToString(GLenumGroup::PrimitiveType, mode), count,
          GLenumToString(GLenumGroup::PrimitiveType, type), (uintptr_t)indices, primcount);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        DrawElementsType typePacked                           = FromGL<DrawElementsType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateDrawElementsInstancedANGLE(context, modePacked, count,
                                                               typePacked, indices, primcount));
        if (isCallValid)
        {
            context->drawElementsInstanced(modePacked, count, typePacked, indices, primcount);
        }
        ANGLE_CAPTURE(DrawElementsInstancedANGLE, isCallValid, context, modePacked, count,
                      typePacked, indices, primcount);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DrawElementsInstancedBaseVertexContextANGLE(GLeglContext ctx,
                                                             GLenum mode,
                                                             GLsizei count,
                                                             GLenum type,
                                                             const void *indices,
                                                             GLsizei instancecount,
                                                             GLint basevertex)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DrawElementsInstancedBaseVertex,
          "glDrawElementsInstancedBaseVertex",
          "context = %d, mode = %s, count = %d, type = %s, indices = 0x%016" PRIxPTR
          ", instancecount = %d, basevertex = %d",
          CID(context), GLenumToString(GLenumGroup::PrimitiveType, mode), count,
          GLenumToString(GLenumGroup::DrawElementsType, type), (uintptr_t)indices, instancecount,
          basevertex);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        DrawElementsType typePacked                           = FromGL<DrawElementsType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateDrawElementsInstancedBaseVertex(
                                                             context, modePacked, count, typePacked,
                                                             indices, instancecount, basevertex));
        if (isCallValid)
        {
            context->drawElementsInstancedBaseVertex(modePacked, count, typePacked, indices,
                                                     instancecount, basevertex);
        }
        ANGLE_CAPTURE(DrawElementsInstancedBaseVertex, isCallValid, context, modePacked, count,
                      typePacked, indices, instancecount, basevertex);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DrawElementsInstancedBaseVertexEXTContextANGLE(GLeglContext ctx,
                                                                GLenum mode,
                                                                GLsizei count,
                                                                GLenum type,
                                                                const void *indices,
                                                                GLsizei instancecount,
                                                                GLint basevertex)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DrawElementsInstancedBaseVertexEXT,
          "glDrawElementsInstancedBaseVertexEXT",
          "context = %d, mode = %s, count = %d, type = %s, indices = 0x%016" PRIxPTR
          ", instancecount = %d, basevertex = %d",
          CID(context), GLenumToString(GLenumGroup::PrimitiveType, mode), count,
          GLenumToString(GLenumGroup::DrawElementsType, type), (uintptr_t)indices, instancecount,
          basevertex);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        DrawElementsType typePacked                           = FromGL<DrawElementsType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateDrawElementsInstancedBaseVertexEXT(
                                                             context, modePacked, count, typePacked,
                                                             indices, instancecount, basevertex));
        if (isCallValid)
        {
            context->drawElementsInstancedBaseVertex(modePacked, count, typePacked, indices,
                                                     instancecount, basevertex);
        }
        ANGLE_CAPTURE(DrawElementsInstancedBaseVertexEXT, isCallValid, context, modePacked, count,
                      typePacked, indices, instancecount, basevertex);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DrawElementsInstancedBaseVertexOESContextANGLE(GLeglContext ctx,
                                                                GLenum mode,
                                                                GLsizei count,
                                                                GLenum type,
                                                                const void *indices,
                                                                GLsizei instancecount,
                                                                GLint basevertex)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DrawElementsInstancedBaseVertexOES,
          "glDrawElementsInstancedBaseVertexOES",
          "context = %d, mode = %s, count = %d, type = %s, indices = 0x%016" PRIxPTR
          ", instancecount = %d, basevertex = %d",
          CID(context), GLenumToString(GLenumGroup::PrimitiveType, mode), count,
          GLenumToString(GLenumGroup::DrawElementsType, type), (uintptr_t)indices, instancecount,
          basevertex);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        DrawElementsType typePacked                           = FromGL<DrawElementsType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateDrawElementsInstancedBaseVertexOES(
                                                             context, modePacked, count, typePacked,
                                                             indices, instancecount, basevertex));
        if (isCallValid)
        {
            context->drawElementsInstancedBaseVertex(modePacked, count, typePacked, indices,
                                                     instancecount, basevertex);
        }
        ANGLE_CAPTURE(DrawElementsInstancedBaseVertexOES, isCallValid, context, modePacked, count,
                      typePacked, indices, instancecount, basevertex);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DrawElementsInstancedEXTContextANGLE(GLeglContext ctx,
                                                      GLenum mode,
                                                      GLsizei count,
                                                      GLenum type,
                                                      const void *indices,
                                                      GLsizei primcount)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DrawElementsInstancedEXT, "glDrawElementsInstancedEXT",
          "context = %d, mode = %s, count = %d, type = %s, indices = 0x%016" PRIxPTR
          ", primcount = %d",
          CID(context), GLenumToString(GLenumGroup::PrimitiveType, mode), count,
          GLenumToString(GLenumGroup::DrawElementsType, type), (uintptr_t)indices, primcount);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        DrawElementsType typePacked                           = FromGL<DrawElementsType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateDrawElementsInstancedEXT(context, modePacked, count, typePacked,
                                                             indices, primcount));
        if (isCallValid)
        {
            context->drawElementsInstanced(modePacked, count, typePacked, indices, primcount);
        }
        ANGLE_CAPTURE(DrawElementsInstancedEXT, isCallValid, context, modePacked, count, typePacked,
                      indices, primcount);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DrawRangeElementsContextANGLE(GLeglContext ctx,
                                               GLenum mode,
                                               GLuint start,
                                               GLuint end,
                                               GLsizei count,
                                               GLenum type,
                                               const void *indices)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DrawRangeElements, "glDrawRangeElements",
          "context = %d, mode = %s, start = %u, end = %u, count = %d, type = %s, indices = "
          "0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::PrimitiveType, mode), start, end, count,
          GLenumToString(GLenumGroup::DrawElementsType, type), (uintptr_t)indices);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        DrawElementsType typePacked                           = FromGL<DrawElementsType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateDrawRangeElements(context, modePacked, start, end,
                                                                    count, typePacked, indices));
        if (isCallValid)
        {
            context->drawRangeElements(modePacked, start, end, count, typePacked, indices);
        }
        ANGLE_CAPTURE(DrawRangeElements, isCallValid, context, modePacked, start, end, count,
                      typePacked, indices);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DrawRangeElementsBaseVertexContextANGLE(GLeglContext ctx,
                                                         GLenum mode,
                                                         GLuint start,
                                                         GLuint end,
                                                         GLsizei count,
                                                         GLenum type,
                                                         const void *indices,
                                                         GLint basevertex)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DrawRangeElementsBaseVertex, "glDrawRangeElementsBaseVertex",
          "context = %d, mode = %s, start = %u, end = %u, count = %d, type = %s, indices = "
          "0x%016" PRIxPTR ", basevertex = %d",
          CID(context), GLenumToString(GLenumGroup::PrimitiveType, mode), start, end, count,
          GLenumToString(GLenumGroup::DrawElementsType, type), (uintptr_t)indices, basevertex);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        DrawElementsType typePacked                           = FromGL<DrawElementsType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateDrawRangeElementsBaseVertex(
                                                             context, modePacked, start, end, count,
                                                             typePacked, indices, basevertex));
        if (isCallValid)
        {
            context->drawRangeElementsBaseVertex(modePacked, start, end, count, typePacked, indices,
                                                 basevertex);
        }
        ANGLE_CAPTURE(DrawRangeElementsBaseVertex, isCallValid, context, modePacked, start, end,
                      count, typePacked, indices, basevertex);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DrawRangeElementsBaseVertexEXTContextANGLE(GLeglContext ctx,
                                                            GLenum mode,
                                                            GLuint start,
                                                            GLuint end,
                                                            GLsizei count,
                                                            GLenum type,
                                                            const void *indices,
                                                            GLint basevertex)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DrawRangeElementsBaseVertexEXT,
          "glDrawRangeElementsBaseVertexEXT",
          "context = %d, mode = %s, start = %u, end = %u, count = %d, type = %s, indices = "
          "0x%016" PRIxPTR ", basevertex = %d",
          CID(context), GLenumToString(GLenumGroup::PrimitiveType, mode), start, end, count,
          GLenumToString(GLenumGroup::DrawElementsType, type), (uintptr_t)indices, basevertex);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        DrawElementsType typePacked                           = FromGL<DrawElementsType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateDrawRangeElementsBaseVertexEXT(
                                                             context, modePacked, start, end, count,
                                                             typePacked, indices, basevertex));
        if (isCallValid)
        {
            context->drawRangeElementsBaseVertex(modePacked, start, end, count, typePacked, indices,
                                                 basevertex);
        }
        ANGLE_CAPTURE(DrawRangeElementsBaseVertexEXT, isCallValid, context, modePacked, start, end,
                      count, typePacked, indices, basevertex);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DrawRangeElementsBaseVertexOESContextANGLE(GLeglContext ctx,
                                                            GLenum mode,
                                                            GLuint start,
                                                            GLuint end,
                                                            GLsizei count,
                                                            GLenum type,
                                                            const void *indices,
                                                            GLint basevertex)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DrawRangeElementsBaseVertexOES,
          "glDrawRangeElementsBaseVertexOES",
          "context = %d, mode = %s, start = %u, end = %u, count = %d, type = %s, indices = "
          "0x%016" PRIxPTR ", basevertex = %d",
          CID(context), GLenumToString(GLenumGroup::PrimitiveType, mode), start, end, count,
          GLenumToString(GLenumGroup::DrawElementsType, type), (uintptr_t)indices, basevertex);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        DrawElementsType typePacked                           = FromGL<DrawElementsType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateDrawRangeElementsBaseVertexOES(
                                                             context, modePacked, start, end, count,
                                                             typePacked, indices, basevertex));
        if (isCallValid)
        {
            context->drawRangeElementsBaseVertex(modePacked, start, end, count, typePacked, indices,
                                                 basevertex);
        }
        ANGLE_CAPTURE(DrawRangeElementsBaseVertexOES, isCallValid, context, modePacked, start, end,
                      count, typePacked, indices, basevertex);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DrawTexfOESContextANGLE(GLeglContext ctx,
                                         GLfloat x,
                                         GLfloat y,
                                         GLfloat z,
                                         GLfloat width,
                                         GLfloat height)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DrawTexfOES, "glDrawTexfOES",
          "context = %d, x = %f, y = %f, z = %f, width = %f, height = %f", CID(context), x, y, z,
          width, height);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateDrawTexfOES(context, x, y, z, width, height));
        if (isCallValid)
        {
            context->drawTexf(x, y, z, width, height);
        }
        ANGLE_CAPTURE(DrawTexfOES, isCallValid, context, x, y, z, width, height);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DrawTexfvOESContextANGLE(GLeglContext ctx, const GLfloat *coords)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DrawTexfvOES, "glDrawTexfvOES",
          "context = %d, coords = 0x%016" PRIxPTR "", CID(context), (uintptr_t)coords);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateDrawTexfvOES(context, coords));
        if (isCallValid)
        {
            context->drawTexfv(coords);
        }
        ANGLE_CAPTURE(DrawTexfvOES, isCallValid, context, coords);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY
DrawTexiOESContextANGLE(GLeglContext ctx, GLint x, GLint y, GLint z, GLint width, GLint height)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DrawTexiOES, "glDrawTexiOES",
          "context = %d, x = %d, y = %d, z = %d, width = %d, height = %d", CID(context), x, y, z,
          width, height);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateDrawTexiOES(context, x, y, z, width, height));
        if (isCallValid)
        {
            context->drawTexi(x, y, z, width, height);
        }
        ANGLE_CAPTURE(DrawTexiOES, isCallValid, context, x, y, z, width, height);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DrawTexivOESContextANGLE(GLeglContext ctx, const GLint *coords)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DrawTexivOES, "glDrawTexivOES",
          "context = %d, coords = 0x%016" PRIxPTR "", CID(context), (uintptr_t)coords);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateDrawTexivOES(context, coords));
        if (isCallValid)
        {
            context->drawTexiv(coords);
        }
        ANGLE_CAPTURE(DrawTexivOES, isCallValid, context, coords);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DrawTexsOESContextANGLE(GLeglContext ctx,
                                         GLshort x,
                                         GLshort y,
                                         GLshort z,
                                         GLshort width,
                                         GLshort height)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DrawTexsOES, "glDrawTexsOES",
          "context = %d, x = %d, y = %d, z = %d, width = %d, height = %d", CID(context), x, y, z,
          width, height);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateDrawTexsOES(context, x, y, z, width, height));
        if (isCallValid)
        {
            context->drawTexs(x, y, z, width, height);
        }
        ANGLE_CAPTURE(DrawTexsOES, isCallValid, context, x, y, z, width, height);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DrawTexsvOESContextANGLE(GLeglContext ctx, const GLshort *coords)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DrawTexsvOES, "glDrawTexsvOES",
          "context = %d, coords = 0x%016" PRIxPTR "", CID(context), (uintptr_t)coords);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateDrawTexsvOES(context, coords));
        if (isCallValid)
        {
            context->drawTexsv(coords);
        }
        ANGLE_CAPTURE(DrawTexsvOES, isCallValid, context, coords);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DrawTexxOESContextANGLE(GLeglContext ctx,
                                         GLfixed x,
                                         GLfixed y,
                                         GLfixed z,
                                         GLfixed width,
                                         GLfixed height)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DrawTexxOES, "glDrawTexxOES",
          "context = %d, x = 0x%X, y = 0x%X, z = 0x%X, width = 0x%X, height = 0x%X", CID(context),
          x, y, z, width, height);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateDrawTexxOES(context, x, y, z, width, height));
        if (isCallValid)
        {
            context->drawTexx(x, y, z, width, height);
        }
        ANGLE_CAPTURE(DrawTexxOES, isCallValid, context, x, y, z, width, height);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DrawTexxvOESContextANGLE(GLeglContext ctx, const GLfixed *coords)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DrawTexxvOES, "glDrawTexxvOES",
          "context = %d, coords = 0x%016" PRIxPTR "", CID(context), (uintptr_t)coords);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateDrawTexxvOES(context, coords));
        if (isCallValid)
        {
            context->drawTexxv(coords);
        }
        ANGLE_CAPTURE(DrawTexxvOES, isCallValid, context, coords);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY EGLImageTargetRenderbufferStorageOESContextANGLE(GLeglContext ctx,
                                                                  GLenum target,
                                                                  GLeglImageOES image)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::EGLImageTargetRenderbufferStorageOES,
          "glEGLImageTargetRenderbufferStorageOES",
          "context = %d, target = %s, image = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::DefaultGroup, target), (uintptr_t)image);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateEGLImageTargetRenderbufferStorageOES(context, target, image));
        if (isCallValid)
        {
            context->eGLImageTargetRenderbufferStorage(target, image);
        }
        ANGLE_CAPTURE(EGLImageTargetRenderbufferStorageOES, isCallValid, context, target, image);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY EGLImageTargetTexture2DOESContextANGLE(GLeglContext ctx,
                                                        GLenum target,
                                                        GLeglImageOES image)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::EGLImageTargetTexture2DOES, "glEGLImageTargetTexture2DOES",
          "context = %d, target = %s, image = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::DefaultGroup, target), (uintptr_t)image);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateEGLImageTargetTexture2DOES(context, targetPacked, image));
        if (isCallValid)
        {
            context->eGLImageTargetTexture2D(targetPacked, image);
        }
        ANGLE_CAPTURE(EGLImageTargetTexture2DOES, isCallValid, context, targetPacked, image);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY EnableContextANGLE(GLeglContext ctx, GLenum cap)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Enable, "glEnable", "context = %d, cap = %s", CID(context),
          GLenumToString(GLenumGroup::EnableCap, cap));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateEnable(context, cap));
        if (isCallValid)
        {
            context->enable(cap);
        }
        ANGLE_CAPTURE(Enable, isCallValid, context, cap);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY EnableClientStateContextANGLE(GLeglContext ctx, GLenum array)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::EnableClientState, "glEnableClientState",
          "context = %d, array = %s", CID(context), GLenumToString(GLenumGroup::EnableCap, array));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ClientVertexArrayType arrayPacked = FromGL<ClientVertexArrayType>(array);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateEnableClientState(context, arrayPacked));
        if (isCallValid)
        {
            context->enableClientState(arrayPacked);
        }
        ANGLE_CAPTURE(EnableClientState, isCallValid, context, arrayPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY EnableVertexAttribArrayContextANGLE(GLeglContext ctx, GLuint index)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::EnableVertexAttribArray, "glEnableVertexAttribArray",
          "context = %d, index = %u", CID(context), index);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateEnableVertexAttribArray(context, index));
        if (isCallValid)
        {
            context->enableVertexAttribArray(index);
        }
        ANGLE_CAPTURE(EnableVertexAttribArray, isCallValid, context, index);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY EnableiContextANGLE(GLeglContext ctx, GLenum target, GLuint index)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Enablei, "glEnablei", "context = %d, target = %s, index = %u",
          CID(context), GLenumToString(GLenumGroup::EnableCap, target), index);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateEnablei(context, target, index));
        if (isCallValid)
        {
            context->enablei(target, index);
        }
        ANGLE_CAPTURE(Enablei, isCallValid, context, target, index);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY EnableiEXTContextANGLE(GLeglContext ctx, GLenum target, GLuint index)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::EnableiEXT, "glEnableiEXT",
          "context = %d, target = %s, index = %u", CID(context),
          GLenumToString(GLenumGroup::EnableCap, target), index);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateEnableiEXT(context, target, index));
        if (isCallValid)
        {
            context->enablei(target, index);
        }
        ANGLE_CAPTURE(EnableiEXT, isCallValid, context, target, index);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY EnableiOESContextANGLE(GLeglContext ctx, GLenum target, GLuint index)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::EnableiOES, "glEnableiOES",
          "context = %d, target = %s, index = %u", CID(context),
          GLenumToString(GLenumGroup::EnableCap, target), index);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateEnableiOES(context, target, index));
        if (isCallValid)
        {
            context->enablei(target, index);
        }
        ANGLE_CAPTURE(EnableiOES, isCallValid, context, target, index);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY EndQueryContextANGLE(GLeglContext ctx, GLenum target)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::EndQuery, "glEndQuery", "context = %d, target = %s",
          CID(context), GLenumToString(GLenumGroup::QueryTarget, target));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        QueryType targetPacked                                = FromGL<QueryType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateEndQuery(context, targetPacked));
        if (isCallValid)
        {
            context->endQuery(targetPacked);
        }
        ANGLE_CAPTURE(EndQuery, isCallValid, context, targetPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY EndQueryEXTContextANGLE(GLeglContext ctx, GLenum target)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::EndQueryEXT, "glEndQueryEXT", "context = %d, target = %s",
          CID(context), GLenumToString(GLenumGroup::QueryTarget, target));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        QueryType targetPacked                                = FromGL<QueryType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateEndQueryEXT(context, targetPacked));
        if (isCallValid)
        {
            context->endQuery(targetPacked);
        }
        ANGLE_CAPTURE(EndQueryEXT, isCallValid, context, targetPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY EndTransformFeedbackContextANGLE(GLeglContext ctx)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::EndTransformFeedback, "glEndTransformFeedback", "context = %d",
          CID(context));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateEndTransformFeedback(context));
        if (isCallValid)
        {
            context->endTransformFeedback();
        }
        ANGLE_CAPTURE(EndTransformFeedback, isCallValid, context);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

GLsync GL_APIENTRY FenceSyncContextANGLE(GLeglContext ctx, GLenum condition, GLbitfield flags)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::FenceSync, "glFenceSync",
          "context = %d, condition = %s, flags = %s", CID(context),
          GLenumToString(GLenumGroup::SyncCondition, condition),
          GLbitfieldToString(GLenumGroup::DefaultGroup, flags).c_str());

    GLsync returnValue;
    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateFenceSync(context, condition, flags));
        if (isCallValid)
        {
            returnValue = context->fenceSync(condition, flags);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::FenceSync, GLsync>();
        }
        ANGLE_CAPTURE(FenceSync, isCallValid, context, condition, flags, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
        returnValue = GetDefaultReturnValue<EntryPoint::FenceSync, GLsync>();
    }
    return returnValue;
}

void GL_APIENTRY FinishContextANGLE(GLeglContext ctx)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Finish, "glFinish", "context = %d", CID(context));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateFinish(context));
        if (isCallValid)
        {
            context->finish();
        }
        ANGLE_CAPTURE(Finish, isCallValid, context);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY FinishFenceNVContextANGLE(GLeglContext ctx, GLuint fence)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::FinishFenceNV, "glFinishFenceNV", "context = %d, fence = %u",
          CID(context), fence);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        FenceNVID fencePacked                                 = FromGL<FenceNVID>(fence);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateFinishFenceNV(context, fencePacked));
        if (isCallValid)
        {
            context->finishFenceNV(fencePacked);
        }
        ANGLE_CAPTURE(FinishFenceNV, isCallValid, context, fencePacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY FlushContextANGLE(GLeglContext ctx)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Flush, "glFlush", "context = %d", CID(context));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateFlush(context));
        if (isCallValid)
        {
            context->flush();
        }
        ANGLE_CAPTURE(Flush, isCallValid, context);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY FlushMappedBufferRangeContextANGLE(GLeglContext ctx,
                                                    GLenum target,
                                                    GLintptr offset,
                                                    GLsizeiptr length)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::FlushMappedBufferRange, "glFlushMappedBufferRange",
          "context = %d, target = %s, offset = %llu, length = %llu", CID(context),
          GLenumToString(GLenumGroup::BufferTargetARB, target),
          static_cast<unsigned long long>(offset), static_cast<unsigned long long>(length));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        BufferBinding targetPacked                            = FromGL<BufferBinding>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateFlushMappedBufferRange(context, targetPacked, offset, length));
        if (isCallValid)
        {
            context->flushMappedBufferRange(targetPacked, offset, length);
        }
        ANGLE_CAPTURE(FlushMappedBufferRange, isCallValid, context, targetPacked, offset, length);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY FlushMappedBufferRangeEXTContextANGLE(GLeglContext ctx,
                                                       GLenum target,
                                                       GLintptr offset,
                                                       GLsizeiptr length)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::FlushMappedBufferRangeEXT, "glFlushMappedBufferRangeEXT",
          "context = %d, target = %s, offset = %llu, length = %llu", CID(context),
          GLenumToString(GLenumGroup::BufferTargetARB, target),
          static_cast<unsigned long long>(offset), static_cast<unsigned long long>(length));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        BufferBinding targetPacked                            = FromGL<BufferBinding>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateFlushMappedBufferRangeEXT(context, targetPacked, offset, length));
        if (isCallValid)
        {
            context->flushMappedBufferRange(targetPacked, offset, length);
        }
        ANGLE_CAPTURE(FlushMappedBufferRangeEXT, isCallValid, context, targetPacked, offset,
                      length);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY FogfContextANGLE(GLeglContext ctx, GLenum pname, GLfloat param)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Fogf, "glFogf", "context = %d, pname = %s, param = %f",
          CID(context), GLenumToString(GLenumGroup::FogParameter, pname), param);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateFogf(context, pname, param));
        if (isCallValid)
        {
            context->fogf(pname, param);
        }
        ANGLE_CAPTURE(Fogf, isCallValid, context, pname, param);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY FogfvContextANGLE(GLeglContext ctx, GLenum pname, const GLfloat *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Fogfv, "glFogfv",
          "context = %d, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::FogParameter, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateFogfv(context, pname, params));
        if (isCallValid)
        {
            context->fogfv(pname, params);
        }
        ANGLE_CAPTURE(Fogfv, isCallValid, context, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY FogxContextANGLE(GLeglContext ctx, GLenum pname, GLfixed param)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Fogx, "glFogx", "context = %d, pname = %s, param = 0x%X",
          CID(context), GLenumToString(GLenumGroup::FogPName, pname), param);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateFogx(context, pname, param));
        if (isCallValid)
        {
            context->fogx(pname, param);
        }
        ANGLE_CAPTURE(Fogx, isCallValid, context, pname, param);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY FogxvContextANGLE(GLeglContext ctx, GLenum pname, const GLfixed *param)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Fogxv, "glFogxv",
          "context = %d, pname = %s, param = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::FogPName, pname), (uintptr_t)param);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateFogxv(context, pname, param));
        if (isCallValid)
        {
            context->fogxv(pname, param);
        }
        ANGLE_CAPTURE(Fogxv, isCallValid, context, pname, param);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY FramebufferParameteriContextANGLE(GLeglContext ctx,
                                                   GLenum target,
                                                   GLenum pname,
                                                   GLint param)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::FramebufferParameteri, "glFramebufferParameteri",
          "context = %d, target = %s, pname = %s, param = %d", CID(context),
          GLenumToString(GLenumGroup::FramebufferTarget, target),
          GLenumToString(GLenumGroup::FramebufferParameterName, pname), param);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateFramebufferParameteri(context, target, pname, param));
        if (isCallValid)
        {
            context->framebufferParameteri(target, pname, param);
        }
        ANGLE_CAPTURE(FramebufferParameteri, isCallValid, context, target, pname, param);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY FramebufferRenderbufferContextANGLE(GLeglContext ctx,
                                                     GLenum target,
                                                     GLenum attachment,
                                                     GLenum renderbuffertarget,
                                                     GLuint renderbuffer)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::FramebufferRenderbuffer, "glFramebufferRenderbuffer",
          "context = %d, target = %s, attachment = %s, renderbuffertarget = %s, renderbuffer = %u",
          CID(context), GLenumToString(GLenumGroup::FramebufferTarget, target),
          GLenumToString(GLenumGroup::FramebufferAttachment, attachment),
          GLenumToString(GLenumGroup::RenderbufferTarget, renderbuffertarget), renderbuffer);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        RenderbufferID renderbufferPacked = FromGL<RenderbufferID>(renderbuffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateFramebufferRenderbuffer(context, target, attachment, renderbuffertarget,
                                             renderbufferPacked));
        if (isCallValid)
        {
            context->framebufferRenderbuffer(target, attachment, renderbuffertarget,
                                             renderbufferPacked);
        }
        ANGLE_CAPTURE(FramebufferRenderbuffer, isCallValid, context, target, attachment,
                      renderbuffertarget, renderbufferPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY FramebufferRenderbufferOESContextANGLE(GLeglContext ctx,
                                                        GLenum target,
                                                        GLenum attachment,
                                                        GLenum renderbuffertarget,
                                                        GLuint renderbuffer)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::FramebufferRenderbufferOES, "glFramebufferRenderbufferOES",
          "context = %d, target = %s, attachment = %s, renderbuffertarget = %s, renderbuffer = %u",
          CID(context), GLenumToString(GLenumGroup::FramebufferTarget, target),
          GLenumToString(GLenumGroup::FramebufferAttachment, attachment),
          GLenumToString(GLenumGroup::RenderbufferTarget, renderbuffertarget), renderbuffer);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        RenderbufferID renderbufferPacked = FromGL<RenderbufferID>(renderbuffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateFramebufferRenderbufferOES(context, target, attachment, renderbuffertarget,
                                                renderbufferPacked));
        if (isCallValid)
        {
            context->framebufferRenderbuffer(target, attachment, renderbuffertarget,
                                             renderbufferPacked);
        }
        ANGLE_CAPTURE(FramebufferRenderbufferOES, isCallValid, context, target, attachment,
                      renderbuffertarget, renderbufferPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY FramebufferTextureContextANGLE(GLeglContext ctx,
                                                GLenum target,
                                                GLenum attachment,
                                                GLuint texture,
                                                GLint level)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::FramebufferTexture, "glFramebufferTexture",
          "context = %d, target = %s, attachment = %s, texture = %u, level = %d", CID(context),
          GLenumToString(GLenumGroup::FramebufferTarget, target),
          GLenumToString(GLenumGroup::FramebufferAttachment, attachment), texture, level);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureID texturePacked                               = FromGL<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateFramebufferTexture(context, target, attachment, texturePacked, level));
        if (isCallValid)
        {
            context->framebufferTexture(target, attachment, texturePacked, level);
        }
        ANGLE_CAPTURE(FramebufferTexture, isCallValid, context, target, attachment, texturePacked,
                      level);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY FramebufferTexture2DContextANGLE(GLeglContext ctx,
                                                  GLenum target,
                                                  GLenum attachment,
                                                  GLenum textarget,
                                                  GLuint texture,
                                                  GLint level)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::FramebufferTexture2D, "glFramebufferTexture2D",
          "context = %d, target = %s, attachment = %s, textarget = %s, texture = %u, level = %d",
          CID(context), GLenumToString(GLenumGroup::FramebufferTarget, target),
          GLenumToString(GLenumGroup::FramebufferAttachment, attachment),
          GLenumToString(GLenumGroup::TextureTarget, textarget), texture, level);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureTarget textargetPacked                         = FromGL<TextureTarget>(textarget);
        TextureID texturePacked                               = FromGL<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateFramebufferTexture2D(context, target, attachment,
                                                         textargetPacked, texturePacked, level));
        if (isCallValid)
        {
            context->framebufferTexture2D(target, attachment, textargetPacked, texturePacked,
                                          level);
        }
        ANGLE_CAPTURE(FramebufferTexture2D, isCallValid, context, target, attachment,
                      textargetPacked, texturePacked, level);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY FramebufferTexture2DMultisampleEXTContextANGLE(GLeglContext ctx,
                                                                GLenum target,
                                                                GLenum attachment,
                                                                GLenum textarget,
                                                                GLuint texture,
                                                                GLint level,
                                                                GLsizei samples)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::FramebufferTexture2DMultisampleEXT,
          "glFramebufferTexture2DMultisampleEXT",
          "context = %d, target = %s, attachment = %s, textarget = %s, texture = %u, level = %d, "
          "samples = %d",
          CID(context), GLenumToString(GLenumGroup::FramebufferTarget, target),
          GLenumToString(GLenumGroup::FramebufferAttachment, attachment),
          GLenumToString(GLenumGroup::TextureTarget, textarget), texture, level, samples);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureTarget textargetPacked                         = FromGL<TextureTarget>(textarget);
        TextureID texturePacked                               = FromGL<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateFramebufferTexture2DMultisampleEXT(
                 context, target, attachment, textargetPacked, texturePacked, level, samples));
        if (isCallValid)
        {
            context->framebufferTexture2DMultisample(target, attachment, textargetPacked,
                                                     texturePacked, level, samples);
        }
        ANGLE_CAPTURE(FramebufferTexture2DMultisampleEXT, isCallValid, context, target, attachment,
                      textargetPacked, texturePacked, level, samples);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY FramebufferTexture2DOESContextANGLE(GLeglContext ctx,
                                                     GLenum target,
                                                     GLenum attachment,
                                                     GLenum textarget,
                                                     GLuint texture,
                                                     GLint level)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::FramebufferTexture2DOES, "glFramebufferTexture2DOES",
          "context = %d, target = %s, attachment = %s, textarget = %s, texture = %u, level = %d",
          CID(context), GLenumToString(GLenumGroup::FramebufferTarget, target),
          GLenumToString(GLenumGroup::FramebufferAttachment, attachment),
          GLenumToString(GLenumGroup::TextureTarget, textarget), texture, level);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureTarget textargetPacked                         = FromGL<TextureTarget>(textarget);
        TextureID texturePacked                               = FromGL<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateFramebufferTexture2DOES(context, target, attachment,
                                                            textargetPacked, texturePacked, level));
        if (isCallValid)
        {
            context->framebufferTexture2D(target, attachment, textargetPacked, texturePacked,
                                          level);
        }
        ANGLE_CAPTURE(FramebufferTexture2DOES, isCallValid, context, target, attachment,
                      textargetPacked, texturePacked, level);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY FramebufferTexture3DOESContextANGLE(GLeglContext ctx,
                                                     GLenum target,
                                                     GLenum attachment,
                                                     GLenum textarget,
                                                     GLuint texture,
                                                     GLint level,
                                                     GLint zoffset)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::FramebufferTexture3DOES, "glFramebufferTexture3DOES",
          "context = %d, target = %s, attachment = %s, textarget = %s, texture = %u, level = %d, "
          "zoffset = %d",
          CID(context), GLenumToString(GLenumGroup::FramebufferTarget, target),
          GLenumToString(GLenumGroup::FramebufferAttachment, attachment),
          GLenumToString(GLenumGroup::TextureTarget, textarget), texture, level, zoffset);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureTarget textargetPacked                         = FromGL<TextureTarget>(textarget);
        TextureID texturePacked                               = FromGL<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateFramebufferTexture3DOES(context, target, attachment, textargetPacked,
                                             texturePacked, level, zoffset));
        if (isCallValid)
        {
            context->framebufferTexture3D(target, attachment, textargetPacked, texturePacked, level,
                                          zoffset);
        }
        ANGLE_CAPTURE(FramebufferTexture3DOES, isCallValid, context, target, attachment,
                      textargetPacked, texturePacked, level, zoffset);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY FramebufferTextureEXTContextANGLE(GLeglContext ctx,
                                                   GLenum target,
                                                   GLenum attachment,
                                                   GLuint texture,
                                                   GLint level)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::FramebufferTextureEXT, "glFramebufferTextureEXT",
          "context = %d, target = %s, attachment = %s, texture = %u, level = %d", CID(context),
          GLenumToString(GLenumGroup::FramebufferTarget, target),
          GLenumToString(GLenumGroup::FramebufferAttachment, attachment), texture, level);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureID texturePacked                               = FromGL<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateFramebufferTextureEXT(context, target, attachment, texturePacked, level));
        if (isCallValid)
        {
            context->framebufferTexture(target, attachment, texturePacked, level);
        }
        ANGLE_CAPTURE(FramebufferTextureEXT, isCallValid, context, target, attachment,
                      texturePacked, level);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY FramebufferTextureLayerContextANGLE(GLeglContext ctx,
                                                     GLenum target,
                                                     GLenum attachment,
                                                     GLuint texture,
                                                     GLint level,
                                                     GLint layer)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::FramebufferTextureLayer, "glFramebufferTextureLayer",
          "context = %d, target = %s, attachment = %s, texture = %u, level = %d, layer = %d",
          CID(context), GLenumToString(GLenumGroup::FramebufferTarget, target),
          GLenumToString(GLenumGroup::FramebufferAttachment, attachment), texture, level, layer);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureID texturePacked                               = FromGL<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateFramebufferTextureLayer(context, target, attachment,
                                                            texturePacked, level, layer));
        if (isCallValid)
        {
            context->framebufferTextureLayer(target, attachment, texturePacked, level, layer);
        }
        ANGLE_CAPTURE(FramebufferTextureLayer, isCallValid, context, target, attachment,
                      texturePacked, level, layer);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY FramebufferTextureMultiviewOVRContextANGLE(GLeglContext ctx,
                                                            GLenum target,
                                                            GLenum attachment,
                                                            GLuint texture,
                                                            GLint level,
                                                            GLint baseViewIndex,
                                                            GLsizei numViews)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::FramebufferTextureMultiviewOVR,
          "glFramebufferTextureMultiviewOVR",
          "context = %d, target = %s, attachment = %s, texture = %u, level = %d, baseViewIndex = "
          "%d, numViews = %d",
          CID(context), GLenumToString(GLenumGroup::FramebufferTarget, target),
          GLenumToString(GLenumGroup::FramebufferAttachment, attachment), texture, level,
          baseViewIndex, numViews);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureID texturePacked                               = FromGL<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateFramebufferTextureMultiviewOVR(context, target, attachment, texturePacked,
                                                    level, baseViewIndex, numViews));
        if (isCallValid)
        {
            context->framebufferTextureMultiview(target, attachment, texturePacked, level,
                                                 baseViewIndex, numViews);
        }
        ANGLE_CAPTURE(FramebufferTextureMultiviewOVR, isCallValid, context, target, attachment,
                      texturePacked, level, baseViewIndex, numViews);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY FrontFaceContextANGLE(GLeglContext ctx, GLenum mode)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::FrontFace, "glFrontFace", "context = %d, mode = %s",
          CID(context), GLenumToString(GLenumGroup::FrontFaceDirection, mode));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateFrontFace(context, mode));
        if (isCallValid)
        {
            context->frontFace(mode);
        }
        ANGLE_CAPTURE(FrontFace, isCallValid, context, mode);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY FrustumfContextANGLE(GLeglContext ctx,
                                      GLfloat l,
                                      GLfloat r,
                                      GLfloat b,
                                      GLfloat t,
                                      GLfloat n,
                                      GLfloat f)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Frustumf, "glFrustumf",
          "context = %d, l = %f, r = %f, b = %f, t = %f, n = %f, f = %f", CID(context), l, r, b, t,
          n, f);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateFrustumf(context, l, r, b, t, n, f));
        if (isCallValid)
        {
            context->frustumf(l, r, b, t, n, f);
        }
        ANGLE_CAPTURE(Frustumf, isCallValid, context, l, r, b, t, n, f);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY FrustumxContextANGLE(GLeglContext ctx,
                                      GLfixed l,
                                      GLfixed r,
                                      GLfixed b,
                                      GLfixed t,
                                      GLfixed n,
                                      GLfixed f)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Frustumx, "glFrustumx",
          "context = %d, l = 0x%X, r = 0x%X, b = 0x%X, t = 0x%X, n = 0x%X, f = 0x%X", CID(context),
          l, r, b, t, n, f);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateFrustumx(context, l, r, b, t, n, f));
        if (isCallValid)
        {
            context->frustumx(l, r, b, t, n, f);
        }
        ANGLE_CAPTURE(Frustumx, isCallValid, context, l, r, b, t, n, f);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GenBuffersContextANGLE(GLeglContext ctx, GLsizei n, GLuint *buffers)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GenBuffers, "glGenBuffers",
          "context = %d, n = %d, buffers = 0x%016" PRIxPTR "", CID(context), n, (uintptr_t)buffers);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        BufferID *buffersPacked                               = FromGL<BufferID *>(buffers);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGenBuffers(context, n, buffersPacked));
        if (isCallValid)
        {
            context->genBuffers(n, buffersPacked);
        }
        ANGLE_CAPTURE(GenBuffers, isCallValid, context, n, buffersPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GenFencesNVContextANGLE(GLeglContext ctx, GLsizei n, GLuint *fences)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GenFencesNV, "glGenFencesNV",
          "context = %d, n = %d, fences = 0x%016" PRIxPTR "", CID(context), n, (uintptr_t)fences);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        FenceNVID *fencesPacked                               = FromGL<FenceNVID *>(fences);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGenFencesNV(context, n, fencesPacked));
        if (isCallValid)
        {
            context->genFencesNV(n, fencesPacked);
        }
        ANGLE_CAPTURE(GenFencesNV, isCallValid, context, n, fencesPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GenFramebuffersContextANGLE(GLeglContext ctx, GLsizei n, GLuint *framebuffers)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GenFramebuffers, "glGenFramebuffers",
          "context = %d, n = %d, framebuffers = 0x%016" PRIxPTR "", CID(context), n,
          (uintptr_t)framebuffers);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        FramebufferID *framebuffersPacked = FromGL<FramebufferID *>(framebuffers);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGenFramebuffers(context, n, framebuffersPacked));
        if (isCallValid)
        {
            context->genFramebuffers(n, framebuffersPacked);
        }
        ANGLE_CAPTURE(GenFramebuffers, isCallValid, context, n, framebuffersPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GenFramebuffersOESContextANGLE(GLeglContext ctx, GLsizei n, GLuint *framebuffers)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GenFramebuffersOES, "glGenFramebuffersOES",
          "context = %d, n = %d, framebuffers = 0x%016" PRIxPTR "", CID(context), n,
          (uintptr_t)framebuffers);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        FramebufferID *framebuffersPacked = FromGL<FramebufferID *>(framebuffers);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGenFramebuffersOES(context, n, framebuffersPacked));
        if (isCallValid)
        {
            context->genFramebuffers(n, framebuffersPacked);
        }
        ANGLE_CAPTURE(GenFramebuffersOES, isCallValid, context, n, framebuffersPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GenProgramPipelinesContextANGLE(GLeglContext ctx, GLsizei n, GLuint *pipelines)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GenProgramPipelines, "glGenProgramPipelines",
          "context = %d, n = %d, pipelines = 0x%016" PRIxPTR "", CID(context), n,
          (uintptr_t)pipelines);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ProgramPipelineID *pipelinesPacked = FromGL<ProgramPipelineID *>(pipelines);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGenProgramPipelines(context, n, pipelinesPacked));
        if (isCallValid)
        {
            context->genProgramPipelines(n, pipelinesPacked);
        }
        ANGLE_CAPTURE(GenProgramPipelines, isCallValid, context, n, pipelinesPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GenQueriesContextANGLE(GLeglContext ctx, GLsizei n, GLuint *ids)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GenQueries, "glGenQueries",
          "context = %d, n = %d, ids = 0x%016" PRIxPTR "", CID(context), n, (uintptr_t)ids);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        QueryID *idsPacked                                    = FromGL<QueryID *>(ids);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateGenQueries(context, n, idsPacked));
        if (isCallValid)
        {
            context->genQueries(n, idsPacked);
        }
        ANGLE_CAPTURE(GenQueries, isCallValid, context, n, idsPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GenQueriesEXTContextANGLE(GLeglContext ctx, GLsizei n, GLuint *ids)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GenQueriesEXT, "glGenQueriesEXT",
          "context = %d, n = %d, ids = 0x%016" PRIxPTR "", CID(context), n, (uintptr_t)ids);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        QueryID *idsPacked                                    = FromGL<QueryID *>(ids);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGenQueriesEXT(context, n, idsPacked));
        if (isCallValid)
        {
            context->genQueries(n, idsPacked);
        }
        ANGLE_CAPTURE(GenQueriesEXT, isCallValid, context, n, idsPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GenRenderbuffersContextANGLE(GLeglContext ctx, GLsizei n, GLuint *renderbuffers)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GenRenderbuffers, "glGenRenderbuffers",
          "context = %d, n = %d, renderbuffers = 0x%016" PRIxPTR "", CID(context), n,
          (uintptr_t)renderbuffers);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        RenderbufferID *renderbuffersPacked = FromGL<RenderbufferID *>(renderbuffers);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGenRenderbuffers(context, n, renderbuffersPacked));
        if (isCallValid)
        {
            context->genRenderbuffers(n, renderbuffersPacked);
        }
        ANGLE_CAPTURE(GenRenderbuffers, isCallValid, context, n, renderbuffersPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GenRenderbuffersOESContextANGLE(GLeglContext ctx, GLsizei n, GLuint *renderbuffers)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GenRenderbuffersOES, "glGenRenderbuffersOES",
          "context = %d, n = %d, renderbuffers = 0x%016" PRIxPTR "", CID(context), n,
          (uintptr_t)renderbuffers);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        RenderbufferID *renderbuffersPacked = FromGL<RenderbufferID *>(renderbuffers);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGenRenderbuffersOES(context, n, renderbuffersPacked));
        if (isCallValid)
        {
            context->genRenderbuffers(n, renderbuffersPacked);
        }
        ANGLE_CAPTURE(GenRenderbuffersOES, isCallValid, context, n, renderbuffersPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GenSamplersContextANGLE(GLeglContext ctx, GLsizei count, GLuint *samplers)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GenSamplers, "glGenSamplers",
          "context = %d, count = %d, samplers = 0x%016" PRIxPTR "", CID(context), count,
          (uintptr_t)samplers);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        SamplerID *samplersPacked                             = FromGL<SamplerID *>(samplers);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGenSamplers(context, count, samplersPacked));
        if (isCallValid)
        {
            context->genSamplers(count, samplersPacked);
        }
        ANGLE_CAPTURE(GenSamplers, isCallValid, context, count, samplersPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GenSemaphoresEXTContextANGLE(GLeglContext ctx, GLsizei n, GLuint *semaphores)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GenSemaphoresEXT, "glGenSemaphoresEXT",
          "context = %d, n = %d, semaphores = 0x%016" PRIxPTR "", CID(context), n,
          (uintptr_t)semaphores);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        SemaphoreID *semaphoresPacked                         = FromGL<SemaphoreID *>(semaphores);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGenSemaphoresEXT(context, n, semaphoresPacked));
        if (isCallValid)
        {
            context->genSemaphores(n, semaphoresPacked);
        }
        ANGLE_CAPTURE(GenSemaphoresEXT, isCallValid, context, n, semaphoresPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GenTexturesContextANGLE(GLeglContext ctx, GLsizei n, GLuint *textures)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GenTextures, "glGenTextures",
          "context = %d, n = %d, textures = 0x%016" PRIxPTR "", CID(context), n,
          (uintptr_t)textures);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureID *texturesPacked                             = FromGL<TextureID *>(textures);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGenTextures(context, n, texturesPacked));
        if (isCallValid)
        {
            context->genTextures(n, texturesPacked);
        }
        ANGLE_CAPTURE(GenTextures, isCallValid, context, n, texturesPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GenTransformFeedbacksContextANGLE(GLeglContext ctx, GLsizei n, GLuint *ids)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GenTransformFeedbacks, "glGenTransformFeedbacks",
          "context = %d, n = %d, ids = 0x%016" PRIxPTR "", CID(context), n, (uintptr_t)ids);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TransformFeedbackID *idsPacked                        = FromGL<TransformFeedbackID *>(ids);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGenTransformFeedbacks(context, n, idsPacked));
        if (isCallValid)
        {
            context->genTransformFeedbacks(n, idsPacked);
        }
        ANGLE_CAPTURE(GenTransformFeedbacks, isCallValid, context, n, idsPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GenVertexArraysContextANGLE(GLeglContext ctx, GLsizei n, GLuint *arrays)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GenVertexArrays, "glGenVertexArrays",
          "context = %d, n = %d, arrays = 0x%016" PRIxPTR "", CID(context), n, (uintptr_t)arrays);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        VertexArrayID *arraysPacked                           = FromGL<VertexArrayID *>(arrays);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGenVertexArrays(context, n, arraysPacked));
        if (isCallValid)
        {
            context->genVertexArrays(n, arraysPacked);
        }
        ANGLE_CAPTURE(GenVertexArrays, isCallValid, context, n, arraysPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GenVertexArraysOESContextANGLE(GLeglContext ctx, GLsizei n, GLuint *arrays)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GenVertexArraysOES, "glGenVertexArraysOES",
          "context = %d, n = %d, arrays = 0x%016" PRIxPTR "", CID(context), n, (uintptr_t)arrays);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        VertexArrayID *arraysPacked                           = FromGL<VertexArrayID *>(arrays);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGenVertexArraysOES(context, n, arraysPacked));
        if (isCallValid)
        {
            context->genVertexArrays(n, arraysPacked);
        }
        ANGLE_CAPTURE(GenVertexArraysOES, isCallValid, context, n, arraysPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GenerateMipmapContextANGLE(GLeglContext ctx, GLenum target)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GenerateMipmap, "glGenerateMipmap", "context = %d, target = %s",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGenerateMipmap(context, targetPacked));
        if (isCallValid)
        {
            context->generateMipmap(targetPacked);
        }
        ANGLE_CAPTURE(GenerateMipmap, isCallValid, context, targetPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GenerateMipmapOESContextANGLE(GLeglContext ctx, GLenum target)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GenerateMipmapOES, "glGenerateMipmapOES",
          "context = %d, target = %s", CID(context),
          GLenumToString(GLenumGroup::TextureTarget, target));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGenerateMipmapOES(context, targetPacked));
        if (isCallValid)
        {
            context->generateMipmap(targetPacked);
        }
        ANGLE_CAPTURE(GenerateMipmapOES, isCallValid, context, targetPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetActiveAttribContextANGLE(GLeglContext ctx,
                                             GLuint program,
                                             GLuint index,
                                             GLsizei bufSize,
                                             GLsizei *length,
                                             GLint *size,
                                             GLenum *type,
                                             GLchar *name)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetActiveAttrib, "glGetActiveAttrib",
          "context = %d, program = %u, index = %u, bufSize = %d, length = 0x%016" PRIxPTR
          ", size = 0x%016" PRIxPTR ", type = 0x%016" PRIxPTR ", name = 0x%016" PRIxPTR "",
          CID(context), program, index, bufSize, (uintptr_t)length, (uintptr_t)size,
          (uintptr_t)type, (uintptr_t)name);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetActiveAttrib(context, programPacked, index, bufSize, length,
                                                    size, type, name));
        if (isCallValid)
        {
            context->getActiveAttrib(programPacked, index, bufSize, length, size, type, name);
        }
        ANGLE_CAPTURE(GetActiveAttrib, isCallValid, context, programPacked, index, bufSize, length,
                      size, type, name);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetActiveUniformContextANGLE(GLeglContext ctx,
                                              GLuint program,
                                              GLuint index,
                                              GLsizei bufSize,
                                              GLsizei *length,
                                              GLint *size,
                                              GLenum *type,
                                              GLchar *name)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetActiveUniform, "glGetActiveUniform",
          "context = %d, program = %u, index = %u, bufSize = %d, length = 0x%016" PRIxPTR
          ", size = 0x%016" PRIxPTR ", type = 0x%016" PRIxPTR ", name = 0x%016" PRIxPTR "",
          CID(context), program, index, bufSize, (uintptr_t)length, (uintptr_t)size,
          (uintptr_t)type, (uintptr_t)name);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetActiveUniform(context, programPacked, index, bufSize, length,
                                                     size, type, name));
        if (isCallValid)
        {
            context->getActiveUniform(programPacked, index, bufSize, length, size, type, name);
        }
        ANGLE_CAPTURE(GetActiveUniform, isCallValid, context, programPacked, index, bufSize, length,
                      size, type, name);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetActiveUniformBlockNameContextANGLE(GLeglContext ctx,
                                                       GLuint program,
                                                       GLuint uniformBlockIndex,
                                                       GLsizei bufSize,
                                                       GLsizei *length,
                                                       GLchar *uniformBlockName)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(
        context, gl::EntryPoint::GetActiveUniformBlockName, "glGetActiveUniformBlockName",
        "context = %d, program = %u, uniformBlockIndex = %u, bufSize = %d, length = 0x%016" PRIxPTR
        ", uniformBlockName = 0x%016" PRIxPTR "",
        CID(context), program, uniformBlockIndex, bufSize, (uintptr_t)length,
        (uintptr_t)uniformBlockName);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetActiveUniformBlockName(context, programPacked, uniformBlockIndex, bufSize,
                                               length, uniformBlockName));
        if (isCallValid)
        {
            context->getActiveUniformBlockName(programPacked, uniformBlockIndex, bufSize, length,
                                               uniformBlockName);
        }
        ANGLE_CAPTURE(GetActiveUniformBlockName, isCallValid, context, programPacked,
                      uniformBlockIndex, bufSize, length, uniformBlockName);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetActiveUniformBlockivContextANGLE(GLeglContext ctx,
                                                     GLuint program,
                                                     GLuint uniformBlockIndex,
                                                     GLenum pname,
                                                     GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetActiveUniformBlockiv, "glGetActiveUniformBlockiv",
          "context = %d, program = %u, uniformBlockIndex = %u, pname = %s, params = 0x%016" PRIxPTR
          "",
          CID(context), program, uniformBlockIndex,
          GLenumToString(GLenumGroup::UniformBlockPName, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetActiveUniformBlockiv(context, programPacked,
                                                            uniformBlockIndex, pname, params));
        if (isCallValid)
        {
            context->getActiveUniformBlockiv(programPacked, uniformBlockIndex, pname, params);
        }
        ANGLE_CAPTURE(GetActiveUniformBlockiv, isCallValid, context, programPacked,
                      uniformBlockIndex, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetActiveUniformsivContextANGLE(GLeglContext ctx,
                                                 GLuint program,
                                                 GLsizei uniformCount,
                                                 const GLuint *uniformIndices,
                                                 GLenum pname,
                                                 GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetActiveUniformsiv, "glGetActiveUniformsiv",
          "context = %d, program = %u, uniformCount = %d, uniformIndices = 0x%016" PRIxPTR
          ", pname = %s, params = 0x%016" PRIxPTR "",
          CID(context), program, uniformCount, (uintptr_t)uniformIndices,
          GLenumToString(GLenumGroup::UniformPName, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetActiveUniformsiv(context, programPacked, uniformCount,
                                                        uniformIndices, pname, params));
        if (isCallValid)
        {
            context->getActiveUniformsiv(programPacked, uniformCount, uniformIndices, pname,
                                         params);
        }
        ANGLE_CAPTURE(GetActiveUniformsiv, isCallValid, context, programPacked, uniformCount,
                      uniformIndices, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetAttachedShadersContextANGLE(GLeglContext ctx,
                                                GLuint program,
                                                GLsizei maxCount,
                                                GLsizei *count,
                                                GLuint *shaders)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetAttachedShaders, "glGetAttachedShaders",
          "context = %d, program = %u, maxCount = %d, count = 0x%016" PRIxPTR
          ", shaders = 0x%016" PRIxPTR "",
          CID(context), program, maxCount, (uintptr_t)count, (uintptr_t)shaders);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        ShaderProgramID *shadersPacked                        = FromGL<ShaderProgramID *>(shaders);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetAttachedShaders(context, programPacked, maxCount, count, shadersPacked));
        if (isCallValid)
        {
            context->getAttachedShaders(programPacked, maxCount, count, shadersPacked);
        }
        ANGLE_CAPTURE(GetAttachedShaders, isCallValid, context, programPacked, maxCount, count,
                      shadersPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

GLint GL_APIENTRY GetAttribLocationContextANGLE(GLeglContext ctx,
                                                GLuint program,
                                                const GLchar *name)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetAttribLocation, "glGetAttribLocation",
          "context = %d, program = %u, name = 0x%016" PRIxPTR "", CID(context), program,
          (uintptr_t)name);

    GLint returnValue;
    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetAttribLocation(context, programPacked, name));
        if (isCallValid)
        {
            returnValue = context->getAttribLocation(programPacked, name);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::GetAttribLocation, GLint>();
        }
        ANGLE_CAPTURE(GetAttribLocation, isCallValid, context, programPacked, name, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
        returnValue = GetDefaultReturnValue<EntryPoint::GetAttribLocation, GLint>();
    }
    return returnValue;
}

void GL_APIENTRY GetBooleani_vContextANGLE(GLeglContext ctx,
                                           GLenum target,
                                           GLuint index,
                                           GLboolean *data)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetBooleani_v, "glGetBooleani_v",
          "context = %d, target = %s, index = %u, data = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::BufferTargetARB, target), index, (uintptr_t)data);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetBooleani_v(context, target, index, data));
        if (isCallValid)
        {
            context->getBooleani_v(target, index, data);
        }
        ANGLE_CAPTURE(GetBooleani_v, isCallValid, context, target, index, data);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetBooleanvContextANGLE(GLeglContext ctx, GLenum pname, GLboolean *data)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetBooleanv, "glGetBooleanv",
          "context = %d, pname = %s, data = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::GetPName, pname), (uintptr_t)data);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateGetBooleanv(context, pname, data));
        if (isCallValid)
        {
            context->getBooleanv(pname, data);
        }
        ANGLE_CAPTURE(GetBooleanv, isCallValid, context, pname, data);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetBufferParameteri64vContextANGLE(GLeglContext ctx,
                                                    GLenum target,
                                                    GLenum pname,
                                                    GLint64 *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetBufferParameteri64v, "glGetBufferParameteri64v",
          "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::BufferTargetARB, target),
          GLenumToString(GLenumGroup::DefaultGroup, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        BufferBinding targetPacked                            = FromGL<BufferBinding>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetBufferParameteri64v(context, targetPacked, pname, params));
        if (isCallValid)
        {
            context->getBufferParameteri64v(targetPacked, pname, params);
        }
        ANGLE_CAPTURE(GetBufferParameteri64v, isCallValid, context, targetPacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetBufferParameterivContextANGLE(GLeglContext ctx,
                                                  GLenum target,
                                                  GLenum pname,
                                                  GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetBufferParameteriv, "glGetBufferParameteriv",
          "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::BufferTargetARB, target),
          GLenumToString(GLenumGroup::DefaultGroup, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        BufferBinding targetPacked                            = FromGL<BufferBinding>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetBufferParameteriv(context, targetPacked, pname, params));
        if (isCallValid)
        {
            context->getBufferParameteriv(targetPacked, pname, params);
        }
        ANGLE_CAPTURE(GetBufferParameteriv, isCallValid, context, targetPacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetBufferPointervContextANGLE(GLeglContext ctx,
                                               GLenum target,
                                               GLenum pname,
                                               void **params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetBufferPointerv, "glGetBufferPointerv",
          "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::BufferTargetARB, target),
          GLenumToString(GLenumGroup::DefaultGroup, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        BufferBinding targetPacked                            = FromGL<BufferBinding>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetBufferPointerv(context, targetPacked, pname, params));
        if (isCallValid)
        {
            context->getBufferPointerv(targetPacked, pname, params);
        }
        ANGLE_CAPTURE(GetBufferPointerv, isCallValid, context, targetPacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetBufferPointervOESContextANGLE(GLeglContext ctx,
                                                  GLenum target,
                                                  GLenum pname,
                                                  void **params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetBufferPointervOES, "glGetBufferPointervOES",
          "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::BufferTargetARB, target),
          GLenumToString(GLenumGroup::DefaultGroup, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        BufferBinding targetPacked                            = FromGL<BufferBinding>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetBufferPointervOES(context, targetPacked, pname, params));
        if (isCallValid)
        {
            context->getBufferPointerv(targetPacked, pname, params);
        }
        ANGLE_CAPTURE(GetBufferPointervOES, isCallValid, context, targetPacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetClipPlanefContextANGLE(GLeglContext ctx, GLenum plane, GLfloat *equation)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetClipPlanef, "glGetClipPlanef",
          "context = %d, plane = %s, equation = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::ClipPlaneName, plane), (uintptr_t)equation);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetClipPlanef(context, plane, equation));
        if (isCallValid)
        {
            context->getClipPlanef(plane, equation);
        }
        ANGLE_CAPTURE(GetClipPlanef, isCallValid, context, plane, equation);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetClipPlanexContextANGLE(GLeglContext ctx, GLenum plane, GLfixed *equation)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetClipPlanex, "glGetClipPlanex",
          "context = %d, plane = %s, equation = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::ClipPlaneName, plane), (uintptr_t)equation);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetClipPlanex(context, plane, equation));
        if (isCallValid)
        {
            context->getClipPlanex(plane, equation);
        }
        ANGLE_CAPTURE(GetClipPlanex, isCallValid, context, plane, equation);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

GLuint GL_APIENTRY GetDebugMessageLogContextANGLE(GLeglContext ctx,
                                                  GLuint count,
                                                  GLsizei bufSize,
                                                  GLenum *sources,
                                                  GLenum *types,
                                                  GLuint *ids,
                                                  GLenum *severities,
                                                  GLsizei *lengths,
                                                  GLchar *messageLog)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetDebugMessageLog, "glGetDebugMessageLog",
          "context = %d, count = %u, bufSize = %d, sources = 0x%016" PRIxPTR
          ", types = 0x%016" PRIxPTR ", ids = 0x%016" PRIxPTR ", severities = 0x%016" PRIxPTR
          ", lengths = 0x%016" PRIxPTR ", messageLog = 0x%016" PRIxPTR "",
          CID(context), count, bufSize, (uintptr_t)sources, (uintptr_t)types, (uintptr_t)ids,
          (uintptr_t)severities, (uintptr_t)lengths, (uintptr_t)messageLog);

    GLuint returnValue;
    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetDebugMessageLog(context, count, bufSize, sources, types, ids,
                                                       severities, lengths, messageLog));
        if (isCallValid)
        {
            returnValue = context->getDebugMessageLog(count, bufSize, sources, types, ids,
                                                      severities, lengths, messageLog);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::GetDebugMessageLog, GLuint>();
        }
        ANGLE_CAPTURE(GetDebugMessageLog, isCallValid, context, count, bufSize, sources, types, ids,
                      severities, lengths, messageLog, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
        returnValue = GetDefaultReturnValue<EntryPoint::GetDebugMessageLog, GLuint>();
    }
    return returnValue;
}

GLuint GL_APIENTRY GetDebugMessageLogKHRContextANGLE(GLeglContext ctx,
                                                     GLuint count,
                                                     GLsizei bufSize,
                                                     GLenum *sources,
                                                     GLenum *types,
                                                     GLuint *ids,
                                                     GLenum *severities,
                                                     GLsizei *lengths,
                                                     GLchar *messageLog)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetDebugMessageLogKHR, "glGetDebugMessageLogKHR",
          "context = %d, count = %u, bufSize = %d, sources = 0x%016" PRIxPTR
          ", types = 0x%016" PRIxPTR ", ids = 0x%016" PRIxPTR ", severities = 0x%016" PRIxPTR
          ", lengths = 0x%016" PRIxPTR ", messageLog = 0x%016" PRIxPTR "",
          CID(context), count, bufSize, (uintptr_t)sources, (uintptr_t)types, (uintptr_t)ids,
          (uintptr_t)severities, (uintptr_t)lengths, (uintptr_t)messageLog);

    GLuint returnValue;
    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetDebugMessageLogKHR(context, count, bufSize, sources, types,
                                                          ids, severities, lengths, messageLog));
        if (isCallValid)
        {
            returnValue = context->getDebugMessageLog(count, bufSize, sources, types, ids,
                                                      severities, lengths, messageLog);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::GetDebugMessageLogKHR, GLuint>();
        }
        ANGLE_CAPTURE(GetDebugMessageLogKHR, isCallValid, context, count, bufSize, sources, types,
                      ids, severities, lengths, messageLog, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
        returnValue = GetDefaultReturnValue<EntryPoint::GetDebugMessageLogKHR, GLuint>();
    }
    return returnValue;
}

GLenum GL_APIENTRY GetErrorContextANGLE(GLeglContext ctx)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetError, "glGetError", "context = %d", CID(context));

    GLenum returnValue;
    if (context)
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateGetError(context));
        if (isCallValid)
        {
            returnValue = context->getError();
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::GetError, GLenum>();
        }
        ANGLE_CAPTURE(GetError, isCallValid, context, returnValue);
    }
    else
    {

        returnValue = GetDefaultReturnValue<EntryPoint::GetError, GLenum>();
    }
    return returnValue;
}

void GL_APIENTRY GetFenceivNVContextANGLE(GLeglContext ctx,
                                          GLuint fence,
                                          GLenum pname,
                                          GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetFenceivNV, "glGetFenceivNV",
          "context = %d, fence = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context), fence,
          GLenumToString(GLenumGroup::DefaultGroup, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        FenceNVID fencePacked                                 = FromGL<FenceNVID>(fence);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetFenceivNV(context, fencePacked, pname, params));
        if (isCallValid)
        {
            context->getFenceivNV(fencePacked, pname, params);
        }
        ANGLE_CAPTURE(GetFenceivNV, isCallValid, context, fencePacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetFixedvContextANGLE(GLeglContext ctx, GLenum pname, GLfixed *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetFixedv, "glGetFixedv",
          "context = %d, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::GetPName, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateGetFixedv(context, pname, params));
        if (isCallValid)
        {
            context->getFixedv(pname, params);
        }
        ANGLE_CAPTURE(GetFixedv, isCallValid, context, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetFloatvContextANGLE(GLeglContext ctx, GLenum pname, GLfloat *data)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetFloatv, "glGetFloatv",
          "context = %d, pname = %s, data = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::GetPName, pname), (uintptr_t)data);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateGetFloatv(context, pname, data));
        if (isCallValid)
        {
            context->getFloatv(pname, data);
        }
        ANGLE_CAPTURE(GetFloatv, isCallValid, context, pname, data);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

GLint GL_APIENTRY GetFragDataIndexEXTContextANGLE(GLeglContext ctx,
                                                  GLuint program,
                                                  const GLchar *name)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetFragDataIndexEXT, "glGetFragDataIndexEXT",
          "context = %d, program = %u, name = 0x%016" PRIxPTR "", CID(context), program,
          (uintptr_t)name);

    GLint returnValue;
    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetFragDataIndexEXT(context, programPacked, name));
        if (isCallValid)
        {
            returnValue = context->getFragDataIndex(programPacked, name);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::GetFragDataIndexEXT, GLint>();
        }
        ANGLE_CAPTURE(GetFragDataIndexEXT, isCallValid, context, programPacked, name, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
        returnValue = GetDefaultReturnValue<EntryPoint::GetFragDataIndexEXT, GLint>();
    }
    return returnValue;
}

GLint GL_APIENTRY GetFragDataLocationContextANGLE(GLeglContext ctx,
                                                  GLuint program,
                                                  const GLchar *name)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetFragDataLocation, "glGetFragDataLocation",
          "context = %d, program = %u, name = 0x%016" PRIxPTR "", CID(context), program,
          (uintptr_t)name);

    GLint returnValue;
    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetFragDataLocation(context, programPacked, name));
        if (isCallValid)
        {
            returnValue = context->getFragDataLocation(programPacked, name);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::GetFragDataLocation, GLint>();
        }
        ANGLE_CAPTURE(GetFragDataLocation, isCallValid, context, programPacked, name, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
        returnValue = GetDefaultReturnValue<EntryPoint::GetFragDataLocation, GLint>();
    }
    return returnValue;
}

void GL_APIENTRY GetFramebufferAttachmentParameterivContextANGLE(GLeglContext ctx,
                                                                 GLenum target,
                                                                 GLenum attachment,
                                                                 GLenum pname,
                                                                 GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetFramebufferAttachmentParameteriv,
          "glGetFramebufferAttachmentParameteriv",
          "context = %d, target = %s, attachment = %s, pname = %s, params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::FramebufferTarget, target),
          GLenumToString(GLenumGroup::FramebufferAttachment, attachment),
          GLenumToString(GLenumGroup::FramebufferAttachmentParameterName, pname),
          (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetFramebufferAttachmentParameteriv(
                                              context, target, attachment, pname, params));
        if (isCallValid)
        {
            context->getFramebufferAttachmentParameteriv(target, attachment, pname, params);
        }
        ANGLE_CAPTURE(GetFramebufferAttachmentParameteriv, isCallValid, context, target, attachment,
                      pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetFramebufferAttachmentParameterivOESContextANGLE(GLeglContext ctx,
                                                                    GLenum target,
                                                                    GLenum attachment,
                                                                    GLenum pname,
                                                                    GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetFramebufferAttachmentParameterivOES,
          "glGetFramebufferAttachmentParameterivOES",
          "context = %d, target = %s, attachment = %s, pname = %s, params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::FramebufferTarget, target),
          GLenumToString(GLenumGroup::FramebufferAttachment, attachment),
          GLenumToString(GLenumGroup::FramebufferAttachmentParameterName, pname),
          (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetFramebufferAttachmentParameterivOES(
                                              context, target, attachment, pname, params));
        if (isCallValid)
        {
            context->getFramebufferAttachmentParameteriv(target, attachment, pname, params);
        }
        ANGLE_CAPTURE(GetFramebufferAttachmentParameterivOES, isCallValid, context, target,
                      attachment, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetFramebufferParameterivContextANGLE(GLeglContext ctx,
                                                       GLenum target,
                                                       GLenum pname,
                                                       GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetFramebufferParameteriv, "glGetFramebufferParameteriv",
          "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::FramebufferTarget, target),
          GLenumToString(GLenumGroup::FramebufferAttachmentParameterName, pname),
          (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetFramebufferParameteriv(context, target, pname, params));
        if (isCallValid)
        {
            context->getFramebufferParameteriv(target, pname, params);
        }
        ANGLE_CAPTURE(GetFramebufferParameteriv, isCallValid, context, target, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

GLenum GL_APIENTRY GetGraphicsResetStatusContextANGLE(GLeglContext ctx)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetGraphicsResetStatus, "glGetGraphicsResetStatus",
          "context = %d", CID(context));

    GLenum returnValue;
    if (context)
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateGetGraphicsResetStatus(context));
        if (isCallValid)
        {
            returnValue = context->getGraphicsResetStatus();
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::GetGraphicsResetStatus, GLenum>();
        }
        ANGLE_CAPTURE(GetGraphicsResetStatus, isCallValid, context, returnValue);
    }
    else
    {

        returnValue = GetDefaultReturnValue<EntryPoint::GetGraphicsResetStatus, GLenum>();
    }
    return returnValue;
}

GLenum GL_APIENTRY GetGraphicsResetStatusEXTContextANGLE(GLeglContext ctx)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetGraphicsResetStatusEXT, "glGetGraphicsResetStatusEXT",
          "context = %d", CID(context));

    GLenum returnValue;
    if (context)
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetGraphicsResetStatusEXT(context));
        if (isCallValid)
        {
            returnValue = context->getGraphicsResetStatus();
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::GetGraphicsResetStatusEXT, GLenum>();
        }
        ANGLE_CAPTURE(GetGraphicsResetStatusEXT, isCallValid, context, returnValue);
    }
    else
    {

        returnValue = GetDefaultReturnValue<EntryPoint::GetGraphicsResetStatusEXT, GLenum>();
    }
    return returnValue;
}

void GL_APIENTRY GetInteger64i_vContextANGLE(GLeglContext ctx,
                                             GLenum target,
                                             GLuint index,
                                             GLint64 *data)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetInteger64i_v, "glGetInteger64i_v",
          "context = %d, target = %s, index = %u, data = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::TypeEnum, target), index, (uintptr_t)data);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetInteger64i_v(context, target, index, data));
        if (isCallValid)
        {
            context->getInteger64i_v(target, index, data);
        }
        ANGLE_CAPTURE(GetInteger64i_v, isCallValid, context, target, index, data);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetInteger64vContextANGLE(GLeglContext ctx, GLenum pname, GLint64 *data)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetInteger64v, "glGetInteger64v",
          "context = %d, pname = %s, data = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::GetPName, pname), (uintptr_t)data);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetInteger64v(context, pname, data));
        if (isCallValid)
        {
            context->getInteger64v(pname, data);
        }
        ANGLE_CAPTURE(GetInteger64v, isCallValid, context, pname, data);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetInteger64vEXTContextANGLE(GLeglContext ctx, GLenum pname, GLint64 *data)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetInteger64vEXT, "glGetInteger64vEXT",
          "context = %d, pname = %s, data = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::GetPName, pname), (uintptr_t)data);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetInteger64vEXT(context, pname, data));
        if (isCallValid)
        {
            context->getInteger64v(pname, data);
        }
        ANGLE_CAPTURE(GetInteger64vEXT, isCallValid, context, pname, data);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetIntegeri_vContextANGLE(GLeglContext ctx,
                                           GLenum target,
                                           GLuint index,
                                           GLint *data)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetIntegeri_v, "glGetIntegeri_v",
          "context = %d, target = %s, index = %u, data = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::TypeEnum, target), index, (uintptr_t)data);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetIntegeri_v(context, target, index, data));
        if (isCallValid)
        {
            context->getIntegeri_v(target, index, data);
        }
        ANGLE_CAPTURE(GetIntegeri_v, isCallValid, context, target, index, data);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetIntegervContextANGLE(GLeglContext ctx, GLenum pname, GLint *data)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetIntegerv, "glGetIntegerv",
          "context = %d, pname = %s, data = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::GetPName, pname), (uintptr_t)data);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateGetIntegerv(context, pname, data));
        if (isCallValid)
        {
            context->getIntegerv(pname, data);
        }
        ANGLE_CAPTURE(GetIntegerv, isCallValid, context, pname, data);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetInternalformativContextANGLE(GLeglContext ctx,
                                                 GLenum target,
                                                 GLenum internalformat,
                                                 GLenum pname,
                                                 GLsizei bufSize,
                                                 GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetInternalformativ, "glGetInternalformativ",
          "context = %d, target = %s, internalformat = %s, pname = %s, bufSize = %d, params = "
          "0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target),
          GLenumToString(GLenumGroup::InternalFormat, internalformat),
          GLenumToString(GLenumGroup::InternalFormatPName, pname), bufSize, (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetInternalformativ(context, target, internalformat, pname, bufSize, params));
        if (isCallValid)
        {
            context->getInternalformativ(target, internalformat, pname, bufSize, params);
        }
        ANGLE_CAPTURE(GetInternalformativ, isCallValid, context, target, internalformat, pname,
                      bufSize, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetLightfvContextANGLE(GLeglContext ctx,
                                        GLenum light,
                                        GLenum pname,
                                        GLfloat *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetLightfv, "glGetLightfv",
          "context = %d, light = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::LightName, light),
          GLenumToString(GLenumGroup::LightParameter, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        LightParameter pnamePacked                            = FromGL<LightParameter>(pname);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetLightfv(context, light, pnamePacked, params));
        if (isCallValid)
        {
            context->getLightfv(light, pnamePacked, params);
        }
        ANGLE_CAPTURE(GetLightfv, isCallValid, context, light, pnamePacked, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetLightxvContextANGLE(GLeglContext ctx,
                                        GLenum light,
                                        GLenum pname,
                                        GLfixed *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetLightxv, "glGetLightxv",
          "context = %d, light = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::LightName, light),
          GLenumToString(GLenumGroup::LightParameter, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        LightParameter pnamePacked                            = FromGL<LightParameter>(pname);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetLightxv(context, light, pnamePacked, params));
        if (isCallValid)
        {
            context->getLightxv(light, pnamePacked, params);
        }
        ANGLE_CAPTURE(GetLightxv, isCallValid, context, light, pnamePacked, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetMaterialfvContextANGLE(GLeglContext ctx,
                                           GLenum face,
                                           GLenum pname,
                                           GLfloat *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetMaterialfv, "glGetMaterialfv",
          "context = %d, face = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::MaterialFace, face),
          GLenumToString(GLenumGroup::MaterialParameter, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        MaterialParameter pnamePacked                         = FromGL<MaterialParameter>(pname);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetMaterialfv(context, face, pnamePacked, params));
        if (isCallValid)
        {
            context->getMaterialfv(face, pnamePacked, params);
        }
        ANGLE_CAPTURE(GetMaterialfv, isCallValid, context, face, pnamePacked, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetMaterialxvContextANGLE(GLeglContext ctx,
                                           GLenum face,
                                           GLenum pname,
                                           GLfixed *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetMaterialxv, "glGetMaterialxv",
          "context = %d, face = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::MaterialFace, face),
          GLenumToString(GLenumGroup::MaterialParameter, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        MaterialParameter pnamePacked                         = FromGL<MaterialParameter>(pname);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetMaterialxv(context, face, pnamePacked, params));
        if (isCallValid)
        {
            context->getMaterialxv(face, pnamePacked, params);
        }
        ANGLE_CAPTURE(GetMaterialxv, isCallValid, context, face, pnamePacked, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetMemoryObjectParameterivEXTContextANGLE(GLeglContext ctx,
                                                           GLuint memoryObject,
                                                           GLenum pname,
                                                           GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetMemoryObjectParameterivEXT, "glGetMemoryObjectParameterivEXT",
          "context = %d, memoryObject = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          memoryObject, GLenumToString(GLenumGroup::MemoryObjectParameterName, pname),
          (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        MemoryObjectID memoryObjectPacked = FromGL<MemoryObjectID>(memoryObject);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetMemoryObjectParameterivEXT(context, memoryObjectPacked, pname, params));
        if (isCallValid)
        {
            context->getMemoryObjectParameteriv(memoryObjectPacked, pname, params);
        }
        ANGLE_CAPTURE(GetMemoryObjectParameterivEXT, isCallValid, context, memoryObjectPacked,
                      pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetMultisamplefvContextANGLE(GLeglContext ctx,
                                              GLenum pname,
                                              GLuint index,
                                              GLfloat *val)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetMultisamplefv, "glGetMultisamplefv",
          "context = %d, pname = %s, index = %u, val = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::DefaultGroup, pname), index, (uintptr_t)val);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetMultisamplefv(context, pname, index, val));
        if (isCallValid)
        {
            context->getMultisamplefv(pname, index, val);
        }
        ANGLE_CAPTURE(GetMultisamplefv, isCallValid, context, pname, index, val);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetObjectLabelContextANGLE(GLeglContext ctx,
                                            GLenum identifier,
                                            GLuint name,
                                            GLsizei bufSize,
                                            GLsizei *length,
                                            GLchar *label)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetObjectLabel, "glGetObjectLabel",
          "context = %d, identifier = %s, name = %u, bufSize = %d, length = 0x%016" PRIxPTR
          ", label = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, identifier), name, bufSize,
          (uintptr_t)length, (uintptr_t)label);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetObjectLabel(context, identifier, name, bufSize, length, label));
        if (isCallValid)
        {
            context->getObjectLabel(identifier, name, bufSize, length, label);
        }
        ANGLE_CAPTURE(GetObjectLabel, isCallValid, context, identifier, name, bufSize, length,
                      label);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetObjectLabelKHRContextANGLE(GLeglContext ctx,
                                               GLenum identifier,
                                               GLuint name,
                                               GLsizei bufSize,
                                               GLsizei *length,
                                               GLchar *label)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetObjectLabelKHR, "glGetObjectLabelKHR",
          "context = %d, identifier = %s, name = %u, bufSize = %d, length = 0x%016" PRIxPTR
          ", label = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, identifier), name, bufSize,
          (uintptr_t)length, (uintptr_t)label);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetObjectLabelKHR(context, identifier, name, bufSize, length, label));
        if (isCallValid)
        {
            context->getObjectLabel(identifier, name, bufSize, length, label);
        }
        ANGLE_CAPTURE(GetObjectLabelKHR, isCallValid, context, identifier, name, bufSize, length,
                      label);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetObjectPtrLabelContextANGLE(GLeglContext ctx,
                                               const void *ptr,
                                               GLsizei bufSize,
                                               GLsizei *length,
                                               GLchar *label)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetObjectPtrLabel, "glGetObjectPtrLabel",
          "context = %d, ptr = 0x%016" PRIxPTR ", bufSize = %d, length = 0x%016" PRIxPTR
          ", label = 0x%016" PRIxPTR "",
          CID(context), (uintptr_t)ptr, bufSize, (uintptr_t)length, (uintptr_t)label);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetObjectPtrLabel(context, ptr, bufSize, length, label));
        if (isCallValid)
        {
            context->getObjectPtrLabel(ptr, bufSize, length, label);
        }
        ANGLE_CAPTURE(GetObjectPtrLabel, isCallValid, context, ptr, bufSize, length, label);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetObjectPtrLabelKHRContextANGLE(GLeglContext ctx,
                                                  const void *ptr,
                                                  GLsizei bufSize,
                                                  GLsizei *length,
                                                  GLchar *label)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetObjectPtrLabelKHR, "glGetObjectPtrLabelKHR",
          "context = %d, ptr = 0x%016" PRIxPTR ", bufSize = %d, length = 0x%016" PRIxPTR
          ", label = 0x%016" PRIxPTR "",
          CID(context), (uintptr_t)ptr, bufSize, (uintptr_t)length, (uintptr_t)label);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetObjectPtrLabelKHR(context, ptr, bufSize, length, label));
        if (isCallValid)
        {
            context->getObjectPtrLabel(ptr, bufSize, length, label);
        }
        ANGLE_CAPTURE(GetObjectPtrLabelKHR, isCallValid, context, ptr, bufSize, length, label);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetPointervContextANGLE(GLeglContext ctx, GLenum pname, void **params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetPointerv, "glGetPointerv",
          "context = %d, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::GetPointervPName, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetPointerv(context, pname, params));
        if (isCallValid)
        {
            context->getPointerv(pname, params);
        }
        ANGLE_CAPTURE(GetPointerv, isCallValid, context, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetPointervKHRContextANGLE(GLeglContext ctx, GLenum pname, void **params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetPointervKHR, "glGetPointervKHR",
          "context = %d, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::DefaultGroup, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetPointervKHR(context, pname, params));
        if (isCallValid)
        {
            context->getPointerv(pname, params);
        }
        ANGLE_CAPTURE(GetPointervKHR, isCallValid, context, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetProgramBinaryContextANGLE(GLeglContext ctx,
                                              GLuint program,
                                              GLsizei bufSize,
                                              GLsizei *length,
                                              GLenum *binaryFormat,
                                              void *binary)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetProgramBinary, "glGetProgramBinary",
          "context = %d, program = %u, bufSize = %d, length = 0x%016" PRIxPTR
          ", binaryFormat = 0x%016" PRIxPTR ", binary = 0x%016" PRIxPTR "",
          CID(context), program, bufSize, (uintptr_t)length, (uintptr_t)binaryFormat,
          (uintptr_t)binary);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetProgramBinary(context, programPacked, bufSize,
                                                                   length, binaryFormat, binary));
        if (isCallValid)
        {
            context->getProgramBinary(programPacked, bufSize, length, binaryFormat, binary);
        }
        ANGLE_CAPTURE(GetProgramBinary, isCallValid, context, programPacked, bufSize, length,
                      binaryFormat, binary);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetProgramBinaryOESContextANGLE(GLeglContext ctx,
                                                 GLuint program,
                                                 GLsizei bufSize,
                                                 GLsizei *length,
                                                 GLenum *binaryFormat,
                                                 void *binary)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetProgramBinaryOES, "glGetProgramBinaryOES",
          "context = %d, program = %u, bufSize = %d, length = 0x%016" PRIxPTR
          ", binaryFormat = 0x%016" PRIxPTR ", binary = 0x%016" PRIxPTR "",
          CID(context), program, bufSize, (uintptr_t)length, (uintptr_t)binaryFormat,
          (uintptr_t)binary);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetProgramBinaryOES(context, programPacked, bufSize, length,
                                                        binaryFormat, binary));
        if (isCallValid)
        {
            context->getProgramBinary(programPacked, bufSize, length, binaryFormat, binary);
        }
        ANGLE_CAPTURE(GetProgramBinaryOES, isCallValid, context, programPacked, bufSize, length,
                      binaryFormat, binary);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetProgramInfoLogContextANGLE(GLeglContext ctx,
                                               GLuint program,
                                               GLsizei bufSize,
                                               GLsizei *length,
                                               GLchar *infoLog)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetProgramInfoLog, "glGetProgramInfoLog",
          "context = %d, program = %u, bufSize = %d, length = 0x%016" PRIxPTR
          ", infoLog = 0x%016" PRIxPTR "",
          CID(context), program, bufSize, (uintptr_t)length, (uintptr_t)infoLog);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetProgramInfoLog(context, programPacked, bufSize, length, infoLog));
        if (isCallValid)
        {
            context->getProgramInfoLog(programPacked, bufSize, length, infoLog);
        }
        ANGLE_CAPTURE(GetProgramInfoLog, isCallValid, context, programPacked, bufSize, length,
                      infoLog);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetProgramInterfaceivContextANGLE(GLeglContext ctx,
                                                   GLuint program,
                                                   GLenum programInterface,
                                                   GLenum pname,
                                                   GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetProgramInterfaceiv, "glGetProgramInterfaceiv",
          "context = %d, program = %u, programInterface = %s, pname = %s, params = 0x%016" PRIxPTR
          "",
          CID(context), program, GLenumToString(GLenumGroup::ProgramInterface, programInterface),
          GLenumToString(GLenumGroup::ProgramInterfacePName, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetProgramInterfaceiv(context, programPacked, programInterface,
                                                          pname, params));
        if (isCallValid)
        {
            context->getProgramInterfaceiv(programPacked, programInterface, pname, params);
        }
        ANGLE_CAPTURE(GetProgramInterfaceiv, isCallValid, context, programPacked, programInterface,
                      pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetProgramPipelineInfoLogContextANGLE(GLeglContext ctx,
                                                       GLuint pipeline,
                                                       GLsizei bufSize,
                                                       GLsizei *length,
                                                       GLchar *infoLog)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetProgramPipelineInfoLog, "glGetProgramPipelineInfoLog",
          "context = %d, pipeline = %u, bufSize = %d, length = 0x%016" PRIxPTR
          ", infoLog = 0x%016" PRIxPTR "",
          CID(context), pipeline, bufSize, (uintptr_t)length, (uintptr_t)infoLog);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ProgramPipelineID pipelinePacked                      = FromGL<ProgramPipelineID>(pipeline);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetProgramPipelineInfoLog(context, pipelinePacked, bufSize, length, infoLog));
        if (isCallValid)
        {
            context->getProgramPipelineInfoLog(pipelinePacked, bufSize, length, infoLog);
        }
        ANGLE_CAPTURE(GetProgramPipelineInfoLog, isCallValid, context, pipelinePacked, bufSize,
                      length, infoLog);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetProgramPipelineivContextANGLE(GLeglContext ctx,
                                                  GLuint pipeline,
                                                  GLenum pname,
                                                  GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetProgramPipelineiv, "glGetProgramPipelineiv",
          "context = %d, pipeline = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          pipeline, GLenumToString(GLenumGroup::PipelineParameterName, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ProgramPipelineID pipelinePacked                      = FromGL<ProgramPipelineID>(pipeline);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetProgramPipelineiv(context, pipelinePacked, pname, params));
        if (isCallValid)
        {
            context->getProgramPipelineiv(pipelinePacked, pname, params);
        }
        ANGLE_CAPTURE(GetProgramPipelineiv, isCallValid, context, pipelinePacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

GLuint GL_APIENTRY GetProgramResourceIndexContextANGLE(GLeglContext ctx,
                                                       GLuint program,
                                                       GLenum programInterface,
                                                       const GLchar *name)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetProgramResourceIndex, "glGetProgramResourceIndex",
          "context = %d, program = %u, programInterface = %s, name = 0x%016" PRIxPTR "",
          CID(context), program, GLenumToString(GLenumGroup::ProgramInterface, programInterface),
          (uintptr_t)name);

    GLuint returnValue;
    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetProgramResourceIndex(context, programPacked, programInterface, name));
        if (isCallValid)
        {
            returnValue = context->getProgramResourceIndex(programPacked, programInterface, name);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::GetProgramResourceIndex, GLuint>();
        }
        ANGLE_CAPTURE(GetProgramResourceIndex, isCallValid, context, programPacked,
                      programInterface, name, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
        returnValue = GetDefaultReturnValue<EntryPoint::GetProgramResourceIndex, GLuint>();
    }
    return returnValue;
}

GLint GL_APIENTRY GetProgramResourceLocationContextANGLE(GLeglContext ctx,
                                                         GLuint program,
                                                         GLenum programInterface,
                                                         const GLchar *name)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetProgramResourceLocation, "glGetProgramResourceLocation",
          "context = %d, program = %u, programInterface = %s, name = 0x%016" PRIxPTR "",
          CID(context), program, GLenumToString(GLenumGroup::ProgramInterface, programInterface),
          (uintptr_t)name);

    GLint returnValue;
    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetProgramResourceLocation(context, programPacked, programInterface, name));
        if (isCallValid)
        {
            returnValue =
                context->getProgramResourceLocation(programPacked, programInterface, name);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::GetProgramResourceLocation, GLint>();
        }
        ANGLE_CAPTURE(GetProgramResourceLocation, isCallValid, context, programPacked,
                      programInterface, name, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
        returnValue = GetDefaultReturnValue<EntryPoint::GetProgramResourceLocation, GLint>();
    }
    return returnValue;
}

GLint GL_APIENTRY GetProgramResourceLocationIndexEXTContextANGLE(GLeglContext ctx,
                                                                 GLuint program,
                                                                 GLenum programInterface,
                                                                 const GLchar *name)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetProgramResourceLocationIndexEXT,
          "glGetProgramResourceLocationIndexEXT",
          "context = %d, program = %u, programInterface = %s, name = 0x%016" PRIxPTR "",
          CID(context), program, GLenumToString(GLenumGroup::ProgramInterface, programInterface),
          (uintptr_t)name);

    GLint returnValue;
    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetProgramResourceLocationIndexEXT(
                                              context, programPacked, programInterface, name));
        if (isCallValid)
        {
            returnValue =
                context->getProgramResourceLocationIndex(programPacked, programInterface, name);
        }
        else
        {
            returnValue =
                GetDefaultReturnValue<EntryPoint::GetProgramResourceLocationIndexEXT, GLint>();
        }
        ANGLE_CAPTURE(GetProgramResourceLocationIndexEXT, isCallValid, context, programPacked,
                      programInterface, name, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
        returnValue =
            GetDefaultReturnValue<EntryPoint::GetProgramResourceLocationIndexEXT, GLint>();
    }
    return returnValue;
}

void GL_APIENTRY GetProgramResourceNameContextANGLE(GLeglContext ctx,
                                                    GLuint program,
                                                    GLenum programInterface,
                                                    GLuint index,
                                                    GLsizei bufSize,
                                                    GLsizei *length,
                                                    GLchar *name)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetProgramResourceName, "glGetProgramResourceName",
          "context = %d, program = %u, programInterface = %s, index = %u, bufSize = %d, length = "
          "0x%016" PRIxPTR ", name = 0x%016" PRIxPTR "",
          CID(context), program, GLenumToString(GLenumGroup::ProgramInterface, programInterface),
          index, bufSize, (uintptr_t)length, (uintptr_t)name);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetProgramResourceName(context, programPacked, programInterface,
                                                           index, bufSize, length, name));
        if (isCallValid)
        {
            context->getProgramResourceName(programPacked, programInterface, index, bufSize, length,
                                            name);
        }
        ANGLE_CAPTURE(GetProgramResourceName, isCallValid, context, programPacked, programInterface,
                      index, bufSize, length, name);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetProgramResourceivContextANGLE(GLeglContext ctx,
                                                  GLuint program,
                                                  GLenum programInterface,
                                                  GLuint index,
                                                  GLsizei propCount,
                                                  const GLenum *props,
                                                  GLsizei bufSize,
                                                  GLsizei *length,
                                                  GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetProgramResourceiv, "glGetProgramResourceiv",
          "context = %d, program = %u, programInterface = %s, index = %u, propCount = %d, props = "
          "0x%016" PRIxPTR ", bufSize = %d, length = 0x%016" PRIxPTR ", params = 0x%016" PRIxPTR "",
          CID(context), program, GLenumToString(GLenumGroup::ProgramInterface, programInterface),
          index, propCount, (uintptr_t)props, bufSize, (uintptr_t)length, (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetProgramResourceiv(context, programPacked, programInterface, index,
                                          propCount, props, bufSize, length, params));
        if (isCallValid)
        {
            context->getProgramResourceiv(programPacked, programInterface, index, propCount, props,
                                          bufSize, length, params);
        }
        ANGLE_CAPTURE(GetProgramResourceiv, isCallValid, context, programPacked, programInterface,
                      index, propCount, props, bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetProgramivContextANGLE(GLeglContext ctx,
                                          GLuint program,
                                          GLenum pname,
                                          GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetProgramiv, "glGetProgramiv",
          "context = %d, program = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          program, GLenumToString(GLenumGroup::ProgramPropertyARB, pname), (uintptr_t)params);

    if (context)
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetProgramiv(context, programPacked, pname, params));
        if (isCallValid)
        {
            context->getProgramiv(programPacked, pname, params);
        }
        ANGLE_CAPTURE(GetProgramiv, isCallValid, context, programPacked, pname, params);
    }
    else
    {}
}

void GL_APIENTRY GetQueryObjecti64vEXTContextANGLE(GLeglContext ctx,
                                                   GLuint id,
                                                   GLenum pname,
                                                   GLint64 *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetQueryObjecti64vEXT, "glGetQueryObjecti64vEXT",
          "context = %d, id = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context), id,
          GLenumToString(GLenumGroup::QueryObjectParameterName, pname), (uintptr_t)params);

    if (context)
    {
        ASSERT(context == GetValidGlobalContext());
        QueryID idPacked                                      = FromGL<QueryID>(id);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetQueryObjecti64vEXT(context, idPacked, pname, params));
        if (isCallValid)
        {
            context->getQueryObjecti64v(idPacked, pname, params);
        }
        ANGLE_CAPTURE(GetQueryObjecti64vEXT, isCallValid, context, idPacked, pname, params);
    }
    else
    {}
}

void GL_APIENTRY GetQueryObjectivEXTContextANGLE(GLeglContext ctx,
                                                 GLuint id,
                                                 GLenum pname,
                                                 GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetQueryObjectivEXT, "glGetQueryObjectivEXT",
          "context = %d, id = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context), id,
          GLenumToString(GLenumGroup::QueryObjectParameterName, pname), (uintptr_t)params);

    if (context)
    {
        ASSERT(context == GetValidGlobalContext());
        QueryID idPacked                                      = FromGL<QueryID>(id);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetQueryObjectivEXT(context, idPacked, pname, params));
        if (isCallValid)
        {
            context->getQueryObjectiv(idPacked, pname, params);
        }
        ANGLE_CAPTURE(GetQueryObjectivEXT, isCallValid, context, idPacked, pname, params);
    }
    else
    {}
}

void GL_APIENTRY GetQueryObjectui64vEXTContextANGLE(GLeglContext ctx,
                                                    GLuint id,
                                                    GLenum pname,
                                                    GLuint64 *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetQueryObjectui64vEXT, "glGetQueryObjectui64vEXT",
          "context = %d, id = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context), id,
          GLenumToString(GLenumGroup::QueryObjectParameterName, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        QueryID idPacked                                      = FromGL<QueryID>(id);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetQueryObjectui64vEXT(context, idPacked, pname, params));
        if (isCallValid)
        {
            context->getQueryObjectui64v(idPacked, pname, params);
        }
        ANGLE_CAPTURE(GetQueryObjectui64vEXT, isCallValid, context, idPacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetQueryObjectuivContextANGLE(GLeglContext ctx,
                                               GLuint id,
                                               GLenum pname,
                                               GLuint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetQueryObjectuiv, "glGetQueryObjectuiv",
          "context = %d, id = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context), id,
          GLenumToString(GLenumGroup::QueryObjectParameterName, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        QueryID idPacked                                      = FromGL<QueryID>(id);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetQueryObjectuiv(context, idPacked, pname, params));
        if (isCallValid)
        {
            context->getQueryObjectuiv(idPacked, pname, params);
        }
        ANGLE_CAPTURE(GetQueryObjectuiv, isCallValid, context, idPacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetQueryObjectuivEXTContextANGLE(GLeglContext ctx,
                                                  GLuint id,
                                                  GLenum pname,
                                                  GLuint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetQueryObjectuivEXT, "glGetQueryObjectuivEXT",
          "context = %d, id = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context), id,
          GLenumToString(GLenumGroup::QueryObjectParameterName, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        QueryID idPacked                                      = FromGL<QueryID>(id);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetQueryObjectuivEXT(context, idPacked, pname, params));
        if (isCallValid)
        {
            context->getQueryObjectuiv(idPacked, pname, params);
        }
        ANGLE_CAPTURE(GetQueryObjectuivEXT, isCallValid, context, idPacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetQueryivContextANGLE(GLeglContext ctx,
                                        GLenum target,
                                        GLenum pname,
                                        GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetQueryiv, "glGetQueryiv",
          "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::QueryTarget, target),
          GLenumToString(GLenumGroup::QueryParameterName, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        QueryType targetPacked                                = FromGL<QueryType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetQueryiv(context, targetPacked, pname, params));
        if (isCallValid)
        {
            context->getQueryiv(targetPacked, pname, params);
        }
        ANGLE_CAPTURE(GetQueryiv, isCallValid, context, targetPacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetQueryivEXTContextANGLE(GLeglContext ctx,
                                           GLenum target,
                                           GLenum pname,
                                           GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetQueryivEXT, "glGetQueryivEXT",
          "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::QueryTarget, target),
          GLenumToString(GLenumGroup::QueryParameterName, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        QueryType targetPacked                                = FromGL<QueryType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetQueryivEXT(context, targetPacked, pname, params));
        if (isCallValid)
        {
            context->getQueryiv(targetPacked, pname, params);
        }
        ANGLE_CAPTURE(GetQueryivEXT, isCallValid, context, targetPacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetRenderbufferParameterivContextANGLE(GLeglContext ctx,
                                                        GLenum target,
                                                        GLenum pname,
                                                        GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetRenderbufferParameteriv, "glGetRenderbufferParameteriv",
          "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::RenderbufferTarget, target),
          GLenumToString(GLenumGroup::RenderbufferParameterName, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetRenderbufferParameteriv(context, target, pname, params));
        if (isCallValid)
        {
            context->getRenderbufferParameteriv(target, pname, params);
        }
        ANGLE_CAPTURE(GetRenderbufferParameteriv, isCallValid, context, target, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetRenderbufferParameterivOESContextANGLE(GLeglContext ctx,
                                                           GLenum target,
                                                           GLenum pname,
                                                           GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetRenderbufferParameterivOES, "glGetRenderbufferParameterivOES",
          "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::RenderbufferTarget, target),
          GLenumToString(GLenumGroup::RenderbufferParameterName, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetRenderbufferParameterivOES(context, target, pname, params));
        if (isCallValid)
        {
            context->getRenderbufferParameteriv(target, pname, params);
        }
        ANGLE_CAPTURE(GetRenderbufferParameterivOES, isCallValid, context, target, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetSamplerParameterIivContextANGLE(GLeglContext ctx,
                                                    GLuint sampler,
                                                    GLenum pname,
                                                    GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetSamplerParameterIiv, "glGetSamplerParameterIiv",
          "context = %d, sampler = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          sampler, GLenumToString(GLenumGroup::SamplerParameterName, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        SamplerID samplerPacked                               = FromGL<SamplerID>(sampler);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetSamplerParameterIiv(context, samplerPacked, pname, params));
        if (isCallValid)
        {
            context->getSamplerParameterIiv(samplerPacked, pname, params);
        }
        ANGLE_CAPTURE(GetSamplerParameterIiv, isCallValid, context, samplerPacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetSamplerParameterIivOESContextANGLE(GLeglContext ctx,
                                                       GLuint sampler,
                                                       GLenum pname,
                                                       GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetSamplerParameterIivOES, "glGetSamplerParameterIivOES",
          "context = %d, sampler = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          sampler, GLenumToString(GLenumGroup::SamplerParameterName, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        SamplerID samplerPacked                               = FromGL<SamplerID>(sampler);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetSamplerParameterIivOES(context, samplerPacked, pname, params));
        if (isCallValid)
        {
            context->getSamplerParameterIiv(samplerPacked, pname, params);
        }
        ANGLE_CAPTURE(GetSamplerParameterIivOES, isCallValid, context, samplerPacked, pname,
                      params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetSamplerParameterIuivContextANGLE(GLeglContext ctx,
                                                     GLuint sampler,
                                                     GLenum pname,
                                                     GLuint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetSamplerParameterIuiv, "glGetSamplerParameterIuiv",
          "context = %d, sampler = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          sampler, GLenumToString(GLenumGroup::SamplerParameterName, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        SamplerID samplerPacked                               = FromGL<SamplerID>(sampler);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetSamplerParameterIuiv(context, samplerPacked, pname, params));
        if (isCallValid)
        {
            context->getSamplerParameterIuiv(samplerPacked, pname, params);
        }
        ANGLE_CAPTURE(GetSamplerParameterIuiv, isCallValid, context, samplerPacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetSamplerParameterIuivOESContextANGLE(GLeglContext ctx,
                                                        GLuint sampler,
                                                        GLenum pname,
                                                        GLuint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetSamplerParameterIuivOES, "glGetSamplerParameterIuivOES",
          "context = %d, sampler = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          sampler, GLenumToString(GLenumGroup::SamplerParameterName, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        SamplerID samplerPacked                               = FromGL<SamplerID>(sampler);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetSamplerParameterIuivOES(context, samplerPacked, pname, params));
        if (isCallValid)
        {
            context->getSamplerParameterIuiv(samplerPacked, pname, params);
        }
        ANGLE_CAPTURE(GetSamplerParameterIuivOES, isCallValid, context, samplerPacked, pname,
                      params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetSamplerParameterfvContextANGLE(GLeglContext ctx,
                                                   GLuint sampler,
                                                   GLenum pname,
                                                   GLfloat *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetSamplerParameterfv, "glGetSamplerParameterfv",
          "context = %d, sampler = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          sampler, GLenumToString(GLenumGroup::SamplerParameterName, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        SamplerID samplerPacked                               = FromGL<SamplerID>(sampler);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetSamplerParameterfv(context, samplerPacked, pname, params));
        if (isCallValid)
        {
            context->getSamplerParameterfv(samplerPacked, pname, params);
        }
        ANGLE_CAPTURE(GetSamplerParameterfv, isCallValid, context, samplerPacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetSamplerParameterivContextANGLE(GLeglContext ctx,
                                                   GLuint sampler,
                                                   GLenum pname,
                                                   GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetSamplerParameteriv, "glGetSamplerParameteriv",
          "context = %d, sampler = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          sampler, GLenumToString(GLenumGroup::SamplerParameterName, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        SamplerID samplerPacked                               = FromGL<SamplerID>(sampler);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetSamplerParameteriv(context, samplerPacked, pname, params));
        if (isCallValid)
        {
            context->getSamplerParameteriv(samplerPacked, pname, params);
        }
        ANGLE_CAPTURE(GetSamplerParameteriv, isCallValid, context, samplerPacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetSemaphoreParameterui64vEXTContextANGLE(GLeglContext ctx,
                                                           GLuint semaphore,
                                                           GLenum pname,
                                                           GLuint64 *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetSemaphoreParameterui64vEXT, "glGetSemaphoreParameterui64vEXT",
          "context = %d, semaphore = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          semaphore, GLenumToString(GLenumGroup::SemaphoreParameterName, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        SemaphoreID semaphorePacked                           = FromGL<SemaphoreID>(semaphore);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetSemaphoreParameterui64vEXT(context, semaphorePacked, pname, params));
        if (isCallValid)
        {
            context->getSemaphoreParameterui64v(semaphorePacked, pname, params);
        }
        ANGLE_CAPTURE(GetSemaphoreParameterui64vEXT, isCallValid, context, semaphorePacked, pname,
                      params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetShaderInfoLogContextANGLE(GLeglContext ctx,
                                              GLuint shader,
                                              GLsizei bufSize,
                                              GLsizei *length,
                                              GLchar *infoLog)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetShaderInfoLog, "glGetShaderInfoLog",
          "context = %d, shader = %u, bufSize = %d, length = 0x%016" PRIxPTR
          ", infoLog = 0x%016" PRIxPTR "",
          CID(context), shader, bufSize, (uintptr_t)length, (uintptr_t)infoLog);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID shaderPacked                          = FromGL<ShaderProgramID>(shader);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetShaderInfoLog(context, shaderPacked, bufSize, length, infoLog));
        if (isCallValid)
        {
            context->getShaderInfoLog(shaderPacked, bufSize, length, infoLog);
        }
        ANGLE_CAPTURE(GetShaderInfoLog, isCallValid, context, shaderPacked, bufSize, length,
                      infoLog);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetShaderPrecisionFormatContextANGLE(GLeglContext ctx,
                                                      GLenum shadertype,
                                                      GLenum precisiontype,
                                                      GLint *range,
                                                      GLint *precision)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetShaderPrecisionFormat, "glGetShaderPrecisionFormat",
          "context = %d, shadertype = %s, precisiontype = %s, range = 0x%016" PRIxPTR
          ", precision = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::ShaderType, shadertype),
          GLenumToString(GLenumGroup::PrecisionType, precisiontype), (uintptr_t)range,
          (uintptr_t)precision);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetShaderPrecisionFormat(context, shadertype, precisiontype,
                                                             range, precision));
        if (isCallValid)
        {
            context->getShaderPrecisionFormat(shadertype, precisiontype, range, precision);
        }
        ANGLE_CAPTURE(GetShaderPrecisionFormat, isCallValid, context, shadertype, precisiontype,
                      range, precision);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetShaderSourceContextANGLE(GLeglContext ctx,
                                             GLuint shader,
                                             GLsizei bufSize,
                                             GLsizei *length,
                                             GLchar *source)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetShaderSource, "glGetShaderSource",
          "context = %d, shader = %u, bufSize = %d, length = 0x%016" PRIxPTR
          ", source = 0x%016" PRIxPTR "",
          CID(context), shader, bufSize, (uintptr_t)length, (uintptr_t)source);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID shaderPacked                          = FromGL<ShaderProgramID>(shader);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetShaderSource(context, shaderPacked, bufSize, length, source));
        if (isCallValid)
        {
            context->getShaderSource(shaderPacked, bufSize, length, source);
        }
        ANGLE_CAPTURE(GetShaderSource, isCallValid, context, shaderPacked, bufSize, length, source);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetShaderivContextANGLE(GLeglContext ctx,
                                         GLuint shader,
                                         GLenum pname,
                                         GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetShaderiv, "glGetShaderiv",
          "context = %d, shader = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context), shader,
          GLenumToString(GLenumGroup::ShaderParameterName, pname), (uintptr_t)params);

    if (context)
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID shaderPacked                          = FromGL<ShaderProgramID>(shader);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetShaderiv(context, shaderPacked, pname, params));
        if (isCallValid)
        {
            context->getShaderiv(shaderPacked, pname, params);
        }
        ANGLE_CAPTURE(GetShaderiv, isCallValid, context, shaderPacked, pname, params);
    }
    else
    {}
}

const GLubyte *GL_APIENTRY GetStringContextANGLE(GLeglContext ctx, GLenum name)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetString, "glGetString", "context = %d, name = %s",
          CID(context), GLenumToString(GLenumGroup::StringName, name));

    const GLubyte *returnValue;
    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateGetString(context, name));
        if (isCallValid)
        {
            returnValue = context->getString(name);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::GetString, const GLubyte *>();
        }
        ANGLE_CAPTURE(GetString, isCallValid, context, name, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
        returnValue = GetDefaultReturnValue<EntryPoint::GetString, const GLubyte *>();
    }
    return returnValue;
}

const GLubyte *GL_APIENTRY GetStringiContextANGLE(GLeglContext ctx, GLenum name, GLuint index)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetStringi, "glGetStringi",
          "context = %d, name = %s, index = %u", CID(context),
          GLenumToString(GLenumGroup::StringName, name), index);

    const GLubyte *returnValue;
    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateGetStringi(context, name, index));
        if (isCallValid)
        {
            returnValue = context->getStringi(name, index);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::GetStringi, const GLubyte *>();
        }
        ANGLE_CAPTURE(GetStringi, isCallValid, context, name, index, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
        returnValue = GetDefaultReturnValue<EntryPoint::GetStringi, const GLubyte *>();
    }
    return returnValue;
}

void GL_APIENTRY GetSyncivContextANGLE(GLeglContext ctx,
                                       GLsync sync,
                                       GLenum pname,
                                       GLsizei bufSize,
                                       GLsizei *length,
                                       GLint *values)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetSynciv, "glGetSynciv",
          "context = %d, sync = 0x%016" PRIxPTR
          ", pname = %s, bufSize = %d, length = 0x%016" PRIxPTR ", values = 0x%016" PRIxPTR "",
          CID(context), (uintptr_t)sync, GLenumToString(GLenumGroup::SyncParameterName, pname),
          bufSize, (uintptr_t)length, (uintptr_t)values);

    if (context)
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetSynciv(context, sync, pname, bufSize, length, values));
        if (isCallValid)
        {
            context->getSynciv(sync, pname, bufSize, length, values);
        }
        ANGLE_CAPTURE(GetSynciv, isCallValid, context, sync, pname, bufSize, length, values);
    }
    else
    {}
}

void GL_APIENTRY GetTexEnvfvContextANGLE(GLeglContext ctx,
                                         GLenum target,
                                         GLenum pname,
                                         GLfloat *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetTexEnvfv, "glGetTexEnvfv",
          "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::TextureEnvTarget, target),
          GLenumToString(GLenumGroup::TextureEnvParameter, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureEnvTarget targetPacked                         = FromGL<TextureEnvTarget>(target);
        TextureEnvParameter pnamePacked                       = FromGL<TextureEnvParameter>(pname);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetTexEnvfv(context, targetPacked, pnamePacked, params));
        if (isCallValid)
        {
            context->getTexEnvfv(targetPacked, pnamePacked, params);
        }
        ANGLE_CAPTURE(GetTexEnvfv, isCallValid, context, targetPacked, pnamePacked, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetTexEnvivContextANGLE(GLeglContext ctx,
                                         GLenum target,
                                         GLenum pname,
                                         GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetTexEnviv, "glGetTexEnviv",
          "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::TextureEnvTarget, target),
          GLenumToString(GLenumGroup::TextureEnvParameter, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureEnvTarget targetPacked                         = FromGL<TextureEnvTarget>(target);
        TextureEnvParameter pnamePacked                       = FromGL<TextureEnvParameter>(pname);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetTexEnviv(context, targetPacked, pnamePacked, params));
        if (isCallValid)
        {
            context->getTexEnviv(targetPacked, pnamePacked, params);
        }
        ANGLE_CAPTURE(GetTexEnviv, isCallValid, context, targetPacked, pnamePacked, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetTexEnvxvContextANGLE(GLeglContext ctx,
                                         GLenum target,
                                         GLenum pname,
                                         GLfixed *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetTexEnvxv, "glGetTexEnvxv",
          "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::TextureEnvTarget, target),
          GLenumToString(GLenumGroup::TextureEnvParameter, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureEnvTarget targetPacked                         = FromGL<TextureEnvTarget>(target);
        TextureEnvParameter pnamePacked                       = FromGL<TextureEnvParameter>(pname);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetTexEnvxv(context, targetPacked, pnamePacked, params));
        if (isCallValid)
        {
            context->getTexEnvxv(targetPacked, pnamePacked, params);
        }
        ANGLE_CAPTURE(GetTexEnvxv, isCallValid, context, targetPacked, pnamePacked, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetTexGenfvOESContextANGLE(GLeglContext ctx,
                                            GLenum coord,
                                            GLenum pname,
                                            GLfloat *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetTexGenfvOES, "glGetTexGenfvOES",
          "context = %d, coord = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::TextureCoordName, coord),
          GLenumToString(GLenumGroup::TextureGenParameter, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetTexGenfvOES(context, coord, pname, params));
        if (isCallValid)
        {
            context->getTexGenfv(coord, pname, params);
        }
        ANGLE_CAPTURE(GetTexGenfvOES, isCallValid, context, coord, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetTexGenivOESContextANGLE(GLeglContext ctx,
                                            GLenum coord,
                                            GLenum pname,
                                            GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetTexGenivOES, "glGetTexGenivOES",
          "context = %d, coord = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::TextureCoordName, coord),
          GLenumToString(GLenumGroup::TextureGenParameter, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetTexGenivOES(context, coord, pname, params));
        if (isCallValid)
        {
            context->getTexGeniv(coord, pname, params);
        }
        ANGLE_CAPTURE(GetTexGenivOES, isCallValid, context, coord, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetTexGenxvOESContextANGLE(GLeglContext ctx,
                                            GLenum coord,
                                            GLenum pname,
                                            GLfixed *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetTexGenxvOES, "glGetTexGenxvOES",
          "context = %d, coord = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::TextureCoordName, coord),
          GLenumToString(GLenumGroup::TextureGenParameter, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetTexGenxvOES(context, coord, pname, params));
        if (isCallValid)
        {
            context->getTexGenxv(coord, pname, params);
        }
        ANGLE_CAPTURE(GetTexGenxvOES, isCallValid, context, coord, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetTexLevelParameterfvContextANGLE(GLeglContext ctx,
                                                    GLenum target,
                                                    GLint level,
                                                    GLenum pname,
                                                    GLfloat *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetTexLevelParameterfv, "glGetTexLevelParameterfv",
          "context = %d, target = %s, level = %d, pname = %s, params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), level,
          GLenumToString(GLenumGroup::GetTextureParameter, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetTexLevelParameterfv(context, targetPacked, level, pname, params));
        if (isCallValid)
        {
            context->getTexLevelParameterfv(targetPacked, level, pname, params);
        }
        ANGLE_CAPTURE(GetTexLevelParameterfv, isCallValid, context, targetPacked, level, pname,
                      params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetTexLevelParameterivContextANGLE(GLeglContext ctx,
                                                    GLenum target,
                                                    GLint level,
                                                    GLenum pname,
                                                    GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetTexLevelParameteriv, "glGetTexLevelParameteriv",
          "context = %d, target = %s, level = %d, pname = %s, params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), level,
          GLenumToString(GLenumGroup::GetTextureParameter, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetTexLevelParameteriv(context, targetPacked, level, pname, params));
        if (isCallValid)
        {
            context->getTexLevelParameteriv(targetPacked, level, pname, params);
        }
        ANGLE_CAPTURE(GetTexLevelParameteriv, isCallValid, context, targetPacked, level, pname,
                      params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetTexParameterIivContextANGLE(GLeglContext ctx,
                                                GLenum target,
                                                GLenum pname,
                                                GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetTexParameterIiv, "glGetTexParameterIiv",
          "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::TextureTarget, target),
          GLenumToString(GLenumGroup::GetTextureParameter, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetTexParameterIiv(context, targetPacked, pname, params));
        if (isCallValid)
        {
            context->getTexParameterIiv(targetPacked, pname, params);
        }
        ANGLE_CAPTURE(GetTexParameterIiv, isCallValid, context, targetPacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetTexParameterIivOESContextANGLE(GLeglContext ctx,
                                                   GLenum target,
                                                   GLenum pname,
                                                   GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetTexParameterIivOES, "glGetTexParameterIivOES",
          "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::TextureTarget, target),
          GLenumToString(GLenumGroup::GetTextureParameter, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetTexParameterIivOES(context, targetPacked, pname, params));
        if (isCallValid)
        {
            context->getTexParameterIiv(targetPacked, pname, params);
        }
        ANGLE_CAPTURE(GetTexParameterIivOES, isCallValid, context, targetPacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetTexParameterIuivContextANGLE(GLeglContext ctx,
                                                 GLenum target,
                                                 GLenum pname,
                                                 GLuint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetTexParameterIuiv, "glGetTexParameterIuiv",
          "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::TextureTarget, target),
          GLenumToString(GLenumGroup::GetTextureParameter, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetTexParameterIuiv(context, targetPacked, pname, params));
        if (isCallValid)
        {
            context->getTexParameterIuiv(targetPacked, pname, params);
        }
        ANGLE_CAPTURE(GetTexParameterIuiv, isCallValid, context, targetPacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetTexParameterIuivOESContextANGLE(GLeglContext ctx,
                                                    GLenum target,
                                                    GLenum pname,
                                                    GLuint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetTexParameterIuivOES, "glGetTexParameterIuivOES",
          "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::TextureTarget, target),
          GLenumToString(GLenumGroup::GetTextureParameter, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetTexParameterIuivOES(context, targetPacked, pname, params));
        if (isCallValid)
        {
            context->getTexParameterIuiv(targetPacked, pname, params);
        }
        ANGLE_CAPTURE(GetTexParameterIuivOES, isCallValid, context, targetPacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetTexParameterfvContextANGLE(GLeglContext ctx,
                                               GLenum target,
                                               GLenum pname,
                                               GLfloat *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetTexParameterfv, "glGetTexParameterfv",
          "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::TextureTarget, target),
          GLenumToString(GLenumGroup::GetTextureParameter, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetTexParameterfv(context, targetPacked, pname, params));
        if (isCallValid)
        {
            context->getTexParameterfv(targetPacked, pname, params);
        }
        ANGLE_CAPTURE(GetTexParameterfv, isCallValid, context, targetPacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetTexParameterivContextANGLE(GLeglContext ctx,
                                               GLenum target,
                                               GLenum pname,
                                               GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetTexParameteriv, "glGetTexParameteriv",
          "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::TextureTarget, target),
          GLenumToString(GLenumGroup::GetTextureParameter, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetTexParameteriv(context, targetPacked, pname, params));
        if (isCallValid)
        {
            context->getTexParameteriv(targetPacked, pname, params);
        }
        ANGLE_CAPTURE(GetTexParameteriv, isCallValid, context, targetPacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetTexParameterxvContextANGLE(GLeglContext ctx,
                                               GLenum target,
                                               GLenum pname,
                                               GLfixed *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetTexParameterxv, "glGetTexParameterxv",
          "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::TextureTarget, target),
          GLenumToString(GLenumGroup::GetTextureParameter, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetTexParameterxv(context, targetPacked, pname, params));
        if (isCallValid)
        {
            context->getTexParameterxv(targetPacked, pname, params);
        }
        ANGLE_CAPTURE(GetTexParameterxv, isCallValid, context, targetPacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetTransformFeedbackVaryingContextANGLE(GLeglContext ctx,
                                                         GLuint program,
                                                         GLuint index,
                                                         GLsizei bufSize,
                                                         GLsizei *length,
                                                         GLsizei *size,
                                                         GLenum *type,
                                                         GLchar *name)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetTransformFeedbackVarying, "glGetTransformFeedbackVarying",
          "context = %d, program = %u, index = %u, bufSize = %d, length = 0x%016" PRIxPTR
          ", size = 0x%016" PRIxPTR ", type = 0x%016" PRIxPTR ", name = 0x%016" PRIxPTR "",
          CID(context), program, index, bufSize, (uintptr_t)length, (uintptr_t)size,
          (uintptr_t)type, (uintptr_t)name);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetTransformFeedbackVarying(context, programPacked, index,
                                                                bufSize, length, size, type, name));
        if (isCallValid)
        {
            context->getTransformFeedbackVarying(programPacked, index, bufSize, length, size, type,
                                                 name);
        }
        ANGLE_CAPTURE(GetTransformFeedbackVarying, isCallValid, context, programPacked, index,
                      bufSize, length, size, type, name);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetTranslatedShaderSourceANGLEContextANGLE(GLeglContext ctx,
                                                            GLuint shader,
                                                            GLsizei bufsize,
                                                            GLsizei *length,
                                                            GLchar *source)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetTranslatedShaderSourceANGLE,
          "glGetTranslatedShaderSourceANGLE",
          "context = %d, shader = %u, bufsize = %d, length = 0x%016" PRIxPTR
          ", source = 0x%016" PRIxPTR "",
          CID(context), shader, bufsize, (uintptr_t)length, (uintptr_t)source);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID shaderPacked                          = FromGL<ShaderProgramID>(shader);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetTranslatedShaderSourceANGLE(
                                              context, shaderPacked, bufsize, length, source));
        if (isCallValid)
        {
            context->getTranslatedShaderSource(shaderPacked, bufsize, length, source);
        }
        ANGLE_CAPTURE(GetTranslatedShaderSourceANGLE, isCallValid, context, shaderPacked, bufsize,
                      length, source);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

GLuint GL_APIENTRY GetUniformBlockIndexContextANGLE(GLeglContext ctx,
                                                    GLuint program,
                                                    const GLchar *uniformBlockName)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetUniformBlockIndex, "glGetUniformBlockIndex",
          "context = %d, program = %u, uniformBlockName = 0x%016" PRIxPTR "", CID(context), program,
          (uintptr_t)uniformBlockName);

    GLuint returnValue;
    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetUniformBlockIndex(context, programPacked, uniformBlockName));
        if (isCallValid)
        {
            returnValue = context->getUniformBlockIndex(programPacked, uniformBlockName);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::GetUniformBlockIndex, GLuint>();
        }
        ANGLE_CAPTURE(GetUniformBlockIndex, isCallValid, context, programPacked, uniformBlockName,
                      returnValue);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
        returnValue = GetDefaultReturnValue<EntryPoint::GetUniformBlockIndex, GLuint>();
    }
    return returnValue;
}

void GL_APIENTRY GetUniformIndicesContextANGLE(GLeglContext ctx,
                                               GLuint program,
                                               GLsizei uniformCount,
                                               const GLchar *const *uniformNames,
                                               GLuint *uniformIndices)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetUniformIndices, "glGetUniformIndices",
          "context = %d, program = %u, uniformCount = %d, uniformNames = 0x%016" PRIxPTR
          ", uniformIndices = 0x%016" PRIxPTR "",
          CID(context), program, uniformCount, (uintptr_t)uniformNames, (uintptr_t)uniformIndices);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetUniformIndices(context, programPacked, uniformCount,
                                                      uniformNames, uniformIndices));
        if (isCallValid)
        {
            context->getUniformIndices(programPacked, uniformCount, uniformNames, uniformIndices);
        }
        ANGLE_CAPTURE(GetUniformIndices, isCallValid, context, programPacked, uniformCount,
                      uniformNames, uniformIndices);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

GLint GL_APIENTRY GetUniformLocationContextANGLE(GLeglContext ctx,
                                                 GLuint program,
                                                 const GLchar *name)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetUniformLocation, "glGetUniformLocation",
          "context = %d, program = %u, name = 0x%016" PRIxPTR "", CID(context), program,
          (uintptr_t)name);

    GLint returnValue;
    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetUniformLocation(context, programPacked, name));
        if (isCallValid)
        {
            returnValue = context->getUniformLocation(programPacked, name);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::GetUniformLocation, GLint>();
        }
        ANGLE_CAPTURE(GetUniformLocation, isCallValid, context, programPacked, name, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
        returnValue = GetDefaultReturnValue<EntryPoint::GetUniformLocation, GLint>();
    }
    return returnValue;
}

void GL_APIENTRY GetUniformfvContextANGLE(GLeglContext ctx,
                                          GLuint program,
                                          GLint location,
                                          GLfloat *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetUniformfv, "glGetUniformfv",
          "context = %d, program = %u, location = %d, params = 0x%016" PRIxPTR "", CID(context),
          program, location, (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetUniformfv(context, programPacked, locationPacked, params));
        if (isCallValid)
        {
            context->getUniformfv(programPacked, locationPacked, params);
        }
        ANGLE_CAPTURE(GetUniformfv, isCallValid, context, programPacked, locationPacked, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetUniformivContextANGLE(GLeglContext ctx,
                                          GLuint program,
                                          GLint location,
                                          GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetUniformiv, "glGetUniformiv",
          "context = %d, program = %u, location = %d, params = 0x%016" PRIxPTR "", CID(context),
          program, location, (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetUniformiv(context, programPacked, locationPacked, params));
        if (isCallValid)
        {
            context->getUniformiv(programPacked, locationPacked, params);
        }
        ANGLE_CAPTURE(GetUniformiv, isCallValid, context, programPacked, locationPacked, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetUniformuivContextANGLE(GLeglContext ctx,
                                           GLuint program,
                                           GLint location,
                                           GLuint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetUniformuiv, "glGetUniformuiv",
          "context = %d, program = %u, location = %d, params = 0x%016" PRIxPTR "", CID(context),
          program, location, (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetUniformuiv(context, programPacked, locationPacked, params));
        if (isCallValid)
        {
            context->getUniformuiv(programPacked, locationPacked, params);
        }
        ANGLE_CAPTURE(GetUniformuiv, isCallValid, context, programPacked, locationPacked, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetUnsignedBytevEXTContextANGLE(GLeglContext ctx, GLenum pname, GLubyte *data)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetUnsignedBytevEXT, "glGetUnsignedBytevEXT",
          "context = %d, pname = %s, data = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::GetPName, pname), (uintptr_t)data);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetUnsignedBytevEXT(context, pname, data));
        if (isCallValid)
        {
            context->getUnsignedBytev(pname, data);
        }
        ANGLE_CAPTURE(GetUnsignedBytevEXT, isCallValid, context, pname, data);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetUnsignedBytei_vEXTContextANGLE(GLeglContext ctx,
                                                   GLenum target,
                                                   GLuint index,
                                                   GLubyte *data)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetUnsignedBytei_vEXT, "glGetUnsignedBytei_vEXT",
          "context = %d, target = %s, index = %u, data = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::DefaultGroup, target), index, (uintptr_t)data);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetUnsignedBytei_vEXT(context, target, index, data));
        if (isCallValid)
        {
            context->getUnsignedBytei_v(target, index, data);
        }
        ANGLE_CAPTURE(GetUnsignedBytei_vEXT, isCallValid, context, target, index, data);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetVertexAttribIivContextANGLE(GLeglContext ctx,
                                                GLuint index,
                                                GLenum pname,
                                                GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetVertexAttribIiv, "glGetVertexAttribIiv",
          "context = %d, index = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context), index,
          GLenumToString(GLenumGroup::VertexAttribEnum, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetVertexAttribIiv(context, index, pname, params));
        if (isCallValid)
        {
            context->getVertexAttribIiv(index, pname, params);
        }
        ANGLE_CAPTURE(GetVertexAttribIiv, isCallValid, context, index, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetVertexAttribIuivContextANGLE(GLeglContext ctx,
                                                 GLuint index,
                                                 GLenum pname,
                                                 GLuint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetVertexAttribIuiv, "glGetVertexAttribIuiv",
          "context = %d, index = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context), index,
          GLenumToString(GLenumGroup::VertexAttribEnum, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetVertexAttribIuiv(context, index, pname, params));
        if (isCallValid)
        {
            context->getVertexAttribIuiv(index, pname, params);
        }
        ANGLE_CAPTURE(GetVertexAttribIuiv, isCallValid, context, index, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetVertexAttribPointervContextANGLE(GLeglContext ctx,
                                                     GLuint index,
                                                     GLenum pname,
                                                     void **pointer)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetVertexAttribPointerv, "glGetVertexAttribPointerv",
          "context = %d, index = %u, pname = %s, pointer = 0x%016" PRIxPTR "", CID(context), index,
          GLenumToString(GLenumGroup::DefaultGroup, pname), (uintptr_t)pointer);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetVertexAttribPointerv(context, index, pname, pointer));
        if (isCallValid)
        {
            context->getVertexAttribPointerv(index, pname, pointer);
        }
        ANGLE_CAPTURE(GetVertexAttribPointerv, isCallValid, context, index, pname, pointer);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetVertexAttribfvContextANGLE(GLeglContext ctx,
                                               GLuint index,
                                               GLenum pname,
                                               GLfloat *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetVertexAttribfv, "glGetVertexAttribfv",
          "context = %d, index = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context), index,
          GLenumToString(GLenumGroup::DefaultGroup, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetVertexAttribfv(context, index, pname, params));
        if (isCallValid)
        {
            context->getVertexAttribfv(index, pname, params);
        }
        ANGLE_CAPTURE(GetVertexAttribfv, isCallValid, context, index, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetVertexAttribivContextANGLE(GLeglContext ctx,
                                               GLuint index,
                                               GLenum pname,
                                               GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetVertexAttribiv, "glGetVertexAttribiv",
          "context = %d, index = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context), index,
          GLenumToString(GLenumGroup::DefaultGroup, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetVertexAttribiv(context, index, pname, params));
        if (isCallValid)
        {
            context->getVertexAttribiv(index, pname, params);
        }
        ANGLE_CAPTURE(GetVertexAttribiv, isCallValid, context, index, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetnUniformfvContextANGLE(GLeglContext ctx,
                                           GLuint program,
                                           GLint location,
                                           GLsizei bufSize,
                                           GLfloat *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetnUniformfv, "glGetnUniformfv",
          "context = %d, program = %u, location = %d, bufSize = %d, params = 0x%016" PRIxPTR "",
          CID(context), program, location, bufSize, (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetnUniformfv(context, programPacked, locationPacked, bufSize, params));
        if (isCallValid)
        {
            context->getnUniformfv(programPacked, locationPacked, bufSize, params);
        }
        ANGLE_CAPTURE(GetnUniformfv, isCallValid, context, programPacked, locationPacked, bufSize,
                      params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetnUniformfvEXTContextANGLE(GLeglContext ctx,
                                              GLuint program,
                                              GLint location,
                                              GLsizei bufSize,
                                              GLfloat *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetnUniformfvEXT, "glGetnUniformfvEXT",
          "context = %d, program = %u, location = %d, bufSize = %d, params = 0x%016" PRIxPTR "",
          CID(context), program, location, bufSize, (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetnUniformfvEXT(context, programPacked, locationPacked, bufSize, params));
        if (isCallValid)
        {
            context->getnUniformfv(programPacked, locationPacked, bufSize, params);
        }
        ANGLE_CAPTURE(GetnUniformfvEXT, isCallValid, context, programPacked, locationPacked,
                      bufSize, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetnUniformivContextANGLE(GLeglContext ctx,
                                           GLuint program,
                                           GLint location,
                                           GLsizei bufSize,
                                           GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetnUniformiv, "glGetnUniformiv",
          "context = %d, program = %u, location = %d, bufSize = %d, params = 0x%016" PRIxPTR "",
          CID(context), program, location, bufSize, (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetnUniformiv(context, programPacked, locationPacked, bufSize, params));
        if (isCallValid)
        {
            context->getnUniformiv(programPacked, locationPacked, bufSize, params);
        }
        ANGLE_CAPTURE(GetnUniformiv, isCallValid, context, programPacked, locationPacked, bufSize,
                      params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetnUniformivEXTContextANGLE(GLeglContext ctx,
                                              GLuint program,
                                              GLint location,
                                              GLsizei bufSize,
                                              GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetnUniformivEXT, "glGetnUniformivEXT",
          "context = %d, program = %u, location = %d, bufSize = %d, params = 0x%016" PRIxPTR "",
          CID(context), program, location, bufSize, (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetnUniformivEXT(context, programPacked, locationPacked, bufSize, params));
        if (isCallValid)
        {
            context->getnUniformiv(programPacked, locationPacked, bufSize, params);
        }
        ANGLE_CAPTURE(GetnUniformivEXT, isCallValid, context, programPacked, locationPacked,
                      bufSize, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetnUniformuivContextANGLE(GLeglContext ctx,
                                            GLuint program,
                                            GLint location,
                                            GLsizei bufSize,
                                            GLuint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetnUniformuiv, "glGetnUniformuiv",
          "context = %d, program = %u, location = %d, bufSize = %d, params = 0x%016" PRIxPTR "",
          CID(context), program, location, bufSize, (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetnUniformuiv(context, programPacked, locationPacked, bufSize, params));
        if (isCallValid)
        {
            context->getnUniformuiv(programPacked, locationPacked, bufSize, params);
        }
        ANGLE_CAPTURE(GetnUniformuiv, isCallValid, context, programPacked, locationPacked, bufSize,
                      params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY HintContextANGLE(GLeglContext ctx, GLenum target, GLenum mode)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Hint, "glHint", "context = %d, target = %s, mode = %s",
          CID(context), GLenumToString(GLenumGroup::HintTarget, target),
          GLenumToString(GLenumGroup::HintMode, mode));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateHint(context, target, mode));
        if (isCallValid)
        {
            context->hint(target, mode);
        }
        ANGLE_CAPTURE(Hint, isCallValid, context, target, mode);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ImportMemoryFdEXTContextANGLE(GLeglContext ctx,
                                               GLuint memory,
                                               GLuint64 size,
                                               GLenum handleType,
                                               GLint fd)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ImportMemoryFdEXT, "glImportMemoryFdEXT",
          "context = %d, memory = %u, size = %llu, handleType = %s, fd = %d", CID(context), memory,
          static_cast<unsigned long long>(size),
          GLenumToString(GLenumGroup::ExternalHandleType, handleType), fd);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        MemoryObjectID memoryPacked                           = FromGL<MemoryObjectID>(memory);
        HandleType handleTypePacked                           = FromGL<HandleType>(handleType);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateImportMemoryFdEXT(context, memoryPacked, size, handleTypePacked, fd));
        if (isCallValid)
        {
            context->importMemoryFd(memoryPacked, size, handleTypePacked, fd);
        }
        ANGLE_CAPTURE(ImportMemoryFdEXT, isCallValid, context, memoryPacked, size, handleTypePacked,
                      fd);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ImportSemaphoreFdEXTContextANGLE(GLeglContext ctx,
                                                  GLuint semaphore,
                                                  GLenum handleType,
                                                  GLint fd)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ImportSemaphoreFdEXT, "glImportSemaphoreFdEXT",
          "context = %d, semaphore = %u, handleType = %s, fd = %d", CID(context), semaphore,
          GLenumToString(GLenumGroup::ExternalHandleType, handleType), fd);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        SemaphoreID semaphorePacked                           = FromGL<SemaphoreID>(semaphore);
        HandleType handleTypePacked                           = FromGL<HandleType>(handleType);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateImportSemaphoreFdEXT(context, semaphorePacked, handleTypePacked, fd));
        if (isCallValid)
        {
            context->importSemaphoreFd(semaphorePacked, handleTypePacked, fd);
        }
        ANGLE_CAPTURE(ImportSemaphoreFdEXT, isCallValid, context, semaphorePacked, handleTypePacked,
                      fd);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY InsertEventMarkerEXTContextANGLE(GLeglContext ctx,
                                                  GLsizei length,
                                                  const GLchar *marker)
{
    Context *context = static_cast<gl::Context *>(ctx);
    // Don't run the EVENT() macro on the EXT_debug_marker entry points.
    // It can interfere with the debug events being set by the caller.
    // EVENT(context, gl::EntryPoint::InsertEventMarkerEXT, "glInsertEventMarkerEXT", "context = %d,
    // length = %d, marker = 0x%016" PRIxPTR "", CID(context), length, (uintptr_t)marker);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateInsertEventMarkerEXT(context, length, marker));
        if (isCallValid)
        {
            context->insertEventMarker(length, marker);
        }
        ANGLE_CAPTURE(InsertEventMarkerEXT, isCallValid, context, length, marker);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY InvalidateFramebufferContextANGLE(GLeglContext ctx,
                                                   GLenum target,
                                                   GLsizei numAttachments,
                                                   const GLenum *attachments)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::InvalidateFramebuffer, "glInvalidateFramebuffer",
          "context = %d, target = %s, numAttachments = %d, attachments = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::FramebufferTarget, target), numAttachments,
          (uintptr_t)attachments);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateInvalidateFramebuffer(context, target, numAttachments, attachments));
        if (isCallValid)
        {
            context->invalidateFramebuffer(target, numAttachments, attachments);
        }
        ANGLE_CAPTURE(InvalidateFramebuffer, isCallValid, context, target, numAttachments,
                      attachments);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY InvalidateSubFramebufferContextANGLE(GLeglContext ctx,
                                                      GLenum target,
                                                      GLsizei numAttachments,
                                                      const GLenum *attachments,
                                                      GLint x,
                                                      GLint y,
                                                      GLsizei width,
                                                      GLsizei height)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::InvalidateSubFramebuffer, "glInvalidateSubFramebuffer",
          "context = %d, target = %s, numAttachments = %d, attachments = 0x%016" PRIxPTR
          ", x = %d, y = %d, width = %d, height = %d",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target), numAttachments,
          (uintptr_t)attachments, x, y, width, height);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateInvalidateSubFramebuffer(context, target, numAttachments,
                                                             attachments, x, y, width, height));
        if (isCallValid)
        {
            context->invalidateSubFramebuffer(target, numAttachments, attachments, x, y, width,
                                              height);
        }
        ANGLE_CAPTURE(InvalidateSubFramebuffer, isCallValid, context, target, numAttachments,
                      attachments, x, y, width, height);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

GLboolean GL_APIENTRY IsBufferContextANGLE(GLeglContext ctx, GLuint buffer)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::IsBuffer, "glIsBuffer", "context = %d, buffer = %u",
          CID(context), buffer);

    GLboolean returnValue;
    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        BufferID bufferPacked                                 = FromGL<BufferID>(buffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateIsBuffer(context, bufferPacked));
        if (isCallValid)
        {
            returnValue = context->isBuffer(bufferPacked);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::IsBuffer, GLboolean>();
        }
        ANGLE_CAPTURE(IsBuffer, isCallValid, context, bufferPacked, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
        returnValue = GetDefaultReturnValue<EntryPoint::IsBuffer, GLboolean>();
    }
    return returnValue;
}

GLboolean GL_APIENTRY IsEnabledContextANGLE(GLeglContext ctx, GLenum cap)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::IsEnabled, "glIsEnabled", "context = %d, cap = %s", CID(context),
          GLenumToString(GLenumGroup::EnableCap, cap));

    GLboolean returnValue;
    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateIsEnabled(context, cap));
        if (isCallValid)
        {
            returnValue = context->isEnabled(cap);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::IsEnabled, GLboolean>();
        }
        ANGLE_CAPTURE(IsEnabled, isCallValid, context, cap, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
        returnValue = GetDefaultReturnValue<EntryPoint::IsEnabled, GLboolean>();
    }
    return returnValue;
}

GLboolean GL_APIENTRY IsEnablediContextANGLE(GLeglContext ctx, GLenum target, GLuint index)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::IsEnabledi, "glIsEnabledi",
          "context = %d, target = %s, index = %u", CID(context),
          GLenumToString(GLenumGroup::EnableCap, target), index);

    GLboolean returnValue;
    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateIsEnabledi(context, target, index));
        if (isCallValid)
        {
            returnValue = context->isEnabledi(target, index);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::IsEnabledi, GLboolean>();
        }
        ANGLE_CAPTURE(IsEnabledi, isCallValid, context, target, index, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
        returnValue = GetDefaultReturnValue<EntryPoint::IsEnabledi, GLboolean>();
    }
    return returnValue;
}

GLboolean GL_APIENTRY IsEnablediEXTContextANGLE(GLeglContext ctx, GLenum target, GLuint index)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::IsEnablediEXT, "glIsEnablediEXT",
          "context = %d, target = %s, index = %u", CID(context),
          GLenumToString(GLenumGroup::EnableCap, target), index);

    GLboolean returnValue;
    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateIsEnablediEXT(context, target, index));
        if (isCallValid)
        {
            returnValue = context->isEnabledi(target, index);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::IsEnablediEXT, GLboolean>();
        }
        ANGLE_CAPTURE(IsEnablediEXT, isCallValid, context, target, index, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
        returnValue = GetDefaultReturnValue<EntryPoint::IsEnablediEXT, GLboolean>();
    }
    return returnValue;
}

GLboolean GL_APIENTRY IsEnablediOESContextANGLE(GLeglContext ctx, GLenum target, GLuint index)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::IsEnablediOES, "glIsEnablediOES",
          "context = %d, target = %s, index = %u", CID(context),
          GLenumToString(GLenumGroup::EnableCap, target), index);

    GLboolean returnValue;
    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateIsEnablediOES(context, target, index));
        if (isCallValid)
        {
            returnValue = context->isEnabledi(target, index);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::IsEnablediOES, GLboolean>();
        }
        ANGLE_CAPTURE(IsEnablediOES, isCallValid, context, target, index, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
        returnValue = GetDefaultReturnValue<EntryPoint::IsEnablediOES, GLboolean>();
    }
    return returnValue;
}

GLboolean GL_APIENTRY IsFenceNVContextANGLE(GLeglContext ctx, GLuint fence)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::IsFenceNV, "glIsFenceNV", "context = %d, fence = %u",
          CID(context), fence);

    GLboolean returnValue;
    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        FenceNVID fencePacked                                 = FromGL<FenceNVID>(fence);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateIsFenceNV(context, fencePacked));
        if (isCallValid)
        {
            returnValue = context->isFenceNV(fencePacked);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::IsFenceNV, GLboolean>();
        }
        ANGLE_CAPTURE(IsFenceNV, isCallValid, context, fencePacked, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
        returnValue = GetDefaultReturnValue<EntryPoint::IsFenceNV, GLboolean>();
    }
    return returnValue;
}

GLboolean GL_APIENTRY IsFramebufferContextANGLE(GLeglContext ctx, GLuint framebuffer)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::IsFramebuffer, "glIsFramebuffer",
          "context = %d, framebuffer = %u", CID(context), framebuffer);

    GLboolean returnValue;
    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        FramebufferID framebufferPacked                       = FromGL<FramebufferID>(framebuffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateIsFramebuffer(context, framebufferPacked));
        if (isCallValid)
        {
            returnValue = context->isFramebuffer(framebufferPacked);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::IsFramebuffer, GLboolean>();
        }
        ANGLE_CAPTURE(IsFramebuffer, isCallValid, context, framebufferPacked, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
        returnValue = GetDefaultReturnValue<EntryPoint::IsFramebuffer, GLboolean>();
    }
    return returnValue;
}

GLboolean GL_APIENTRY IsFramebufferOESContextANGLE(GLeglContext ctx, GLuint framebuffer)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::IsFramebufferOES, "glIsFramebufferOES",
          "context = %d, framebuffer = %u", CID(context), framebuffer);

    GLboolean returnValue;
    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        FramebufferID framebufferPacked                       = FromGL<FramebufferID>(framebuffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateIsFramebufferOES(context, framebufferPacked));
        if (isCallValid)
        {
            returnValue = context->isFramebuffer(framebufferPacked);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::IsFramebufferOES, GLboolean>();
        }
        ANGLE_CAPTURE(IsFramebufferOES, isCallValid, context, framebufferPacked, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
        returnValue = GetDefaultReturnValue<EntryPoint::IsFramebufferOES, GLboolean>();
    }
    return returnValue;
}

GLboolean GL_APIENTRY IsMemoryObjectEXTContextANGLE(GLeglContext ctx, GLuint memoryObject)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::IsMemoryObjectEXT, "glIsMemoryObjectEXT",
          "context = %d, memoryObject = %u", CID(context), memoryObject);

    GLboolean returnValue;
    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        MemoryObjectID memoryObjectPacked = FromGL<MemoryObjectID>(memoryObject);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateIsMemoryObjectEXT(context, memoryObjectPacked));
        if (isCallValid)
        {
            returnValue = context->isMemoryObject(memoryObjectPacked);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::IsMemoryObjectEXT, GLboolean>();
        }
        ANGLE_CAPTURE(IsMemoryObjectEXT, isCallValid, context, memoryObjectPacked, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
        returnValue = GetDefaultReturnValue<EntryPoint::IsMemoryObjectEXT, GLboolean>();
    }
    return returnValue;
}

GLboolean GL_APIENTRY IsProgramContextANGLE(GLeglContext ctx, GLuint program)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::IsProgram, "glIsProgram", "context = %d, program = %u",
          CID(context), program);

    GLboolean returnValue;
    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateIsProgram(context, programPacked));
        if (isCallValid)
        {
            returnValue = context->isProgram(programPacked);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::IsProgram, GLboolean>();
        }
        ANGLE_CAPTURE(IsProgram, isCallValid, context, programPacked, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
        returnValue = GetDefaultReturnValue<EntryPoint::IsProgram, GLboolean>();
    }
    return returnValue;
}

GLboolean GL_APIENTRY IsProgramPipelineContextANGLE(GLeglContext ctx, GLuint pipeline)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::IsProgramPipeline, "glIsProgramPipeline",
          "context = %d, pipeline = %u", CID(context), pipeline);

    GLboolean returnValue;
    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ProgramPipelineID pipelinePacked                      = FromGL<ProgramPipelineID>(pipeline);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateIsProgramPipeline(context, pipelinePacked));
        if (isCallValid)
        {
            returnValue = context->isProgramPipeline(pipelinePacked);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::IsProgramPipeline, GLboolean>();
        }
        ANGLE_CAPTURE(IsProgramPipeline, isCallValid, context, pipelinePacked, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
        returnValue = GetDefaultReturnValue<EntryPoint::IsProgramPipeline, GLboolean>();
    }
    return returnValue;
}

GLboolean GL_APIENTRY IsQueryContextANGLE(GLeglContext ctx, GLuint id)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::IsQuery, "glIsQuery", "context = %d, id = %u", CID(context), id);

    GLboolean returnValue;
    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        QueryID idPacked                                      = FromGL<QueryID>(id);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateIsQuery(context, idPacked));
        if (isCallValid)
        {
            returnValue = context->isQuery(idPacked);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::IsQuery, GLboolean>();
        }
        ANGLE_CAPTURE(IsQuery, isCallValid, context, idPacked, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
        returnValue = GetDefaultReturnValue<EntryPoint::IsQuery, GLboolean>();
    }
    return returnValue;
}

GLboolean GL_APIENTRY IsQueryEXTContextANGLE(GLeglContext ctx, GLuint id)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::IsQueryEXT, "glIsQueryEXT", "context = %d, id = %u",
          CID(context), id);

    GLboolean returnValue;
    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        QueryID idPacked                                      = FromGL<QueryID>(id);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateIsQueryEXT(context, idPacked));
        if (isCallValid)
        {
            returnValue = context->isQuery(idPacked);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::IsQueryEXT, GLboolean>();
        }
        ANGLE_CAPTURE(IsQueryEXT, isCallValid, context, idPacked, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
        returnValue = GetDefaultReturnValue<EntryPoint::IsQueryEXT, GLboolean>();
    }
    return returnValue;
}

GLboolean GL_APIENTRY IsRenderbufferContextANGLE(GLeglContext ctx, GLuint renderbuffer)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::IsRenderbuffer, "glIsRenderbuffer",
          "context = %d, renderbuffer = %u", CID(context), renderbuffer);

    GLboolean returnValue;
    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        RenderbufferID renderbufferPacked = FromGL<RenderbufferID>(renderbuffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateIsRenderbuffer(context, renderbufferPacked));
        if (isCallValid)
        {
            returnValue = context->isRenderbuffer(renderbufferPacked);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::IsRenderbuffer, GLboolean>();
        }
        ANGLE_CAPTURE(IsRenderbuffer, isCallValid, context, renderbufferPacked, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
        returnValue = GetDefaultReturnValue<EntryPoint::IsRenderbuffer, GLboolean>();
    }
    return returnValue;
}

GLboolean GL_APIENTRY IsRenderbufferOESContextANGLE(GLeglContext ctx, GLuint renderbuffer)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::IsRenderbufferOES, "glIsRenderbufferOES",
          "context = %d, renderbuffer = %u", CID(context), renderbuffer);

    GLboolean returnValue;
    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        RenderbufferID renderbufferPacked = FromGL<RenderbufferID>(renderbuffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateIsRenderbufferOES(context, renderbufferPacked));
        if (isCallValid)
        {
            returnValue = context->isRenderbuffer(renderbufferPacked);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::IsRenderbufferOES, GLboolean>();
        }
        ANGLE_CAPTURE(IsRenderbufferOES, isCallValid, context, renderbufferPacked, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
        returnValue = GetDefaultReturnValue<EntryPoint::IsRenderbufferOES, GLboolean>();
    }
    return returnValue;
}

GLboolean GL_APIENTRY IsSemaphoreEXTContextANGLE(GLeglContext ctx, GLuint semaphore)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::IsSemaphoreEXT, "glIsSemaphoreEXT",
          "context = %d, semaphore = %u", CID(context), semaphore);

    GLboolean returnValue;
    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        SemaphoreID semaphorePacked                           = FromGL<SemaphoreID>(semaphore);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateIsSemaphoreEXT(context, semaphorePacked));
        if (isCallValid)
        {
            returnValue = context->isSemaphore(semaphorePacked);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::IsSemaphoreEXT, GLboolean>();
        }
        ANGLE_CAPTURE(IsSemaphoreEXT, isCallValid, context, semaphorePacked, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
        returnValue = GetDefaultReturnValue<EntryPoint::IsSemaphoreEXT, GLboolean>();
    }
    return returnValue;
}

GLboolean GL_APIENTRY IsSamplerContextANGLE(GLeglContext ctx, GLuint sampler)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::IsSampler, "glIsSampler", "context = %d, sampler = %u",
          CID(context), sampler);

    GLboolean returnValue;
    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        SamplerID samplerPacked                               = FromGL<SamplerID>(sampler);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateIsSampler(context, samplerPacked));
        if (isCallValid)
        {
            returnValue = context->isSampler(samplerPacked);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::IsSampler, GLboolean>();
        }
        ANGLE_CAPTURE(IsSampler, isCallValid, context, samplerPacked, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
        returnValue = GetDefaultReturnValue<EntryPoint::IsSampler, GLboolean>();
    }
    return returnValue;
}

GLboolean GL_APIENTRY IsShaderContextANGLE(GLeglContext ctx, GLuint shader)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::IsShader, "glIsShader", "context = %d, shader = %u",
          CID(context), shader);

    GLboolean returnValue;
    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID shaderPacked                          = FromGL<ShaderProgramID>(shader);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateIsShader(context, shaderPacked));
        if (isCallValid)
        {
            returnValue = context->isShader(shaderPacked);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::IsShader, GLboolean>();
        }
        ANGLE_CAPTURE(IsShader, isCallValid, context, shaderPacked, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
        returnValue = GetDefaultReturnValue<EntryPoint::IsShader, GLboolean>();
    }
    return returnValue;
}

GLboolean GL_APIENTRY IsSyncContextANGLE(GLeglContext ctx, GLsync sync)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::IsSync, "glIsSync", "context = %d, sync = 0x%016" PRIxPTR "",
          CID(context), (uintptr_t)sync);

    GLboolean returnValue;
    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateIsSync(context, sync));
        if (isCallValid)
        {
            returnValue = context->isSync(sync);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::IsSync, GLboolean>();
        }
        ANGLE_CAPTURE(IsSync, isCallValid, context, sync, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
        returnValue = GetDefaultReturnValue<EntryPoint::IsSync, GLboolean>();
    }
    return returnValue;
}

GLboolean GL_APIENTRY IsTextureContextANGLE(GLeglContext ctx, GLuint texture)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::IsTexture, "glIsTexture", "context = %d, texture = %u",
          CID(context), texture);

    GLboolean returnValue;
    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureID texturePacked                               = FromGL<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateIsTexture(context, texturePacked));
        if (isCallValid)
        {
            returnValue = context->isTexture(texturePacked);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::IsTexture, GLboolean>();
        }
        ANGLE_CAPTURE(IsTexture, isCallValid, context, texturePacked, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
        returnValue = GetDefaultReturnValue<EntryPoint::IsTexture, GLboolean>();
    }
    return returnValue;
}

GLboolean GL_APIENTRY IsTransformFeedbackContextANGLE(GLeglContext ctx, GLuint id)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::IsTransformFeedback, "glIsTransformFeedback",
          "context = %d, id = %u", CID(context), id);

    GLboolean returnValue;
    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TransformFeedbackID idPacked                          = FromGL<TransformFeedbackID>(id);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateIsTransformFeedback(context, idPacked));
        if (isCallValid)
        {
            returnValue = context->isTransformFeedback(idPacked);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::IsTransformFeedback, GLboolean>();
        }
        ANGLE_CAPTURE(IsTransformFeedback, isCallValid, context, idPacked, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
        returnValue = GetDefaultReturnValue<EntryPoint::IsTransformFeedback, GLboolean>();
    }
    return returnValue;
}

GLboolean GL_APIENTRY IsVertexArrayContextANGLE(GLeglContext ctx, GLuint array)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::IsVertexArray, "glIsVertexArray", "context = %d, array = %u",
          CID(context), array);

    GLboolean returnValue;
    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        VertexArrayID arrayPacked                             = FromGL<VertexArrayID>(array);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateIsVertexArray(context, arrayPacked));
        if (isCallValid)
        {
            returnValue = context->isVertexArray(arrayPacked);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::IsVertexArray, GLboolean>();
        }
        ANGLE_CAPTURE(IsVertexArray, isCallValid, context, arrayPacked, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
        returnValue = GetDefaultReturnValue<EntryPoint::IsVertexArray, GLboolean>();
    }
    return returnValue;
}

GLboolean GL_APIENTRY IsVertexArrayOESContextANGLE(GLeglContext ctx, GLuint array)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::IsVertexArrayOES, "glIsVertexArrayOES",
          "context = %d, array = %u", CID(context), array);

    GLboolean returnValue;
    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        VertexArrayID arrayPacked                             = FromGL<VertexArrayID>(array);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateIsVertexArrayOES(context, arrayPacked));
        if (isCallValid)
        {
            returnValue = context->isVertexArray(arrayPacked);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::IsVertexArrayOES, GLboolean>();
        }
        ANGLE_CAPTURE(IsVertexArrayOES, isCallValid, context, arrayPacked, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
        returnValue = GetDefaultReturnValue<EntryPoint::IsVertexArrayOES, GLboolean>();
    }
    return returnValue;
}

void GL_APIENTRY LightModelfContextANGLE(GLeglContext ctx, GLenum pname, GLfloat param)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::LightModelf, "glLightModelf",
          "context = %d, pname = %s, param = %f", CID(context),
          GLenumToString(GLenumGroup::LightModelParameter, pname), param);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateLightModelf(context, pname, param));
        if (isCallValid)
        {
            context->lightModelf(pname, param);
        }
        ANGLE_CAPTURE(LightModelf, isCallValid, context, pname, param);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY LightModelfvContextANGLE(GLeglContext ctx, GLenum pname, const GLfloat *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::LightModelfv, "glLightModelfv",
          "context = %d, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::LightModelParameter, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateLightModelfv(context, pname, params));
        if (isCallValid)
        {
            context->lightModelfv(pname, params);
        }
        ANGLE_CAPTURE(LightModelfv, isCallValid, context, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY LightModelxContextANGLE(GLeglContext ctx, GLenum pname, GLfixed param)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::LightModelx, "glLightModelx",
          "context = %d, pname = %s, param = 0x%X", CID(context),
          GLenumToString(GLenumGroup::LightModelParameter, pname), param);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateLightModelx(context, pname, param));
        if (isCallValid)
        {
            context->lightModelx(pname, param);
        }
        ANGLE_CAPTURE(LightModelx, isCallValid, context, pname, param);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY LightModelxvContextANGLE(GLeglContext ctx, GLenum pname, const GLfixed *param)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::LightModelxv, "glLightModelxv",
          "context = %d, pname = %s, param = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::LightModelParameter, pname), (uintptr_t)param);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateLightModelxv(context, pname, param));
        if (isCallValid)
        {
            context->lightModelxv(pname, param);
        }
        ANGLE_CAPTURE(LightModelxv, isCallValid, context, pname, param);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY LightfContextANGLE(GLeglContext ctx, GLenum light, GLenum pname, GLfloat param)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Lightf, "glLightf",
          "context = %d, light = %s, pname = %s, param = %f", CID(context),
          GLenumToString(GLenumGroup::LightName, light),
          GLenumToString(GLenumGroup::LightParameter, pname), param);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        LightParameter pnamePacked                            = FromGL<LightParameter>(pname);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateLightf(context, light, pnamePacked, param));
        if (isCallValid)
        {
            context->lightf(light, pnamePacked, param);
        }
        ANGLE_CAPTURE(Lightf, isCallValid, context, light, pnamePacked, param);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY LightfvContextANGLE(GLeglContext ctx,
                                     GLenum light,
                                     GLenum pname,
                                     const GLfloat *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Lightfv, "glLightfv",
          "context = %d, light = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::LightName, light),
          GLenumToString(GLenumGroup::LightParameter, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        LightParameter pnamePacked                            = FromGL<LightParameter>(pname);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateLightfv(context, light, pnamePacked, params));
        if (isCallValid)
        {
            context->lightfv(light, pnamePacked, params);
        }
        ANGLE_CAPTURE(Lightfv, isCallValid, context, light, pnamePacked, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY LightxContextANGLE(GLeglContext ctx, GLenum light, GLenum pname, GLfixed param)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Lightx, "glLightx",
          "context = %d, light = %s, pname = %s, param = 0x%X", CID(context),
          GLenumToString(GLenumGroup::LightName, light),
          GLenumToString(GLenumGroup::LightParameter, pname), param);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        LightParameter pnamePacked                            = FromGL<LightParameter>(pname);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateLightx(context, light, pnamePacked, param));
        if (isCallValid)
        {
            context->lightx(light, pnamePacked, param);
        }
        ANGLE_CAPTURE(Lightx, isCallValid, context, light, pnamePacked, param);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY LightxvContextANGLE(GLeglContext ctx,
                                     GLenum light,
                                     GLenum pname,
                                     const GLfixed *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Lightxv, "glLightxv",
          "context = %d, light = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::LightName, light),
          GLenumToString(GLenumGroup::LightParameter, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        LightParameter pnamePacked                            = FromGL<LightParameter>(pname);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateLightxv(context, light, pnamePacked, params));
        if (isCallValid)
        {
            context->lightxv(light, pnamePacked, params);
        }
        ANGLE_CAPTURE(Lightxv, isCallValid, context, light, pnamePacked, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY LineWidthContextANGLE(GLeglContext ctx, GLfloat width)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::LineWidth, "glLineWidth", "context = %d, width = %f",
          CID(context), width);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateLineWidth(context, width));
        if (isCallValid)
        {
            context->lineWidth(width);
        }
        ANGLE_CAPTURE(LineWidth, isCallValid, context, width);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY LineWidthxContextANGLE(GLeglContext ctx, GLfixed width)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::LineWidthx, "glLineWidthx", "context = %d, width = 0x%X",
          CID(context), width);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateLineWidthx(context, width));
        if (isCallValid)
        {
            context->lineWidthx(width);
        }
        ANGLE_CAPTURE(LineWidthx, isCallValid, context, width);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY LinkProgramContextANGLE(GLeglContext ctx, GLuint program)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::LinkProgram, "glLinkProgram", "context = %d, program = %u",
          CID(context), program);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateLinkProgram(context, programPacked));
        if (isCallValid)
        {
            context->linkProgram(programPacked);
        }
        ANGLE_CAPTURE(LinkProgram, isCallValid, context, programPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY LoadIdentityContextANGLE(GLeglContext ctx)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::LoadIdentity, "glLoadIdentity", "context = %d", CID(context));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateLoadIdentity(context));
        if (isCallValid)
        {
            context->loadIdentity();
        }
        ANGLE_CAPTURE(LoadIdentity, isCallValid, context);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY LoadMatrixfContextANGLE(GLeglContext ctx, const GLfloat *m)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::LoadMatrixf, "glLoadMatrixf",
          "context = %d, m = 0x%016" PRIxPTR "", CID(context), (uintptr_t)m);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateLoadMatrixf(context, m));
        if (isCallValid)
        {
            context->loadMatrixf(m);
        }
        ANGLE_CAPTURE(LoadMatrixf, isCallValid, context, m);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY LoadMatrixxContextANGLE(GLeglContext ctx, const GLfixed *m)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::LoadMatrixx, "glLoadMatrixx",
          "context = %d, m = 0x%016" PRIxPTR "", CID(context), (uintptr_t)m);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateLoadMatrixx(context, m));
        if (isCallValid)
        {
            context->loadMatrixx(m);
        }
        ANGLE_CAPTURE(LoadMatrixx, isCallValid, context, m);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY LoadPaletteFromModelViewMatrixOESContextANGLE(GLeglContext ctx)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::LoadPaletteFromModelViewMatrixOES,
          "glLoadPaletteFromModelViewMatrixOES", "context = %d", CID(context));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateLoadPaletteFromModelViewMatrixOES(context));
        if (isCallValid)
        {
            context->loadPaletteFromModelViewMatrix();
        }
        ANGLE_CAPTURE(LoadPaletteFromModelViewMatrixOES, isCallValid, context);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY LogicOpContextANGLE(GLeglContext ctx, GLenum opcode)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::LogicOp, "glLogicOp", "context = %d, opcode = %s", CID(context),
          GLenumToString(GLenumGroup::LogicOp, opcode));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        LogicalOperation opcodePacked                         = FromGL<LogicalOperation>(opcode);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateLogicOp(context, opcodePacked));
        if (isCallValid)
        {
            context->logicOp(opcodePacked);
        }
        ANGLE_CAPTURE(LogicOp, isCallValid, context, opcodePacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void *GL_APIENTRY MapBufferOESContextANGLE(GLeglContext ctx, GLenum target, GLenum access)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::MapBufferOES, "glMapBufferOES",
          "context = %d, target = %s, access = %s", CID(context),
          GLenumToString(GLenumGroup::BufferTargetARB, target),
          GLenumToString(GLenumGroup::BufferAccessARB, access));

    void *returnValue;
    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        BufferBinding targetPacked                            = FromGL<BufferBinding>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateMapBufferOES(context, targetPacked, access));
        if (isCallValid)
        {
            returnValue = context->mapBuffer(targetPacked, access);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::MapBufferOES, void *>();
        }
        ANGLE_CAPTURE(MapBufferOES, isCallValid, context, targetPacked, access, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
        returnValue = GetDefaultReturnValue<EntryPoint::MapBufferOES, void *>();
    }
    return returnValue;
}

void *GL_APIENTRY MapBufferRangeContextANGLE(GLeglContext ctx,
                                             GLenum target,
                                             GLintptr offset,
                                             GLsizeiptr length,
                                             GLbitfield access)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::MapBufferRange, "glMapBufferRange",
          "context = %d, target = %s, offset = %llu, length = %llu, access = %s", CID(context),
          GLenumToString(GLenumGroup::BufferTargetARB, target),
          static_cast<unsigned long long>(offset), static_cast<unsigned long long>(length),
          GLbitfieldToString(GLenumGroup::BufferAccessMask, access).c_str());

    void *returnValue;
    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        BufferBinding targetPacked                            = FromGL<BufferBinding>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateMapBufferRange(context, targetPacked, offset, length, access));
        if (isCallValid)
        {
            returnValue = context->mapBufferRange(targetPacked, offset, length, access);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::MapBufferRange, void *>();
        }
        ANGLE_CAPTURE(MapBufferRange, isCallValid, context, targetPacked, offset, length, access,
                      returnValue);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
        returnValue = GetDefaultReturnValue<EntryPoint::MapBufferRange, void *>();
    }
    return returnValue;
}

void *GL_APIENTRY MapBufferRangeEXTContextANGLE(GLeglContext ctx,
                                                GLenum target,
                                                GLintptr offset,
                                                GLsizeiptr length,
                                                GLbitfield access)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::MapBufferRangeEXT, "glMapBufferRangeEXT",
          "context = %d, target = %s, offset = %llu, length = %llu, access = %s", CID(context),
          GLenumToString(GLenumGroup::BufferTargetARB, target),
          static_cast<unsigned long long>(offset), static_cast<unsigned long long>(length),
          GLbitfieldToString(GLenumGroup::BufferAccessMask, access).c_str());

    void *returnValue;
    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        BufferBinding targetPacked                            = FromGL<BufferBinding>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateMapBufferRangeEXT(context, targetPacked, offset, length, access));
        if (isCallValid)
        {
            returnValue = context->mapBufferRange(targetPacked, offset, length, access);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::MapBufferRangeEXT, void *>();
        }
        ANGLE_CAPTURE(MapBufferRangeEXT, isCallValid, context, targetPacked, offset, length, access,
                      returnValue);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
        returnValue = GetDefaultReturnValue<EntryPoint::MapBufferRangeEXT, void *>();
    }
    return returnValue;
}

void GL_APIENTRY MaterialfContextANGLE(GLeglContext ctx, GLenum face, GLenum pname, GLfloat param)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Materialf, "glMaterialf",
          "context = %d, face = %s, pname = %s, param = %f", CID(context),
          GLenumToString(GLenumGroup::MaterialFace, face),
          GLenumToString(GLenumGroup::MaterialParameter, pname), param);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        MaterialParameter pnamePacked                         = FromGL<MaterialParameter>(pname);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateMaterialf(context, face, pnamePacked, param));
        if (isCallValid)
        {
            context->materialf(face, pnamePacked, param);
        }
        ANGLE_CAPTURE(Materialf, isCallValid, context, face, pnamePacked, param);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY MaterialfvContextANGLE(GLeglContext ctx,
                                        GLenum face,
                                        GLenum pname,
                                        const GLfloat *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Materialfv, "glMaterialfv",
          "context = %d, face = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::MaterialFace, face),
          GLenumToString(GLenumGroup::MaterialParameter, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        MaterialParameter pnamePacked                         = FromGL<MaterialParameter>(pname);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateMaterialfv(context, face, pnamePacked, params));
        if (isCallValid)
        {
            context->materialfv(face, pnamePacked, params);
        }
        ANGLE_CAPTURE(Materialfv, isCallValid, context, face, pnamePacked, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY MaterialxContextANGLE(GLeglContext ctx, GLenum face, GLenum pname, GLfixed param)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Materialx, "glMaterialx",
          "context = %d, face = %s, pname = %s, param = 0x%X", CID(context),
          GLenumToString(GLenumGroup::MaterialFace, face),
          GLenumToString(GLenumGroup::MaterialParameter, pname), param);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        MaterialParameter pnamePacked                         = FromGL<MaterialParameter>(pname);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateMaterialx(context, face, pnamePacked, param));
        if (isCallValid)
        {
            context->materialx(face, pnamePacked, param);
        }
        ANGLE_CAPTURE(Materialx, isCallValid, context, face, pnamePacked, param);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY MaterialxvContextANGLE(GLeglContext ctx,
                                        GLenum face,
                                        GLenum pname,
                                        const GLfixed *param)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Materialxv, "glMaterialxv",
          "context = %d, face = %s, pname = %s, param = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::MaterialFace, face),
          GLenumToString(GLenumGroup::MaterialParameter, pname), (uintptr_t)param);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        MaterialParameter pnamePacked                         = FromGL<MaterialParameter>(pname);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateMaterialxv(context, face, pnamePacked, param));
        if (isCallValid)
        {
            context->materialxv(face, pnamePacked, param);
        }
        ANGLE_CAPTURE(Materialxv, isCallValid, context, face, pnamePacked, param);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY MatrixIndexPointerOESContextANGLE(GLeglContext ctx,
                                                   GLint size,
                                                   GLenum type,
                                                   GLsizei stride,
                                                   const void *pointer)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::MatrixIndexPointerOES, "glMatrixIndexPointerOES",
          "context = %d, size = %d, type = %s, stride = %d, pointer = 0x%016" PRIxPTR "",
          CID(context), size, GLenumToString(GLenumGroup::DefaultGroup, type), stride,
          (uintptr_t)pointer);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateMatrixIndexPointerOES(context, size, type, stride, pointer));
        if (isCallValid)
        {
            context->matrixIndexPointer(size, type, stride, pointer);
        }
        ANGLE_CAPTURE(MatrixIndexPointerOES, isCallValid, context, size, type, stride, pointer);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY MatrixModeContextANGLE(GLeglContext ctx, GLenum mode)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::MatrixMode, "glMatrixMode", "context = %d, mode = %s",
          CID(context), GLenumToString(GLenumGroup::MatrixMode, mode));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        MatrixType modePacked                                 = FromGL<MatrixType>(mode);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateMatrixMode(context, modePacked));
        if (isCallValid)
        {
            context->matrixMode(modePacked);
        }
        ANGLE_CAPTURE(MatrixMode, isCallValid, context, modePacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY MaxShaderCompilerThreadsKHRContextANGLE(GLeglContext ctx, GLuint count)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::MaxShaderCompilerThreadsKHR, "glMaxShaderCompilerThreadsKHR",
          "context = %d, count = %u", CID(context), count);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateMaxShaderCompilerThreadsKHR(context, count));
        if (isCallValid)
        {
            context->maxShaderCompilerThreads(count);
        }
        ANGLE_CAPTURE(MaxShaderCompilerThreadsKHR, isCallValid, context, count);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY MemoryBarrierContextANGLE(GLeglContext ctx, GLbitfield barriers)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::MemoryBarrier, "glMemoryBarrier", "context = %d, barriers = %s",
          CID(context), GLbitfieldToString(GLenumGroup::MemoryBarrierMask, barriers).c_str());

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateMemoryBarrier(context, barriers));
        if (isCallValid)
        {
            context->memoryBarrier(barriers);
        }
        ANGLE_CAPTURE(MemoryBarrier, isCallValid, context, barriers);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY MemoryBarrierByRegionContextANGLE(GLeglContext ctx, GLbitfield barriers)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::MemoryBarrierByRegion, "glMemoryBarrierByRegion",
          "context = %d, barriers = %s", CID(context),
          GLbitfieldToString(GLenumGroup::MemoryBarrierMask, barriers).c_str());

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateMemoryBarrierByRegion(context, barriers));
        if (isCallValid)
        {
            context->memoryBarrierByRegion(barriers);
        }
        ANGLE_CAPTURE(MemoryBarrierByRegion, isCallValid, context, barriers);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY MemoryObjectParameterivEXTContextANGLE(GLeglContext ctx,
                                                        GLuint memoryObject,
                                                        GLenum pname,
                                                        const GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::MemoryObjectParameterivEXT, "glMemoryObjectParameterivEXT",
          "context = %d, memoryObject = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          memoryObject, GLenumToString(GLenumGroup::MemoryObjectParameterName, pname),
          (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        MemoryObjectID memoryObjectPacked = FromGL<MemoryObjectID>(memoryObject);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateMemoryObjectParameterivEXT(context, memoryObjectPacked, pname, params));
        if (isCallValid)
        {
            context->memoryObjectParameteriv(memoryObjectPacked, pname, params);
        }
        ANGLE_CAPTURE(MemoryObjectParameterivEXT, isCallValid, context, memoryObjectPacked, pname,
                      params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY MinSampleShadingContextANGLE(GLeglContext ctx, GLfloat value)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::MinSampleShading, "glMinSampleShading",
          "context = %d, value = %f", CID(context), value);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateMinSampleShading(context, value));
        if (isCallValid)
        {
            context->minSampleShading(value);
        }
        ANGLE_CAPTURE(MinSampleShading, isCallValid, context, value);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY MinSampleShadingOESContextANGLE(GLeglContext ctx, GLfloat value)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::MinSampleShadingOES, "glMinSampleShadingOES",
          "context = %d, value = %f", CID(context), value);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateMinSampleShadingOES(context, value));
        if (isCallValid)
        {
            context->minSampleShading(value);
        }
        ANGLE_CAPTURE(MinSampleShadingOES, isCallValid, context, value);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY MultMatrixfContextANGLE(GLeglContext ctx, const GLfloat *m)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::MultMatrixf, "glMultMatrixf",
          "context = %d, m = 0x%016" PRIxPTR "", CID(context), (uintptr_t)m);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateMultMatrixf(context, m));
        if (isCallValid)
        {
            context->multMatrixf(m);
        }
        ANGLE_CAPTURE(MultMatrixf, isCallValid, context, m);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY MultMatrixxContextANGLE(GLeglContext ctx, const GLfixed *m)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::MultMatrixx, "glMultMatrixx",
          "context = %d, m = 0x%016" PRIxPTR "", CID(context), (uintptr_t)m);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateMultMatrixx(context, m));
        if (isCallValid)
        {
            context->multMatrixx(m);
        }
        ANGLE_CAPTURE(MultMatrixx, isCallValid, context, m);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY MultiDrawElementsBaseVertexEXTContextANGLE(GLeglContext ctx,
                                                            GLenum mode,
                                                            const GLsizei *count,
                                                            GLenum type,
                                                            const void *const *indices,
                                                            GLsizei primcount,
                                                            const GLint *basevertex)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::MultiDrawElementsBaseVertexEXT,
          "glMultiDrawElementsBaseVertexEXT",
          "context = %d, mode = %s, count = 0x%016" PRIxPTR ", type = %s, indices = 0x%016" PRIxPTR
          ", primcount = %d, basevertex = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::PrimitiveType, mode), (uintptr_t)count,
          GLenumToString(GLenumGroup::DrawElementsType, type), (uintptr_t)indices, primcount,
          (uintptr_t)basevertex);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        DrawElementsType typePacked                           = FromGL<DrawElementsType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateMultiDrawElementsBaseVertexEXT(
                                                             context, modePacked, count, typePacked,
                                                             indices, primcount, basevertex));
        if (isCallValid)
        {
            context->multiDrawElementsBaseVertex(modePacked, count, typePacked, indices, primcount,
                                                 basevertex);
        }
        ANGLE_CAPTURE(MultiDrawElementsBaseVertexEXT, isCallValid, context, modePacked, count,
                      typePacked, indices, primcount, basevertex);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY MultiTexCoord4fContextANGLE(GLeglContext ctx,
                                             GLenum target,
                                             GLfloat s,
                                             GLfloat t,
                                             GLfloat r,
                                             GLfloat q)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::MultiTexCoord4f, "glMultiTexCoord4f",
          "context = %d, target = %s, s = %f, t = %f, r = %f, q = %f", CID(context),
          GLenumToString(GLenumGroup::TextureUnit, target), s, t, r, q);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateMultiTexCoord4f(context, target, s, t, r, q));
        if (isCallValid)
        {
            context->multiTexCoord4f(target, s, t, r, q);
        }
        ANGLE_CAPTURE(MultiTexCoord4f, isCallValid, context, target, s, t, r, q);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY MultiTexCoord4xContextANGLE(GLeglContext ctx,
                                             GLenum texture,
                                             GLfixed s,
                                             GLfixed t,
                                             GLfixed r,
                                             GLfixed q)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::MultiTexCoord4x, "glMultiTexCoord4x",
          "context = %d, texture = %s, s = 0x%X, t = 0x%X, r = 0x%X, q = 0x%X", CID(context),
          GLenumToString(GLenumGroup::TextureUnit, texture), s, t, r, q);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateMultiTexCoord4x(context, texture, s, t, r, q));
        if (isCallValid)
        {
            context->multiTexCoord4x(texture, s, t, r, q);
        }
        ANGLE_CAPTURE(MultiTexCoord4x, isCallValid, context, texture, s, t, r, q);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY NamedBufferStorageExternalEXTContextANGLE(GLeglContext ctx,
                                                           GLuint buffer,
                                                           GLintptr offset,
                                                           GLsizeiptr size,
                                                           GLeglClientBufferEXT clientBuffer,
                                                           GLbitfield flags)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::NamedBufferStorageExternalEXT, "glNamedBufferStorageExternalEXT",
          "context = %d, buffer = %u, offset = %llu, size = %llu, clientBuffer = 0x%016" PRIxPTR
          ", flags = %s",
          CID(context), buffer, static_cast<unsigned long long>(offset),
          static_cast<unsigned long long>(size), (uintptr_t)clientBuffer,
          GLbitfieldToString(GLenumGroup::MapBufferUsageMask, flags).c_str());

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateNamedBufferStorageExternalEXT(
                                              context, buffer, offset, size, clientBuffer, flags));
        if (isCallValid)
        {
            context->namedBufferStorageExternal(buffer, offset, size, clientBuffer, flags);
        }
        ANGLE_CAPTURE(NamedBufferStorageExternalEXT, isCallValid, context, buffer, offset, size,
                      clientBuffer, flags);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY Normal3fContextANGLE(GLeglContext ctx, GLfloat nx, GLfloat ny, GLfloat nz)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Normal3f, "glNormal3f",
          "context = %d, nx = %f, ny = %f, nz = %f", CID(context), nx, ny, nz);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateNormal3f(context, nx, ny, nz));
        if (isCallValid)
        {
            context->normal3f(nx, ny, nz);
        }
        ANGLE_CAPTURE(Normal3f, isCallValid, context, nx, ny, nz);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY Normal3xContextANGLE(GLeglContext ctx, GLfixed nx, GLfixed ny, GLfixed nz)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Normal3x, "glNormal3x",
          "context = %d, nx = 0x%X, ny = 0x%X, nz = 0x%X", CID(context), nx, ny, nz);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateNormal3x(context, nx, ny, nz));
        if (isCallValid)
        {
            context->normal3x(nx, ny, nz);
        }
        ANGLE_CAPTURE(Normal3x, isCallValid, context, nx, ny, nz);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY NormalPointerContextANGLE(GLeglContext ctx,
                                           GLenum type,
                                           GLsizei stride,
                                           const void *pointer)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::NormalPointer, "glNormalPointer",
          "context = %d, type = %s, stride = %d, pointer = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::NormalPointerType, type), stride, (uintptr_t)pointer);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        VertexAttribType typePacked                           = FromGL<VertexAttribType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateNormalPointer(context, typePacked, stride, pointer));
        if (isCallValid)
        {
            context->normalPointer(typePacked, stride, pointer);
        }
        ANGLE_CAPTURE(NormalPointer, isCallValid, context, typePacked, stride, pointer);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ObjectLabelContextANGLE(GLeglContext ctx,
                                         GLenum identifier,
                                         GLuint name,
                                         GLsizei length,
                                         const GLchar *label)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ObjectLabel, "glObjectLabel",
          "context = %d, identifier = %s, name = %u, length = %d, label = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::ObjectIdentifier, identifier), name, length,
          (uintptr_t)label);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateObjectLabel(context, identifier, name, length, label));
        if (isCallValid)
        {
            context->objectLabel(identifier, name, length, label);
        }
        ANGLE_CAPTURE(ObjectLabel, isCallValid, context, identifier, name, length, label);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ObjectLabelKHRContextANGLE(GLeglContext ctx,
                                            GLenum identifier,
                                            GLuint name,
                                            GLsizei length,
                                            const GLchar *label)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ObjectLabelKHR, "glObjectLabelKHR",
          "context = %d, identifier = %s, name = %u, length = %d, label = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::ObjectIdentifier, identifier), name, length,
          (uintptr_t)label);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateObjectLabelKHR(context, identifier, name, length, label));
        if (isCallValid)
        {
            context->objectLabel(identifier, name, length, label);
        }
        ANGLE_CAPTURE(ObjectLabelKHR, isCallValid, context, identifier, name, length, label);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ObjectPtrLabelContextANGLE(GLeglContext ctx,
                                            const void *ptr,
                                            GLsizei length,
                                            const GLchar *label)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ObjectPtrLabel, "glObjectPtrLabel",
          "context = %d, ptr = 0x%016" PRIxPTR ", length = %d, label = 0x%016" PRIxPTR "",
          CID(context), (uintptr_t)ptr, length, (uintptr_t)label);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateObjectPtrLabel(context, ptr, length, label));
        if (isCallValid)
        {
            context->objectPtrLabel(ptr, length, label);
        }
        ANGLE_CAPTURE(ObjectPtrLabel, isCallValid, context, ptr, length, label);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ObjectPtrLabelKHRContextANGLE(GLeglContext ctx,
                                               const void *ptr,
                                               GLsizei length,
                                               const GLchar *label)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ObjectPtrLabelKHR, "glObjectPtrLabelKHR",
          "context = %d, ptr = 0x%016" PRIxPTR ", length = %d, label = 0x%016" PRIxPTR "",
          CID(context), (uintptr_t)ptr, length, (uintptr_t)label);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateObjectPtrLabelKHR(context, ptr, length, label));
        if (isCallValid)
        {
            context->objectPtrLabel(ptr, length, label);
        }
        ANGLE_CAPTURE(ObjectPtrLabelKHR, isCallValid, context, ptr, length, label);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY OrthofContextANGLE(GLeglContext ctx,
                                    GLfloat l,
                                    GLfloat r,
                                    GLfloat b,
                                    GLfloat t,
                                    GLfloat n,
                                    GLfloat f)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Orthof, "glOrthof",
          "context = %d, l = %f, r = %f, b = %f, t = %f, n = %f, f = %f", CID(context), l, r, b, t,
          n, f);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateOrthof(context, l, r, b, t, n, f));
        if (isCallValid)
        {
            context->orthof(l, r, b, t, n, f);
        }
        ANGLE_CAPTURE(Orthof, isCallValid, context, l, r, b, t, n, f);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY OrthoxContextANGLE(GLeglContext ctx,
                                    GLfixed l,
                                    GLfixed r,
                                    GLfixed b,
                                    GLfixed t,
                                    GLfixed n,
                                    GLfixed f)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Orthox, "glOrthox",
          "context = %d, l = 0x%X, r = 0x%X, b = 0x%X, t = 0x%X, n = 0x%X, f = 0x%X", CID(context),
          l, r, b, t, n, f);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateOrthox(context, l, r, b, t, n, f));
        if (isCallValid)
        {
            context->orthox(l, r, b, t, n, f);
        }
        ANGLE_CAPTURE(Orthox, isCallValid, context, l, r, b, t, n, f);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY PatchParameteriContextANGLE(GLeglContext ctx, GLenum pname, GLint value)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::PatchParameteri, "glPatchParameteri",
          "context = %d, pname = %s, value = %d", CID(context),
          GLenumToString(GLenumGroup::PatchParameterName, pname), value);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidatePatchParameteri(context, pname, value));
        if (isCallValid)
        {
            context->patchParameteri(pname, value);
        }
        ANGLE_CAPTURE(PatchParameteri, isCallValid, context, pname, value);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY PauseTransformFeedbackContextANGLE(GLeglContext ctx)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::PauseTransformFeedback, "glPauseTransformFeedback",
          "context = %d", CID(context));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidatePauseTransformFeedback(context));
        if (isCallValid)
        {
            context->pauseTransformFeedback();
        }
        ANGLE_CAPTURE(PauseTransformFeedback, isCallValid, context);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY PixelStoreiContextANGLE(GLeglContext ctx, GLenum pname, GLint param)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::PixelStorei, "glPixelStorei",
          "context = %d, pname = %s, param = %d", CID(context),
          GLenumToString(GLenumGroup::PixelStoreParameter, pname), param);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidatePixelStorei(context, pname, param));
        if (isCallValid)
        {
            context->pixelStorei(pname, param);
        }
        ANGLE_CAPTURE(PixelStorei, isCallValid, context, pname, param);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY PointParameterfContextANGLE(GLeglContext ctx, GLenum pname, GLfloat param)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::PointParameterf, "glPointParameterf",
          "context = %d, pname = %s, param = %f", CID(context),
          GLenumToString(GLenumGroup::DefaultGroup, pname), param);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        PointParameter pnamePacked                            = FromGL<PointParameter>(pname);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidatePointParameterf(context, pnamePacked, param));
        if (isCallValid)
        {
            context->pointParameterf(pnamePacked, param);
        }
        ANGLE_CAPTURE(PointParameterf, isCallValid, context, pnamePacked, param);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY PointParameterfvContextANGLE(GLeglContext ctx, GLenum pname, const GLfloat *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::PointParameterfv, "glPointParameterfv",
          "context = %d, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::DefaultGroup, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        PointParameter pnamePacked                            = FromGL<PointParameter>(pname);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidatePointParameterfv(context, pnamePacked, params));
        if (isCallValid)
        {
            context->pointParameterfv(pnamePacked, params);
        }
        ANGLE_CAPTURE(PointParameterfv, isCallValid, context, pnamePacked, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY PointParameterxContextANGLE(GLeglContext ctx, GLenum pname, GLfixed param)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::PointParameterx, "glPointParameterx",
          "context = %d, pname = %s, param = 0x%X", CID(context),
          GLenumToString(GLenumGroup::DefaultGroup, pname), param);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        PointParameter pnamePacked                            = FromGL<PointParameter>(pname);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidatePointParameterx(context, pnamePacked, param));
        if (isCallValid)
        {
            context->pointParameterx(pnamePacked, param);
        }
        ANGLE_CAPTURE(PointParameterx, isCallValid, context, pnamePacked, param);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY PointParameterxvContextANGLE(GLeglContext ctx, GLenum pname, const GLfixed *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::PointParameterxv, "glPointParameterxv",
          "context = %d, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::DefaultGroup, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        PointParameter pnamePacked                            = FromGL<PointParameter>(pname);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidatePointParameterxv(context, pnamePacked, params));
        if (isCallValid)
        {
            context->pointParameterxv(pnamePacked, params);
        }
        ANGLE_CAPTURE(PointParameterxv, isCallValid, context, pnamePacked, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY PointSizeContextANGLE(GLeglContext ctx, GLfloat size)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::PointSize, "glPointSize", "context = %d, size = %f",
          CID(context), size);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidatePointSize(context, size));
        if (isCallValid)
        {
            context->pointSize(size);
        }
        ANGLE_CAPTURE(PointSize, isCallValid, context, size);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY PointSizePointerOESContextANGLE(GLeglContext ctx,
                                                 GLenum type,
                                                 GLsizei stride,
                                                 const void *pointer)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::PointSizePointerOES, "glPointSizePointerOES",
          "context = %d, type = %s, stride = %d, pointer = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::DefaultGroup, type), stride, (uintptr_t)pointer);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        VertexAttribType typePacked                           = FromGL<VertexAttribType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidatePointSizePointerOES(context, typePacked, stride, pointer));
        if (isCallValid)
        {
            context->pointSizePointer(typePacked, stride, pointer);
        }
        ANGLE_CAPTURE(PointSizePointerOES, isCallValid, context, typePacked, stride, pointer);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY PointSizexContextANGLE(GLeglContext ctx, GLfixed size)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::PointSizex, "glPointSizex", "context = %d, size = 0x%X",
          CID(context), size);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidatePointSizex(context, size));
        if (isCallValid)
        {
            context->pointSizex(size);
        }
        ANGLE_CAPTURE(PointSizex, isCallValid, context, size);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY PolygonOffsetContextANGLE(GLeglContext ctx, GLfloat factor, GLfloat units)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::PolygonOffset, "glPolygonOffset",
          "context = %d, factor = %f, units = %f", CID(context), factor, units);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidatePolygonOffset(context, factor, units));
        if (isCallValid)
        {
            context->polygonOffset(factor, units);
        }
        ANGLE_CAPTURE(PolygonOffset, isCallValid, context, factor, units);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY PolygonOffsetxContextANGLE(GLeglContext ctx, GLfixed factor, GLfixed units)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::PolygonOffsetx, "glPolygonOffsetx",
          "context = %d, factor = 0x%X, units = 0x%X", CID(context), factor, units);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidatePolygonOffsetx(context, factor, units));
        if (isCallValid)
        {
            context->polygonOffsetx(factor, units);
        }
        ANGLE_CAPTURE(PolygonOffsetx, isCallValid, context, factor, units);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY PopDebugGroupContextANGLE(GLeglContext ctx)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::PopDebugGroup, "glPopDebugGroup", "context = %d", CID(context));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidatePopDebugGroup(context));
        if (isCallValid)
        {
            context->popDebugGroup();
        }
        ANGLE_CAPTURE(PopDebugGroup, isCallValid, context);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY PopDebugGroupKHRContextANGLE(GLeglContext ctx)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::PopDebugGroupKHR, "glPopDebugGroupKHR", "context = %d",
          CID(context));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidatePopDebugGroupKHR(context));
        if (isCallValid)
        {
            context->popDebugGroup();
        }
        ANGLE_CAPTURE(PopDebugGroupKHR, isCallValid, context);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY PopGroupMarkerEXTContextANGLE(GLeglContext ctx)
{
    Context *context = static_cast<gl::Context *>(ctx);
    // Don't run the EVENT() macro on the EXT_debug_marker entry points.
    // It can interfere with the debug events being set by the caller.
    // EVENT(context, gl::EntryPoint::PopGroupMarkerEXT, "glPopGroupMarkerEXT", "context = %d",
    // CID(context));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidatePopGroupMarkerEXT(context));
        if (isCallValid)
        {
            context->popGroupMarker();
        }
        ANGLE_CAPTURE(PopGroupMarkerEXT, isCallValid, context);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY PopMatrixContextANGLE(GLeglContext ctx)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::PopMatrix, "glPopMatrix", "context = %d", CID(context));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidatePopMatrix(context));
        if (isCallValid)
        {
            context->popMatrix();
        }
        ANGLE_CAPTURE(PopMatrix, isCallValid, context);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY PrimitiveBoundingBoxContextANGLE(GLeglContext ctx,
                                                  GLfloat minX,
                                                  GLfloat minY,
                                                  GLfloat minZ,
                                                  GLfloat minW,
                                                  GLfloat maxX,
                                                  GLfloat maxY,
                                                  GLfloat maxZ,
                                                  GLfloat maxW)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::PrimitiveBoundingBox, "glPrimitiveBoundingBox",
          "context = %d, minX = %f, minY = %f, minZ = %f, minW = %f, maxX = %f, maxY = %f, maxZ = "
          "%f, maxW = %f",
          CID(context), minX, minY, minZ, minW, maxX, maxY, maxZ, maxW);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidatePrimitiveBoundingBox(context, minX, minY, minZ, minW, maxX, maxY, maxZ, maxW));
        if (isCallValid)
        {
            context->primitiveBoundingBox(minX, minY, minZ, minW, maxX, maxY, maxZ, maxW);
        }
        ANGLE_CAPTURE(PrimitiveBoundingBox, isCallValid, context, minX, minY, minZ, minW, maxX,
                      maxY, maxZ, maxW);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ProgramBinaryContextANGLE(GLeglContext ctx,
                                           GLuint program,
                                           GLenum binaryFormat,
                                           const void *binary,
                                           GLsizei length)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ProgramBinary, "glProgramBinary",
          "context = %d, program = %u, binaryFormat = %s, binary = 0x%016" PRIxPTR ", length = %d",
          CID(context), program, GLenumToString(GLenumGroup::DefaultGroup, binaryFormat),
          (uintptr_t)binary, length);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramBinary(context, programPacked, binaryFormat, binary, length));
        if (isCallValid)
        {
            context->programBinary(programPacked, binaryFormat, binary, length);
        }
        ANGLE_CAPTURE(ProgramBinary, isCallValid, context, programPacked, binaryFormat, binary,
                      length);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ProgramBinaryOESContextANGLE(GLeglContext ctx,
                                              GLuint program,
                                              GLenum binaryFormat,
                                              const void *binary,
                                              GLint length)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ProgramBinaryOES, "glProgramBinaryOES",
          "context = %d, program = %u, binaryFormat = %s, binary = 0x%016" PRIxPTR ", length = %d",
          CID(context), program, GLenumToString(GLenumGroup::DefaultGroup, binaryFormat),
          (uintptr_t)binary, length);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramBinaryOES(context, programPacked, binaryFormat, binary, length));
        if (isCallValid)
        {
            context->programBinary(programPacked, binaryFormat, binary, length);
        }
        ANGLE_CAPTURE(ProgramBinaryOES, isCallValid, context, programPacked, binaryFormat, binary,
                      length);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ProgramParameteriContextANGLE(GLeglContext ctx,
                                               GLuint program,
                                               GLenum pname,
                                               GLint value)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ProgramParameteri, "glProgramParameteri",
          "context = %d, program = %u, pname = %s, value = %d", CID(context), program,
          GLenumToString(GLenumGroup::ProgramParameterPName, pname), value);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateProgramParameteri(context, programPacked, pname, value));
        if (isCallValid)
        {
            context->programParameteri(programPacked, pname, value);
        }
        ANGLE_CAPTURE(ProgramParameteri, isCallValid, context, programPacked, pname, value);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ProgramUniform1fContextANGLE(GLeglContext ctx,
                                              GLuint program,
                                              GLint location,
                                              GLfloat v0)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ProgramUniform1f, "glProgramUniform1f",
          "context = %d, program = %u, location = %d, v0 = %f", CID(context), program, location,
          v0);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateProgramUniform1f(context, programPacked, locationPacked, v0));
        if (isCallValid)
        {
            context->programUniform1f(programPacked, locationPacked, v0);
        }
        ANGLE_CAPTURE(ProgramUniform1f, isCallValid, context, programPacked, locationPacked, v0);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ProgramUniform1fvContextANGLE(GLeglContext ctx,
                                               GLuint program,
                                               GLint location,
                                               GLsizei count,
                                               const GLfloat *value)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ProgramUniform1fv, "glProgramUniform1fv",
          "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
          CID(context), program, location, count, (uintptr_t)value);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramUniform1fv(context, programPacked, locationPacked, count, value));
        if (isCallValid)
        {
            context->programUniform1fv(programPacked, locationPacked, count, value);
        }
        ANGLE_CAPTURE(ProgramUniform1fv, isCallValid, context, programPacked, locationPacked, count,
                      value);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ProgramUniform1iContextANGLE(GLeglContext ctx,
                                              GLuint program,
                                              GLint location,
                                              GLint v0)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ProgramUniform1i, "glProgramUniform1i",
          "context = %d, program = %u, location = %d, v0 = %d", CID(context), program, location,
          v0);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateProgramUniform1i(context, programPacked, locationPacked, v0));
        if (isCallValid)
        {
            context->programUniform1i(programPacked, locationPacked, v0);
        }
        ANGLE_CAPTURE(ProgramUniform1i, isCallValid, context, programPacked, locationPacked, v0);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ProgramUniform1ivContextANGLE(GLeglContext ctx,
                                               GLuint program,
                                               GLint location,
                                               GLsizei count,
                                               const GLint *value)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ProgramUniform1iv, "glProgramUniform1iv",
          "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
          CID(context), program, location, count, (uintptr_t)value);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramUniform1iv(context, programPacked, locationPacked, count, value));
        if (isCallValid)
        {
            context->programUniform1iv(programPacked, locationPacked, count, value);
        }
        ANGLE_CAPTURE(ProgramUniform1iv, isCallValid, context, programPacked, locationPacked, count,
                      value);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ProgramUniform1uiContextANGLE(GLeglContext ctx,
                                               GLuint program,
                                               GLint location,
                                               GLuint v0)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ProgramUniform1ui, "glProgramUniform1ui",
          "context = %d, program = %u, location = %d, v0 = %u", CID(context), program, location,
          v0);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateProgramUniform1ui(context, programPacked, locationPacked, v0));
        if (isCallValid)
        {
            context->programUniform1ui(programPacked, locationPacked, v0);
        }
        ANGLE_CAPTURE(ProgramUniform1ui, isCallValid, context, programPacked, locationPacked, v0);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ProgramUniform1uivContextANGLE(GLeglContext ctx,
                                                GLuint program,
                                                GLint location,
                                                GLsizei count,
                                                const GLuint *value)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ProgramUniform1uiv, "glProgramUniform1uiv",
          "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
          CID(context), program, location, count, (uintptr_t)value);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramUniform1uiv(context, programPacked, locationPacked, count, value));
        if (isCallValid)
        {
            context->programUniform1uiv(programPacked, locationPacked, count, value);
        }
        ANGLE_CAPTURE(ProgramUniform1uiv, isCallValid, context, programPacked, locationPacked,
                      count, value);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ProgramUniform2fContextANGLE(GLeglContext ctx,
                                              GLuint program,
                                              GLint location,
                                              GLfloat v0,
                                              GLfloat v1)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ProgramUniform2f, "glProgramUniform2f",
          "context = %d, program = %u, location = %d, v0 = %f, v1 = %f", CID(context), program,
          location, v0, v1);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramUniform2f(context, programPacked, locationPacked, v0, v1));
        if (isCallValid)
        {
            context->programUniform2f(programPacked, locationPacked, v0, v1);
        }
        ANGLE_CAPTURE(ProgramUniform2f, isCallValid, context, programPacked, locationPacked, v0,
                      v1);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ProgramUniform2fvContextANGLE(GLeglContext ctx,
                                               GLuint program,
                                               GLint location,
                                               GLsizei count,
                                               const GLfloat *value)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ProgramUniform2fv, "glProgramUniform2fv",
          "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
          CID(context), program, location, count, (uintptr_t)value);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramUniform2fv(context, programPacked, locationPacked, count, value));
        if (isCallValid)
        {
            context->programUniform2fv(programPacked, locationPacked, count, value);
        }
        ANGLE_CAPTURE(ProgramUniform2fv, isCallValid, context, programPacked, locationPacked, count,
                      value);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY
ProgramUniform2iContextANGLE(GLeglContext ctx, GLuint program, GLint location, GLint v0, GLint v1)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ProgramUniform2i, "glProgramUniform2i",
          "context = %d, program = %u, location = %d, v0 = %d, v1 = %d", CID(context), program,
          location, v0, v1);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramUniform2i(context, programPacked, locationPacked, v0, v1));
        if (isCallValid)
        {
            context->programUniform2i(programPacked, locationPacked, v0, v1);
        }
        ANGLE_CAPTURE(ProgramUniform2i, isCallValid, context, programPacked, locationPacked, v0,
                      v1);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ProgramUniform2ivContextANGLE(GLeglContext ctx,
                                               GLuint program,
                                               GLint location,
                                               GLsizei count,
                                               const GLint *value)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ProgramUniform2iv, "glProgramUniform2iv",
          "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
          CID(context), program, location, count, (uintptr_t)value);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramUniform2iv(context, programPacked, locationPacked, count, value));
        if (isCallValid)
        {
            context->programUniform2iv(programPacked, locationPacked, count, value);
        }
        ANGLE_CAPTURE(ProgramUniform2iv, isCallValid, context, programPacked, locationPacked, count,
                      value);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ProgramUniform2uiContextANGLE(GLeglContext ctx,
                                               GLuint program,
                                               GLint location,
                                               GLuint v0,
                                               GLuint v1)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ProgramUniform2ui, "glProgramUniform2ui",
          "context = %d, program = %u, location = %d, v0 = %u, v1 = %u", CID(context), program,
          location, v0, v1);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramUniform2ui(context, programPacked, locationPacked, v0, v1));
        if (isCallValid)
        {
            context->programUniform2ui(programPacked, locationPacked, v0, v1);
        }
        ANGLE_CAPTURE(ProgramUniform2ui, isCallValid, context, programPacked, locationPacked, v0,
                      v1);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ProgramUniform2uivContextANGLE(GLeglContext ctx,
                                                GLuint program,
                                                GLint location,
                                                GLsizei count,
                                                const GLuint *value)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ProgramUniform2uiv, "glProgramUniform2uiv",
          "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
          CID(context), program, location, count, (uintptr_t)value);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramUniform2uiv(context, programPacked, locationPacked, count, value));
        if (isCallValid)
        {
            context->programUniform2uiv(programPacked, locationPacked, count, value);
        }
        ANGLE_CAPTURE(ProgramUniform2uiv, isCallValid, context, programPacked, locationPacked,
                      count, value);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ProgramUniform3fContextANGLE(GLeglContext ctx,
                                              GLuint program,
                                              GLint location,
                                              GLfloat v0,
                                              GLfloat v1,
                                              GLfloat v2)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ProgramUniform3f, "glProgramUniform3f",
          "context = %d, program = %u, location = %d, v0 = %f, v1 = %f, v2 = %f", CID(context),
          program, location, v0, v1, v2);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramUniform3f(context, programPacked, locationPacked, v0, v1, v2));
        if (isCallValid)
        {
            context->programUniform3f(programPacked, locationPacked, v0, v1, v2);
        }
        ANGLE_CAPTURE(ProgramUniform3f, isCallValid, context, programPacked, locationPacked, v0, v1,
                      v2);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ProgramUniform3fvContextANGLE(GLeglContext ctx,
                                               GLuint program,
                                               GLint location,
                                               GLsizei count,
                                               const GLfloat *value)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ProgramUniform3fv, "glProgramUniform3fv",
          "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
          CID(context), program, location, count, (uintptr_t)value);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramUniform3fv(context, programPacked, locationPacked, count, value));
        if (isCallValid)
        {
            context->programUniform3fv(programPacked, locationPacked, count, value);
        }
        ANGLE_CAPTURE(ProgramUniform3fv, isCallValid, context, programPacked, locationPacked, count,
                      value);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ProgramUniform3iContextANGLE(GLeglContext ctx,
                                              GLuint program,
                                              GLint location,
                                              GLint v0,
                                              GLint v1,
                                              GLint v2)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ProgramUniform3i, "glProgramUniform3i",
          "context = %d, program = %u, location = %d, v0 = %d, v1 = %d, v2 = %d", CID(context),
          program, location, v0, v1, v2);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramUniform3i(context, programPacked, locationPacked, v0, v1, v2));
        if (isCallValid)
        {
            context->programUniform3i(programPacked, locationPacked, v0, v1, v2);
        }
        ANGLE_CAPTURE(ProgramUniform3i, isCallValid, context, programPacked, locationPacked, v0, v1,
                      v2);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ProgramUniform3ivContextANGLE(GLeglContext ctx,
                                               GLuint program,
                                               GLint location,
                                               GLsizei count,
                                               const GLint *value)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ProgramUniform3iv, "glProgramUniform3iv",
          "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
          CID(context), program, location, count, (uintptr_t)value);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramUniform3iv(context, programPacked, locationPacked, count, value));
        if (isCallValid)
        {
            context->programUniform3iv(programPacked, locationPacked, count, value);
        }
        ANGLE_CAPTURE(ProgramUniform3iv, isCallValid, context, programPacked, locationPacked, count,
                      value);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ProgramUniform3uiContextANGLE(GLeglContext ctx,
                                               GLuint program,
                                               GLint location,
                                               GLuint v0,
                                               GLuint v1,
                                               GLuint v2)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ProgramUniform3ui, "glProgramUniform3ui",
          "context = %d, program = %u, location = %d, v0 = %u, v1 = %u, v2 = %u", CID(context),
          program, location, v0, v1, v2);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramUniform3ui(context, programPacked, locationPacked, v0, v1, v2));
        if (isCallValid)
        {
            context->programUniform3ui(programPacked, locationPacked, v0, v1, v2);
        }
        ANGLE_CAPTURE(ProgramUniform3ui, isCallValid, context, programPacked, locationPacked, v0,
                      v1, v2);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ProgramUniform3uivContextANGLE(GLeglContext ctx,
                                                GLuint program,
                                                GLint location,
                                                GLsizei count,
                                                const GLuint *value)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ProgramUniform3uiv, "glProgramUniform3uiv",
          "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
          CID(context), program, location, count, (uintptr_t)value);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramUniform3uiv(context, programPacked, locationPacked, count, value));
        if (isCallValid)
        {
            context->programUniform3uiv(programPacked, locationPacked, count, value);
        }
        ANGLE_CAPTURE(ProgramUniform3uiv, isCallValid, context, programPacked, locationPacked,
                      count, value);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ProgramUniform4fContextANGLE(GLeglContext ctx,
                                              GLuint program,
                                              GLint location,
                                              GLfloat v0,
                                              GLfloat v1,
                                              GLfloat v2,
                                              GLfloat v3)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ProgramUniform4f, "glProgramUniform4f",
          "context = %d, program = %u, location = %d, v0 = %f, v1 = %f, v2 = %f, v3 = %f",
          CID(context), program, location, v0, v1, v2, v3);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramUniform4f(context, programPacked, locationPacked, v0, v1, v2, v3));
        if (isCallValid)
        {
            context->programUniform4f(programPacked, locationPacked, v0, v1, v2, v3);
        }
        ANGLE_CAPTURE(ProgramUniform4f, isCallValid, context, programPacked, locationPacked, v0, v1,
                      v2, v3);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ProgramUniform4fvContextANGLE(GLeglContext ctx,
                                               GLuint program,
                                               GLint location,
                                               GLsizei count,
                                               const GLfloat *value)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ProgramUniform4fv, "glProgramUniform4fv",
          "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
          CID(context), program, location, count, (uintptr_t)value);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramUniform4fv(context, programPacked, locationPacked, count, value));
        if (isCallValid)
        {
            context->programUniform4fv(programPacked, locationPacked, count, value);
        }
        ANGLE_CAPTURE(ProgramUniform4fv, isCallValid, context, programPacked, locationPacked, count,
                      value);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ProgramUniform4iContextANGLE(GLeglContext ctx,
                                              GLuint program,
                                              GLint location,
                                              GLint v0,
                                              GLint v1,
                                              GLint v2,
                                              GLint v3)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ProgramUniform4i, "glProgramUniform4i",
          "context = %d, program = %u, location = %d, v0 = %d, v1 = %d, v2 = %d, v3 = %d",
          CID(context), program, location, v0, v1, v2, v3);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramUniform4i(context, programPacked, locationPacked, v0, v1, v2, v3));
        if (isCallValid)
        {
            context->programUniform4i(programPacked, locationPacked, v0, v1, v2, v3);
        }
        ANGLE_CAPTURE(ProgramUniform4i, isCallValid, context, programPacked, locationPacked, v0, v1,
                      v2, v3);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ProgramUniform4ivContextANGLE(GLeglContext ctx,
                                               GLuint program,
                                               GLint location,
                                               GLsizei count,
                                               const GLint *value)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ProgramUniform4iv, "glProgramUniform4iv",
          "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
          CID(context), program, location, count, (uintptr_t)value);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramUniform4iv(context, programPacked, locationPacked, count, value));
        if (isCallValid)
        {
            context->programUniform4iv(programPacked, locationPacked, count, value);
        }
        ANGLE_CAPTURE(ProgramUniform4iv, isCallValid, context, programPacked, locationPacked, count,
                      value);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ProgramUniform4uiContextANGLE(GLeglContext ctx,
                                               GLuint program,
                                               GLint location,
                                               GLuint v0,
                                               GLuint v1,
                                               GLuint v2,
                                               GLuint v3)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ProgramUniform4ui, "glProgramUniform4ui",
          "context = %d, program = %u, location = %d, v0 = %u, v1 = %u, v2 = %u, v3 = %u",
          CID(context), program, location, v0, v1, v2, v3);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramUniform4ui(context, programPacked, locationPacked, v0, v1, v2, v3));
        if (isCallValid)
        {
            context->programUniform4ui(programPacked, locationPacked, v0, v1, v2, v3);
        }
        ANGLE_CAPTURE(ProgramUniform4ui, isCallValid, context, programPacked, locationPacked, v0,
                      v1, v2, v3);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ProgramUniform4uivContextANGLE(GLeglContext ctx,
                                                GLuint program,
                                                GLint location,
                                                GLsizei count,
                                                const GLuint *value)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ProgramUniform4uiv, "glProgramUniform4uiv",
          "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
          CID(context), program, location, count, (uintptr_t)value);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramUniform4uiv(context, programPacked, locationPacked, count, value));
        if (isCallValid)
        {
            context->programUniform4uiv(programPacked, locationPacked, count, value);
        }
        ANGLE_CAPTURE(ProgramUniform4uiv, isCallValid, context, programPacked, locationPacked,
                      count, value);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ProgramUniformMatrix2fvContextANGLE(GLeglContext ctx,
                                                     GLuint program,
                                                     GLint location,
                                                     GLsizei count,
                                                     GLboolean transpose,
                                                     const GLfloat *value)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ProgramUniformMatrix2fv, "glProgramUniformMatrix2fv",
          "context = %d, program = %u, location = %d, count = %d, transpose = %s, value = "
          "0x%016" PRIxPTR "",
          CID(context), program, location, count, GLbooleanToString(transpose), (uintptr_t)value);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateProgramUniformMatrix2fv(context, programPacked, locationPacked,
                                                            count, transpose, value));
        if (isCallValid)
        {
            context->programUniformMatrix2fv(programPacked, locationPacked, count, transpose,
                                             value);
        }
        ANGLE_CAPTURE(ProgramUniformMatrix2fv, isCallValid, context, programPacked, locationPacked,
                      count, transpose, value);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ProgramUniformMatrix2x3fvContextANGLE(GLeglContext ctx,
                                                       GLuint program,
                                                       GLint location,
                                                       GLsizei count,
                                                       GLboolean transpose,
                                                       const GLfloat *value)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ProgramUniformMatrix2x3fv, "glProgramUniformMatrix2x3fv",
          "context = %d, program = %u, location = %d, count = %d, transpose = %s, value = "
          "0x%016" PRIxPTR "",
          CID(context), program, location, count, GLbooleanToString(transpose), (uintptr_t)value);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateProgramUniformMatrix2x3fv(
                                context, programPacked, locationPacked, count, transpose, value));
        if (isCallValid)
        {
            context->programUniformMatrix2x3fv(programPacked, locationPacked, count, transpose,
                                               value);
        }
        ANGLE_CAPTURE(ProgramUniformMatrix2x3fv, isCallValid, context, programPacked,
                      locationPacked, count, transpose, value);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ProgramUniformMatrix2x4fvContextANGLE(GLeglContext ctx,
                                                       GLuint program,
                                                       GLint location,
                                                       GLsizei count,
                                                       GLboolean transpose,
                                                       const GLfloat *value)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ProgramUniformMatrix2x4fv, "glProgramUniformMatrix2x4fv",
          "context = %d, program = %u, location = %d, count = %d, transpose = %s, value = "
          "0x%016" PRIxPTR "",
          CID(context), program, location, count, GLbooleanToString(transpose), (uintptr_t)value);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateProgramUniformMatrix2x4fv(
                                context, programPacked, locationPacked, count, transpose, value));
        if (isCallValid)
        {
            context->programUniformMatrix2x4fv(programPacked, locationPacked, count, transpose,
                                               value);
        }
        ANGLE_CAPTURE(ProgramUniformMatrix2x4fv, isCallValid, context, programPacked,
                      locationPacked, count, transpose, value);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ProgramUniformMatrix3fvContextANGLE(GLeglContext ctx,
                                                     GLuint program,
                                                     GLint location,
                                                     GLsizei count,
                                                     GLboolean transpose,
                                                     const GLfloat *value)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ProgramUniformMatrix3fv, "glProgramUniformMatrix3fv",
          "context = %d, program = %u, location = %d, count = %d, transpose = %s, value = "
          "0x%016" PRIxPTR "",
          CID(context), program, location, count, GLbooleanToString(transpose), (uintptr_t)value);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateProgramUniformMatrix3fv(context, programPacked, locationPacked,
                                                            count, transpose, value));
        if (isCallValid)
        {
            context->programUniformMatrix3fv(programPacked, locationPacked, count, transpose,
                                             value);
        }
        ANGLE_CAPTURE(ProgramUniformMatrix3fv, isCallValid, context, programPacked, locationPacked,
                      count, transpose, value);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ProgramUniformMatrix3x2fvContextANGLE(GLeglContext ctx,
                                                       GLuint program,
                                                       GLint location,
                                                       GLsizei count,
                                                       GLboolean transpose,
                                                       const GLfloat *value)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ProgramUniformMatrix3x2fv, "glProgramUniformMatrix3x2fv",
          "context = %d, program = %u, location = %d, count = %d, transpose = %s, value = "
          "0x%016" PRIxPTR "",
          CID(context), program, location, count, GLbooleanToString(transpose), (uintptr_t)value);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateProgramUniformMatrix3x2fv(
                                context, programPacked, locationPacked, count, transpose, value));
        if (isCallValid)
        {
            context->programUniformMatrix3x2fv(programPacked, locationPacked, count, transpose,
                                               value);
        }
        ANGLE_CAPTURE(ProgramUniformMatrix3x2fv, isCallValid, context, programPacked,
                      locationPacked, count, transpose, value);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ProgramUniformMatrix3x4fvContextANGLE(GLeglContext ctx,
                                                       GLuint program,
                                                       GLint location,
                                                       GLsizei count,
                                                       GLboolean transpose,
                                                       const GLfloat *value)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ProgramUniformMatrix3x4fv, "glProgramUniformMatrix3x4fv",
          "context = %d, program = %u, location = %d, count = %d, transpose = %s, value = "
          "0x%016" PRIxPTR "",
          CID(context), program, location, count, GLbooleanToString(transpose), (uintptr_t)value);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateProgramUniformMatrix3x4fv(
                                context, programPacked, locationPacked, count, transpose, value));
        if (isCallValid)
        {
            context->programUniformMatrix3x4fv(programPacked, locationPacked, count, transpose,
                                               value);
        }
        ANGLE_CAPTURE(ProgramUniformMatrix3x4fv, isCallValid, context, programPacked,
                      locationPacked, count, transpose, value);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ProgramUniformMatrix4fvContextANGLE(GLeglContext ctx,
                                                     GLuint program,
                                                     GLint location,
                                                     GLsizei count,
                                                     GLboolean transpose,
                                                     const GLfloat *value)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ProgramUniformMatrix4fv, "glProgramUniformMatrix4fv",
          "context = %d, program = %u, location = %d, count = %d, transpose = %s, value = "
          "0x%016" PRIxPTR "",
          CID(context), program, location, count, GLbooleanToString(transpose), (uintptr_t)value);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateProgramUniformMatrix4fv(context, programPacked, locationPacked,
                                                            count, transpose, value));
        if (isCallValid)
        {
            context->programUniformMatrix4fv(programPacked, locationPacked, count, transpose,
                                             value);
        }
        ANGLE_CAPTURE(ProgramUniformMatrix4fv, isCallValid, context, programPacked, locationPacked,
                      count, transpose, value);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ProgramUniformMatrix4x2fvContextANGLE(GLeglContext ctx,
                                                       GLuint program,
                                                       GLint location,
                                                       GLsizei count,
                                                       GLboolean transpose,
                                                       const GLfloat *value)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ProgramUniformMatrix4x2fv, "glProgramUniformMatrix4x2fv",
          "context = %d, program = %u, location = %d, count = %d, transpose = %s, value = "
          "0x%016" PRIxPTR "",
          CID(context), program, location, count, GLbooleanToString(transpose), (uintptr_t)value);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateProgramUniformMatrix4x2fv(
                                context, programPacked, locationPacked, count, transpose, value));
        if (isCallValid)
        {
            context->programUniformMatrix4x2fv(programPacked, locationPacked, count, transpose,
                                               value);
        }
        ANGLE_CAPTURE(ProgramUniformMatrix4x2fv, isCallValid, context, programPacked,
                      locationPacked, count, transpose, value);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ProgramUniformMatrix4x3fvContextANGLE(GLeglContext ctx,
                                                       GLuint program,
                                                       GLint location,
                                                       GLsizei count,
                                                       GLboolean transpose,
                                                       const GLfloat *value)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ProgramUniformMatrix4x3fv, "glProgramUniformMatrix4x3fv",
          "context = %d, program = %u, location = %d, count = %d, transpose = %s, value = "
          "0x%016" PRIxPTR "",
          CID(context), program, location, count, GLbooleanToString(transpose), (uintptr_t)value);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateProgramUniformMatrix4x3fv(
                                context, programPacked, locationPacked, count, transpose, value));
        if (isCallValid)
        {
            context->programUniformMatrix4x3fv(programPacked, locationPacked, count, transpose,
                                               value);
        }
        ANGLE_CAPTURE(ProgramUniformMatrix4x3fv, isCallValid, context, programPacked,
                      locationPacked, count, transpose, value);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY PushDebugGroupContextANGLE(GLeglContext ctx,
                                            GLenum source,
                                            GLuint id,
                                            GLsizei length,
                                            const GLchar *message)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::PushDebugGroup, "glPushDebugGroup",
          "context = %d, source = %s, id = %u, length = %d, message = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DebugSource, source), id, length,
          (uintptr_t)message);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidatePushDebugGroup(context, source, id, length, message));
        if (isCallValid)
        {
            context->pushDebugGroup(source, id, length, message);
        }
        ANGLE_CAPTURE(PushDebugGroup, isCallValid, context, source, id, length, message);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY PushDebugGroupKHRContextANGLE(GLeglContext ctx,
                                               GLenum source,
                                               GLuint id,
                                               GLsizei length,
                                               const GLchar *message)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::PushDebugGroupKHR, "glPushDebugGroupKHR",
          "context = %d, source = %s, id = %u, length = %d, message = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DebugSource, source), id, length,
          (uintptr_t)message);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidatePushDebugGroupKHR(context, source, id, length, message));
        if (isCallValid)
        {
            context->pushDebugGroup(source, id, length, message);
        }
        ANGLE_CAPTURE(PushDebugGroupKHR, isCallValid, context, source, id, length, message);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY PushGroupMarkerEXTContextANGLE(GLeglContext ctx,
                                                GLsizei length,
                                                const GLchar *marker)
{
    Context *context = static_cast<gl::Context *>(ctx);
    // Don't run the EVENT() macro on the EXT_debug_marker entry points.
    // It can interfere with the debug events being set by the caller.
    // EVENT(context, gl::EntryPoint::PushGroupMarkerEXT, "glPushGroupMarkerEXT", "context = %d,
    // length = %d, marker = 0x%016" PRIxPTR "", CID(context), length, (uintptr_t)marker);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidatePushGroupMarkerEXT(context, length, marker));
        if (isCallValid)
        {
            context->pushGroupMarker(length, marker);
        }
        ANGLE_CAPTURE(PushGroupMarkerEXT, isCallValid, context, length, marker);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY PushMatrixContextANGLE(GLeglContext ctx)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::PushMatrix, "glPushMatrix", "context = %d", CID(context));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidatePushMatrix(context));
        if (isCallValid)
        {
            context->pushMatrix();
        }
        ANGLE_CAPTURE(PushMatrix, isCallValid, context);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY QueryCounterEXTContextANGLE(GLeglContext ctx, GLuint id, GLenum target)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::QueryCounterEXT, "glQueryCounterEXT",
          "context = %d, id = %u, target = %s", CID(context), id,
          GLenumToString(GLenumGroup::QueryTarget, target));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        QueryID idPacked                                      = FromGL<QueryID>(id);
        QueryType targetPacked                                = FromGL<QueryType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateQueryCounterEXT(context, idPacked, targetPacked));
        if (isCallValid)
        {
            context->queryCounter(idPacked, targetPacked);
        }
        ANGLE_CAPTURE(QueryCounterEXT, isCallValid, context, idPacked, targetPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

GLbitfield GL_APIENTRY QueryMatrixxOESContextANGLE(GLeglContext ctx,
                                                   GLfixed *mantissa,
                                                   GLint *exponent)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::QueryMatrixxOES, "glQueryMatrixxOES",
          "context = %d, mantissa = 0x%016" PRIxPTR ", exponent = 0x%016" PRIxPTR "", CID(context),
          (uintptr_t)mantissa, (uintptr_t)exponent);

    GLbitfield returnValue;
    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateQueryMatrixxOES(context, mantissa, exponent));
        if (isCallValid)
        {
            returnValue = context->queryMatrixx(mantissa, exponent);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::QueryMatrixxOES, GLbitfield>();
        }
        ANGLE_CAPTURE(QueryMatrixxOES, isCallValid, context, mantissa, exponent, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
        returnValue = GetDefaultReturnValue<EntryPoint::QueryMatrixxOES, GLbitfield>();
    }
    return returnValue;
}

void GL_APIENTRY ReadBufferContextANGLE(GLeglContext ctx, GLenum src)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ReadBuffer, "glReadBuffer", "context = %d, src = %s",
          CID(context), GLenumToString(GLenumGroup::ReadBufferMode, src));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateReadBuffer(context, src));
        if (isCallValid)
        {
            context->readBuffer(src);
        }
        ANGLE_CAPTURE(ReadBuffer, isCallValid, context, src);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ReadPixelsContextANGLE(GLeglContext ctx,
                                        GLint x,
                                        GLint y,
                                        GLsizei width,
                                        GLsizei height,
                                        GLenum format,
                                        GLenum type,
                                        void *pixels)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ReadPixels, "glReadPixels",
          "context = %d, x = %d, y = %d, width = %d, height = %d, format = %s, type = %s, pixels = "
          "0x%016" PRIxPTR "",
          CID(context), x, y, width, height, GLenumToString(GLenumGroup::PixelFormat, format),
          GLenumToString(GLenumGroup::PixelType, type), (uintptr_t)pixels);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateReadPixels(context, x, y, width, height, format, type, pixels));
        if (isCallValid)
        {
            context->readPixels(x, y, width, height, format, type, pixels);
        }
        ANGLE_CAPTURE(ReadPixels, isCallValid, context, x, y, width, height, format, type, pixels);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ReadnPixelsContextANGLE(GLeglContext ctx,
                                         GLint x,
                                         GLint y,
                                         GLsizei width,
                                         GLsizei height,
                                         GLenum format,
                                         GLenum type,
                                         GLsizei bufSize,
                                         void *data)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ReadnPixels, "glReadnPixels",
          "context = %d, x = %d, y = %d, width = %d, height = %d, format = %s, type = %s, bufSize "
          "= %d, data = 0x%016" PRIxPTR "",
          CID(context), x, y, width, height, GLenumToString(GLenumGroup::PixelFormat, format),
          GLenumToString(GLenumGroup::PixelType, type), bufSize, (uintptr_t)data);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateReadnPixels(context, x, y, width, height, format, type, bufSize, data));
        if (isCallValid)
        {
            context->readnPixels(x, y, width, height, format, type, bufSize, data);
        }
        ANGLE_CAPTURE(ReadnPixels, isCallValid, context, x, y, width, height, format, type, bufSize,
                      data);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ReadnPixelsEXTContextANGLE(GLeglContext ctx,
                                            GLint x,
                                            GLint y,
                                            GLsizei width,
                                            GLsizei height,
                                            GLenum format,
                                            GLenum type,
                                            GLsizei bufSize,
                                            void *data)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ReadnPixelsEXT, "glReadnPixelsEXT",
          "context = %d, x = %d, y = %d, width = %d, height = %d, format = %s, type = %s, bufSize "
          "= %d, data = 0x%016" PRIxPTR "",
          CID(context), x, y, width, height, GLenumToString(GLenumGroup::PixelFormat, format),
          GLenumToString(GLenumGroup::PixelType, type), bufSize, (uintptr_t)data);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateReadnPixelsEXT(context, x, y, width, height, format, type, bufSize, data));
        if (isCallValid)
        {
            context->readnPixels(x, y, width, height, format, type, bufSize, data);
        }
        ANGLE_CAPTURE(ReadnPixelsEXT, isCallValid, context, x, y, width, height, format, type,
                      bufSize, data);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ReleaseShaderCompilerContextANGLE(GLeglContext ctx)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ReleaseShaderCompiler, "glReleaseShaderCompiler", "context = %d",
          CID(context));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateReleaseShaderCompiler(context));
        if (isCallValid)
        {
            context->releaseShaderCompiler();
        }
        ANGLE_CAPTURE(ReleaseShaderCompiler, isCallValid, context);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY RenderbufferStorageContextANGLE(GLeglContext ctx,
                                                 GLenum target,
                                                 GLenum internalformat,
                                                 GLsizei width,
                                                 GLsizei height)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::RenderbufferStorage, "glRenderbufferStorage",
          "context = %d, target = %s, internalformat = %s, width = %d, height = %d", CID(context),
          GLenumToString(GLenumGroup::RenderbufferTarget, target),
          GLenumToString(GLenumGroup::InternalFormat, internalformat), width, height);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateRenderbufferStorage(context, target, internalformat, width, height));
        if (isCallValid)
        {
            context->renderbufferStorage(target, internalformat, width, height);
        }
        ANGLE_CAPTURE(RenderbufferStorage, isCallValid, context, target, internalformat, width,
                      height);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY RenderbufferStorageMultisampleContextANGLE(GLeglContext ctx,
                                                            GLenum target,
                                                            GLsizei samples,
                                                            GLenum internalformat,
                                                            GLsizei width,
                                                            GLsizei height)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::RenderbufferStorageMultisample,
          "glRenderbufferStorageMultisample",
          "context = %d, target = %s, samples = %d, internalformat = %s, width = %d, height = %d",
          CID(context), GLenumToString(GLenumGroup::RenderbufferTarget, target), samples,
          GLenumToString(GLenumGroup::InternalFormat, internalformat), width, height);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateRenderbufferStorageMultisample(context, target, samples,
                                                                   internalformat, width, height));
        if (isCallValid)
        {
            context->renderbufferStorageMultisample(target, samples, internalformat, width, height);
        }
        ANGLE_CAPTURE(RenderbufferStorageMultisample, isCallValid, context, target, samples,
                      internalformat, width, height);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY RenderbufferStorageMultisampleANGLEContextANGLE(GLeglContext ctx,
                                                                 GLenum target,
                                                                 GLsizei samples,
                                                                 GLenum internalformat,
                                                                 GLsizei width,
                                                                 GLsizei height)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::RenderbufferStorageMultisampleANGLE,
          "glRenderbufferStorageMultisampleANGLE",
          "context = %d, target = %s, samples = %d, internalformat = %s, width = %d, height = %d",
          CID(context), GLenumToString(GLenumGroup::RenderbufferTarget, target), samples,
          GLenumToString(GLenumGroup::InternalFormat, internalformat), width, height);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateRenderbufferStorageMultisampleANGLE(
                                context, target, samples, internalformat, width, height));
        if (isCallValid)
        {
            context->renderbufferStorageMultisample(target, samples, internalformat, width, height);
        }
        ANGLE_CAPTURE(RenderbufferStorageMultisampleANGLE, isCallValid, context, target, samples,
                      internalformat, width, height);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY RenderbufferStorageMultisampleEXTContextANGLE(GLeglContext ctx,
                                                               GLenum target,
                                                               GLsizei samples,
                                                               GLenum internalformat,
                                                               GLsizei width,
                                                               GLsizei height)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::RenderbufferStorageMultisampleEXT,
          "glRenderbufferStorageMultisampleEXT",
          "context = %d, target = %s, samples = %d, internalformat = %s, width = %d, height = %d",
          CID(context), GLenumToString(GLenumGroup::RenderbufferTarget, target), samples,
          GLenumToString(GLenumGroup::InternalFormat, internalformat), width, height);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateRenderbufferStorageMultisampleEXT(
                                context, target, samples, internalformat, width, height));
        if (isCallValid)
        {
            context->renderbufferStorageMultisampleEXT(target, samples, internalformat, width,
                                                       height);
        }
        ANGLE_CAPTURE(RenderbufferStorageMultisampleEXT, isCallValid, context, target, samples,
                      internalformat, width, height);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY RenderbufferStorageOESContextANGLE(GLeglContext ctx,
                                                    GLenum target,
                                                    GLenum internalformat,
                                                    GLsizei width,
                                                    GLsizei height)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::RenderbufferStorageOES, "glRenderbufferStorageOES",
          "context = %d, target = %s, internalformat = %s, width = %d, height = %d", CID(context),
          GLenumToString(GLenumGroup::RenderbufferTarget, target),
          GLenumToString(GLenumGroup::InternalFormat, internalformat), width, height);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateRenderbufferStorageOES(context, target, internalformat, width, height));
        if (isCallValid)
        {
            context->renderbufferStorage(target, internalformat, width, height);
        }
        ANGLE_CAPTURE(RenderbufferStorageOES, isCallValid, context, target, internalformat, width,
                      height);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ResumeTransformFeedbackContextANGLE(GLeglContext ctx)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ResumeTransformFeedback, "glResumeTransformFeedback",
          "context = %d", CID(context));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateResumeTransformFeedback(context));
        if (isCallValid)
        {
            context->resumeTransformFeedback();
        }
        ANGLE_CAPTURE(ResumeTransformFeedback, isCallValid, context);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY
RotatefContextANGLE(GLeglContext ctx, GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Rotatef, "glRotatef",
          "context = %d, angle = %f, x = %f, y = %f, z = %f", CID(context), angle, x, y, z);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateRotatef(context, angle, x, y, z));
        if (isCallValid)
        {
            context->rotatef(angle, x, y, z);
        }
        ANGLE_CAPTURE(Rotatef, isCallValid, context, angle, x, y, z);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY
RotatexContextANGLE(GLeglContext ctx, GLfixed angle, GLfixed x, GLfixed y, GLfixed z)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Rotatex, "glRotatex",
          "context = %d, angle = 0x%X, x = 0x%X, y = 0x%X, z = 0x%X", CID(context), angle, x, y, z);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateRotatex(context, angle, x, y, z));
        if (isCallValid)
        {
            context->rotatex(angle, x, y, z);
        }
        ANGLE_CAPTURE(Rotatex, isCallValid, context, angle, x, y, z);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY SampleCoverageContextANGLE(GLeglContext ctx, GLfloat value, GLboolean invert)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::SampleCoverage, "glSampleCoverage",
          "context = %d, value = %f, invert = %s", CID(context), value, GLbooleanToString(invert));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateSampleCoverage(context, value, invert));
        if (isCallValid)
        {
            context->sampleCoverage(value, invert);
        }
        ANGLE_CAPTURE(SampleCoverage, isCallValid, context, value, invert);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY SampleCoveragexContextANGLE(GLeglContext ctx, GLclampx value, GLboolean invert)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::SampleCoveragex, "glSampleCoveragex",
          "context = %d, value = 0x%X, invert = %s", CID(context), value,
          GLbooleanToString(invert));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateSampleCoveragex(context, value, invert));
        if (isCallValid)
        {
            context->sampleCoveragex(value, invert);
        }
        ANGLE_CAPTURE(SampleCoveragex, isCallValid, context, value, invert);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY SampleMaskiContextANGLE(GLeglContext ctx, GLuint maskNumber, GLbitfield mask)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::SampleMaski, "glSampleMaski",
          "context = %d, maskNumber = %u, mask = %s", CID(context), maskNumber,
          GLbitfieldToString(GLenumGroup::DefaultGroup, mask).c_str());

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateSampleMaski(context, maskNumber, mask));
        if (isCallValid)
        {
            context->sampleMaski(maskNumber, mask);
        }
        ANGLE_CAPTURE(SampleMaski, isCallValid, context, maskNumber, mask);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY SamplerParameterIivContextANGLE(GLeglContext ctx,
                                                 GLuint sampler,
                                                 GLenum pname,
                                                 const GLint *param)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::SamplerParameterIiv, "glSamplerParameterIiv",
          "context = %d, sampler = %u, pname = %s, param = 0x%016" PRIxPTR "", CID(context),
          sampler, GLenumToString(GLenumGroup::SamplerParameterName, pname), (uintptr_t)param);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        SamplerID samplerPacked                               = FromGL<SamplerID>(sampler);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateSamplerParameterIiv(context, samplerPacked, pname, param));
        if (isCallValid)
        {
            context->samplerParameterIiv(samplerPacked, pname, param);
        }
        ANGLE_CAPTURE(SamplerParameterIiv, isCallValid, context, samplerPacked, pname, param);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY SamplerParameterIivOESContextANGLE(GLeglContext ctx,
                                                    GLuint sampler,
                                                    GLenum pname,
                                                    const GLint *param)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::SamplerParameterIivOES, "glSamplerParameterIivOES",
          "context = %d, sampler = %u, pname = %s, param = 0x%016" PRIxPTR "", CID(context),
          sampler, GLenumToString(GLenumGroup::SamplerParameterName, pname), (uintptr_t)param);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        SamplerID samplerPacked                               = FromGL<SamplerID>(sampler);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateSamplerParameterIivOES(context, samplerPacked, pname, param));
        if (isCallValid)
        {
            context->samplerParameterIiv(samplerPacked, pname, param);
        }
        ANGLE_CAPTURE(SamplerParameterIivOES, isCallValid, context, samplerPacked, pname, param);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY SamplerParameterIuivContextANGLE(GLeglContext ctx,
                                                  GLuint sampler,
                                                  GLenum pname,
                                                  const GLuint *param)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::SamplerParameterIuiv, "glSamplerParameterIuiv",
          "context = %d, sampler = %u, pname = %s, param = 0x%016" PRIxPTR "", CID(context),
          sampler, GLenumToString(GLenumGroup::SamplerParameterName, pname), (uintptr_t)param);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        SamplerID samplerPacked                               = FromGL<SamplerID>(sampler);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateSamplerParameterIuiv(context, samplerPacked, pname, param));
        if (isCallValid)
        {
            context->samplerParameterIuiv(samplerPacked, pname, param);
        }
        ANGLE_CAPTURE(SamplerParameterIuiv, isCallValid, context, samplerPacked, pname, param);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY SamplerParameterIuivOESContextANGLE(GLeglContext ctx,
                                                     GLuint sampler,
                                                     GLenum pname,
                                                     const GLuint *param)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::SamplerParameterIuivOES, "glSamplerParameterIuivOES",
          "context = %d, sampler = %u, pname = %s, param = 0x%016" PRIxPTR "", CID(context),
          sampler, GLenumToString(GLenumGroup::SamplerParameterName, pname), (uintptr_t)param);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        SamplerID samplerPacked                               = FromGL<SamplerID>(sampler);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateSamplerParameterIuivOES(context, samplerPacked, pname, param));
        if (isCallValid)
        {
            context->samplerParameterIuiv(samplerPacked, pname, param);
        }
        ANGLE_CAPTURE(SamplerParameterIuivOES, isCallValid, context, samplerPacked, pname, param);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY SamplerParameterfContextANGLE(GLeglContext ctx,
                                               GLuint sampler,
                                               GLenum pname,
                                               GLfloat param)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::SamplerParameterf, "glSamplerParameterf",
          "context = %d, sampler = %u, pname = %s, param = %f", CID(context), sampler,
          GLenumToString(GLenumGroup::SamplerParameterName, pname), param);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        SamplerID samplerPacked                               = FromGL<SamplerID>(sampler);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateSamplerParameterf(context, samplerPacked, pname, param));
        if (isCallValid)
        {
            context->samplerParameterf(samplerPacked, pname, param);
        }
        ANGLE_CAPTURE(SamplerParameterf, isCallValid, context, samplerPacked, pname, param);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY SamplerParameterfvContextANGLE(GLeglContext ctx,
                                                GLuint sampler,
                                                GLenum pname,
                                                const GLfloat *param)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::SamplerParameterfv, "glSamplerParameterfv",
          "context = %d, sampler = %u, pname = %s, param = 0x%016" PRIxPTR "", CID(context),
          sampler, GLenumToString(GLenumGroup::SamplerParameterName, pname), (uintptr_t)param);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        SamplerID samplerPacked                               = FromGL<SamplerID>(sampler);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateSamplerParameterfv(context, samplerPacked, pname, param));
        if (isCallValid)
        {
            context->samplerParameterfv(samplerPacked, pname, param);
        }
        ANGLE_CAPTURE(SamplerParameterfv, isCallValid, context, samplerPacked, pname, param);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY SamplerParameteriContextANGLE(GLeglContext ctx,
                                               GLuint sampler,
                                               GLenum pname,
                                               GLint param)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::SamplerParameteri, "glSamplerParameteri",
          "context = %d, sampler = %u, pname = %s, param = %d", CID(context), sampler,
          GLenumToString(GLenumGroup::SamplerParameterName, pname), param);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        SamplerID samplerPacked                               = FromGL<SamplerID>(sampler);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateSamplerParameteri(context, samplerPacked, pname, param));
        if (isCallValid)
        {
            context->samplerParameteri(samplerPacked, pname, param);
        }
        ANGLE_CAPTURE(SamplerParameteri, isCallValid, context, samplerPacked, pname, param);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY SamplerParameterivContextANGLE(GLeglContext ctx,
                                                GLuint sampler,
                                                GLenum pname,
                                                const GLint *param)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::SamplerParameteriv, "glSamplerParameteriv",
          "context = %d, sampler = %u, pname = %s, param = 0x%016" PRIxPTR "", CID(context),
          sampler, GLenumToString(GLenumGroup::SamplerParameterName, pname), (uintptr_t)param);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        SamplerID samplerPacked                               = FromGL<SamplerID>(sampler);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateSamplerParameteriv(context, samplerPacked, pname, param));
        if (isCallValid)
        {
            context->samplerParameteriv(samplerPacked, pname, param);
        }
        ANGLE_CAPTURE(SamplerParameteriv, isCallValid, context, samplerPacked, pname, param);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ScalefContextANGLE(GLeglContext ctx, GLfloat x, GLfloat y, GLfloat z)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Scalef, "glScalef", "context = %d, x = %f, y = %f, z = %f",
          CID(context), x, y, z);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateScalef(context, x, y, z));
        if (isCallValid)
        {
            context->scalef(x, y, z);
        }
        ANGLE_CAPTURE(Scalef, isCallValid, context, x, y, z);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ScalexContextANGLE(GLeglContext ctx, GLfixed x, GLfixed y, GLfixed z)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Scalex, "glScalex", "context = %d, x = 0x%X, y = 0x%X, z = 0x%X",
          CID(context), x, y, z);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateScalex(context, x, y, z));
        if (isCallValid)
        {
            context->scalex(x, y, z);
        }
        ANGLE_CAPTURE(Scalex, isCallValid, context, x, y, z);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY
ScissorContextANGLE(GLeglContext ctx, GLint x, GLint y, GLsizei width, GLsizei height)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Scissor, "glScissor",
          "context = %d, x = %d, y = %d, width = %d, height = %d", CID(context), x, y, width,
          height);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateScissor(context, x, y, width, height));
        if (isCallValid)
        {
            context->scissor(x, y, width, height);
        }
        ANGLE_CAPTURE(Scissor, isCallValid, context, x, y, width, height);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY SemaphoreParameterui64vEXTContextANGLE(GLeglContext ctx,
                                                        GLuint semaphore,
                                                        GLenum pname,
                                                        const GLuint64 *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::SemaphoreParameterui64vEXT, "glSemaphoreParameterui64vEXT",
          "context = %d, semaphore = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          semaphore, GLenumToString(GLenumGroup::SemaphoreParameterName, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        SemaphoreID semaphorePacked                           = FromGL<SemaphoreID>(semaphore);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateSemaphoreParameterui64vEXT(context, semaphorePacked, pname, params));
        if (isCallValid)
        {
            context->semaphoreParameterui64v(semaphorePacked, pname, params);
        }
        ANGLE_CAPTURE(SemaphoreParameterui64vEXT, isCallValid, context, semaphorePacked, pname,
                      params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY SetFenceNVContextANGLE(GLeglContext ctx, GLuint fence, GLenum condition)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::SetFenceNV, "glSetFenceNV",
          "context = %d, fence = %u, condition = %s", CID(context), fence,
          GLenumToString(GLenumGroup::DefaultGroup, condition));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        FenceNVID fencePacked                                 = FromGL<FenceNVID>(fence);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateSetFenceNV(context, fencePacked, condition));
        if (isCallValid)
        {
            context->setFenceNV(fencePacked, condition);
        }
        ANGLE_CAPTURE(SetFenceNV, isCallValid, context, fencePacked, condition);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ShadeModelContextANGLE(GLeglContext ctx, GLenum mode)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ShadeModel, "glShadeModel", "context = %d, mode = %s",
          CID(context), GLenumToString(GLenumGroup::ShadingModel, mode));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShadingModel modePacked                               = FromGL<ShadingModel>(mode);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateShadeModel(context, modePacked));
        if (isCallValid)
        {
            context->shadeModel(modePacked);
        }
        ANGLE_CAPTURE(ShadeModel, isCallValid, context, modePacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ShaderBinaryContextANGLE(GLeglContext ctx,
                                          GLsizei count,
                                          const GLuint *shaders,
                                          GLenum binaryformat,
                                          const void *binary,
                                          GLsizei length)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ShaderBinary, "glShaderBinary",
          "context = %d, count = %d, shaders = 0x%016" PRIxPTR
          ", binaryformat = %s, binary = 0x%016" PRIxPTR ", length = %d",
          CID(context), count, (uintptr_t)shaders,
          GLenumToString(GLenumGroup::DefaultGroup, binaryformat), (uintptr_t)binary, length);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        const ShaderProgramID *shadersPacked = FromGL<const ShaderProgramID *>(shaders);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateShaderBinary(context, count, shadersPacked, binaryformat, binary, length));
        if (isCallValid)
        {
            context->shaderBinary(count, shadersPacked, binaryformat, binary, length);
        }
        ANGLE_CAPTURE(ShaderBinary, isCallValid, context, count, shadersPacked, binaryformat,
                      binary, length);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ShaderSourceContextANGLE(GLeglContext ctx,
                                          GLuint shader,
                                          GLsizei count,
                                          const GLchar *const *string,
                                          const GLint *length)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ShaderSource, "glShaderSource",
          "context = %d, shader = %u, count = %d, string = 0x%016" PRIxPTR
          ", length = 0x%016" PRIxPTR "",
          CID(context), shader, count, (uintptr_t)string, (uintptr_t)length);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID shaderPacked                          = FromGL<ShaderProgramID>(shader);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateShaderSource(context, shaderPacked, count, string, length));
        if (isCallValid)
        {
            context->shaderSource(shaderPacked, count, string, length);
        }
        ANGLE_CAPTURE(ShaderSource, isCallValid, context, shaderPacked, count, string, length);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY SignalSemaphoreEXTContextANGLE(GLeglContext ctx,
                                                GLuint semaphore,
                                                GLuint numBufferBarriers,
                                                const GLuint *buffers,
                                                GLuint numTextureBarriers,
                                                const GLuint *textures,
                                                const GLenum *dstLayouts)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::SignalSemaphoreEXT, "glSignalSemaphoreEXT",
          "context = %d, semaphore = %u, numBufferBarriers = %u, buffers = 0x%016" PRIxPTR
          ", numTextureBarriers = %u, textures = 0x%016" PRIxPTR ", dstLayouts = 0x%016" PRIxPTR "",
          CID(context), semaphore, numBufferBarriers, (uintptr_t)buffers, numTextureBarriers,
          (uintptr_t)textures, (uintptr_t)dstLayouts);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        SemaphoreID semaphorePacked                           = FromGL<SemaphoreID>(semaphore);
        const BufferID *buffersPacked                         = FromGL<const BufferID *>(buffers);
        const TextureID *texturesPacked                       = FromGL<const TextureID *>(textures);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateSignalSemaphoreEXT(context, semaphorePacked, numBufferBarriers, buffersPacked,
                                        numTextureBarriers, texturesPacked, dstLayouts));
        if (isCallValid)
        {
            context->signalSemaphore(semaphorePacked, numBufferBarriers, buffersPacked,
                                     numTextureBarriers, texturesPacked, dstLayouts);
        }
        ANGLE_CAPTURE(SignalSemaphoreEXT, isCallValid, context, semaphorePacked, numBufferBarriers,
                      buffersPacked, numTextureBarriers, texturesPacked, dstLayouts);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY StencilFuncContextANGLE(GLeglContext ctx, GLenum func, GLint ref, GLuint mask)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::StencilFunc, "glStencilFunc",
          "context = %d, func = %s, ref = %d, mask = %u", CID(context),
          GLenumToString(GLenumGroup::StencilFunction, func), ref, mask);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateStencilFunc(context, func, ref, mask));
        if (isCallValid)
        {
            context->stencilFunc(func, ref, mask);
        }
        ANGLE_CAPTURE(StencilFunc, isCallValid, context, func, ref, mask);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY
StencilFuncSeparateContextANGLE(GLeglContext ctx, GLenum face, GLenum func, GLint ref, GLuint mask)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::StencilFuncSeparate, "glStencilFuncSeparate",
          "context = %d, face = %s, func = %s, ref = %d, mask = %u", CID(context),
          GLenumToString(GLenumGroup::StencilFaceDirection, face),
          GLenumToString(GLenumGroup::StencilFunction, func), ref, mask);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateStencilFuncSeparate(context, face, func, ref, mask));
        if (isCallValid)
        {
            context->stencilFuncSeparate(face, func, ref, mask);
        }
        ANGLE_CAPTURE(StencilFuncSeparate, isCallValid, context, face, func, ref, mask);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY StencilMaskContextANGLE(GLeglContext ctx, GLuint mask)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::StencilMask, "glStencilMask", "context = %d, mask = %u",
          CID(context), mask);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateStencilMask(context, mask));
        if (isCallValid)
        {
            context->stencilMask(mask);
        }
        ANGLE_CAPTURE(StencilMask, isCallValid, context, mask);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY StencilMaskSeparateContextANGLE(GLeglContext ctx, GLenum face, GLuint mask)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::StencilMaskSeparate, "glStencilMaskSeparate",
          "context = %d, face = %s, mask = %u", CID(context),
          GLenumToString(GLenumGroup::StencilFaceDirection, face), mask);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateStencilMaskSeparate(context, face, mask));
        if (isCallValid)
        {
            context->stencilMaskSeparate(face, mask);
        }
        ANGLE_CAPTURE(StencilMaskSeparate, isCallValid, context, face, mask);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY StencilOpContextANGLE(GLeglContext ctx, GLenum fail, GLenum zfail, GLenum zpass)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::StencilOp, "glStencilOp",
          "context = %d, fail = %s, zfail = %s, zpass = %s", CID(context),
          GLenumToString(GLenumGroup::StencilOp, fail),
          GLenumToString(GLenumGroup::StencilOp, zfail),
          GLenumToString(GLenumGroup::StencilOp, zpass));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateStencilOp(context, fail, zfail, zpass));
        if (isCallValid)
        {
            context->stencilOp(fail, zfail, zpass);
        }
        ANGLE_CAPTURE(StencilOp, isCallValid, context, fail, zfail, zpass);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY StencilOpSeparateContextANGLE(GLeglContext ctx,
                                               GLenum face,
                                               GLenum sfail,
                                               GLenum dpfail,
                                               GLenum dppass)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::StencilOpSeparate, "glStencilOpSeparate",
          "context = %d, face = %s, sfail = %s, dpfail = %s, dppass = %s", CID(context),
          GLenumToString(GLenumGroup::StencilFaceDirection, face),
          GLenumToString(GLenumGroup::StencilOp, sfail),
          GLenumToString(GLenumGroup::StencilOp, dpfail),
          GLenumToString(GLenumGroup::StencilOp, dppass));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateStencilOpSeparate(context, face, sfail, dpfail, dppass));
        if (isCallValid)
        {
            context->stencilOpSeparate(face, sfail, dpfail, dppass);
        }
        ANGLE_CAPTURE(StencilOpSeparate, isCallValid, context, face, sfail, dpfail, dppass);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

GLboolean GL_APIENTRY TestFenceNVContextANGLE(GLeglContext ctx, GLuint fence)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TestFenceNV, "glTestFenceNV", "context = %d, fence = %u",
          CID(context), fence);

    GLboolean returnValue;
    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        FenceNVID fencePacked                                 = FromGL<FenceNVID>(fence);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateTestFenceNV(context, fencePacked));
        if (isCallValid)
        {
            returnValue = context->testFenceNV(fencePacked);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::TestFenceNV, GLboolean>();
        }
        ANGLE_CAPTURE(TestFenceNV, isCallValid, context, fencePacked, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
        returnValue = GetDefaultReturnValue<EntryPoint::TestFenceNV, GLboolean>();
    }
    return returnValue;
}

void GL_APIENTRY TexBufferContextANGLE(GLeglContext ctx,
                                       GLenum target,
                                       GLenum internalformat,
                                       GLuint buffer)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexBuffer, "glTexBuffer",
          "context = %d, target = %s, internalformat = %s, buffer = %u", CID(context),
          GLenumToString(GLenumGroup::TextureTarget, target),
          GLenumToString(GLenumGroup::InternalFormat, internalformat), buffer);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        BufferID bufferPacked                                 = FromGL<BufferID>(buffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateTexBuffer(context, targetPacked, internalformat, bufferPacked));
        if (isCallValid)
        {
            context->texBuffer(targetPacked, internalformat, bufferPacked);
        }
        ANGLE_CAPTURE(TexBuffer, isCallValid, context, targetPacked, internalformat, bufferPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexBufferEXTContextANGLE(GLeglContext ctx,
                                          GLenum target,
                                          GLenum internalformat,
                                          GLuint buffer)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexBufferEXT, "glTexBufferEXT",
          "context = %d, target = %s, internalformat = %s, buffer = %u", CID(context),
          GLenumToString(GLenumGroup::TextureTarget, target),
          GLenumToString(GLenumGroup::InternalFormat, internalformat), buffer);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        BufferID bufferPacked                                 = FromGL<BufferID>(buffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTexBufferEXT(context, targetPacked, internalformat, bufferPacked));
        if (isCallValid)
        {
            context->texBuffer(targetPacked, internalformat, bufferPacked);
        }
        ANGLE_CAPTURE(TexBufferEXT, isCallValid, context, targetPacked, internalformat,
                      bufferPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexBufferOESContextANGLE(GLeglContext ctx,
                                          GLenum target,
                                          GLenum internalformat,
                                          GLuint buffer)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexBufferOES, "glTexBufferOES",
          "context = %d, target = %s, internalformat = %s, buffer = %u", CID(context),
          GLenumToString(GLenumGroup::TextureTarget, target),
          GLenumToString(GLenumGroup::InternalFormat, internalformat), buffer);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        BufferID bufferPacked                                 = FromGL<BufferID>(buffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTexBufferOES(context, targetPacked, internalformat, bufferPacked));
        if (isCallValid)
        {
            context->texBuffer(targetPacked, internalformat, bufferPacked);
        }
        ANGLE_CAPTURE(TexBufferOES, isCallValid, context, targetPacked, internalformat,
                      bufferPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexBufferRangeContextANGLE(GLeglContext ctx,
                                            GLenum target,
                                            GLenum internalformat,
                                            GLuint buffer,
                                            GLintptr offset,
                                            GLsizeiptr size)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexBufferRange, "glTexBufferRange",
          "context = %d, target = %s, internalformat = %s, buffer = %u, offset = %llu, size = %llu",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target),
          GLenumToString(GLenumGroup::InternalFormat, internalformat), buffer,
          static_cast<unsigned long long>(offset), static_cast<unsigned long long>(size));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        BufferID bufferPacked                                 = FromGL<BufferID>(buffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateTexBufferRange(context, targetPacked, internalformat,
                                                   bufferPacked, offset, size));
        if (isCallValid)
        {
            context->texBufferRange(targetPacked, internalformat, bufferPacked, offset, size);
        }
        ANGLE_CAPTURE(TexBufferRange, isCallValid, context, targetPacked, internalformat,
                      bufferPacked, offset, size);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexBufferRangeEXTContextANGLE(GLeglContext ctx,
                                               GLenum target,
                                               GLenum internalformat,
                                               GLuint buffer,
                                               GLintptr offset,
                                               GLsizeiptr size)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexBufferRangeEXT, "glTexBufferRangeEXT",
          "context = %d, target = %s, internalformat = %s, buffer = %u, offset = %llu, size = %llu",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target),
          GLenumToString(GLenumGroup::InternalFormat, internalformat), buffer,
          static_cast<unsigned long long>(offset), static_cast<unsigned long long>(size));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        BufferID bufferPacked                                 = FromGL<BufferID>(buffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateTexBufferRangeEXT(context, targetPacked, internalformat,
                                                      bufferPacked, offset, size));
        if (isCallValid)
        {
            context->texBufferRange(targetPacked, internalformat, bufferPacked, offset, size);
        }
        ANGLE_CAPTURE(TexBufferRangeEXT, isCallValid, context, targetPacked, internalformat,
                      bufferPacked, offset, size);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexBufferRangeOESContextANGLE(GLeglContext ctx,
                                               GLenum target,
                                               GLenum internalformat,
                                               GLuint buffer,
                                               GLintptr offset,
                                               GLsizeiptr size)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexBufferRangeOES, "glTexBufferRangeOES",
          "context = %d, target = %s, internalformat = %s, buffer = %u, offset = %llu, size = %llu",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target),
          GLenumToString(GLenumGroup::InternalFormat, internalformat), buffer,
          static_cast<unsigned long long>(offset), static_cast<unsigned long long>(size));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        BufferID bufferPacked                                 = FromGL<BufferID>(buffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateTexBufferRangeOES(context, targetPacked, internalformat,
                                                      bufferPacked, offset, size));
        if (isCallValid)
        {
            context->texBufferRange(targetPacked, internalformat, bufferPacked, offset, size);
        }
        ANGLE_CAPTURE(TexBufferRangeOES, isCallValid, context, targetPacked, internalformat,
                      bufferPacked, offset, size);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexCoordPointerContextANGLE(GLeglContext ctx,
                                             GLint size,
                                             GLenum type,
                                             GLsizei stride,
                                             const void *pointer)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexCoordPointer, "glTexCoordPointer",
          "context = %d, size = %d, type = %s, stride = %d, pointer = 0x%016" PRIxPTR "",
          CID(context), size, GLenumToString(GLenumGroup::TexCoordPointerType, type), stride,
          (uintptr_t)pointer);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        VertexAttribType typePacked                           = FromGL<VertexAttribType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateTexCoordPointer(context, size, typePacked, stride, pointer));
        if (isCallValid)
        {
            context->texCoordPointer(size, typePacked, stride, pointer);
        }
        ANGLE_CAPTURE(TexCoordPointer, isCallValid, context, size, typePacked, stride, pointer);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexEnvfContextANGLE(GLeglContext ctx, GLenum target, GLenum pname, GLfloat param)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexEnvf, "glTexEnvf",
          "context = %d, target = %s, pname = %s, param = %f", CID(context),
          GLenumToString(GLenumGroup::TextureEnvTarget, target),
          GLenumToString(GLenumGroup::TextureEnvParameter, pname), param);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureEnvTarget targetPacked                         = FromGL<TextureEnvTarget>(target);
        TextureEnvParameter pnamePacked                       = FromGL<TextureEnvParameter>(pname);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateTexEnvf(context, targetPacked, pnamePacked, param));
        if (isCallValid)
        {
            context->texEnvf(targetPacked, pnamePacked, param);
        }
        ANGLE_CAPTURE(TexEnvf, isCallValid, context, targetPacked, pnamePacked, param);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexEnvfvContextANGLE(GLeglContext ctx,
                                      GLenum target,
                                      GLenum pname,
                                      const GLfloat *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexEnvfv, "glTexEnvfv",
          "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::TextureEnvTarget, target),
          GLenumToString(GLenumGroup::TextureEnvParameter, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureEnvTarget targetPacked                         = FromGL<TextureEnvTarget>(target);
        TextureEnvParameter pnamePacked                       = FromGL<TextureEnvParameter>(pname);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateTexEnvfv(context, targetPacked, pnamePacked, params));
        if (isCallValid)
        {
            context->texEnvfv(targetPacked, pnamePacked, params);
        }
        ANGLE_CAPTURE(TexEnvfv, isCallValid, context, targetPacked, pnamePacked, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexEnviContextANGLE(GLeglContext ctx, GLenum target, GLenum pname, GLint param)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexEnvi, "glTexEnvi",
          "context = %d, target = %s, pname = %s, param = %d", CID(context),
          GLenumToString(GLenumGroup::TextureEnvTarget, target),
          GLenumToString(GLenumGroup::TextureEnvParameter, pname), param);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureEnvTarget targetPacked                         = FromGL<TextureEnvTarget>(target);
        TextureEnvParameter pnamePacked                       = FromGL<TextureEnvParameter>(pname);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateTexEnvi(context, targetPacked, pnamePacked, param));
        if (isCallValid)
        {
            context->texEnvi(targetPacked, pnamePacked, param);
        }
        ANGLE_CAPTURE(TexEnvi, isCallValid, context, targetPacked, pnamePacked, param);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexEnvivContextANGLE(GLeglContext ctx,
                                      GLenum target,
                                      GLenum pname,
                                      const GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexEnviv, "glTexEnviv",
          "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::TextureEnvTarget, target),
          GLenumToString(GLenumGroup::TextureEnvParameter, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureEnvTarget targetPacked                         = FromGL<TextureEnvTarget>(target);
        TextureEnvParameter pnamePacked                       = FromGL<TextureEnvParameter>(pname);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateTexEnviv(context, targetPacked, pnamePacked, params));
        if (isCallValid)
        {
            context->texEnviv(targetPacked, pnamePacked, params);
        }
        ANGLE_CAPTURE(TexEnviv, isCallValid, context, targetPacked, pnamePacked, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexEnvxContextANGLE(GLeglContext ctx, GLenum target, GLenum pname, GLfixed param)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexEnvx, "glTexEnvx",
          "context = %d, target = %s, pname = %s, param = 0x%X", CID(context),
          GLenumToString(GLenumGroup::TextureEnvTarget, target),
          GLenumToString(GLenumGroup::TextureEnvParameter, pname), param);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureEnvTarget targetPacked                         = FromGL<TextureEnvTarget>(target);
        TextureEnvParameter pnamePacked                       = FromGL<TextureEnvParameter>(pname);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateTexEnvx(context, targetPacked, pnamePacked, param));
        if (isCallValid)
        {
            context->texEnvx(targetPacked, pnamePacked, param);
        }
        ANGLE_CAPTURE(TexEnvx, isCallValid, context, targetPacked, pnamePacked, param);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexEnvxvContextANGLE(GLeglContext ctx,
                                      GLenum target,
                                      GLenum pname,
                                      const GLfixed *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexEnvxv, "glTexEnvxv",
          "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::TextureEnvTarget, target),
          GLenumToString(GLenumGroup::TextureEnvParameter, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureEnvTarget targetPacked                         = FromGL<TextureEnvTarget>(target);
        TextureEnvParameter pnamePacked                       = FromGL<TextureEnvParameter>(pname);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateTexEnvxv(context, targetPacked, pnamePacked, params));
        if (isCallValid)
        {
            context->texEnvxv(targetPacked, pnamePacked, params);
        }
        ANGLE_CAPTURE(TexEnvxv, isCallValid, context, targetPacked, pnamePacked, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexGenfOESContextANGLE(GLeglContext ctx, GLenum coord, GLenum pname, GLfloat param)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexGenfOES, "glTexGenfOES",
          "context = %d, coord = %s, pname = %s, param = %f", CID(context),
          GLenumToString(GLenumGroup::TextureCoordName, coord),
          GLenumToString(GLenumGroup::TextureGenParameter, pname), param);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateTexGenfOES(context, coord, pname, param));
        if (isCallValid)
        {
            context->texGenf(coord, pname, param);
        }
        ANGLE_CAPTURE(TexGenfOES, isCallValid, context, coord, pname, param);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexGenfvOESContextANGLE(GLeglContext ctx,
                                         GLenum coord,
                                         GLenum pname,
                                         const GLfloat *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexGenfvOES, "glTexGenfvOES",
          "context = %d, coord = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::TextureCoordName, coord),
          GLenumToString(GLenumGroup::TextureGenParameter, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateTexGenfvOES(context, coord, pname, params));
        if (isCallValid)
        {
            context->texGenfv(coord, pname, params);
        }
        ANGLE_CAPTURE(TexGenfvOES, isCallValid, context, coord, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexGeniOESContextANGLE(GLeglContext ctx, GLenum coord, GLenum pname, GLint param)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexGeniOES, "glTexGeniOES",
          "context = %d, coord = %s, pname = %s, param = %d", CID(context),
          GLenumToString(GLenumGroup::TextureCoordName, coord),
          GLenumToString(GLenumGroup::TextureGenParameter, pname), param);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateTexGeniOES(context, coord, pname, param));
        if (isCallValid)
        {
            context->texGeni(coord, pname, param);
        }
        ANGLE_CAPTURE(TexGeniOES, isCallValid, context, coord, pname, param);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexGenivOESContextANGLE(GLeglContext ctx,
                                         GLenum coord,
                                         GLenum pname,
                                         const GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexGenivOES, "glTexGenivOES",
          "context = %d, coord = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::TextureCoordName, coord),
          GLenumToString(GLenumGroup::TextureGenParameter, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateTexGenivOES(context, coord, pname, params));
        if (isCallValid)
        {
            context->texGeniv(coord, pname, params);
        }
        ANGLE_CAPTURE(TexGenivOES, isCallValid, context, coord, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexGenxOESContextANGLE(GLeglContext ctx, GLenum coord, GLenum pname, GLfixed param)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexGenxOES, "glTexGenxOES",
          "context = %d, coord = %s, pname = %s, param = 0x%X", CID(context),
          GLenumToString(GLenumGroup::TextureCoordName, coord),
          GLenumToString(GLenumGroup::TextureGenParameter, pname), param);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateTexGenxOES(context, coord, pname, param));
        if (isCallValid)
        {
            context->texGenx(coord, pname, param);
        }
        ANGLE_CAPTURE(TexGenxOES, isCallValid, context, coord, pname, param);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexGenxvOESContextANGLE(GLeglContext ctx,
                                         GLenum coord,
                                         GLenum pname,
                                         const GLfixed *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexGenxvOES, "glTexGenxvOES",
          "context = %d, coord = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::TextureCoordName, coord),
          GLenumToString(GLenumGroup::TextureGenParameter, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateTexGenxvOES(context, coord, pname, params));
        if (isCallValid)
        {
            context->texGenxv(coord, pname, params);
        }
        ANGLE_CAPTURE(TexGenxvOES, isCallValid, context, coord, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexImage2DContextANGLE(GLeglContext ctx,
                                        GLenum target,
                                        GLint level,
                                        GLint internalformat,
                                        GLsizei width,
                                        GLsizei height,
                                        GLint border,
                                        GLenum format,
                                        GLenum type,
                                        const void *pixels)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexImage2D, "glTexImage2D",
          "context = %d, target = %s, level = %d, internalformat = %d, width = %d, height = %d, "
          "border = %d, format = %s, type = %s, pixels = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), level, internalformat,
          width, height, border, GLenumToString(GLenumGroup::PixelFormat, format),
          GLenumToString(GLenumGroup::PixelType, type), (uintptr_t)pixels);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateTexImage2D(context, targetPacked, level, internalformat, width,
                                               height, border, format, type, pixels));
        if (isCallValid)
        {
            context->texImage2D(targetPacked, level, internalformat, width, height, border, format,
                                type, pixels);
        }
        ANGLE_CAPTURE(TexImage2D, isCallValid, context, targetPacked, level, internalformat, width,
                      height, border, format, type, pixels);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexImage3DContextANGLE(GLeglContext ctx,
                                        GLenum target,
                                        GLint level,
                                        GLint internalformat,
                                        GLsizei width,
                                        GLsizei height,
                                        GLsizei depth,
                                        GLint border,
                                        GLenum format,
                                        GLenum type,
                                        const void *pixels)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexImage3D, "glTexImage3D",
          "context = %d, target = %s, level = %d, internalformat = %d, width = %d, height = %d, "
          "depth = %d, border = %d, format = %s, type = %s, pixels = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), level, internalformat,
          width, height, depth, border, GLenumToString(GLenumGroup::PixelFormat, format),
          GLenumToString(GLenumGroup::PixelType, type), (uintptr_t)pixels);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateTexImage3D(context, targetPacked, level, internalformat, width,
                                               height, depth, border, format, type, pixels));
        if (isCallValid)
        {
            context->texImage3D(targetPacked, level, internalformat, width, height, depth, border,
                                format, type, pixels);
        }
        ANGLE_CAPTURE(TexImage3D, isCallValid, context, targetPacked, level, internalformat, width,
                      height, depth, border, format, type, pixels);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexImage3DOESContextANGLE(GLeglContext ctx,
                                           GLenum target,
                                           GLint level,
                                           GLenum internalformat,
                                           GLsizei width,
                                           GLsizei height,
                                           GLsizei depth,
                                           GLint border,
                                           GLenum format,
                                           GLenum type,
                                           const void *pixels)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexImage3DOES, "glTexImage3DOES",
          "context = %d, target = %s, level = %d, internalformat = %s, width = %d, height = %d, "
          "depth = %d, border = %d, format = %s, type = %s, pixels = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), level,
          GLenumToString(GLenumGroup::InternalFormat, internalformat), width, height, depth, border,
          GLenumToString(GLenumGroup::PixelFormat, format),
          GLenumToString(GLenumGroup::PixelType, type), (uintptr_t)pixels);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTexImage3DOES(context, targetPacked, level, internalformat, width, height,
                                   depth, border, format, type, pixels));
        if (isCallValid)
        {
            context->texImage3D(targetPacked, level, internalformat, width, height, depth, border,
                                format, type, pixels);
        }
        ANGLE_CAPTURE(TexImage3DOES, isCallValid, context, targetPacked, level, internalformat,
                      width, height, depth, border, format, type, pixels);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexParameterIivContextANGLE(GLeglContext ctx,
                                             GLenum target,
                                             GLenum pname,
                                             const GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexParameterIiv, "glTexParameterIiv",
          "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::TextureTarget, target),
          GLenumToString(GLenumGroup::TextureParameterName, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateTexParameterIiv(context, targetPacked, pname, params));
        if (isCallValid)
        {
            context->texParameterIiv(targetPacked, pname, params);
        }
        ANGLE_CAPTURE(TexParameterIiv, isCallValid, context, targetPacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexParameterIivOESContextANGLE(GLeglContext ctx,
                                                GLenum target,
                                                GLenum pname,
                                                const GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexParameterIivOES, "glTexParameterIivOES",
          "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::TextureTarget, target),
          GLenumToString(GLenumGroup::TextureParameterName, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateTexParameterIivOES(context, targetPacked, pname, params));
        if (isCallValid)
        {
            context->texParameterIiv(targetPacked, pname, params);
        }
        ANGLE_CAPTURE(TexParameterIivOES, isCallValid, context, targetPacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexParameterIuivContextANGLE(GLeglContext ctx,
                                              GLenum target,
                                              GLenum pname,
                                              const GLuint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexParameterIuiv, "glTexParameterIuiv",
          "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::TextureTarget, target),
          GLenumToString(GLenumGroup::TextureParameterName, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateTexParameterIuiv(context, targetPacked, pname, params));
        if (isCallValid)
        {
            context->texParameterIuiv(targetPacked, pname, params);
        }
        ANGLE_CAPTURE(TexParameterIuiv, isCallValid, context, targetPacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexParameterIuivOESContextANGLE(GLeglContext ctx,
                                                 GLenum target,
                                                 GLenum pname,
                                                 const GLuint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexParameterIuivOES, "glTexParameterIuivOES",
          "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::TextureTarget, target),
          GLenumToString(GLenumGroup::TextureParameterName, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateTexParameterIuivOES(context, targetPacked, pname, params));
        if (isCallValid)
        {
            context->texParameterIuiv(targetPacked, pname, params);
        }
        ANGLE_CAPTURE(TexParameterIuivOES, isCallValid, context, targetPacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexParameterfContextANGLE(GLeglContext ctx,
                                           GLenum target,
                                           GLenum pname,
                                           GLfloat param)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexParameterf, "glTexParameterf",
          "context = %d, target = %s, pname = %s, param = %f", CID(context),
          GLenumToString(GLenumGroup::TextureTarget, target),
          GLenumToString(GLenumGroup::TextureParameterName, pname), param);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateTexParameterf(context, targetPacked, pname, param));
        if (isCallValid)
        {
            context->texParameterf(targetPacked, pname, param);
        }
        ANGLE_CAPTURE(TexParameterf, isCallValid, context, targetPacked, pname, param);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexParameterfvContextANGLE(GLeglContext ctx,
                                            GLenum target,
                                            GLenum pname,
                                            const GLfloat *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexParameterfv, "glTexParameterfv",
          "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::TextureTarget, target),
          GLenumToString(GLenumGroup::TextureParameterName, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateTexParameterfv(context, targetPacked, pname, params));
        if (isCallValid)
        {
            context->texParameterfv(targetPacked, pname, params);
        }
        ANGLE_CAPTURE(TexParameterfv, isCallValid, context, targetPacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexParameteriContextANGLE(GLeglContext ctx,
                                           GLenum target,
                                           GLenum pname,
                                           GLint param)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexParameteri, "glTexParameteri",
          "context = %d, target = %s, pname = %s, param = %d", CID(context),
          GLenumToString(GLenumGroup::TextureTarget, target),
          GLenumToString(GLenumGroup::TextureParameterName, pname), param);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateTexParameteri(context, targetPacked, pname, param));
        if (isCallValid)
        {
            context->texParameteri(targetPacked, pname, param);
        }
        ANGLE_CAPTURE(TexParameteri, isCallValid, context, targetPacked, pname, param);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexParameterivContextANGLE(GLeglContext ctx,
                                            GLenum target,
                                            GLenum pname,
                                            const GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexParameteriv, "glTexParameteriv",
          "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::TextureTarget, target),
          GLenumToString(GLenumGroup::TextureParameterName, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateTexParameteriv(context, targetPacked, pname, params));
        if (isCallValid)
        {
            context->texParameteriv(targetPacked, pname, params);
        }
        ANGLE_CAPTURE(TexParameteriv, isCallValid, context, targetPacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexParameterxContextANGLE(GLeglContext ctx,
                                           GLenum target,
                                           GLenum pname,
                                           GLfixed param)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexParameterx, "glTexParameterx",
          "context = %d, target = %s, pname = %s, param = 0x%X", CID(context),
          GLenumToString(GLenumGroup::TextureTarget, target),
          GLenumToString(GLenumGroup::GetTextureParameter, pname), param);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateTexParameterx(context, targetPacked, pname, param));
        if (isCallValid)
        {
            context->texParameterx(targetPacked, pname, param);
        }
        ANGLE_CAPTURE(TexParameterx, isCallValid, context, targetPacked, pname, param);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexParameterxvContextANGLE(GLeglContext ctx,
                                            GLenum target,
                                            GLenum pname,
                                            const GLfixed *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexParameterxv, "glTexParameterxv",
          "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::TextureTarget, target),
          GLenumToString(GLenumGroup::GetTextureParameter, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateTexParameterxv(context, targetPacked, pname, params));
        if (isCallValid)
        {
            context->texParameterxv(targetPacked, pname, params);
        }
        ANGLE_CAPTURE(TexParameterxv, isCallValid, context, targetPacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexStorage1DEXTContextANGLE(GLeglContext ctx,
                                             GLenum target,
                                             GLsizei levels,
                                             GLenum internalformat,
                                             GLsizei width)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexStorage1DEXT, "glTexStorage1DEXT",
          "context = %d, target = %s, levels = %d, internalformat = %s, width = %d", CID(context),
          GLenumToString(GLenumGroup::TextureTarget, target), levels,
          GLenumToString(GLenumGroup::InternalFormat, internalformat), width);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTexStorage1DEXT(context, target, levels, internalformat, width));
        if (isCallValid)
        {
            context->texStorage1D(target, levels, internalformat, width);
        }
        ANGLE_CAPTURE(TexStorage1DEXT, isCallValid, context, target, levels, internalformat, width);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexStorage2DContextANGLE(GLeglContext ctx,
                                          GLenum target,
                                          GLsizei levels,
                                          GLenum internalformat,
                                          GLsizei width,
                                          GLsizei height)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexStorage2D, "glTexStorage2D",
          "context = %d, target = %s, levels = %d, internalformat = %s, width = %d, height = %d",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), levels,
          GLenumToString(GLenumGroup::InternalFormat, internalformat), width, height);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTexStorage2D(context, targetPacked, levels, internalformat, width, height));
        if (isCallValid)
        {
            context->texStorage2D(targetPacked, levels, internalformat, width, height);
        }
        ANGLE_CAPTURE(TexStorage2D, isCallValid, context, targetPacked, levels, internalformat,
                      width, height);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexStorage2DEXTContextANGLE(GLeglContext ctx,
                                             GLenum target,
                                             GLsizei levels,
                                             GLenum internalformat,
                                             GLsizei width,
                                             GLsizei height)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexStorage2DEXT, "glTexStorage2DEXT",
          "context = %d, target = %s, levels = %d, internalformat = %s, width = %d, height = %d",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), levels,
          GLenumToString(GLenumGroup::InternalFormat, internalformat), width, height);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTexStorage2DEXT(context, targetPacked, levels, internalformat, width, height));
        if (isCallValid)
        {
            context->texStorage2D(targetPacked, levels, internalformat, width, height);
        }
        ANGLE_CAPTURE(TexStorage2DEXT, isCallValid, context, targetPacked, levels, internalformat,
                      width, height);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexStorage2DMultisampleContextANGLE(GLeglContext ctx,
                                                     GLenum target,
                                                     GLsizei samples,
                                                     GLenum internalformat,
                                                     GLsizei width,
                                                     GLsizei height,
                                                     GLboolean fixedsamplelocations)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexStorage2DMultisample, "glTexStorage2DMultisample",
          "context = %d, target = %s, samples = %d, internalformat = %s, width = %d, height = %d, "
          "fixedsamplelocations = %s",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), samples,
          GLenumToString(GLenumGroup::InternalFormat, internalformat), width, height,
          GLbooleanToString(fixedsamplelocations));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTexStorage2DMultisample(context, targetPacked, samples, internalformat, width,
                                             height, fixedsamplelocations));
        if (isCallValid)
        {
            context->texStorage2DMultisample(targetPacked, samples, internalformat, width, height,
                                             fixedsamplelocations);
        }
        ANGLE_CAPTURE(TexStorage2DMultisample, isCallValid, context, targetPacked, samples,
                      internalformat, width, height, fixedsamplelocations);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexStorage3DContextANGLE(GLeglContext ctx,
                                          GLenum target,
                                          GLsizei levels,
                                          GLenum internalformat,
                                          GLsizei width,
                                          GLsizei height,
                                          GLsizei depth)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexStorage3D, "glTexStorage3D",
          "context = %d, target = %s, levels = %d, internalformat = %s, width = %d, height = %d, "
          "depth = %d",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), levels,
          GLenumToString(GLenumGroup::InternalFormat, internalformat), width, height, depth);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateTexStorage3D(context, targetPacked, levels, internalformat,
                                                 width, height, depth));
        if (isCallValid)
        {
            context->texStorage3D(targetPacked, levels, internalformat, width, height, depth);
        }
        ANGLE_CAPTURE(TexStorage3D, isCallValid, context, targetPacked, levels, internalformat,
                      width, height, depth);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexStorage3DEXTContextANGLE(GLeglContext ctx,
                                             GLenum target,
                                             GLsizei levels,
                                             GLenum internalformat,
                                             GLsizei width,
                                             GLsizei height,
                                             GLsizei depth)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexStorage3DEXT, "glTexStorage3DEXT",
          "context = %d, target = %s, levels = %d, internalformat = %s, width = %d, height = %d, "
          "depth = %d",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), levels,
          GLenumToString(GLenumGroup::InternalFormat, internalformat), width, height, depth);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateTexStorage3DEXT(context, targetPacked, levels, internalformat,
                                                    width, height, depth));
        if (isCallValid)
        {
            context->texStorage3D(targetPacked, levels, internalformat, width, height, depth);
        }
        ANGLE_CAPTURE(TexStorage3DEXT, isCallValid, context, targetPacked, levels, internalformat,
                      width, height, depth);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexStorage3DMultisampleContextANGLE(GLeglContext ctx,
                                                     GLenum target,
                                                     GLsizei samples,
                                                     GLenum internalformat,
                                                     GLsizei width,
                                                     GLsizei height,
                                                     GLsizei depth,
                                                     GLboolean fixedsamplelocations)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexStorage3DMultisample, "glTexStorage3DMultisample",
          "context = %d, target = %s, samples = %d, internalformat = %s, width = %d, height = %d, "
          "depth = %d, fixedsamplelocations = %s",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), samples,
          GLenumToString(GLenumGroup::InternalFormat, internalformat), width, height, depth,
          GLbooleanToString(fixedsamplelocations));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTexStorage3DMultisample(context, targetPacked, samples, internalformat, width,
                                             height, depth, fixedsamplelocations));
        if (isCallValid)
        {
            context->texStorage3DMultisample(targetPacked, samples, internalformat, width, height,
                                             depth, fixedsamplelocations);
        }
        ANGLE_CAPTURE(TexStorage3DMultisample, isCallValid, context, targetPacked, samples,
                      internalformat, width, height, depth, fixedsamplelocations);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexStorage3DMultisampleOESContextANGLE(GLeglContext ctx,
                                                        GLenum target,
                                                        GLsizei samples,
                                                        GLenum internalformat,
                                                        GLsizei width,
                                                        GLsizei height,
                                                        GLsizei depth,
                                                        GLboolean fixedsamplelocations)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexStorage3DMultisampleOES, "glTexStorage3DMultisampleOES",
          "context = %d, target = %s, samples = %d, internalformat = %s, width = %d, height = %d, "
          "depth = %d, fixedsamplelocations = %s",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), samples,
          GLenumToString(GLenumGroup::InternalFormat, internalformat), width, height, depth,
          GLbooleanToString(fixedsamplelocations));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTexStorage3DMultisampleOES(context, targetPacked, samples, internalformat,
                                                width, height, depth, fixedsamplelocations));
        if (isCallValid)
        {
            context->texStorage3DMultisample(targetPacked, samples, internalformat, width, height,
                                             depth, fixedsamplelocations);
        }
        ANGLE_CAPTURE(TexStorage3DMultisampleOES, isCallValid, context, targetPacked, samples,
                      internalformat, width, height, depth, fixedsamplelocations);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexStorageMem2DEXTContextANGLE(GLeglContext ctx,
                                                GLenum target,
                                                GLsizei levels,
                                                GLenum internalFormat,
                                                GLsizei width,
                                                GLsizei height,
                                                GLuint memory,
                                                GLuint64 offset)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexStorageMem2DEXT, "glTexStorageMem2DEXT",
          "context = %d, target = %s, levels = %d, internalFormat = %s, width = %d, height = %d, "
          "memory = %u, offset = %llu",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), levels,
          GLenumToString(GLenumGroup::DefaultGroup, internalFormat), width, height, memory,
          static_cast<unsigned long long>(offset));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        MemoryObjectID memoryPacked                           = FromGL<MemoryObjectID>(memory);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTexStorageMem2DEXT(context, targetPacked, levels, internalFormat, width,
                                        height, memoryPacked, offset));
        if (isCallValid)
        {
            context->texStorageMem2D(targetPacked, levels, internalFormat, width, height,
                                     memoryPacked, offset);
        }
        ANGLE_CAPTURE(TexStorageMem2DEXT, isCallValid, context, targetPacked, levels,
                      internalFormat, width, height, memoryPacked, offset);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexStorageMem2DMultisampleEXTContextANGLE(GLeglContext ctx,
                                                           GLenum target,
                                                           GLsizei samples,
                                                           GLenum internalFormat,
                                                           GLsizei width,
                                                           GLsizei height,
                                                           GLboolean fixedSampleLocations,
                                                           GLuint memory,
                                                           GLuint64 offset)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexStorageMem2DMultisampleEXT, "glTexStorageMem2DMultisampleEXT",
          "context = %d, target = %s, samples = %d, internalFormat = %s, width = %d, height = %d, "
          "fixedSampleLocations = %s, memory = %u, offset = %llu",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), samples,
          GLenumToString(GLenumGroup::DefaultGroup, internalFormat), width, height,
          GLbooleanToString(fixedSampleLocations), memory, static_cast<unsigned long long>(offset));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        MemoryObjectID memoryPacked                           = FromGL<MemoryObjectID>(memory);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateTexStorageMem2DMultisampleEXT(
                                              context, targetPacked, samples, internalFormat, width,
                                              height, fixedSampleLocations, memoryPacked, offset));
        if (isCallValid)
        {
            context->texStorageMem2DMultisample(targetPacked, samples, internalFormat, width,
                                                height, fixedSampleLocations, memoryPacked, offset);
        }
        ANGLE_CAPTURE(TexStorageMem2DMultisampleEXT, isCallValid, context, targetPacked, samples,
                      internalFormat, width, height, fixedSampleLocations, memoryPacked, offset);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexStorageMem3DEXTContextANGLE(GLeglContext ctx,
                                                GLenum target,
                                                GLsizei levels,
                                                GLenum internalFormat,
                                                GLsizei width,
                                                GLsizei height,
                                                GLsizei depth,
                                                GLuint memory,
                                                GLuint64 offset)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexStorageMem3DEXT, "glTexStorageMem3DEXT",
          "context = %d, target = %s, levels = %d, internalFormat = %s, width = %d, height = %d, "
          "depth = %d, memory = %u, offset = %llu",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), levels,
          GLenumToString(GLenumGroup::DefaultGroup, internalFormat), width, height, depth, memory,
          static_cast<unsigned long long>(offset));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        MemoryObjectID memoryPacked                           = FromGL<MemoryObjectID>(memory);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTexStorageMem3DEXT(context, targetPacked, levels, internalFormat, width,
                                        height, depth, memoryPacked, offset));
        if (isCallValid)
        {
            context->texStorageMem3D(targetPacked, levels, internalFormat, width, height, depth,
                                     memoryPacked, offset);
        }
        ANGLE_CAPTURE(TexStorageMem3DEXT, isCallValid, context, targetPacked, levels,
                      internalFormat, width, height, depth, memoryPacked, offset);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexStorageMem3DMultisampleEXTContextANGLE(GLeglContext ctx,
                                                           GLenum target,
                                                           GLsizei samples,
                                                           GLenum internalFormat,
                                                           GLsizei width,
                                                           GLsizei height,
                                                           GLsizei depth,
                                                           GLboolean fixedSampleLocations,
                                                           GLuint memory,
                                                           GLuint64 offset)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexStorageMem3DMultisampleEXT, "glTexStorageMem3DMultisampleEXT",
          "context = %d, target = %s, samples = %d, internalFormat = %s, width = %d, height = %d, "
          "depth = %d, fixedSampleLocations = %s, memory = %u, offset = %llu",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), samples,
          GLenumToString(GLenumGroup::DefaultGroup, internalFormat), width, height, depth,
          GLbooleanToString(fixedSampleLocations), memory, static_cast<unsigned long long>(offset));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        MemoryObjectID memoryPacked                           = FromGL<MemoryObjectID>(memory);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateTexStorageMem3DMultisampleEXT(
                                context, targetPacked, samples, internalFormat, width, height,
                                depth, fixedSampleLocations, memoryPacked, offset));
        if (isCallValid)
        {
            context->texStorageMem3DMultisample(targetPacked, samples, internalFormat, width,
                                                height, depth, fixedSampleLocations, memoryPacked,
                                                offset);
        }
        ANGLE_CAPTURE(TexStorageMem3DMultisampleEXT, isCallValid, context, targetPacked, samples,
                      internalFormat, width, height, depth, fixedSampleLocations, memoryPacked,
                      offset);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexSubImage2DContextANGLE(GLeglContext ctx,
                                           GLenum target,
                                           GLint level,
                                           GLint xoffset,
                                           GLint yoffset,
                                           GLsizei width,
                                           GLsizei height,
                                           GLenum format,
                                           GLenum type,
                                           const void *pixels)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexSubImage2D, "glTexSubImage2D",
          "context = %d, target = %s, level = %d, xoffset = %d, yoffset = %d, width = %d, height = "
          "%d, format = %s, type = %s, pixels = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), level, xoffset, yoffset,
          width, height, GLenumToString(GLenumGroup::PixelFormat, format),
          GLenumToString(GLenumGroup::PixelType, type), (uintptr_t)pixels);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateTexSubImage2D(context, targetPacked, level, xoffset, yoffset,
                                                  width, height, format, type, pixels));
        if (isCallValid)
        {
            context->texSubImage2D(targetPacked, level, xoffset, yoffset, width, height, format,
                                   type, pixels);
        }
        ANGLE_CAPTURE(TexSubImage2D, isCallValid, context, targetPacked, level, xoffset, yoffset,
                      width, height, format, type, pixels);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexSubImage3DContextANGLE(GLeglContext ctx,
                                           GLenum target,
                                           GLint level,
                                           GLint xoffset,
                                           GLint yoffset,
                                           GLint zoffset,
                                           GLsizei width,
                                           GLsizei height,
                                           GLsizei depth,
                                           GLenum format,
                                           GLenum type,
                                           const void *pixels)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexSubImage3D, "glTexSubImage3D",
          "context = %d, target = %s, level = %d, xoffset = %d, yoffset = %d, zoffset = %d, width "
          "= %d, height = %d, depth = %d, format = %s, type = %s, pixels = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), level, xoffset, yoffset,
          zoffset, width, height, depth, GLenumToString(GLenumGroup::PixelFormat, format),
          GLenumToString(GLenumGroup::PixelType, type), (uintptr_t)pixels);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTexSubImage3D(context, targetPacked, level, xoffset, yoffset, zoffset, width,
                                   height, depth, format, type, pixels));
        if (isCallValid)
        {
            context->texSubImage3D(targetPacked, level, xoffset, yoffset, zoffset, width, height,
                                   depth, format, type, pixels);
        }
        ANGLE_CAPTURE(TexSubImage3D, isCallValid, context, targetPacked, level, xoffset, yoffset,
                      zoffset, width, height, depth, format, type, pixels);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexSubImage3DOESContextANGLE(GLeglContext ctx,
                                              GLenum target,
                                              GLint level,
                                              GLint xoffset,
                                              GLint yoffset,
                                              GLint zoffset,
                                              GLsizei width,
                                              GLsizei height,
                                              GLsizei depth,
                                              GLenum format,
                                              GLenum type,
                                              const void *pixels)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexSubImage3DOES, "glTexSubImage3DOES",
          "context = %d, target = %s, level = %d, xoffset = %d, yoffset = %d, zoffset = %d, width "
          "= %d, height = %d, depth = %d, format = %s, type = %s, pixels = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), level, xoffset, yoffset,
          zoffset, width, height, depth, GLenumToString(GLenumGroup::PixelFormat, format),
          GLenumToString(GLenumGroup::PixelType, type), (uintptr_t)pixels);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTexSubImage3DOES(context, targetPacked, level, xoffset, yoffset, zoffset,
                                      width, height, depth, format, type, pixels));
        if (isCallValid)
        {
            context->texSubImage3D(targetPacked, level, xoffset, yoffset, zoffset, width, height,
                                   depth, format, type, pixels);
        }
        ANGLE_CAPTURE(TexSubImage3DOES, isCallValid, context, targetPacked, level, xoffset, yoffset,
                      zoffset, width, height, depth, format, type, pixels);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TransformFeedbackVaryingsContextANGLE(GLeglContext ctx,
                                                       GLuint program,
                                                       GLsizei count,
                                                       const GLchar *const *varyings,
                                                       GLenum bufferMode)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TransformFeedbackVaryings, "glTransformFeedbackVaryings",
          "context = %d, program = %u, count = %d, varyings = 0x%016" PRIxPTR ", bufferMode = %s",
          CID(context), program, count, (uintptr_t)varyings,
          GLenumToString(GLenumGroup::DefaultGroup, bufferMode));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateTransformFeedbackVaryings(
                                              context, programPacked, count, varyings, bufferMode));
        if (isCallValid)
        {
            context->transformFeedbackVaryings(programPacked, count, varyings, bufferMode);
        }
        ANGLE_CAPTURE(TransformFeedbackVaryings, isCallValid, context, programPacked, count,
                      varyings, bufferMode);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TranslatefContextANGLE(GLeglContext ctx, GLfloat x, GLfloat y, GLfloat z)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Translatef, "glTranslatef",
          "context = %d, x = %f, y = %f, z = %f", CID(context), x, y, z);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateTranslatef(context, x, y, z));
        if (isCallValid)
        {
            context->translatef(x, y, z);
        }
        ANGLE_CAPTURE(Translatef, isCallValid, context, x, y, z);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TranslatexContextANGLE(GLeglContext ctx, GLfixed x, GLfixed y, GLfixed z)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Translatex, "glTranslatex",
          "context = %d, x = 0x%X, y = 0x%X, z = 0x%X", CID(context), x, y, z);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateTranslatex(context, x, y, z));
        if (isCallValid)
        {
            context->translatex(x, y, z);
        }
        ANGLE_CAPTURE(Translatex, isCallValid, context, x, y, z);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY Uniform1fContextANGLE(GLeglContext ctx, GLint location, GLfloat v0)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Uniform1f, "glUniform1f", "context = %d, location = %d, v0 = %f",
          CID(context), location, v0);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateUniform1f(context, locationPacked, v0));
        if (isCallValid)
        {
            context->uniform1f(locationPacked, v0);
        }
        ANGLE_CAPTURE(Uniform1f, isCallValid, context, locationPacked, v0);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY Uniform1fvContextANGLE(GLeglContext ctx,
                                        GLint location,
                                        GLsizei count,
                                        const GLfloat *value)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Uniform1fv, "glUniform1fv",
          "context = %d, location = %d, count = %d, value = 0x%016" PRIxPTR "", CID(context),
          location, count, (uintptr_t)value);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateUniform1fv(context, locationPacked, count, value));
        if (isCallValid)
        {
            context->uniform1fv(locationPacked, count, value);
        }
        ANGLE_CAPTURE(Uniform1fv, isCallValid, context, locationPacked, count, value);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY Uniform1iContextANGLE(GLeglContext ctx, GLint location, GLint v0)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Uniform1i, "glUniform1i", "context = %d, location = %d, v0 = %d",
          CID(context), location, v0);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateUniform1i(context, locationPacked, v0));
        if (isCallValid)
        {
            context->uniform1i(locationPacked, v0);
        }
        ANGLE_CAPTURE(Uniform1i, isCallValid, context, locationPacked, v0);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY Uniform1ivContextANGLE(GLeglContext ctx,
                                        GLint location,
                                        GLsizei count,
                                        const GLint *value)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Uniform1iv, "glUniform1iv",
          "context = %d, location = %d, count = %d, value = 0x%016" PRIxPTR "", CID(context),
          location, count, (uintptr_t)value);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateUniform1iv(context, locationPacked, count, value));
        if (isCallValid)
        {
            context->uniform1iv(locationPacked, count, value);
        }
        ANGLE_CAPTURE(Uniform1iv, isCallValid, context, locationPacked, count, value);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY Uniform1uiContextANGLE(GLeglContext ctx, GLint location, GLuint v0)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Uniform1ui, "glUniform1ui",
          "context = %d, location = %d, v0 = %u", CID(context), location, v0);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateUniform1ui(context, locationPacked, v0));
        if (isCallValid)
        {
            context->uniform1ui(locationPacked, v0);
        }
        ANGLE_CAPTURE(Uniform1ui, isCallValid, context, locationPacked, v0);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY Uniform1uivContextANGLE(GLeglContext ctx,
                                         GLint location,
                                         GLsizei count,
                                         const GLuint *value)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Uniform1uiv, "glUniform1uiv",
          "context = %d, location = %d, count = %d, value = 0x%016" PRIxPTR "", CID(context),
          location, count, (uintptr_t)value);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateUniform1uiv(context, locationPacked, count, value));
        if (isCallValid)
        {
            context->uniform1uiv(locationPacked, count, value);
        }
        ANGLE_CAPTURE(Uniform1uiv, isCallValid, context, locationPacked, count, value);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY Uniform2fContextANGLE(GLeglContext ctx, GLint location, GLfloat v0, GLfloat v1)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Uniform2f, "glUniform2f",
          "context = %d, location = %d, v0 = %f, v1 = %f", CID(context), location, v0, v1);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateUniform2f(context, locationPacked, v0, v1));
        if (isCallValid)
        {
            context->uniform2f(locationPacked, v0, v1);
        }
        ANGLE_CAPTURE(Uniform2f, isCallValid, context, locationPacked, v0, v1);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY Uniform2fvContextANGLE(GLeglContext ctx,
                                        GLint location,
                                        GLsizei count,
                                        const GLfloat *value)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Uniform2fv, "glUniform2fv",
          "context = %d, location = %d, count = %d, value = 0x%016" PRIxPTR "", CID(context),
          location, count, (uintptr_t)value);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateUniform2fv(context, locationPacked, count, value));
        if (isCallValid)
        {
            context->uniform2fv(locationPacked, count, value);
        }
        ANGLE_CAPTURE(Uniform2fv, isCallValid, context, locationPacked, count, value);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY Uniform2iContextANGLE(GLeglContext ctx, GLint location, GLint v0, GLint v1)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Uniform2i, "glUniform2i",
          "context = %d, location = %d, v0 = %d, v1 = %d", CID(context), location, v0, v1);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateUniform2i(context, locationPacked, v0, v1));
        if (isCallValid)
        {
            context->uniform2i(locationPacked, v0, v1);
        }
        ANGLE_CAPTURE(Uniform2i, isCallValid, context, locationPacked, v0, v1);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY Uniform2ivContextANGLE(GLeglContext ctx,
                                        GLint location,
                                        GLsizei count,
                                        const GLint *value)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Uniform2iv, "glUniform2iv",
          "context = %d, location = %d, count = %d, value = 0x%016" PRIxPTR "", CID(context),
          location, count, (uintptr_t)value);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateUniform2iv(context, locationPacked, count, value));
        if (isCallValid)
        {
            context->uniform2iv(locationPacked, count, value);
        }
        ANGLE_CAPTURE(Uniform2iv, isCallValid, context, locationPacked, count, value);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY Uniform2uiContextANGLE(GLeglContext ctx, GLint location, GLuint v0, GLuint v1)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Uniform2ui, "glUniform2ui",
          "context = %d, location = %d, v0 = %u, v1 = %u", CID(context), location, v0, v1);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateUniform2ui(context, locationPacked, v0, v1));
        if (isCallValid)
        {
            context->uniform2ui(locationPacked, v0, v1);
        }
        ANGLE_CAPTURE(Uniform2ui, isCallValid, context, locationPacked, v0, v1);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY Uniform2uivContextANGLE(GLeglContext ctx,
                                         GLint location,
                                         GLsizei count,
                                         const GLuint *value)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Uniform2uiv, "glUniform2uiv",
          "context = %d, location = %d, count = %d, value = 0x%016" PRIxPTR "", CID(context),
          location, count, (uintptr_t)value);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateUniform2uiv(context, locationPacked, count, value));
        if (isCallValid)
        {
            context->uniform2uiv(locationPacked, count, value);
        }
        ANGLE_CAPTURE(Uniform2uiv, isCallValid, context, locationPacked, count, value);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY
Uniform3fContextANGLE(GLeglContext ctx, GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Uniform3f, "glUniform3f",
          "context = %d, location = %d, v0 = %f, v1 = %f, v2 = %f", CID(context), location, v0, v1,
          v2);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateUniform3f(context, locationPacked, v0, v1, v2));
        if (isCallValid)
        {
            context->uniform3f(locationPacked, v0, v1, v2);
        }
        ANGLE_CAPTURE(Uniform3f, isCallValid, context, locationPacked, v0, v1, v2);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY Uniform3fvContextANGLE(GLeglContext ctx,
                                        GLint location,
                                        GLsizei count,
                                        const GLfloat *value)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Uniform3fv, "glUniform3fv",
          "context = %d, location = %d, count = %d, value = 0x%016" PRIxPTR "", CID(context),
          location, count, (uintptr_t)value);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateUniform3fv(context, locationPacked, count, value));
        if (isCallValid)
        {
            context->uniform3fv(locationPacked, count, value);
        }
        ANGLE_CAPTURE(Uniform3fv, isCallValid, context, locationPacked, count, value);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY
Uniform3iContextANGLE(GLeglContext ctx, GLint location, GLint v0, GLint v1, GLint v2)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Uniform3i, "glUniform3i",
          "context = %d, location = %d, v0 = %d, v1 = %d, v2 = %d", CID(context), location, v0, v1,
          v2);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateUniform3i(context, locationPacked, v0, v1, v2));
        if (isCallValid)
        {
            context->uniform3i(locationPacked, v0, v1, v2);
        }
        ANGLE_CAPTURE(Uniform3i, isCallValid, context, locationPacked, v0, v1, v2);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY Uniform3ivContextANGLE(GLeglContext ctx,
                                        GLint location,
                                        GLsizei count,
                                        const GLint *value)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Uniform3iv, "glUniform3iv",
          "context = %d, location = %d, count = %d, value = 0x%016" PRIxPTR "", CID(context),
          location, count, (uintptr_t)value);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateUniform3iv(context, locationPacked, count, value));
        if (isCallValid)
        {
            context->uniform3iv(locationPacked, count, value);
        }
        ANGLE_CAPTURE(Uniform3iv, isCallValid, context, locationPacked, count, value);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY
Uniform3uiContextANGLE(GLeglContext ctx, GLint location, GLuint v0, GLuint v1, GLuint v2)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Uniform3ui, "glUniform3ui",
          "context = %d, location = %d, v0 = %u, v1 = %u, v2 = %u", CID(context), location, v0, v1,
          v2);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateUniform3ui(context, locationPacked, v0, v1, v2));
        if (isCallValid)
        {
            context->uniform3ui(locationPacked, v0, v1, v2);
        }
        ANGLE_CAPTURE(Uniform3ui, isCallValid, context, locationPacked, v0, v1, v2);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY Uniform3uivContextANGLE(GLeglContext ctx,
                                         GLint location,
                                         GLsizei count,
                                         const GLuint *value)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Uniform3uiv, "glUniform3uiv",
          "context = %d, location = %d, count = %d, value = 0x%016" PRIxPTR "", CID(context),
          location, count, (uintptr_t)value);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateUniform3uiv(context, locationPacked, count, value));
        if (isCallValid)
        {
            context->uniform3uiv(locationPacked, count, value);
        }
        ANGLE_CAPTURE(Uniform3uiv, isCallValid, context, locationPacked, count, value);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY Uniform4fContextANGLE(GLeglContext ctx,
                                       GLint location,
                                       GLfloat v0,
                                       GLfloat v1,
                                       GLfloat v2,
                                       GLfloat v3)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Uniform4f, "glUniform4f",
          "context = %d, location = %d, v0 = %f, v1 = %f, v2 = %f, v3 = %f", CID(context), location,
          v0, v1, v2, v3);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateUniform4f(context, locationPacked, v0, v1, v2, v3));
        if (isCallValid)
        {
            context->uniform4f(locationPacked, v0, v1, v2, v3);
        }
        ANGLE_CAPTURE(Uniform4f, isCallValid, context, locationPacked, v0, v1, v2, v3);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY Uniform4fvContextANGLE(GLeglContext ctx,
                                        GLint location,
                                        GLsizei count,
                                        const GLfloat *value)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Uniform4fv, "glUniform4fv",
          "context = %d, location = %d, count = %d, value = 0x%016" PRIxPTR "", CID(context),
          location, count, (uintptr_t)value);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateUniform4fv(context, locationPacked, count, value));
        if (isCallValid)
        {
            context->uniform4fv(locationPacked, count, value);
        }
        ANGLE_CAPTURE(Uniform4fv, isCallValid, context, locationPacked, count, value);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY
Uniform4iContextANGLE(GLeglContext ctx, GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Uniform4i, "glUniform4i",
          "context = %d, location = %d, v0 = %d, v1 = %d, v2 = %d, v3 = %d", CID(context), location,
          v0, v1, v2, v3);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateUniform4i(context, locationPacked, v0, v1, v2, v3));
        if (isCallValid)
        {
            context->uniform4i(locationPacked, v0, v1, v2, v3);
        }
        ANGLE_CAPTURE(Uniform4i, isCallValid, context, locationPacked, v0, v1, v2, v3);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY Uniform4ivContextANGLE(GLeglContext ctx,
                                        GLint location,
                                        GLsizei count,
                                        const GLint *value)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Uniform4iv, "glUniform4iv",
          "context = %d, location = %d, count = %d, value = 0x%016" PRIxPTR "", CID(context),
          location, count, (uintptr_t)value);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateUniform4iv(context, locationPacked, count, value));
        if (isCallValid)
        {
            context->uniform4iv(locationPacked, count, value);
        }
        ANGLE_CAPTURE(Uniform4iv, isCallValid, context, locationPacked, count, value);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY
Uniform4uiContextANGLE(GLeglContext ctx, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Uniform4ui, "glUniform4ui",
          "context = %d, location = %d, v0 = %u, v1 = %u, v2 = %u, v3 = %u", CID(context), location,
          v0, v1, v2, v3);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateUniform4ui(context, locationPacked, v0, v1, v2, v3));
        if (isCallValid)
        {
            context->uniform4ui(locationPacked, v0, v1, v2, v3);
        }
        ANGLE_CAPTURE(Uniform4ui, isCallValid, context, locationPacked, v0, v1, v2, v3);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY Uniform4uivContextANGLE(GLeglContext ctx,
                                         GLint location,
                                         GLsizei count,
                                         const GLuint *value)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Uniform4uiv, "glUniform4uiv",
          "context = %d, location = %d, count = %d, value = 0x%016" PRIxPTR "", CID(context),
          location, count, (uintptr_t)value);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateUniform4uiv(context, locationPacked, count, value));
        if (isCallValid)
        {
            context->uniform4uiv(locationPacked, count, value);
        }
        ANGLE_CAPTURE(Uniform4uiv, isCallValid, context, locationPacked, count, value);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY UniformBlockBindingContextANGLE(GLeglContext ctx,
                                                 GLuint program,
                                                 GLuint uniformBlockIndex,
                                                 GLuint uniformBlockBinding)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::UniformBlockBinding, "glUniformBlockBinding",
          "context = %d, program = %u, uniformBlockIndex = %u, uniformBlockBinding = %u",
          CID(context), program, uniformBlockIndex, uniformBlockBinding);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateUniformBlockBinding(context, programPacked, uniformBlockIndex,
                                                        uniformBlockBinding));
        if (isCallValid)
        {
            context->uniformBlockBinding(programPacked, uniformBlockIndex, uniformBlockBinding);
        }
        ANGLE_CAPTURE(UniformBlockBinding, isCallValid, context, programPacked, uniformBlockIndex,
                      uniformBlockBinding);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY UniformMatrix2fvContextANGLE(GLeglContext ctx,
                                              GLint location,
                                              GLsizei count,
                                              GLboolean transpose,
                                              const GLfloat *value)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::UniformMatrix2fv, "glUniformMatrix2fv",
          "context = %d, location = %d, count = %d, transpose = %s, value = 0x%016" PRIxPTR "",
          CID(context), location, count, GLbooleanToString(transpose), (uintptr_t)value);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateUniformMatrix2fv(context, locationPacked, count, transpose, value));
        if (isCallValid)
        {
            context->uniformMatrix2fv(locationPacked, count, transpose, value);
        }
        ANGLE_CAPTURE(UniformMatrix2fv, isCallValid, context, locationPacked, count, transpose,
                      value);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY UniformMatrix2x3fvContextANGLE(GLeglContext ctx,
                                                GLint location,
                                                GLsizei count,
                                                GLboolean transpose,
                                                const GLfloat *value)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::UniformMatrix2x3fv, "glUniformMatrix2x3fv",
          "context = %d, location = %d, count = %d, transpose = %s, value = 0x%016" PRIxPTR "",
          CID(context), location, count, GLbooleanToString(transpose), (uintptr_t)value);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateUniformMatrix2x3fv(context, locationPacked, count, transpose, value));
        if (isCallValid)
        {
            context->uniformMatrix2x3fv(locationPacked, count, transpose, value);
        }
        ANGLE_CAPTURE(UniformMatrix2x3fv, isCallValid, context, locationPacked, count, transpose,
                      value);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY UniformMatrix2x4fvContextANGLE(GLeglContext ctx,
                                                GLint location,
                                                GLsizei count,
                                                GLboolean transpose,
                                                const GLfloat *value)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::UniformMatrix2x4fv, "glUniformMatrix2x4fv",
          "context = %d, location = %d, count = %d, transpose = %s, value = 0x%016" PRIxPTR "",
          CID(context), location, count, GLbooleanToString(transpose), (uintptr_t)value);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateUniformMatrix2x4fv(context, locationPacked, count, transpose, value));
        if (isCallValid)
        {
            context->uniformMatrix2x4fv(locationPacked, count, transpose, value);
        }
        ANGLE_CAPTURE(UniformMatrix2x4fv, isCallValid, context, locationPacked, count, transpose,
                      value);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY UniformMatrix3fvContextANGLE(GLeglContext ctx,
                                              GLint location,
                                              GLsizei count,
                                              GLboolean transpose,
                                              const GLfloat *value)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::UniformMatrix3fv, "glUniformMatrix3fv",
          "context = %d, location = %d, count = %d, transpose = %s, value = 0x%016" PRIxPTR "",
          CID(context), location, count, GLbooleanToString(transpose), (uintptr_t)value);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateUniformMatrix3fv(context, locationPacked, count, transpose, value));
        if (isCallValid)
        {
            context->uniformMatrix3fv(locationPacked, count, transpose, value);
        }
        ANGLE_CAPTURE(UniformMatrix3fv, isCallValid, context, locationPacked, count, transpose,
                      value);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY UniformMatrix3x2fvContextANGLE(GLeglContext ctx,
                                                GLint location,
                                                GLsizei count,
                                                GLboolean transpose,
                                                const GLfloat *value)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::UniformMatrix3x2fv, "glUniformMatrix3x2fv",
          "context = %d, location = %d, count = %d, transpose = %s, value = 0x%016" PRIxPTR "",
          CID(context), location, count, GLbooleanToString(transpose), (uintptr_t)value);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateUniformMatrix3x2fv(context, locationPacked, count, transpose, value));
        if (isCallValid)
        {
            context->uniformMatrix3x2fv(locationPacked, count, transpose, value);
        }
        ANGLE_CAPTURE(UniformMatrix3x2fv, isCallValid, context, locationPacked, count, transpose,
                      value);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY UniformMatrix3x4fvContextANGLE(GLeglContext ctx,
                                                GLint location,
                                                GLsizei count,
                                                GLboolean transpose,
                                                const GLfloat *value)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::UniformMatrix3x4fv, "glUniformMatrix3x4fv",
          "context = %d, location = %d, count = %d, transpose = %s, value = 0x%016" PRIxPTR "",
          CID(context), location, count, GLbooleanToString(transpose), (uintptr_t)value);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateUniformMatrix3x4fv(context, locationPacked, count, transpose, value));
        if (isCallValid)
        {
            context->uniformMatrix3x4fv(locationPacked, count, transpose, value);
        }
        ANGLE_CAPTURE(UniformMatrix3x4fv, isCallValid, context, locationPacked, count, transpose,
                      value);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY UniformMatrix4fvContextANGLE(GLeglContext ctx,
                                              GLint location,
                                              GLsizei count,
                                              GLboolean transpose,
                                              const GLfloat *value)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::UniformMatrix4fv, "glUniformMatrix4fv",
          "context = %d, location = %d, count = %d, transpose = %s, value = 0x%016" PRIxPTR "",
          CID(context), location, count, GLbooleanToString(transpose), (uintptr_t)value);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateUniformMatrix4fv(context, locationPacked, count, transpose, value));
        if (isCallValid)
        {
            context->uniformMatrix4fv(locationPacked, count, transpose, value);
        }
        ANGLE_CAPTURE(UniformMatrix4fv, isCallValid, context, locationPacked, count, transpose,
                      value);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY UniformMatrix4x2fvContextANGLE(GLeglContext ctx,
                                                GLint location,
                                                GLsizei count,
                                                GLboolean transpose,
                                                const GLfloat *value)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::UniformMatrix4x2fv, "glUniformMatrix4x2fv",
          "context = %d, location = %d, count = %d, transpose = %s, value = 0x%016" PRIxPTR "",
          CID(context), location, count, GLbooleanToString(transpose), (uintptr_t)value);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateUniformMatrix4x2fv(context, locationPacked, count, transpose, value));
        if (isCallValid)
        {
            context->uniformMatrix4x2fv(locationPacked, count, transpose, value);
        }
        ANGLE_CAPTURE(UniformMatrix4x2fv, isCallValid, context, locationPacked, count, transpose,
                      value);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY UniformMatrix4x3fvContextANGLE(GLeglContext ctx,
                                                GLint location,
                                                GLsizei count,
                                                GLboolean transpose,
                                                const GLfloat *value)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::UniformMatrix4x3fv, "glUniformMatrix4x3fv",
          "context = %d, location = %d, count = %d, transpose = %s, value = 0x%016" PRIxPTR "",
          CID(context), location, count, GLbooleanToString(transpose), (uintptr_t)value);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateUniformMatrix4x3fv(context, locationPacked, count, transpose, value));
        if (isCallValid)
        {
            context->uniformMatrix4x3fv(locationPacked, count, transpose, value);
        }
        ANGLE_CAPTURE(UniformMatrix4x3fv, isCallValid, context, locationPacked, count, transpose,
                      value);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

GLboolean GL_APIENTRY UnmapBufferContextANGLE(GLeglContext ctx, GLenum target)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::UnmapBuffer, "glUnmapBuffer", "context = %d, target = %s",
          CID(context), GLenumToString(GLenumGroup::BufferTargetARB, target));

    GLboolean returnValue;
    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        BufferBinding targetPacked                            = FromGL<BufferBinding>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateUnmapBuffer(context, targetPacked));
        if (isCallValid)
        {
            returnValue = context->unmapBuffer(targetPacked);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::UnmapBuffer, GLboolean>();
        }
        ANGLE_CAPTURE(UnmapBuffer, isCallValid, context, targetPacked, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
        returnValue = GetDefaultReturnValue<EntryPoint::UnmapBuffer, GLboolean>();
    }
    return returnValue;
}

GLboolean GL_APIENTRY UnmapBufferOESContextANGLE(GLeglContext ctx, GLenum target)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::UnmapBufferOES, "glUnmapBufferOES", "context = %d, target = %s",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target));

    GLboolean returnValue;
    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        BufferBinding targetPacked                            = FromGL<BufferBinding>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateUnmapBufferOES(context, targetPacked));
        if (isCallValid)
        {
            returnValue = context->unmapBuffer(targetPacked);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::UnmapBufferOES, GLboolean>();
        }
        ANGLE_CAPTURE(UnmapBufferOES, isCallValid, context, targetPacked, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
        returnValue = GetDefaultReturnValue<EntryPoint::UnmapBufferOES, GLboolean>();
    }
    return returnValue;
}

void GL_APIENTRY UseProgramContextANGLE(GLeglContext ctx, GLuint program)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::UseProgram, "glUseProgram", "context = %d, program = %u",
          CID(context), program);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateUseProgram(context, programPacked));
        if (isCallValid)
        {
            context->useProgram(programPacked);
        }
        ANGLE_CAPTURE(UseProgram, isCallValid, context, programPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY UseProgramStagesContextANGLE(GLeglContext ctx,
                                              GLuint pipeline,
                                              GLbitfield stages,
                                              GLuint program)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::UseProgramStages, "glUseProgramStages",
          "context = %d, pipeline = %u, stages = %s, program = %u", CID(context), pipeline,
          GLbitfieldToString(GLenumGroup::UseProgramStageMask, stages).c_str(), program);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ProgramPipelineID pipelinePacked                      = FromGL<ProgramPipelineID>(pipeline);
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateUseProgramStages(context, pipelinePacked, stages, programPacked));
        if (isCallValid)
        {
            context->useProgramStages(pipelinePacked, stages, programPacked);
        }
        ANGLE_CAPTURE(UseProgramStages, isCallValid, context, pipelinePacked, stages,
                      programPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ValidateProgramContextANGLE(GLeglContext ctx, GLuint program)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ValidateProgram, "glValidateProgram",
          "context = %d, program = %u", CID(context), program);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateValidateProgram(context, programPacked));
        if (isCallValid)
        {
            context->validateProgram(programPacked);
        }
        ANGLE_CAPTURE(ValidateProgram, isCallValid, context, programPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ValidateProgramPipelineContextANGLE(GLeglContext ctx, GLuint pipeline)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ValidateProgramPipeline, "glValidateProgramPipeline",
          "context = %d, pipeline = %u", CID(context), pipeline);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ProgramPipelineID pipelinePacked                      = FromGL<ProgramPipelineID>(pipeline);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateValidateProgramPipeline(context, pipelinePacked));
        if (isCallValid)
        {
            context->validateProgramPipeline(pipelinePacked);
        }
        ANGLE_CAPTURE(ValidateProgramPipeline, isCallValid, context, pipelinePacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY VertexAttrib1fContextANGLE(GLeglContext ctx, GLuint index, GLfloat x)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::VertexAttrib1f, "glVertexAttrib1f",
          "context = %d, index = %u, x = %f", CID(context), index, x);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateVertexAttrib1f(context, index, x));
        if (isCallValid)
        {
            context->vertexAttrib1f(index, x);
        }
        ANGLE_CAPTURE(VertexAttrib1f, isCallValid, context, index, x);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY VertexAttrib1fvContextANGLE(GLeglContext ctx, GLuint index, const GLfloat *v)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::VertexAttrib1fv, "glVertexAttrib1fv",
          "context = %d, index = %u, v = 0x%016" PRIxPTR "", CID(context), index, (uintptr_t)v);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateVertexAttrib1fv(context, index, v));
        if (isCallValid)
        {
            context->vertexAttrib1fv(index, v);
        }
        ANGLE_CAPTURE(VertexAttrib1fv, isCallValid, context, index, v);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY VertexAttrib2fContextANGLE(GLeglContext ctx, GLuint index, GLfloat x, GLfloat y)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::VertexAttrib2f, "glVertexAttrib2f",
          "context = %d, index = %u, x = %f, y = %f", CID(context), index, x, y);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateVertexAttrib2f(context, index, x, y));
        if (isCallValid)
        {
            context->vertexAttrib2f(index, x, y);
        }
        ANGLE_CAPTURE(VertexAttrib2f, isCallValid, context, index, x, y);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY VertexAttrib2fvContextANGLE(GLeglContext ctx, GLuint index, const GLfloat *v)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::VertexAttrib2fv, "glVertexAttrib2fv",
          "context = %d, index = %u, v = 0x%016" PRIxPTR "", CID(context), index, (uintptr_t)v);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateVertexAttrib2fv(context, index, v));
        if (isCallValid)
        {
            context->vertexAttrib2fv(index, v);
        }
        ANGLE_CAPTURE(VertexAttrib2fv, isCallValid, context, index, v);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY
VertexAttrib3fContextANGLE(GLeglContext ctx, GLuint index, GLfloat x, GLfloat y, GLfloat z)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::VertexAttrib3f, "glVertexAttrib3f",
          "context = %d, index = %u, x = %f, y = %f, z = %f", CID(context), index, x, y, z);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateVertexAttrib3f(context, index, x, y, z));
        if (isCallValid)
        {
            context->vertexAttrib3f(index, x, y, z);
        }
        ANGLE_CAPTURE(VertexAttrib3f, isCallValid, context, index, x, y, z);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY VertexAttrib3fvContextANGLE(GLeglContext ctx, GLuint index, const GLfloat *v)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::VertexAttrib3fv, "glVertexAttrib3fv",
          "context = %d, index = %u, v = 0x%016" PRIxPTR "", CID(context), index, (uintptr_t)v);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateVertexAttrib3fv(context, index, v));
        if (isCallValid)
        {
            context->vertexAttrib3fv(index, v);
        }
        ANGLE_CAPTURE(VertexAttrib3fv, isCallValid, context, index, v);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY VertexAttrib4fContextANGLE(GLeglContext ctx,
                                            GLuint index,
                                            GLfloat x,
                                            GLfloat y,
                                            GLfloat z,
                                            GLfloat w)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::VertexAttrib4f, "glVertexAttrib4f",
          "context = %d, index = %u, x = %f, y = %f, z = %f, w = %f", CID(context), index, x, y, z,
          w);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateVertexAttrib4f(context, index, x, y, z, w));
        if (isCallValid)
        {
            context->vertexAttrib4f(index, x, y, z, w);
        }
        ANGLE_CAPTURE(VertexAttrib4f, isCallValid, context, index, x, y, z, w);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY VertexAttrib4fvContextANGLE(GLeglContext ctx, GLuint index, const GLfloat *v)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::VertexAttrib4fv, "glVertexAttrib4fv",
          "context = %d, index = %u, v = 0x%016" PRIxPTR "", CID(context), index, (uintptr_t)v);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateVertexAttrib4fv(context, index, v));
        if (isCallValid)
        {
            context->vertexAttrib4fv(index, v);
        }
        ANGLE_CAPTURE(VertexAttrib4fv, isCallValid, context, index, v);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY VertexAttribBindingContextANGLE(GLeglContext ctx,
                                                 GLuint attribindex,
                                                 GLuint bindingindex)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::VertexAttribBinding, "glVertexAttribBinding",
          "context = %d, attribindex = %u, bindingindex = %u", CID(context), attribindex,
          bindingindex);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateVertexAttribBinding(context, attribindex, bindingindex));
        if (isCallValid)
        {
            context->vertexAttribBinding(attribindex, bindingindex);
        }
        ANGLE_CAPTURE(VertexAttribBinding, isCallValid, context, attribindex, bindingindex);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY VertexAttribDivisorContextANGLE(GLeglContext ctx, GLuint index, GLuint divisor)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::VertexAttribDivisor, "glVertexAttribDivisor",
          "context = %d, index = %u, divisor = %u", CID(context), index, divisor);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateVertexAttribDivisor(context, index, divisor));
        if (isCallValid)
        {
            context->vertexAttribDivisor(index, divisor);
        }
        ANGLE_CAPTURE(VertexAttribDivisor, isCallValid, context, index, divisor);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY VertexAttribDivisorANGLEContextANGLE(GLeglContext ctx,
                                                      GLuint index,
                                                      GLuint divisor)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::VertexAttribDivisorANGLE, "glVertexAttribDivisorANGLE",
          "context = %d, index = %u, divisor = %u", CID(context), index, divisor);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateVertexAttribDivisorANGLE(context, index, divisor));
        if (isCallValid)
        {
            context->vertexAttribDivisor(index, divisor);
        }
        ANGLE_CAPTURE(VertexAttribDivisorANGLE, isCallValid, context, index, divisor);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY VertexAttribDivisorEXTContextANGLE(GLeglContext ctx, GLuint index, GLuint divisor)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::VertexAttribDivisorEXT, "glVertexAttribDivisorEXT",
          "context = %d, index = %u, divisor = %u", CID(context), index, divisor);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateVertexAttribDivisorEXT(context, index, divisor));
        if (isCallValid)
        {
            context->vertexAttribDivisor(index, divisor);
        }
        ANGLE_CAPTURE(VertexAttribDivisorEXT, isCallValid, context, index, divisor);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY VertexAttribFormatContextANGLE(GLeglContext ctx,
                                                GLuint attribindex,
                                                GLint size,
                                                GLenum type,
                                                GLboolean normalized,
                                                GLuint relativeoffset)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::VertexAttribFormat, "glVertexAttribFormat",
          "context = %d, attribindex = %u, size = %d, type = %s, normalized = %s, relativeoffset = "
          "%u",
          CID(context), attribindex, size, GLenumToString(GLenumGroup::DefaultGroup, type),
          GLbooleanToString(normalized), relativeoffset);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        VertexAttribType typePacked                           = FromGL<VertexAttribType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateVertexAttribFormat(context, attribindex, size, typePacked,
                                                       normalized, relativeoffset));
        if (isCallValid)
        {
            context->vertexAttribFormat(attribindex, size, typePacked, normalized, relativeoffset);
        }
        ANGLE_CAPTURE(VertexAttribFormat, isCallValid, context, attribindex, size, typePacked,
                      normalized, relativeoffset);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY
VertexAttribI4iContextANGLE(GLeglContext ctx, GLuint index, GLint x, GLint y, GLint z, GLint w)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::VertexAttribI4i, "glVertexAttribI4i",
          "context = %d, index = %u, x = %d, y = %d, z = %d, w = %d", CID(context), index, x, y, z,
          w);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateVertexAttribI4i(context, index, x, y, z, w));
        if (isCallValid)
        {
            context->vertexAttribI4i(index, x, y, z, w);
        }
        ANGLE_CAPTURE(VertexAttribI4i, isCallValid, context, index, x, y, z, w);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY VertexAttribI4ivContextANGLE(GLeglContext ctx, GLuint index, const GLint *v)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::VertexAttribI4iv, "glVertexAttribI4iv",
          "context = %d, index = %u, v = 0x%016" PRIxPTR "", CID(context), index, (uintptr_t)v);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateVertexAttribI4iv(context, index, v));
        if (isCallValid)
        {
            context->vertexAttribI4iv(index, v);
        }
        ANGLE_CAPTURE(VertexAttribI4iv, isCallValid, context, index, v);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY
VertexAttribI4uiContextANGLE(GLeglContext ctx, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::VertexAttribI4ui, "glVertexAttribI4ui",
          "context = %d, index = %u, x = %u, y = %u, z = %u, w = %u", CID(context), index, x, y, z,
          w);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateVertexAttribI4ui(context, index, x, y, z, w));
        if (isCallValid)
        {
            context->vertexAttribI4ui(index, x, y, z, w);
        }
        ANGLE_CAPTURE(VertexAttribI4ui, isCallValid, context, index, x, y, z, w);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY VertexAttribI4uivContextANGLE(GLeglContext ctx, GLuint index, const GLuint *v)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::VertexAttribI4uiv, "glVertexAttribI4uiv",
          "context = %d, index = %u, v = 0x%016" PRIxPTR "", CID(context), index, (uintptr_t)v);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateVertexAttribI4uiv(context, index, v));
        if (isCallValid)
        {
            context->vertexAttribI4uiv(index, v);
        }
        ANGLE_CAPTURE(VertexAttribI4uiv, isCallValid, context, index, v);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY VertexAttribIFormatContextANGLE(GLeglContext ctx,
                                                 GLuint attribindex,
                                                 GLint size,
                                                 GLenum type,
                                                 GLuint relativeoffset)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::VertexAttribIFormat, "glVertexAttribIFormat",
          "context = %d, attribindex = %u, size = %d, type = %s, relativeoffset = %u", CID(context),
          attribindex, size, GLenumToString(GLenumGroup::DefaultGroup, type), relativeoffset);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        VertexAttribType typePacked                           = FromGL<VertexAttribType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateVertexAttribIFormat(context, attribindex, size, typePacked, relativeoffset));
        if (isCallValid)
        {
            context->vertexAttribIFormat(attribindex, size, typePacked, relativeoffset);
        }
        ANGLE_CAPTURE(VertexAttribIFormat, isCallValid, context, attribindex, size, typePacked,
                      relativeoffset);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY VertexAttribIPointerContextANGLE(GLeglContext ctx,
                                                  GLuint index,
                                                  GLint size,
                                                  GLenum type,
                                                  GLsizei stride,
                                                  const void *pointer)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::VertexAttribIPointer, "glVertexAttribIPointer",
          "context = %d, index = %u, size = %d, type = %s, stride = %d, pointer = 0x%016" PRIxPTR
          "",
          CID(context), index, size, GLenumToString(GLenumGroup::VertexAttribPointerType, type),
          stride, (uintptr_t)pointer);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        VertexAttribType typePacked                           = FromGL<VertexAttribType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateVertexAttribIPointer(context, index, size, typePacked, stride, pointer));
        if (isCallValid)
        {
            context->vertexAttribIPointer(index, size, typePacked, stride, pointer);
        }
        ANGLE_CAPTURE(VertexAttribIPointer, isCallValid, context, index, size, typePacked, stride,
                      pointer);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY VertexAttribPointerContextANGLE(GLeglContext ctx,
                                                 GLuint index,
                                                 GLint size,
                                                 GLenum type,
                                                 GLboolean normalized,
                                                 GLsizei stride,
                                                 const void *pointer)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::VertexAttribPointer, "glVertexAttribPointer",
          "context = %d, index = %u, size = %d, type = %s, normalized = %s, stride = %d, pointer = "
          "0x%016" PRIxPTR "",
          CID(context), index, size, GLenumToString(GLenumGroup::VertexAttribPointerType, type),
          GLbooleanToString(normalized), stride, (uintptr_t)pointer);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        VertexAttribType typePacked                           = FromGL<VertexAttribType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateVertexAttribPointer(context, index, size, typePacked,
                                                        normalized, stride, pointer));
        if (isCallValid)
        {
            context->vertexAttribPointer(index, size, typePacked, normalized, stride, pointer);
        }
        ANGLE_CAPTURE(VertexAttribPointer, isCallValid, context, index, size, typePacked,
                      normalized, stride, pointer);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY VertexBindingDivisorContextANGLE(GLeglContext ctx,
                                                  GLuint bindingindex,
                                                  GLuint divisor)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::VertexBindingDivisor, "glVertexBindingDivisor",
          "context = %d, bindingindex = %u, divisor = %u", CID(context), bindingindex, divisor);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateVertexBindingDivisor(context, bindingindex, divisor));
        if (isCallValid)
        {
            context->vertexBindingDivisor(bindingindex, divisor);
        }
        ANGLE_CAPTURE(VertexBindingDivisor, isCallValid, context, bindingindex, divisor);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY VertexPointerContextANGLE(GLeglContext ctx,
                                           GLint size,
                                           GLenum type,
                                           GLsizei stride,
                                           const void *pointer)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::VertexPointer, "glVertexPointer",
          "context = %d, size = %d, type = %s, stride = %d, pointer = 0x%016" PRIxPTR "",
          CID(context), size, GLenumToString(GLenumGroup::VertexPointerType, type), stride,
          (uintptr_t)pointer);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        VertexAttribType typePacked                           = FromGL<VertexAttribType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateVertexPointer(context, size, typePacked, stride, pointer));
        if (isCallValid)
        {
            context->vertexPointer(size, typePacked, stride, pointer);
        }
        ANGLE_CAPTURE(VertexPointer, isCallValid, context, size, typePacked, stride, pointer);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY
ViewportContextANGLE(GLeglContext ctx, GLint x, GLint y, GLsizei width, GLsizei height)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::Viewport, "glViewport",
          "context = %d, x = %d, y = %d, width = %d, height = %d", CID(context), x, y, width,
          height);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateViewport(context, x, y, width, height));
        if (isCallValid)
        {
            context->viewport(x, y, width, height);
        }
        ANGLE_CAPTURE(Viewport, isCallValid, context, x, y, width, height);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY WaitSemaphoreEXTContextANGLE(GLeglContext ctx,
                                              GLuint semaphore,
                                              GLuint numBufferBarriers,
                                              const GLuint *buffers,
                                              GLuint numTextureBarriers,
                                              const GLuint *textures,
                                              const GLenum *srcLayouts)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::WaitSemaphoreEXT, "glWaitSemaphoreEXT",
          "context = %d, semaphore = %u, numBufferBarriers = %u, buffers = 0x%016" PRIxPTR
          ", numTextureBarriers = %u, textures = 0x%016" PRIxPTR ", srcLayouts = 0x%016" PRIxPTR "",
          CID(context), semaphore, numBufferBarriers, (uintptr_t)buffers, numTextureBarriers,
          (uintptr_t)textures, (uintptr_t)srcLayouts);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        SemaphoreID semaphorePacked                           = FromGL<SemaphoreID>(semaphore);
        const BufferID *buffersPacked                         = FromGL<const BufferID *>(buffers);
        const TextureID *texturesPacked                       = FromGL<const TextureID *>(textures);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateWaitSemaphoreEXT(context, semaphorePacked, numBufferBarriers, buffersPacked,
                                      numTextureBarriers, texturesPacked, srcLayouts));
        if (isCallValid)
        {
            context->waitSemaphore(semaphorePacked, numBufferBarriers, buffersPacked,
                                   numTextureBarriers, texturesPacked, srcLayouts);
        }
        ANGLE_CAPTURE(WaitSemaphoreEXT, isCallValid, context, semaphorePacked, numBufferBarriers,
                      buffersPacked, numTextureBarriers, texturesPacked, srcLayouts);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY WaitSyncContextANGLE(GLeglContext ctx,
                                      GLsync sync,
                                      GLbitfield flags,
                                      GLuint64 timeout)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::WaitSync, "glWaitSync",
          "context = %d, sync = 0x%016" PRIxPTR ", flags = %s, timeout = %llu", CID(context),
          (uintptr_t)sync, GLbitfieldToString(GLenumGroup::DefaultGroup, flags).c_str(),
          static_cast<unsigned long long>(timeout));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateWaitSync(context, sync, flags, timeout));
        if (isCallValid)
        {
            context->waitSync(sync, flags, timeout);
        }
        ANGLE_CAPTURE(WaitSync, isCallValid, context, sync, flags, timeout);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY WeightPointerOESContextANGLE(GLeglContext ctx,
                                              GLint size,
                                              GLenum type,
                                              GLsizei stride,
                                              const void *pointer)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::WeightPointerOES, "glWeightPointerOES",
          "context = %d, size = %d, type = %s, stride = %d, pointer = 0x%016" PRIxPTR "",
          CID(context), size, GLenumToString(GLenumGroup::DefaultGroup, type), stride,
          (uintptr_t)pointer);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateWeightPointerOES(context, size, type, stride, pointer));
        if (isCallValid)
        {
            context->weightPointer(size, type, stride, pointer);
        }
        ANGLE_CAPTURE(WeightPointerOES, isCallValid, context, size, type, stride, pointer);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY BindUniformLocationCHROMIUMContextANGLE(GLeglContext ctx,
                                                         GLuint program,
                                                         GLint location,
                                                         const GLchar *name)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::BindUniformLocationCHROMIUM, "glBindUniformLocationCHROMIUM",
          "context = %d, program = %u, location = %d, name = 0x%016" PRIxPTR "", CID(context),
          program, location, (uintptr_t)name);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateBindUniformLocationCHROMIUM(context, programPacked, locationPacked, name));
        if (isCallValid)
        {
            context->bindUniformLocation(programPacked, locationPacked, name);
        }
        ANGLE_CAPTURE(BindUniformLocationCHROMIUM, isCallValid, context, programPacked,
                      locationPacked, name);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY CoverageModulationCHROMIUMContextANGLE(GLeglContext ctx, GLenum components)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::CoverageModulationCHROMIUM, "glCoverageModulationCHROMIUM",
          "context = %d, components = %s", CID(context),
          GLenumToString(GLenumGroup::DefaultGroup, components));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateCoverageModulationCHROMIUM(context, components));
        if (isCallValid)
        {
            context->coverageModulation(components);
        }
        ANGLE_CAPTURE(CoverageModulationCHROMIUM, isCallValid, context, components);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY CopyTextureCHROMIUMContextANGLE(GLeglContext ctx,
                                                 GLuint sourceId,
                                                 GLint sourceLevel,
                                                 GLenum destTarget,
                                                 GLuint destId,
                                                 GLint destLevel,
                                                 GLint internalFormat,
                                                 GLenum destType,
                                                 GLboolean unpackFlipY,
                                                 GLboolean unpackPremultiplyAlpha,
                                                 GLboolean unpackUnmultiplyAlpha)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::CopyTextureCHROMIUM, "glCopyTextureCHROMIUM",
          "context = %d, sourceId = %u, sourceLevel = %d, destTarget = %s, destId = %u, destLevel "
          "= %d, internalFormat = %d, destType = %s, unpackFlipY = %s, unpackPremultiplyAlpha = "
          "%s, unpackUnmultiplyAlpha = %s",
          CID(context), sourceId, sourceLevel,
          GLenumToString(GLenumGroup::DefaultGroup, destTarget), destId, destLevel, internalFormat,
          GLenumToString(GLenumGroup::DefaultGroup, destType), GLbooleanToString(unpackFlipY),
          GLbooleanToString(unpackPremultiplyAlpha), GLbooleanToString(unpackUnmultiplyAlpha));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureID sourceIdPacked                              = FromGL<TextureID>(sourceId);
        TextureTarget destTargetPacked                        = FromGL<TextureTarget>(destTarget);
        TextureID destIdPacked                                = FromGL<TextureID>(destId);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateCopyTextureCHROMIUM(
                                context, sourceIdPacked, sourceLevel, destTargetPacked,
                                destIdPacked, destLevel, internalFormat, destType, unpackFlipY,
                                unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
        if (isCallValid)
        {
            context->copyTexture(sourceIdPacked, sourceLevel, destTargetPacked, destIdPacked,
                                 destLevel, internalFormat, destType, unpackFlipY,
                                 unpackPremultiplyAlpha, unpackUnmultiplyAlpha);
        }
        ANGLE_CAPTURE(CopyTextureCHROMIUM, isCallValid, context, sourceIdPacked, sourceLevel,
                      destTargetPacked, destIdPacked, destLevel, internalFormat, destType,
                      unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY CopySubTextureCHROMIUMContextANGLE(GLeglContext ctx,
                                                    GLuint sourceId,
                                                    GLint sourceLevel,
                                                    GLenum destTarget,
                                                    GLuint destId,
                                                    GLint destLevel,
                                                    GLint xoffset,
                                                    GLint yoffset,
                                                    GLint x,
                                                    GLint y,
                                                    GLint width,
                                                    GLint height,
                                                    GLboolean unpackFlipY,
                                                    GLboolean unpackPremultiplyAlpha,
                                                    GLboolean unpackUnmultiplyAlpha)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::CopySubTextureCHROMIUM, "glCopySubTextureCHROMIUM",
          "context = %d, sourceId = %u, sourceLevel = %d, destTarget = %s, destId = %u, destLevel "
          "= %d, xoffset = %d, yoffset = %d, x = %d, y = %d, width = %d, height = %d, unpackFlipY "
          "= %s, unpackPremultiplyAlpha = %s, unpackUnmultiplyAlpha = %s",
          CID(context), sourceId, sourceLevel,
          GLenumToString(GLenumGroup::DefaultGroup, destTarget), destId, destLevel, xoffset,
          yoffset, x, y, width, height, GLbooleanToString(unpackFlipY),
          GLbooleanToString(unpackPremultiplyAlpha), GLbooleanToString(unpackUnmultiplyAlpha));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureID sourceIdPacked                              = FromGL<TextureID>(sourceId);
        TextureTarget destTargetPacked                        = FromGL<TextureTarget>(destTarget);
        TextureID destIdPacked                                = FromGL<TextureID>(destId);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateCopySubTextureCHROMIUM(
                                context, sourceIdPacked, sourceLevel, destTargetPacked,
                                destIdPacked, destLevel, xoffset, yoffset, x, y, width, height,
                                unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
        if (isCallValid)
        {
            context->copySubTexture(sourceIdPacked, sourceLevel, destTargetPacked, destIdPacked,
                                    destLevel, xoffset, yoffset, x, y, width, height, unpackFlipY,
                                    unpackPremultiplyAlpha, unpackUnmultiplyAlpha);
        }
        ANGLE_CAPTURE(CopySubTextureCHROMIUM, isCallValid, context, sourceIdPacked, sourceLevel,
                      destTargetPacked, destIdPacked, destLevel, xoffset, yoffset, x, y, width,
                      height, unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY CompressedCopyTextureCHROMIUMContextANGLE(GLeglContext ctx,
                                                           GLuint sourceId,
                                                           GLuint destId)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::CompressedCopyTextureCHROMIUM, "glCompressedCopyTextureCHROMIUM",
          "context = %d, sourceId = %u, destId = %u", CID(context), sourceId, destId);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureID sourceIdPacked                              = FromGL<TextureID>(sourceId);
        TextureID destIdPacked                                = FromGL<TextureID>(destId);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateCompressedCopyTextureCHROMIUM(context, sourceIdPacked, destIdPacked));
        if (isCallValid)
        {
            context->compressedCopyTexture(sourceIdPacked, destIdPacked);
        }
        ANGLE_CAPTURE(CompressedCopyTextureCHROMIUM, isCallValid, context, sourceIdPacked,
                      destIdPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY RequestExtensionANGLEContextANGLE(GLeglContext ctx, const GLchar *name)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::RequestExtensionANGLE, "glRequestExtensionANGLE",
          "context = %d, name = 0x%016" PRIxPTR "", CID(context), (uintptr_t)name);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateRequestExtensionANGLE(context, name));
        if (isCallValid)
        {
            context->requestExtension(name);
        }
        ANGLE_CAPTURE(RequestExtensionANGLE, isCallValid, context, name);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DisableExtensionANGLEContextANGLE(GLeglContext ctx, const GLchar *name)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DisableExtensionANGLE, "glDisableExtensionANGLE",
          "context = %d, name = 0x%016" PRIxPTR "", CID(context), (uintptr_t)name);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateDisableExtensionANGLE(context, name));
        if (isCallValid)
        {
            context->disableExtension(name);
        }
        ANGLE_CAPTURE(DisableExtensionANGLE, isCallValid, context, name);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetBooleanvRobustANGLEContextANGLE(GLeglContext ctx,
                                                    GLenum pname,
                                                    GLsizei bufSize,
                                                    GLsizei *length,
                                                    GLboolean *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetBooleanvRobustANGLE, "glGetBooleanvRobustANGLE",
          "context = %d, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize,
          (uintptr_t)length, (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetBooleanvRobustANGLE(context, pname, bufSize, length, params));
        if (isCallValid)
        {
            context->getBooleanvRobust(pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetBooleanvRobustANGLE, isCallValid, context, pname, bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetBufferParameterivRobustANGLEContextANGLE(GLeglContext ctx,
                                                             GLenum target,
                                                             GLenum pname,
                                                             GLsizei bufSize,
                                                             GLsizei *length,
                                                             GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetBufferParameterivRobustANGLE,
          "glGetBufferParameterivRobustANGLE",
          "context = %d, target = %s, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target),
          GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize, (uintptr_t)length,
          (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        BufferBinding targetPacked                            = FromGL<BufferBinding>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetBufferParameterivRobustANGLE(context, targetPacked, pname,
                                                                    bufSize, length, params));
        if (isCallValid)
        {
            context->getBufferParameterivRobust(targetPacked, pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetBufferParameterivRobustANGLE, isCallValid, context, targetPacked, pname,
                      bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetFloatvRobustANGLEContextANGLE(GLeglContext ctx,
                                                  GLenum pname,
                                                  GLsizei bufSize,
                                                  GLsizei *length,
                                                  GLfloat *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetFloatvRobustANGLE, "glGetFloatvRobustANGLE",
          "context = %d, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize,
          (uintptr_t)length, (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetFloatvRobustANGLE(context, pname, bufSize, length, params));
        if (isCallValid)
        {
            context->getFloatvRobust(pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetFloatvRobustANGLE, isCallValid, context, pname, bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetFramebufferAttachmentParameterivRobustANGLEContextANGLE(GLeglContext ctx,
                                                                            GLenum target,
                                                                            GLenum attachment,
                                                                            GLenum pname,
                                                                            GLsizei bufSize,
                                                                            GLsizei *length,
                                                                            GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetFramebufferAttachmentParameterivRobustANGLE,
          "glGetFramebufferAttachmentParameterivRobustANGLE",
          "context = %d, target = %s, attachment = %s, pname = %s, bufSize = %d, length = "
          "0x%016" PRIxPTR ", params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target),
          GLenumToString(GLenumGroup::DefaultGroup, attachment),
          GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize, (uintptr_t)length,
          (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetFramebufferAttachmentParameterivRobustANGLE(
                                context, target, attachment, pname, bufSize, length, params));
        if (isCallValid)
        {
            context->getFramebufferAttachmentParameterivRobust(target, attachment, pname, bufSize,
                                                               length, params);
        }
        ANGLE_CAPTURE(GetFramebufferAttachmentParameterivRobustANGLE, isCallValid, context, target,
                      attachment, pname, bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetIntegervRobustANGLEContextANGLE(GLeglContext ctx,
                                                    GLenum pname,
                                                    GLsizei bufSize,
                                                    GLsizei *length,
                                                    GLint *data)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetIntegervRobustANGLE, "glGetIntegervRobustANGLE",
          "context = %d, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", data = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize,
          (uintptr_t)length, (uintptr_t)data);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetIntegervRobustANGLE(context, pname, bufSize, length, data));
        if (isCallValid)
        {
            context->getIntegervRobust(pname, bufSize, length, data);
        }
        ANGLE_CAPTURE(GetIntegervRobustANGLE, isCallValid, context, pname, bufSize, length, data);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetProgramivRobustANGLEContextANGLE(GLeglContext ctx,
                                                     GLuint program,
                                                     GLenum pname,
                                                     GLsizei bufSize,
                                                     GLsizei *length,
                                                     GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetProgramivRobustANGLE, "glGetProgramivRobustANGLE",
          "context = %d, program = %u, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), program, GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize,
          (uintptr_t)length, (uintptr_t)params);

    if (context)
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetProgramivRobustANGLE(context, programPacked, pname, bufSize,
                                                            length, params));
        if (isCallValid)
        {
            context->getProgramivRobust(programPacked, pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetProgramivRobustANGLE, isCallValid, context, programPacked, pname, bufSize,
                      length, params);
    }
    else
    {}
}

void GL_APIENTRY GetRenderbufferParameterivRobustANGLEContextANGLE(GLeglContext ctx,
                                                                   GLenum target,
                                                                   GLenum pname,
                                                                   GLsizei bufSize,
                                                                   GLsizei *length,
                                                                   GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetRenderbufferParameterivRobustANGLE,
          "glGetRenderbufferParameterivRobustANGLE",
          "context = %d, target = %s, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target),
          GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize, (uintptr_t)length,
          (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetRenderbufferParameterivRobustANGLE(
                                              context, target, pname, bufSize, length, params));
        if (isCallValid)
        {
            context->getRenderbufferParameterivRobust(target, pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetRenderbufferParameterivRobustANGLE, isCallValid, context, target, pname,
                      bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetShaderivRobustANGLEContextANGLE(GLeglContext ctx,
                                                    GLuint shader,
                                                    GLenum pname,
                                                    GLsizei bufSize,
                                                    GLsizei *length,
                                                    GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetShaderivRobustANGLE, "glGetShaderivRobustANGLE",
          "context = %d, shader = %u, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), shader, GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize,
          (uintptr_t)length, (uintptr_t)params);

    if (context)
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID shaderPacked                          = FromGL<ShaderProgramID>(shader);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetShaderivRobustANGLE(context, shaderPacked, pname, bufSize, length, params));
        if (isCallValid)
        {
            context->getShaderivRobust(shaderPacked, pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetShaderivRobustANGLE, isCallValid, context, shaderPacked, pname, bufSize,
                      length, params);
    }
    else
    {}
}

void GL_APIENTRY GetTexParameterfvRobustANGLEContextANGLE(GLeglContext ctx,
                                                          GLenum target,
                                                          GLenum pname,
                                                          GLsizei bufSize,
                                                          GLsizei *length,
                                                          GLfloat *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetTexParameterfvRobustANGLE, "glGetTexParameterfvRobustANGLE",
          "context = %d, target = %s, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target),
          GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize, (uintptr_t)length,
          (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetTexParameterfvRobustANGLE(context, targetPacked, pname,
                                                                 bufSize, length, params));
        if (isCallValid)
        {
            context->getTexParameterfvRobust(targetPacked, pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetTexParameterfvRobustANGLE, isCallValid, context, targetPacked, pname,
                      bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetTexParameterivRobustANGLEContextANGLE(GLeglContext ctx,
                                                          GLenum target,
                                                          GLenum pname,
                                                          GLsizei bufSize,
                                                          GLsizei *length,
                                                          GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetTexParameterivRobustANGLE, "glGetTexParameterivRobustANGLE",
          "context = %d, target = %s, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target),
          GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize, (uintptr_t)length,
          (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetTexParameterivRobustANGLE(context, targetPacked, pname,
                                                                 bufSize, length, params));
        if (isCallValid)
        {
            context->getTexParameterivRobust(targetPacked, pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetTexParameterivRobustANGLE, isCallValid, context, targetPacked, pname,
                      bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetUniformfvRobustANGLEContextANGLE(GLeglContext ctx,
                                                     GLuint program,
                                                     GLint location,
                                                     GLsizei bufSize,
                                                     GLsizei *length,
                                                     GLfloat *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetUniformfvRobustANGLE, "glGetUniformfvRobustANGLE",
          "context = %d, program = %u, location = %d, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), program, location, bufSize, (uintptr_t)length, (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetUniformfvRobustANGLE(context, programPacked, locationPacked,
                                                            bufSize, length, params));
        if (isCallValid)
        {
            context->getUniformfvRobust(programPacked, locationPacked, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetUniformfvRobustANGLE, isCallValid, context, programPacked, locationPacked,
                      bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetUniformivRobustANGLEContextANGLE(GLeglContext ctx,
                                                     GLuint program,
                                                     GLint location,
                                                     GLsizei bufSize,
                                                     GLsizei *length,
                                                     GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetUniformivRobustANGLE, "glGetUniformivRobustANGLE",
          "context = %d, program = %u, location = %d, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), program, location, bufSize, (uintptr_t)length, (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetUniformivRobustANGLE(context, programPacked, locationPacked,
                                                            bufSize, length, params));
        if (isCallValid)
        {
            context->getUniformivRobust(programPacked, locationPacked, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetUniformivRobustANGLE, isCallValid, context, programPacked, locationPacked,
                      bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetVertexAttribfvRobustANGLEContextANGLE(GLeglContext ctx,
                                                          GLuint index,
                                                          GLenum pname,
                                                          GLsizei bufSize,
                                                          GLsizei *length,
                                                          GLfloat *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetVertexAttribfvRobustANGLE, "glGetVertexAttribfvRobustANGLE",
          "context = %d, index = %u, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), index, GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize,
          (uintptr_t)length, (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetVertexAttribfvRobustANGLE(context, index, pname, bufSize, length, params));
        if (isCallValid)
        {
            context->getVertexAttribfvRobust(index, pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetVertexAttribfvRobustANGLE, isCallValid, context, index, pname, bufSize,
                      length, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetVertexAttribivRobustANGLEContextANGLE(GLeglContext ctx,
                                                          GLuint index,
                                                          GLenum pname,
                                                          GLsizei bufSize,
                                                          GLsizei *length,
                                                          GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetVertexAttribivRobustANGLE, "glGetVertexAttribivRobustANGLE",
          "context = %d, index = %u, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), index, GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize,
          (uintptr_t)length, (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetVertexAttribivRobustANGLE(context, index, pname, bufSize, length, params));
        if (isCallValid)
        {
            context->getVertexAttribivRobust(index, pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetVertexAttribivRobustANGLE, isCallValid, context, index, pname, bufSize,
                      length, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetVertexAttribPointervRobustANGLEContextANGLE(GLeglContext ctx,
                                                                GLuint index,
                                                                GLenum pname,
                                                                GLsizei bufSize,
                                                                GLsizei *length,
                                                                void **pointer)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetVertexAttribPointervRobustANGLE,
          "glGetVertexAttribPointervRobustANGLE",
          "context = %d, index = %u, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", pointer = 0x%016" PRIxPTR "",
          CID(context), index, GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize,
          (uintptr_t)length, (uintptr_t)pointer);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetVertexAttribPointervRobustANGLE(
                                              context, index, pname, bufSize, length, pointer));
        if (isCallValid)
        {
            context->getVertexAttribPointervRobust(index, pname, bufSize, length, pointer);
        }
        ANGLE_CAPTURE(GetVertexAttribPointervRobustANGLE, isCallValid, context, index, pname,
                      bufSize, length, pointer);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ReadPixelsRobustANGLEContextANGLE(GLeglContext ctx,
                                                   GLint x,
                                                   GLint y,
                                                   GLsizei width,
                                                   GLsizei height,
                                                   GLenum format,
                                                   GLenum type,
                                                   GLsizei bufSize,
                                                   GLsizei *length,
                                                   GLsizei *columns,
                                                   GLsizei *rows,
                                                   void *pixels)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ReadPixelsRobustANGLE, "glReadPixelsRobustANGLE",
          "context = %d, x = %d, y = %d, width = %d, height = %d, format = %s, type = %s, bufSize "
          "= %d, length = 0x%016" PRIxPTR ", columns = 0x%016" PRIxPTR ", rows = 0x%016" PRIxPTR
          ", pixels = 0x%016" PRIxPTR "",
          CID(context), x, y, width, height, GLenumToString(GLenumGroup::DefaultGroup, format),
          GLenumToString(GLenumGroup::DefaultGroup, type), bufSize, (uintptr_t)length,
          (uintptr_t)columns, (uintptr_t)rows, (uintptr_t)pixels);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateReadPixelsRobustANGLE(context, x, y, width, height, format, type, bufSize,
                                           length, columns, rows, pixels));
        if (isCallValid)
        {
            context->readPixelsRobust(x, y, width, height, format, type, bufSize, length, columns,
                                      rows, pixels);
        }
        ANGLE_CAPTURE(ReadPixelsRobustANGLE, isCallValid, context, x, y, width, height, format,
                      type, bufSize, length, columns, rows, pixels);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexImage2DRobustANGLEContextANGLE(GLeglContext ctx,
                                                   GLenum target,
                                                   GLint level,
                                                   GLint internalformat,
                                                   GLsizei width,
                                                   GLsizei height,
                                                   GLint border,
                                                   GLenum format,
                                                   GLenum type,
                                                   GLsizei bufSize,
                                                   const void *pixels)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexImage2DRobustANGLE, "glTexImage2DRobustANGLE",
          "context = %d, target = %s, level = %d, internalformat = %d, width = %d, height = %d, "
          "border = %d, format = %s, type = %s, bufSize = %d, pixels = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target), level, internalformat,
          width, height, border, GLenumToString(GLenumGroup::DefaultGroup, format),
          GLenumToString(GLenumGroup::DefaultGroup, type), bufSize, (uintptr_t)pixels);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTexImage2DRobustANGLE(context, targetPacked, level, internalformat, width,
                                           height, border, format, type, bufSize, pixels));
        if (isCallValid)
        {
            context->texImage2DRobust(targetPacked, level, internalformat, width, height, border,
                                      format, type, bufSize, pixels);
        }
        ANGLE_CAPTURE(TexImage2DRobustANGLE, isCallValid, context, targetPacked, level,
                      internalformat, width, height, border, format, type, bufSize, pixels);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexParameterfvRobustANGLEContextANGLE(GLeglContext ctx,
                                                       GLenum target,
                                                       GLenum pname,
                                                       GLsizei bufSize,
                                                       const GLfloat *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexParameterfvRobustANGLE, "glTexParameterfvRobustANGLE",
          "context = %d, target = %s, pname = %s, bufSize = %d, params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target),
          GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize, (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTexParameterfvRobustANGLE(context, targetPacked, pname, bufSize, params));
        if (isCallValid)
        {
            context->texParameterfvRobust(targetPacked, pname, bufSize, params);
        }
        ANGLE_CAPTURE(TexParameterfvRobustANGLE, isCallValid, context, targetPacked, pname, bufSize,
                      params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexParameterivRobustANGLEContextANGLE(GLeglContext ctx,
                                                       GLenum target,
                                                       GLenum pname,
                                                       GLsizei bufSize,
                                                       const GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexParameterivRobustANGLE, "glTexParameterivRobustANGLE",
          "context = %d, target = %s, pname = %s, bufSize = %d, params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target),
          GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize, (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTexParameterivRobustANGLE(context, targetPacked, pname, bufSize, params));
        if (isCallValid)
        {
            context->texParameterivRobust(targetPacked, pname, bufSize, params);
        }
        ANGLE_CAPTURE(TexParameterivRobustANGLE, isCallValid, context, targetPacked, pname, bufSize,
                      params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexSubImage2DRobustANGLEContextANGLE(GLeglContext ctx,
                                                      GLenum target,
                                                      GLint level,
                                                      GLint xoffset,
                                                      GLint yoffset,
                                                      GLsizei width,
                                                      GLsizei height,
                                                      GLenum format,
                                                      GLenum type,
                                                      GLsizei bufSize,
                                                      const void *pixels)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexSubImage2DRobustANGLE, "glTexSubImage2DRobustANGLE",
          "context = %d, target = %s, level = %d, xoffset = %d, yoffset = %d, width = %d, height = "
          "%d, format = %s, type = %s, bufSize = %d, pixels = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target), level, xoffset, yoffset,
          width, height, GLenumToString(GLenumGroup::DefaultGroup, format),
          GLenumToString(GLenumGroup::DefaultGroup, type), bufSize, (uintptr_t)pixels);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTexSubImage2DRobustANGLE(context, targetPacked, level, xoffset, yoffset, width,
                                              height, format, type, bufSize, pixels));
        if (isCallValid)
        {
            context->texSubImage2DRobust(targetPacked, level, xoffset, yoffset, width, height,
                                         format, type, bufSize, pixels);
        }
        ANGLE_CAPTURE(TexSubImage2DRobustANGLE, isCallValid, context, targetPacked, level, xoffset,
                      yoffset, width, height, format, type, bufSize, pixels);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexImage3DRobustANGLEContextANGLE(GLeglContext ctx,
                                                   GLenum target,
                                                   GLint level,
                                                   GLint internalformat,
                                                   GLsizei width,
                                                   GLsizei height,
                                                   GLsizei depth,
                                                   GLint border,
                                                   GLenum format,
                                                   GLenum type,
                                                   GLsizei bufSize,
                                                   const void *pixels)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexImage3DRobustANGLE, "glTexImage3DRobustANGLE",
          "context = %d, target = %s, level = %d, internalformat = %d, width = %d, height = %d, "
          "depth = %d, border = %d, format = %s, type = %s, bufSize = %d, pixels = 0x%016" PRIxPTR
          "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target), level, internalformat,
          width, height, depth, border, GLenumToString(GLenumGroup::DefaultGroup, format),
          GLenumToString(GLenumGroup::DefaultGroup, type), bufSize, (uintptr_t)pixels);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTexImage3DRobustANGLE(context, targetPacked, level, internalformat, width,
                                           height, depth, border, format, type, bufSize, pixels));
        if (isCallValid)
        {
            context->texImage3DRobust(targetPacked, level, internalformat, width, height, depth,
                                      border, format, type, bufSize, pixels);
        }
        ANGLE_CAPTURE(TexImage3DRobustANGLE, isCallValid, context, targetPacked, level,
                      internalformat, width, height, depth, border, format, type, bufSize, pixels);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexSubImage3DRobustANGLEContextANGLE(GLeglContext ctx,
                                                      GLenum target,
                                                      GLint level,
                                                      GLint xoffset,
                                                      GLint yoffset,
                                                      GLint zoffset,
                                                      GLsizei width,
                                                      GLsizei height,
                                                      GLsizei depth,
                                                      GLenum format,
                                                      GLenum type,
                                                      GLsizei bufSize,
                                                      const void *pixels)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(
        context, gl::EntryPoint::TexSubImage3DRobustANGLE, "glTexSubImage3DRobustANGLE",
        "context = %d, target = %s, level = %d, xoffset = %d, yoffset = %d, zoffset = %d, width = "
        "%d, height = %d, depth = %d, format = %s, type = %s, bufSize = %d, pixels = 0x%016" PRIxPTR
        "",
        CID(context), GLenumToString(GLenumGroup::DefaultGroup, target), level, xoffset, yoffset,
        zoffset, width, height, depth, GLenumToString(GLenumGroup::DefaultGroup, format),
        GLenumToString(GLenumGroup::DefaultGroup, type), bufSize, (uintptr_t)pixels);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateTexSubImage3DRobustANGLE(context, targetPacked, level, xoffset,
                                                             yoffset, zoffset, width, height, depth,
                                                             format, type, bufSize, pixels));
        if (isCallValid)
        {
            context->texSubImage3DRobust(targetPacked, level, xoffset, yoffset, zoffset, width,
                                         height, depth, format, type, bufSize, pixels);
        }
        ANGLE_CAPTURE(TexSubImage3DRobustANGLE, isCallValid, context, targetPacked, level, xoffset,
                      yoffset, zoffset, width, height, depth, format, type, bufSize, pixels);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY CompressedTexImage2DRobustANGLEContextANGLE(GLeglContext ctx,
                                                             GLenum target,
                                                             GLint level,
                                                             GLenum internalformat,
                                                             GLsizei width,
                                                             GLsizei height,
                                                             GLint border,
                                                             GLsizei imageSize,
                                                             GLsizei dataSize,
                                                             const GLvoid *data)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::CompressedTexImage2DRobustANGLE,
          "glCompressedTexImage2DRobustANGLE",
          "context = %d, target = %s, level = %d, internalformat = %s, width = %d, height = %d, "
          "border = %d, imageSize = %d, dataSize = %d, data = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target), level,
          GLenumToString(GLenumGroup::DefaultGroup, internalformat), width, height, border,
          imageSize, dataSize, (uintptr_t)data);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateCompressedTexImage2DRobustANGLE(
                                              context, targetPacked, level, internalformat, width,
                                              height, border, imageSize, dataSize, data));
        if (isCallValid)
        {
            context->compressedTexImage2DRobust(targetPacked, level, internalformat, width, height,
                                                border, imageSize, dataSize, data);
        }
        ANGLE_CAPTURE(CompressedTexImage2DRobustANGLE, isCallValid, context, targetPacked, level,
                      internalformat, width, height, border, imageSize, dataSize, data);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY CompressedTexSubImage2DRobustANGLEContextANGLE(GLeglContext ctx,
                                                                GLenum target,
                                                                GLint level,
                                                                GLsizei xoffset,
                                                                GLsizei yoffset,
                                                                GLsizei width,
                                                                GLsizei height,
                                                                GLenum format,
                                                                GLsizei imageSize,
                                                                GLsizei dataSize,
                                                                const GLvoid *data)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::CompressedTexSubImage2DRobustANGLE,
          "glCompressedTexSubImage2DRobustANGLE",
          "context = %d, target = %s, level = %d, xoffset = %d, yoffset = %d, width = %d, height = "
          "%d, format = %s, imageSize = %d, dataSize = %d, data = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target), level, xoffset, yoffset,
          width, height, GLenumToString(GLenumGroup::DefaultGroup, format), imageSize, dataSize,
          (uintptr_t)data);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateCompressedTexSubImage2DRobustANGLE(
                                              context, targetPacked, level, xoffset, yoffset, width,
                                              height, format, imageSize, dataSize, data));
        if (isCallValid)
        {
            context->compressedTexSubImage2DRobust(targetPacked, level, xoffset, yoffset, width,
                                                   height, format, imageSize, dataSize, data);
        }
        ANGLE_CAPTURE(CompressedTexSubImage2DRobustANGLE, isCallValid, context, targetPacked, level,
                      xoffset, yoffset, width, height, format, imageSize, dataSize, data);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY CompressedTexImage3DRobustANGLEContextANGLE(GLeglContext ctx,
                                                             GLenum target,
                                                             GLint level,
                                                             GLenum internalformat,
                                                             GLsizei width,
                                                             GLsizei height,
                                                             GLsizei depth,
                                                             GLint border,
                                                             GLsizei imageSize,
                                                             GLsizei dataSize,
                                                             const GLvoid *data)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::CompressedTexImage3DRobustANGLE,
          "glCompressedTexImage3DRobustANGLE",
          "context = %d, target = %s, level = %d, internalformat = %s, width = %d, height = %d, "
          "depth = %d, border = %d, imageSize = %d, dataSize = %d, data = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target), level,
          GLenumToString(GLenumGroup::DefaultGroup, internalformat), width, height, depth, border,
          imageSize, dataSize, (uintptr_t)data);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateCompressedTexImage3DRobustANGLE(
                                              context, targetPacked, level, internalformat, width,
                                              height, depth, border, imageSize, dataSize, data));
        if (isCallValid)
        {
            context->compressedTexImage3DRobust(targetPacked, level, internalformat, width, height,
                                                depth, border, imageSize, dataSize, data);
        }
        ANGLE_CAPTURE(CompressedTexImage3DRobustANGLE, isCallValid, context, targetPacked, level,
                      internalformat, width, height, depth, border, imageSize, dataSize, data);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY CompressedTexSubImage3DRobustANGLEContextANGLE(GLeglContext ctx,
                                                                GLenum target,
                                                                GLint level,
                                                                GLint xoffset,
                                                                GLint yoffset,
                                                                GLint zoffset,
                                                                GLsizei width,
                                                                GLsizei height,
                                                                GLsizei depth,
                                                                GLenum format,
                                                                GLsizei imageSize,
                                                                GLsizei dataSize,
                                                                const GLvoid *data)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::CompressedTexSubImage3DRobustANGLE,
          "glCompressedTexSubImage3DRobustANGLE",
          "context = %d, target = %s, level = %d, xoffset = %d, yoffset = %d, zoffset = %d, width "
          "= %d, height = %d, depth = %d, format = %s, imageSize = %d, dataSize = %d, data = "
          "0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target), level, xoffset, yoffset,
          zoffset, width, height, depth, GLenumToString(GLenumGroup::DefaultGroup, format),
          imageSize, dataSize, (uintptr_t)data);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateCompressedTexSubImage3DRobustANGLE(
                                context, targetPacked, level, xoffset, yoffset, zoffset, width,
                                height, depth, format, imageSize, dataSize, data));
        if (isCallValid)
        {
            context->compressedTexSubImage3DRobust(targetPacked, level, xoffset, yoffset, zoffset,
                                                   width, height, depth, format, imageSize,
                                                   dataSize, data);
        }
        ANGLE_CAPTURE(CompressedTexSubImage3DRobustANGLE, isCallValid, context, targetPacked, level,
                      xoffset, yoffset, zoffset, width, height, depth, format, imageSize, dataSize,
                      data);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetQueryivRobustANGLEContextANGLE(GLeglContext ctx,
                                                   GLenum target,
                                                   GLenum pname,
                                                   GLsizei bufSize,
                                                   GLsizei *length,
                                                   GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetQueryivRobustANGLE, "glGetQueryivRobustANGLE",
          "context = %d, target = %s, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target),
          GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize, (uintptr_t)length,
          (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        QueryType targetPacked                                = FromGL<QueryType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetQueryivRobustANGLE(context, targetPacked, pname, bufSize, length, params));
        if (isCallValid)
        {
            context->getQueryivRobust(targetPacked, pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetQueryivRobustANGLE, isCallValid, context, targetPacked, pname, bufSize,
                      length, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetQueryObjectuivRobustANGLEContextANGLE(GLeglContext ctx,
                                                          GLuint id,
                                                          GLenum pname,
                                                          GLsizei bufSize,
                                                          GLsizei *length,
                                                          GLuint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetQueryObjectuivRobustANGLE, "glGetQueryObjectuivRobustANGLE",
          "context = %d, id = %u, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), id, GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize,
          (uintptr_t)length, (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        QueryID idPacked                                      = FromGL<QueryID>(id);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetQueryObjectuivRobustANGLE(
                                              context, idPacked, pname, bufSize, length, params));
        if (isCallValid)
        {
            context->getQueryObjectuivRobust(idPacked, pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetQueryObjectuivRobustANGLE, isCallValid, context, idPacked, pname, bufSize,
                      length, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetBufferPointervRobustANGLEContextANGLE(GLeglContext ctx,
                                                          GLenum target,
                                                          GLenum pname,
                                                          GLsizei bufSize,
                                                          GLsizei *length,
                                                          void **params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetBufferPointervRobustANGLE, "glGetBufferPointervRobustANGLE",
          "context = %d, target = %s, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target),
          GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize, (uintptr_t)length,
          (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        BufferBinding targetPacked                            = FromGL<BufferBinding>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetBufferPointervRobustANGLE(context, targetPacked, pname,
                                                                 bufSize, length, params));
        if (isCallValid)
        {
            context->getBufferPointervRobust(targetPacked, pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetBufferPointervRobustANGLE, isCallValid, context, targetPacked, pname,
                      bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetIntegeri_vRobustANGLEContextANGLE(GLeglContext ctx,
                                                      GLenum target,
                                                      GLuint index,
                                                      GLsizei bufSize,
                                                      GLsizei *length,
                                                      GLint *data)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetIntegeri_vRobustANGLE, "glGetIntegeri_vRobustANGLE",
          "context = %d, target = %s, index = %u, bufSize = %d, length = 0x%016" PRIxPTR
          ", data = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target), index, bufSize,
          (uintptr_t)length, (uintptr_t)data);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetIntegeri_vRobustANGLE(context, target, index, bufSize, length, data));
        if (isCallValid)
        {
            context->getIntegeri_vRobust(target, index, bufSize, length, data);
        }
        ANGLE_CAPTURE(GetIntegeri_vRobustANGLE, isCallValid, context, target, index, bufSize,
                      length, data);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetInternalformativRobustANGLEContextANGLE(GLeglContext ctx,
                                                            GLenum target,
                                                            GLenum internalformat,
                                                            GLenum pname,
                                                            GLsizei bufSize,
                                                            GLsizei *length,
                                                            GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetInternalformativRobustANGLE,
          "glGetInternalformativRobustANGLE",
          "context = %d, target = %s, internalformat = %s, pname = %s, bufSize = %d, length = "
          "0x%016" PRIxPTR ", params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target),
          GLenumToString(GLenumGroup::DefaultGroup, internalformat),
          GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize, (uintptr_t)length,
          (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetInternalformativRobustANGLE(context, target, internalformat,
                                                                   pname, bufSize, length, params));
        if (isCallValid)
        {
            context->getInternalformativRobust(target, internalformat, pname, bufSize, length,
                                               params);
        }
        ANGLE_CAPTURE(GetInternalformativRobustANGLE, isCallValid, context, target, internalformat,
                      pname, bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetVertexAttribIivRobustANGLEContextANGLE(GLeglContext ctx,
                                                           GLuint index,
                                                           GLenum pname,
                                                           GLsizei bufSize,
                                                           GLsizei *length,
                                                           GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetVertexAttribIivRobustANGLE, "glGetVertexAttribIivRobustANGLE",
          "context = %d, index = %u, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), index, GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize,
          (uintptr_t)length, (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetVertexAttribIivRobustANGLE(context, index, pname, bufSize, length, params));
        if (isCallValid)
        {
            context->getVertexAttribIivRobust(index, pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetVertexAttribIivRobustANGLE, isCallValid, context, index, pname, bufSize,
                      length, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetVertexAttribIuivRobustANGLEContextANGLE(GLeglContext ctx,
                                                            GLuint index,
                                                            GLenum pname,
                                                            GLsizei bufSize,
                                                            GLsizei *length,
                                                            GLuint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetVertexAttribIuivRobustANGLE,
          "glGetVertexAttribIuivRobustANGLE",
          "context = %d, index = %u, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), index, GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize,
          (uintptr_t)length, (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetVertexAttribIuivRobustANGLE(
                                              context, index, pname, bufSize, length, params));
        if (isCallValid)
        {
            context->getVertexAttribIuivRobust(index, pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetVertexAttribIuivRobustANGLE, isCallValid, context, index, pname, bufSize,
                      length, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetUniformuivRobustANGLEContextANGLE(GLeglContext ctx,
                                                      GLuint program,
                                                      GLint location,
                                                      GLsizei bufSize,
                                                      GLsizei *length,
                                                      GLuint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetUniformuivRobustANGLE, "glGetUniformuivRobustANGLE",
          "context = %d, program = %u, location = %d, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), program, location, bufSize, (uintptr_t)length, (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetUniformuivRobustANGLE(context, programPacked, locationPacked,
                                                             bufSize, length, params));
        if (isCallValid)
        {
            context->getUniformuivRobust(programPacked, locationPacked, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetUniformuivRobustANGLE, isCallValid, context, programPacked, locationPacked,
                      bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetActiveUniformBlockivRobustANGLEContextANGLE(GLeglContext ctx,
                                                                GLuint program,
                                                                GLuint uniformBlockIndex,
                                                                GLenum pname,
                                                                GLsizei bufSize,
                                                                GLsizei *length,
                                                                GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetActiveUniformBlockivRobustANGLE,
          "glGetActiveUniformBlockivRobustANGLE",
          "context = %d, program = %u, uniformBlockIndex = %u, pname = %s, bufSize = %d, length = "
          "0x%016" PRIxPTR ", params = 0x%016" PRIxPTR "",
          CID(context), program, uniformBlockIndex,
          GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize, (uintptr_t)length,
          (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetActiveUniformBlockivRobustANGLE(context, programPacked, uniformBlockIndex,
                                                        pname, bufSize, length, params));
        if (isCallValid)
        {
            context->getActiveUniformBlockivRobust(programPacked, uniformBlockIndex, pname, bufSize,
                                                   length, params);
        }
        ANGLE_CAPTURE(GetActiveUniformBlockivRobustANGLE, isCallValid, context, programPacked,
                      uniformBlockIndex, pname, bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetInteger64vRobustANGLEContextANGLE(GLeglContext ctx,
                                                      GLenum pname,
                                                      GLsizei bufSize,
                                                      GLsizei *length,
                                                      GLint64 *data)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetInteger64vRobustANGLE, "glGetInteger64vRobustANGLE",
          "context = %d, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", data = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize,
          (uintptr_t)length, (uintptr_t)data);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetInteger64vRobustANGLE(context, pname, bufSize, length, data));
        if (isCallValid)
        {
            context->getInteger64vRobust(pname, bufSize, length, data);
        }
        ANGLE_CAPTURE(GetInteger64vRobustANGLE, isCallValid, context, pname, bufSize, length, data);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetInteger64i_vRobustANGLEContextANGLE(GLeglContext ctx,
                                                        GLenum target,
                                                        GLuint index,
                                                        GLsizei bufSize,
                                                        GLsizei *length,
                                                        GLint64 *data)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetInteger64i_vRobustANGLE, "glGetInteger64i_vRobustANGLE",
          "context = %d, target = %s, index = %u, bufSize = %d, length = 0x%016" PRIxPTR
          ", data = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target), index, bufSize,
          (uintptr_t)length, (uintptr_t)data);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetInteger64i_vRobustANGLE(context, target, index, bufSize, length, data));
        if (isCallValid)
        {
            context->getInteger64i_vRobust(target, index, bufSize, length, data);
        }
        ANGLE_CAPTURE(GetInteger64i_vRobustANGLE, isCallValid, context, target, index, bufSize,
                      length, data);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetBufferParameteri64vRobustANGLEContextANGLE(GLeglContext ctx,
                                                               GLenum target,
                                                               GLenum pname,
                                                               GLsizei bufSize,
                                                               GLsizei *length,
                                                               GLint64 *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetBufferParameteri64vRobustANGLE,
          "glGetBufferParameteri64vRobustANGLE",
          "context = %d, target = %s, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target),
          GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize, (uintptr_t)length,
          (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        BufferBinding targetPacked                            = FromGL<BufferBinding>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetBufferParameteri64vRobustANGLE(context, targetPacked, pname,
                                                                      bufSize, length, params));
        if (isCallValid)
        {
            context->getBufferParameteri64vRobust(targetPacked, pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetBufferParameteri64vRobustANGLE, isCallValid, context, targetPacked, pname,
                      bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY SamplerParameterivRobustANGLEContextANGLE(GLeglContext ctx,
                                                           GLuint sampler,
                                                           GLuint pname,
                                                           GLsizei bufSize,
                                                           const GLint *param)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::SamplerParameterivRobustANGLE, "glSamplerParameterivRobustANGLE",
          "context = %d, sampler = %u, pname = %u, bufSize = %d, param = 0x%016" PRIxPTR "",
          CID(context), sampler, pname, bufSize, (uintptr_t)param);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        SamplerID samplerPacked                               = FromGL<SamplerID>(sampler);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateSamplerParameterivRobustANGLE(context, samplerPacked, pname, bufSize, param));
        if (isCallValid)
        {
            context->samplerParameterivRobust(samplerPacked, pname, bufSize, param);
        }
        ANGLE_CAPTURE(SamplerParameterivRobustANGLE, isCallValid, context, samplerPacked, pname,
                      bufSize, param);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY SamplerParameterfvRobustANGLEContextANGLE(GLeglContext ctx,
                                                           GLuint sampler,
                                                           GLenum pname,
                                                           GLsizei bufSize,
                                                           const GLfloat *param)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::SamplerParameterfvRobustANGLE, "glSamplerParameterfvRobustANGLE",
          "context = %d, sampler = %u, pname = %s, bufSize = %d, param = 0x%016" PRIxPTR "",
          CID(context), sampler, GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize,
          (uintptr_t)param);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        SamplerID samplerPacked                               = FromGL<SamplerID>(sampler);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateSamplerParameterfvRobustANGLE(context, samplerPacked, pname, bufSize, param));
        if (isCallValid)
        {
            context->samplerParameterfvRobust(samplerPacked, pname, bufSize, param);
        }
        ANGLE_CAPTURE(SamplerParameterfvRobustANGLE, isCallValid, context, samplerPacked, pname,
                      bufSize, param);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetSamplerParameterivRobustANGLEContextANGLE(GLeglContext ctx,
                                                              GLuint sampler,
                                                              GLenum pname,
                                                              GLsizei bufSize,
                                                              GLsizei *length,
                                                              GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetSamplerParameterivRobustANGLE,
          "glGetSamplerParameterivRobustANGLE",
          "context = %d, sampler = %u, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), sampler, GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize,
          (uintptr_t)length, (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        SamplerID samplerPacked                               = FromGL<SamplerID>(sampler);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetSamplerParameterivRobustANGLE(context, samplerPacked, pname,
                                                                     bufSize, length, params));
        if (isCallValid)
        {
            context->getSamplerParameterivRobust(samplerPacked, pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetSamplerParameterivRobustANGLE, isCallValid, context, samplerPacked, pname,
                      bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetSamplerParameterfvRobustANGLEContextANGLE(GLeglContext ctx,
                                                              GLuint sampler,
                                                              GLenum pname,
                                                              GLsizei bufSize,
                                                              GLsizei *length,
                                                              GLfloat *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetSamplerParameterfvRobustANGLE,
          "glGetSamplerParameterfvRobustANGLE",
          "context = %d, sampler = %u, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), sampler, GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize,
          (uintptr_t)length, (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        SamplerID samplerPacked                               = FromGL<SamplerID>(sampler);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetSamplerParameterfvRobustANGLE(context, samplerPacked, pname,
                                                                     bufSize, length, params));
        if (isCallValid)
        {
            context->getSamplerParameterfvRobust(samplerPacked, pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetSamplerParameterfvRobustANGLE, isCallValid, context, samplerPacked, pname,
                      bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetFramebufferParameterivRobustANGLEContextANGLE(GLeglContext ctx,
                                                                  GLenum target,
                                                                  GLenum pname,
                                                                  GLsizei bufSize,
                                                                  GLsizei *length,
                                                                  GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetFramebufferParameterivRobustANGLE,
          "glGetFramebufferParameterivRobustANGLE",
          "context = %d, target = %s, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target),
          GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize, (uintptr_t)length,
          (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetFramebufferParameterivRobustANGLE(
                                              context, target, pname, bufSize, length, params));
        if (isCallValid)
        {
            context->getFramebufferParameterivRobust(target, pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetFramebufferParameterivRobustANGLE, isCallValid, context, target, pname,
                      bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetProgramInterfaceivRobustANGLEContextANGLE(GLeglContext ctx,
                                                              GLuint program,
                                                              GLenum programInterface,
                                                              GLenum pname,
                                                              GLsizei bufSize,
                                                              GLsizei *length,
                                                              GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetProgramInterfaceivRobustANGLE,
          "glGetProgramInterfaceivRobustANGLE",
          "context = %d, program = %u, programInterface = %s, pname = %s, bufSize = %d, length = "
          "0x%016" PRIxPTR ", params = 0x%016" PRIxPTR "",
          CID(context), program, GLenumToString(GLenumGroup::DefaultGroup, programInterface),
          GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize, (uintptr_t)length,
          (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetProgramInterfaceivRobustANGLE(context, programPacked, programInterface,
                                                      pname, bufSize, length, params));
        if (isCallValid)
        {
            context->getProgramInterfaceivRobust(programPacked, programInterface, pname, bufSize,
                                                 length, params);
        }
        ANGLE_CAPTURE(GetProgramInterfaceivRobustANGLE, isCallValid, context, programPacked,
                      programInterface, pname, bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetBooleani_vRobustANGLEContextANGLE(GLeglContext ctx,
                                                      GLenum target,
                                                      GLuint index,
                                                      GLsizei bufSize,
                                                      GLsizei *length,
                                                      GLboolean *data)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetBooleani_vRobustANGLE, "glGetBooleani_vRobustANGLE",
          "context = %d, target = %s, index = %u, bufSize = %d, length = 0x%016" PRIxPTR
          ", data = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target), index, bufSize,
          (uintptr_t)length, (uintptr_t)data);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetBooleani_vRobustANGLE(context, target, index, bufSize, length, data));
        if (isCallValid)
        {
            context->getBooleani_vRobust(target, index, bufSize, length, data);
        }
        ANGLE_CAPTURE(GetBooleani_vRobustANGLE, isCallValid, context, target, index, bufSize,
                      length, data);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetMultisamplefvRobustANGLEContextANGLE(GLeglContext ctx,
                                                         GLenum pname,
                                                         GLuint index,
                                                         GLsizei bufSize,
                                                         GLsizei *length,
                                                         GLfloat *val)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetMultisamplefvRobustANGLE, "glGetMultisamplefvRobustANGLE",
          "context = %d, pname = %s, index = %u, bufSize = %d, length = 0x%016" PRIxPTR
          ", val = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, pname), index, bufSize,
          (uintptr_t)length, (uintptr_t)val);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetMultisamplefvRobustANGLE(context, pname, index, bufSize, length, val));
        if (isCallValid)
        {
            context->getMultisamplefvRobust(pname, index, bufSize, length, val);
        }
        ANGLE_CAPTURE(GetMultisamplefvRobustANGLE, isCallValid, context, pname, index, bufSize,
                      length, val);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetTexLevelParameterivRobustANGLEContextANGLE(GLeglContext ctx,
                                                               GLenum target,
                                                               GLint level,
                                                               GLenum pname,
                                                               GLsizei bufSize,
                                                               GLsizei *length,
                                                               GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetTexLevelParameterivRobustANGLE,
          "glGetTexLevelParameterivRobustANGLE",
          "context = %d, target = %s, level = %d, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target), level,
          GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize, (uintptr_t)length,
          (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetTexLevelParameterivRobustANGLE(
                                context, targetPacked, level, pname, bufSize, length, params));
        if (isCallValid)
        {
            context->getTexLevelParameterivRobust(targetPacked, level, pname, bufSize, length,
                                                  params);
        }
        ANGLE_CAPTURE(GetTexLevelParameterivRobustANGLE, isCallValid, context, targetPacked, level,
                      pname, bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetTexLevelParameterfvRobustANGLEContextANGLE(GLeglContext ctx,
                                                               GLenum target,
                                                               GLint level,
                                                               GLenum pname,
                                                               GLsizei bufSize,
                                                               GLsizei *length,
                                                               GLfloat *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetTexLevelParameterfvRobustANGLE,
          "glGetTexLevelParameterfvRobustANGLE",
          "context = %d, target = %s, level = %d, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target), level,
          GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize, (uintptr_t)length,
          (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetTexLevelParameterfvRobustANGLE(
                                context, targetPacked, level, pname, bufSize, length, params));
        if (isCallValid)
        {
            context->getTexLevelParameterfvRobust(targetPacked, level, pname, bufSize, length,
                                                  params);
        }
        ANGLE_CAPTURE(GetTexLevelParameterfvRobustANGLE, isCallValid, context, targetPacked, level,
                      pname, bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetPointervRobustANGLERobustANGLEContextANGLE(GLeglContext ctx,
                                                               GLenum pname,
                                                               GLsizei bufSize,
                                                               GLsizei *length,
                                                               void **params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetPointervRobustANGLERobustANGLE,
          "glGetPointervRobustANGLERobustANGLE",
          "context = %d, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize,
          (uintptr_t)length, (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetPointervRobustANGLERobustANGLE(context, pname, bufSize, length, params));
        if (isCallValid)
        {
            context->getPointervRobustANGLERobust(pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetPointervRobustANGLERobustANGLE, isCallValid, context, pname, bufSize,
                      length, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ReadnPixelsRobustANGLEContextANGLE(GLeglContext ctx,
                                                    GLint x,
                                                    GLint y,
                                                    GLsizei width,
                                                    GLsizei height,
                                                    GLenum format,
                                                    GLenum type,
                                                    GLsizei bufSize,
                                                    GLsizei *length,
                                                    GLsizei *columns,
                                                    GLsizei *rows,
                                                    void *data)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ReadnPixelsRobustANGLE, "glReadnPixelsRobustANGLE",
          "context = %d, x = %d, y = %d, width = %d, height = %d, format = %s, type = %s, bufSize "
          "= %d, length = 0x%016" PRIxPTR ", columns = 0x%016" PRIxPTR ", rows = 0x%016" PRIxPTR
          ", data = 0x%016" PRIxPTR "",
          CID(context), x, y, width, height, GLenumToString(GLenumGroup::DefaultGroup, format),
          GLenumToString(GLenumGroup::DefaultGroup, type), bufSize, (uintptr_t)length,
          (uintptr_t)columns, (uintptr_t)rows, (uintptr_t)data);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateReadnPixelsRobustANGLE(context, x, y, width, height, format, type, bufSize,
                                            length, columns, rows, data));
        if (isCallValid)
        {
            context->readnPixelsRobust(x, y, width, height, format, type, bufSize, length, columns,
                                       rows, data);
        }
        ANGLE_CAPTURE(ReadnPixelsRobustANGLE, isCallValid, context, x, y, width, height, format,
                      type, bufSize, length, columns, rows, data);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetnUniformfvRobustANGLEContextANGLE(GLeglContext ctx,
                                                      GLuint program,
                                                      GLint location,
                                                      GLsizei bufSize,
                                                      GLsizei *length,
                                                      GLfloat *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetnUniformfvRobustANGLE, "glGetnUniformfvRobustANGLE",
          "context = %d, program = %u, location = %d, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), program, location, bufSize, (uintptr_t)length, (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetnUniformfvRobustANGLE(context, programPacked, locationPacked,
                                                             bufSize, length, params));
        if (isCallValid)
        {
            context->getnUniformfvRobust(programPacked, locationPacked, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetnUniformfvRobustANGLE, isCallValid, context, programPacked, locationPacked,
                      bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetnUniformivRobustANGLEContextANGLE(GLeglContext ctx,
                                                      GLuint program,
                                                      GLint location,
                                                      GLsizei bufSize,
                                                      GLsizei *length,
                                                      GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetnUniformivRobustANGLE, "glGetnUniformivRobustANGLE",
          "context = %d, program = %u, location = %d, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), program, location, bufSize, (uintptr_t)length, (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetnUniformivRobustANGLE(context, programPacked, locationPacked,
                                                             bufSize, length, params));
        if (isCallValid)
        {
            context->getnUniformivRobust(programPacked, locationPacked, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetnUniformivRobustANGLE, isCallValid, context, programPacked, locationPacked,
                      bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetnUniformuivRobustANGLEContextANGLE(GLeglContext ctx,
                                                       GLuint program,
                                                       GLint location,
                                                       GLsizei bufSize,
                                                       GLsizei *length,
                                                       GLuint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetnUniformuivRobustANGLE, "glGetnUniformuivRobustANGLE",
          "context = %d, program = %u, location = %d, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), program, location, bufSize, (uintptr_t)length, (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ShaderProgramID programPacked                         = FromGL<ShaderProgramID>(program);
        UniformLocation locationPacked                        = FromGL<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetnUniformuivRobustANGLE(
                                context, programPacked, locationPacked, bufSize, length, params));
        if (isCallValid)
        {
            context->getnUniformuivRobust(programPacked, locationPacked, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetnUniformuivRobustANGLE, isCallValid, context, programPacked,
                      locationPacked, bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexParameterIivRobustANGLEContextANGLE(GLeglContext ctx,
                                                        GLenum target,
                                                        GLenum pname,
                                                        GLsizei bufSize,
                                                        const GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexParameterIivRobustANGLE, "glTexParameterIivRobustANGLE",
          "context = %d, target = %s, pname = %s, bufSize = %d, params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target),
          GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize, (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTexParameterIivRobustANGLE(context, targetPacked, pname, bufSize, params));
        if (isCallValid)
        {
            context->texParameterIivRobust(targetPacked, pname, bufSize, params);
        }
        ANGLE_CAPTURE(TexParameterIivRobustANGLE, isCallValid, context, targetPacked, pname,
                      bufSize, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexParameterIuivRobustANGLEContextANGLE(GLeglContext ctx,
                                                         GLenum target,
                                                         GLenum pname,
                                                         GLsizei bufSize,
                                                         const GLuint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexParameterIuivRobustANGLE, "glTexParameterIuivRobustANGLE",
          "context = %d, target = %s, pname = %s, bufSize = %d, params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target),
          GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize, (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTexParameterIuivRobustANGLE(context, targetPacked, pname, bufSize, params));
        if (isCallValid)
        {
            context->texParameterIuivRobust(targetPacked, pname, bufSize, params);
        }
        ANGLE_CAPTURE(TexParameterIuivRobustANGLE, isCallValid, context, targetPacked, pname,
                      bufSize, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetTexParameterIivRobustANGLEContextANGLE(GLeglContext ctx,
                                                           GLenum target,
                                                           GLenum pname,
                                                           GLsizei bufSize,
                                                           GLsizei *length,
                                                           GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetTexParameterIivRobustANGLE, "glGetTexParameterIivRobustANGLE",
          "context = %d, target = %s, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target),
          GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize, (uintptr_t)length,
          (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetTexParameterIivRobustANGLE(context, targetPacked, pname,
                                                                  bufSize, length, params));
        if (isCallValid)
        {
            context->getTexParameterIivRobust(targetPacked, pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetTexParameterIivRobustANGLE, isCallValid, context, targetPacked, pname,
                      bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetTexParameterIuivRobustANGLEContextANGLE(GLeglContext ctx,
                                                            GLenum target,
                                                            GLenum pname,
                                                            GLsizei bufSize,
                                                            GLsizei *length,
                                                            GLuint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetTexParameterIuivRobustANGLE,
          "glGetTexParameterIuivRobustANGLE",
          "context = %d, target = %s, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target),
          GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize, (uintptr_t)length,
          (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetTexParameterIuivRobustANGLE(context, targetPacked, pname,
                                                                   bufSize, length, params));
        if (isCallValid)
        {
            context->getTexParameterIuivRobust(targetPacked, pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetTexParameterIuivRobustANGLE, isCallValid, context, targetPacked, pname,
                      bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY SamplerParameterIivRobustANGLEContextANGLE(GLeglContext ctx,
                                                            GLuint sampler,
                                                            GLenum pname,
                                                            GLsizei bufSize,
                                                            const GLint *param)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::SamplerParameterIivRobustANGLE,
          "glSamplerParameterIivRobustANGLE",
          "context = %d, sampler = %u, pname = %s, bufSize = %d, param = 0x%016" PRIxPTR "",
          CID(context), sampler, GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize,
          (uintptr_t)param);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        SamplerID samplerPacked                               = FromGL<SamplerID>(sampler);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateSamplerParameterIivRobustANGLE(context, samplerPacked, pname, bufSize, param));
        if (isCallValid)
        {
            context->samplerParameterIivRobust(samplerPacked, pname, bufSize, param);
        }
        ANGLE_CAPTURE(SamplerParameterIivRobustANGLE, isCallValid, context, samplerPacked, pname,
                      bufSize, param);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY SamplerParameterIuivRobustANGLEContextANGLE(GLeglContext ctx,
                                                             GLuint sampler,
                                                             GLenum pname,
                                                             GLsizei bufSize,
                                                             const GLuint *param)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::SamplerParameterIuivRobustANGLE,
          "glSamplerParameterIuivRobustANGLE",
          "context = %d, sampler = %u, pname = %s, bufSize = %d, param = 0x%016" PRIxPTR "",
          CID(context), sampler, GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize,
          (uintptr_t)param);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        SamplerID samplerPacked                               = FromGL<SamplerID>(sampler);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateSamplerParameterIuivRobustANGLE(
                                              context, samplerPacked, pname, bufSize, param));
        if (isCallValid)
        {
            context->samplerParameterIuivRobust(samplerPacked, pname, bufSize, param);
        }
        ANGLE_CAPTURE(SamplerParameterIuivRobustANGLE, isCallValid, context, samplerPacked, pname,
                      bufSize, param);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetSamplerParameterIivRobustANGLEContextANGLE(GLeglContext ctx,
                                                               GLuint sampler,
                                                               GLenum pname,
                                                               GLsizei bufSize,
                                                               GLsizei *length,
                                                               GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetSamplerParameterIivRobustANGLE,
          "glGetSamplerParameterIivRobustANGLE",
          "context = %d, sampler = %u, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), sampler, GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize,
          (uintptr_t)length, (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        SamplerID samplerPacked                               = FromGL<SamplerID>(sampler);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetSamplerParameterIivRobustANGLE(context, samplerPacked, pname,
                                                                      bufSize, length, params));
        if (isCallValid)
        {
            context->getSamplerParameterIivRobust(samplerPacked, pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetSamplerParameterIivRobustANGLE, isCallValid, context, samplerPacked, pname,
                      bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetSamplerParameterIuivRobustANGLEContextANGLE(GLeglContext ctx,
                                                                GLuint sampler,
                                                                GLenum pname,
                                                                GLsizei bufSize,
                                                                GLsizei *length,
                                                                GLuint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetSamplerParameterIuivRobustANGLE,
          "glGetSamplerParameterIuivRobustANGLE",
          "context = %d, sampler = %u, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), sampler, GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize,
          (uintptr_t)length, (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        SamplerID samplerPacked                               = FromGL<SamplerID>(sampler);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetSamplerParameterIuivRobustANGLE(
                                context, samplerPacked, pname, bufSize, length, params));
        if (isCallValid)
        {
            context->getSamplerParameterIuivRobust(samplerPacked, pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetSamplerParameterIuivRobustANGLE, isCallValid, context, samplerPacked,
                      pname, bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetQueryObjectivRobustANGLEContextANGLE(GLeglContext ctx,
                                                         GLuint id,
                                                         GLenum pname,
                                                         GLsizei bufSize,
                                                         GLsizei *length,
                                                         GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetQueryObjectivRobustANGLE, "glGetQueryObjectivRobustANGLE",
          "context = %d, id = %u, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), id, GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize,
          (uintptr_t)length, (uintptr_t)params);

    if (context)
    {
        ASSERT(context == GetValidGlobalContext());
        QueryID idPacked                                      = FromGL<QueryID>(id);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetQueryObjectivRobustANGLE(
                                              context, idPacked, pname, bufSize, length, params));
        if (isCallValid)
        {
            context->getQueryObjectivRobust(idPacked, pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetQueryObjectivRobustANGLE, isCallValid, context, idPacked, pname, bufSize,
                      length, params);
    }
    else
    {}
}

void GL_APIENTRY GetQueryObjecti64vRobustANGLEContextANGLE(GLeglContext ctx,
                                                           GLuint id,
                                                           GLenum pname,
                                                           GLsizei bufSize,
                                                           GLsizei *length,
                                                           GLint64 *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetQueryObjecti64vRobustANGLE, "glGetQueryObjecti64vRobustANGLE",
          "context = %d, id = %u, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), id, GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize,
          (uintptr_t)length, (uintptr_t)params);

    if (context)
    {
        ASSERT(context == GetValidGlobalContext());
        QueryID idPacked                                      = FromGL<QueryID>(id);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetQueryObjecti64vRobustANGLE(
                                              context, idPacked, pname, bufSize, length, params));
        if (isCallValid)
        {
            context->getQueryObjecti64vRobust(idPacked, pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetQueryObjecti64vRobustANGLE, isCallValid, context, idPacked, pname, bufSize,
                      length, params);
    }
    else
    {}
}

void GL_APIENTRY GetQueryObjectui64vRobustANGLEContextANGLE(GLeglContext ctx,
                                                            GLuint id,
                                                            GLenum pname,
                                                            GLsizei bufSize,
                                                            GLsizei *length,
                                                            GLuint64 *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetQueryObjectui64vRobustANGLE,
          "glGetQueryObjectui64vRobustANGLE",
          "context = %d, id = %u, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
          ", params = 0x%016" PRIxPTR "",
          CID(context), id, GLenumToString(GLenumGroup::DefaultGroup, pname), bufSize,
          (uintptr_t)length, (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        QueryID idPacked                                      = FromGL<QueryID>(id);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetQueryObjectui64vRobustANGLE(
                                              context, idPacked, pname, bufSize, length, params));
        if (isCallValid)
        {
            context->getQueryObjectui64vRobust(idPacked, pname, bufSize, length, params);
        }
        ANGLE_CAPTURE(GetQueryObjectui64vRobustANGLE, isCallValid, context, idPacked, pname,
                      bufSize, length, params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY CopyTexture3DANGLEContextANGLE(GLeglContext ctx,
                                                GLuint sourceId,
                                                GLint sourceLevel,
                                                GLenum destTarget,
                                                GLuint destId,
                                                GLint destLevel,
                                                GLint internalFormat,
                                                GLenum destType,
                                                GLboolean unpackFlipY,
                                                GLboolean unpackPremultiplyAlpha,
                                                GLboolean unpackUnmultiplyAlpha)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::CopyTexture3DANGLE, "glCopyTexture3DANGLE",
          "context = %d, sourceId = %u, sourceLevel = %d, destTarget = %s, destId = %u, destLevel "
          "= %d, internalFormat = %d, destType = %s, unpackFlipY = %s, unpackPremultiplyAlpha = "
          "%s, unpackUnmultiplyAlpha = %s",
          CID(context), sourceId, sourceLevel,
          GLenumToString(GLenumGroup::DefaultGroup, destTarget), destId, destLevel, internalFormat,
          GLenumToString(GLenumGroup::DefaultGroup, destType), GLbooleanToString(unpackFlipY),
          GLbooleanToString(unpackPremultiplyAlpha), GLbooleanToString(unpackUnmultiplyAlpha));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureID sourceIdPacked                              = FromGL<TextureID>(sourceId);
        TextureTarget destTargetPacked                        = FromGL<TextureTarget>(destTarget);
        TextureID destIdPacked                                = FromGL<TextureID>(destId);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateCopyTexture3DANGLE(
                                context, sourceIdPacked, sourceLevel, destTargetPacked,
                                destIdPacked, destLevel, internalFormat, destType, unpackFlipY,
                                unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
        if (isCallValid)
        {
            context->copyTexture3D(sourceIdPacked, sourceLevel, destTargetPacked, destIdPacked,
                                   destLevel, internalFormat, destType, unpackFlipY,
                                   unpackPremultiplyAlpha, unpackUnmultiplyAlpha);
        }
        ANGLE_CAPTURE(CopyTexture3DANGLE, isCallValid, context, sourceIdPacked, sourceLevel,
                      destTargetPacked, destIdPacked, destLevel, internalFormat, destType,
                      unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY CopySubTexture3DANGLEContextANGLE(GLeglContext ctx,
                                                   GLuint sourceId,
                                                   GLint sourceLevel,
                                                   GLenum destTarget,
                                                   GLuint destId,
                                                   GLint destLevel,
                                                   GLint xoffset,
                                                   GLint yoffset,
                                                   GLint zoffset,
                                                   GLint x,
                                                   GLint y,
                                                   GLint z,
                                                   GLint width,
                                                   GLint height,
                                                   GLint depth,
                                                   GLboolean unpackFlipY,
                                                   GLboolean unpackPremultiplyAlpha,
                                                   GLboolean unpackUnmultiplyAlpha)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::CopySubTexture3DANGLE, "glCopySubTexture3DANGLE",
          "context = %d, sourceId = %u, sourceLevel = %d, destTarget = %s, destId = %u, destLevel "
          "= %d, xoffset = %d, yoffset = %d, zoffset = %d, x = %d, y = %d, z = %d, width = %d, "
          "height = %d, depth = %d, unpackFlipY = %s, unpackPremultiplyAlpha = %s, "
          "unpackUnmultiplyAlpha = %s",
          CID(context), sourceId, sourceLevel,
          GLenumToString(GLenumGroup::DefaultGroup, destTarget), destId, destLevel, xoffset,
          yoffset, zoffset, x, y, z, width, height, depth, GLbooleanToString(unpackFlipY),
          GLbooleanToString(unpackPremultiplyAlpha), GLbooleanToString(unpackUnmultiplyAlpha));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureID sourceIdPacked                              = FromGL<TextureID>(sourceId);
        TextureTarget destTargetPacked                        = FromGL<TextureTarget>(destTarget);
        TextureID destIdPacked                                = FromGL<TextureID>(destId);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateCopySubTexture3DANGLE(context, sourceIdPacked, sourceLevel, destTargetPacked,
                                           destIdPacked, destLevel, xoffset, yoffset, zoffset, x, y,
                                           z, width, height, depth, unpackFlipY,
                                           unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
        if (isCallValid)
        {
            context->copySubTexture3D(sourceIdPacked, sourceLevel, destTargetPacked, destIdPacked,
                                      destLevel, xoffset, yoffset, zoffset, x, y, z, width, height,
                                      depth, unpackFlipY, unpackPremultiplyAlpha,
                                      unpackUnmultiplyAlpha);
        }
        ANGLE_CAPTURE(CopySubTexture3DANGLE, isCallValid, context, sourceIdPacked, sourceLevel,
                      destTargetPacked, destIdPacked, destLevel, xoffset, yoffset, zoffset, x, y, z,
                      width, height, depth, unpackFlipY, unpackPremultiplyAlpha,
                      unpackUnmultiplyAlpha);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexStorage2DMultisampleANGLEContextANGLE(GLeglContext ctx,
                                                          GLenum target,
                                                          GLsizei samples,
                                                          GLenum internalformat,
                                                          GLsizei width,
                                                          GLsizei height,
                                                          GLboolean fixedsamplelocations)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexStorage2DMultisampleANGLE, "glTexStorage2DMultisampleANGLE",
          "context = %d, target = %s, samples = %d, internalformat = %s, width = %d, height = %d, "
          "fixedsamplelocations = %s",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target), samples,
          GLenumToString(GLenumGroup::DefaultGroup, internalformat), width, height,
          GLbooleanToString(fixedsamplelocations));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTexStorage2DMultisampleANGLE(context, targetPacked, samples, internalformat,
                                                  width, height, fixedsamplelocations));
        if (isCallValid)
        {
            context->texStorage2DMultisample(targetPacked, samples, internalformat, width, height,
                                             fixedsamplelocations);
        }
        ANGLE_CAPTURE(TexStorage2DMultisampleANGLE, isCallValid, context, targetPacked, samples,
                      internalformat, width, height, fixedsamplelocations);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetTexLevelParameterivANGLEContextANGLE(GLeglContext ctx,
                                                         GLenum target,
                                                         GLint level,
                                                         GLenum pname,
                                                         GLint *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetTexLevelParameterivANGLE, "glGetTexLevelParameterivANGLE",
          "context = %d, target = %s, level = %d, pname = %s, params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target), level,
          GLenumToString(GLenumGroup::DefaultGroup, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetTexLevelParameterivANGLE(context, targetPacked, level, pname, params));
        if (isCallValid)
        {
            context->getTexLevelParameteriv(targetPacked, level, pname, params);
        }
        ANGLE_CAPTURE(GetTexLevelParameterivANGLE, isCallValid, context, targetPacked, level, pname,
                      params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetTexLevelParameterfvANGLEContextANGLE(GLeglContext ctx,
                                                         GLenum target,
                                                         GLint level,
                                                         GLenum pname,
                                                         GLfloat *params)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetTexLevelParameterfvANGLE, "glGetTexLevelParameterfvANGLE",
          "context = %d, target = %s, level = %d, pname = %s, params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target), level,
          GLenumToString(GLenumGroup::DefaultGroup, pname), (uintptr_t)params);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetTexLevelParameterfvANGLE(context, targetPacked, level, pname, params));
        if (isCallValid)
        {
            context->getTexLevelParameterfv(targetPacked, level, pname, params);
        }
        ANGLE_CAPTURE(GetTexLevelParameterfvANGLE, isCallValid, context, targetPacked, level, pname,
                      params);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY MultiDrawArraysANGLEContextANGLE(GLeglContext ctx,
                                                  GLenum mode,
                                                  const GLint *firsts,
                                                  const GLsizei *counts,
                                                  GLsizei drawcount)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::MultiDrawArraysANGLE, "glMultiDrawArraysANGLE",
          "context = %d, mode = %s, firsts = 0x%016" PRIxPTR ", counts = 0x%016" PRIxPTR
          ", drawcount = %d",
          CID(context), GLenumToString(GLenumGroup::PrimitiveType, mode), (uintptr_t)firsts,
          (uintptr_t)counts, drawcount);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateMultiDrawArraysANGLE(context, modePacked, firsts, counts, drawcount));
        if (isCallValid)
        {
            context->multiDrawArrays(modePacked, firsts, counts, drawcount);
        }
        ANGLE_CAPTURE(MultiDrawArraysANGLE, isCallValid, context, modePacked, firsts, counts,
                      drawcount);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY MultiDrawArraysInstancedANGLEContextANGLE(GLeglContext ctx,
                                                           GLenum mode,
                                                           const GLint *firsts,
                                                           const GLsizei *counts,
                                                           const GLsizei *instanceCounts,
                                                           GLsizei drawcount)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::MultiDrawArraysInstancedANGLE, "glMultiDrawArraysInstancedANGLE",
          "context = %d, mode = %s, firsts = 0x%016" PRIxPTR ", counts = 0x%016" PRIxPTR
          ", instanceCounts = 0x%016" PRIxPTR ", drawcount = %d",
          CID(context), GLenumToString(GLenumGroup::PrimitiveType, mode), (uintptr_t)firsts,
          (uintptr_t)counts, (uintptr_t)instanceCounts, drawcount);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateMultiDrawArraysInstancedANGLE(
                                context, modePacked, firsts, counts, instanceCounts, drawcount));
        if (isCallValid)
        {
            context->multiDrawArraysInstanced(modePacked, firsts, counts, instanceCounts,
                                              drawcount);
        }
        ANGLE_CAPTURE(MultiDrawArraysInstancedANGLE, isCallValid, context, modePacked, firsts,
                      counts, instanceCounts, drawcount);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY MultiDrawElementsANGLEContextANGLE(GLeglContext ctx,
                                                    GLenum mode,
                                                    const GLsizei *counts,
                                                    GLenum type,
                                                    const GLvoid *const *indices,
                                                    GLsizei drawcount)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::MultiDrawElementsANGLE, "glMultiDrawElementsANGLE",
          "context = %d, mode = %s, counts = 0x%016" PRIxPTR ", type = %s, indices = 0x%016" PRIxPTR
          ", drawcount = %d",
          CID(context), GLenumToString(GLenumGroup::PrimitiveType, mode), (uintptr_t)counts,
          GLenumToString(GLenumGroup::DrawElementsType, type), (uintptr_t)indices, drawcount);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        DrawElementsType typePacked                           = FromGL<DrawElementsType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateMultiDrawElementsANGLE(context, modePacked, counts, typePacked,
                                                           indices, drawcount));
        if (isCallValid)
        {
            context->multiDrawElements(modePacked, counts, typePacked, indices, drawcount);
        }
        ANGLE_CAPTURE(MultiDrawElementsANGLE, isCallValid, context, modePacked, counts, typePacked,
                      indices, drawcount);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY MultiDrawElementsInstancedANGLEContextANGLE(GLeglContext ctx,
                                                             GLenum mode,
                                                             const GLsizei *counts,
                                                             GLenum type,
                                                             const GLvoid *const *indices,
                                                             const GLsizei *instanceCounts,
                                                             GLsizei drawcount)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::MultiDrawElementsInstancedANGLE,
          "glMultiDrawElementsInstancedANGLE",
          "context = %d, mode = %s, counts = 0x%016" PRIxPTR ", type = %s, indices = 0x%016" PRIxPTR
          ", instanceCounts = 0x%016" PRIxPTR ", drawcount = %d",
          CID(context), GLenumToString(GLenumGroup::PrimitiveType, mode), (uintptr_t)counts,
          GLenumToString(GLenumGroup::DrawElementsType, type), (uintptr_t)indices,
          (uintptr_t)instanceCounts, drawcount);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        DrawElementsType typePacked                           = FromGL<DrawElementsType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateMultiDrawElementsInstancedANGLE(context, modePacked, counts, typePacked,
                                                     indices, instanceCounts, drawcount));
        if (isCallValid)
        {
            context->multiDrawElementsInstanced(modePacked, counts, typePacked, indices,
                                                instanceCounts, drawcount);
        }
        ANGLE_CAPTURE(MultiDrawElementsInstancedANGLE, isCallValid, context, modePacked, counts,
                      typePacked, indices, instanceCounts, drawcount);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY DrawArraysInstancedBaseInstanceANGLEContextANGLE(GLeglContext ctx,
                                                                  GLenum mode,
                                                                  GLint first,
                                                                  GLsizei count,
                                                                  GLsizei instanceCount,
                                                                  GLuint baseInstance)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DrawArraysInstancedBaseInstanceANGLE,
          "glDrawArraysInstancedBaseInstanceANGLE",
          "context = %d, mode = %s, first = %d, count = %d, instanceCount = %d, baseInstance = %u",
          CID(context), GLenumToString(GLenumGroup::PrimitiveType, mode), first, count,
          instanceCount, baseInstance);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateDrawArraysInstancedBaseInstanceANGLE(
                                context, modePacked, first, count, instanceCount, baseInstance));
        if (isCallValid)
        {
            context->drawArraysInstancedBaseInstance(modePacked, first, count, instanceCount,
                                                     baseInstance);
        }
        ANGLE_CAPTURE(DrawArraysInstancedBaseInstanceANGLE, isCallValid, context, modePacked, first,
                      count, instanceCount, baseInstance);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY
DrawElementsInstancedBaseVertexBaseInstanceANGLEContextANGLE(GLeglContext ctx,
                                                             GLenum mode,
                                                             GLsizei count,
                                                             GLenum type,
                                                             const GLvoid *indices,
                                                             GLsizei instanceCounts,
                                                             GLint baseVertex,
                                                             GLuint baseInstance)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::DrawElementsInstancedBaseVertexBaseInstanceANGLE,
          "glDrawElementsInstancedBaseVertexBaseInstanceANGLE",
          "context = %d, mode = %s, count = %d, type = %s, indices = 0x%016" PRIxPTR
          ", instanceCounts = %d, baseVertex = %d, baseInstance = %u",
          CID(context), GLenumToString(GLenumGroup::PrimitiveType, mode), count,
          GLenumToString(GLenumGroup::DrawElementsType, type), (uintptr_t)indices, instanceCounts,
          baseVertex, baseInstance);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        DrawElementsType typePacked                           = FromGL<DrawElementsType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateDrawElementsInstancedBaseVertexBaseInstanceANGLE(
                                              context, modePacked, count, typePacked, indices,
                                              instanceCounts, baseVertex, baseInstance));
        if (isCallValid)
        {
            context->drawElementsInstancedBaseVertexBaseInstance(
                modePacked, count, typePacked, indices, instanceCounts, baseVertex, baseInstance);
        }
        ANGLE_CAPTURE(DrawElementsInstancedBaseVertexBaseInstanceANGLE, isCallValid, context,
                      modePacked, count, typePacked, indices, instanceCounts, baseVertex,
                      baseInstance);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY
MultiDrawArraysInstancedBaseInstanceANGLEContextANGLE(GLeglContext ctx,
                                                      GLenum mode,
                                                      const GLint *firsts,
                                                      const GLsizei *counts,
                                                      const GLsizei *instanceCounts,
                                                      const GLuint *baseInstances,
                                                      GLsizei drawcount)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::MultiDrawArraysInstancedBaseInstanceANGLE,
          "glMultiDrawArraysInstancedBaseInstanceANGLE",
          "context = %d, mode = %s, firsts = 0x%016" PRIxPTR ", counts = 0x%016" PRIxPTR
          ", instanceCounts = 0x%016" PRIxPTR ", baseInstances = 0x%016" PRIxPTR ", drawcount = %d",
          CID(context), GLenumToString(GLenumGroup::PrimitiveType, mode), (uintptr_t)firsts,
          (uintptr_t)counts, (uintptr_t)instanceCounts, (uintptr_t)baseInstances, drawcount);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateMultiDrawArraysInstancedBaseInstanceANGLE(
                 context, modePacked, firsts, counts, instanceCounts, baseInstances, drawcount));
        if (isCallValid)
        {
            context->multiDrawArraysInstancedBaseInstance(modePacked, firsts, counts,
                                                          instanceCounts, baseInstances, drawcount);
        }
        ANGLE_CAPTURE(MultiDrawArraysInstancedBaseInstanceANGLE, isCallValid, context, modePacked,
                      firsts, counts, instanceCounts, baseInstances, drawcount);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY
MultiDrawElementsInstancedBaseVertexBaseInstanceANGLEContextANGLE(GLeglContext ctx,
                                                                  GLenum mode,
                                                                  const GLsizei *counts,
                                                                  GLenum type,
                                                                  const GLvoid *const *indices,
                                                                  const GLsizei *instanceCounts,
                                                                  const GLint *baseVertices,
                                                                  const GLuint *baseInstances,
                                                                  GLsizei drawcount)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::MultiDrawElementsInstancedBaseVertexBaseInstanceANGLE,
          "glMultiDrawElementsInstancedBaseVertexBaseInstanceANGLE",
          "context = %d, mode = %s, counts = 0x%016" PRIxPTR ", type = %s, indices = 0x%016" PRIxPTR
          ", instanceCounts = 0x%016" PRIxPTR ", baseVertices = 0x%016" PRIxPTR
          ", baseInstances = 0x%016" PRIxPTR ", drawcount = %d",
          CID(context), GLenumToString(GLenumGroup::PrimitiveType, mode), (uintptr_t)counts,
          GLenumToString(GLenumGroup::DrawElementsType, type), (uintptr_t)indices,
          (uintptr_t)instanceCounts, (uintptr_t)baseVertices, (uintptr_t)baseInstances, drawcount);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        PrimitiveMode modePacked                              = FromGL<PrimitiveMode>(mode);
        DrawElementsType typePacked                           = FromGL<DrawElementsType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateMultiDrawElementsInstancedBaseVertexBaseInstanceANGLE(
                                context, modePacked, counts, typePacked, indices, instanceCounts,
                                baseVertices, baseInstances, drawcount));
        if (isCallValid)
        {
            context->multiDrawElementsInstancedBaseVertexBaseInstance(
                modePacked, counts, typePacked, indices, instanceCounts, baseVertices,
                baseInstances, drawcount);
        }
        ANGLE_CAPTURE(MultiDrawElementsInstancedBaseVertexBaseInstanceANGLE, isCallValid, context,
                      modePacked, counts, typePacked, indices, instanceCounts, baseVertices,
                      baseInstances, drawcount);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetMultisamplefvANGLEContextANGLE(GLeglContext ctx,
                                                   GLenum pname,
                                                   GLuint index,
                                                   GLfloat *val)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetMultisamplefvANGLE, "glGetMultisamplefvANGLE",
          "context = %d, pname = %s, index = %u, val = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::DefaultGroup, pname), index, (uintptr_t)val);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetMultisamplefvANGLE(context, pname, index, val));
        if (isCallValid)
        {
            context->getMultisamplefv(pname, index, val);
        }
        ANGLE_CAPTURE(GetMultisamplefvANGLE, isCallValid, context, pname, index, val);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY SampleMaskiANGLEContextANGLE(GLeglContext ctx, GLuint maskNumber, GLbitfield mask)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::SampleMaskiANGLE, "glSampleMaskiANGLE",
          "context = %d, maskNumber = %u, mask = %s", CID(context), maskNumber,
          GLbitfieldToString(GLenumGroup::DefaultGroup, mask).c_str());

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateSampleMaskiANGLE(context, maskNumber, mask));
        if (isCallValid)
        {
            context->sampleMaski(maskNumber, mask);
        }
        ANGLE_CAPTURE(SampleMaskiANGLE, isCallValid, context, maskNumber, mask);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ProvokingVertexANGLEContextANGLE(GLeglContext ctx, GLenum mode)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ProvokingVertexANGLE, "glProvokingVertexANGLE",
          "context = %d, mode = %s", CID(context),
          GLenumToString(GLenumGroup::VertexProvokingMode, mode));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        ProvokingVertexConvention modePacked = FromGL<ProvokingVertexConvention>(mode);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateProvokingVertexANGLE(context, modePacked));
        if (isCallValid)
        {
            context->provokingVertex(modePacked);
        }
        ANGLE_CAPTURE(ProvokingVertexANGLE, isCallValid, context, modePacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY LoseContextCHROMIUMContextANGLE(GLeglContext ctx, GLenum current, GLenum other)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::LoseContextCHROMIUM, "glLoseContextCHROMIUM",
          "context = %d, current = %s, other = %s", CID(context),
          GLenumToString(GLenumGroup::GraphicsResetStatus, current),
          GLenumToString(GLenumGroup::GraphicsResetStatus, other));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        GraphicsResetStatus currentPacked = FromGL<GraphicsResetStatus>(current);
        GraphicsResetStatus otherPacked   = FromGL<GraphicsResetStatus>(other);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateLoseContextCHROMIUM(context, currentPacked, otherPacked));
        if (isCallValid)
        {
            context->loseContext(currentPacked, otherPacked);
        }
        ANGLE_CAPTURE(LoseContextCHROMIUM, isCallValid, context, currentPacked, otherPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexImage2DExternalANGLEContextANGLE(GLeglContext ctx,
                                                     GLenum target,
                                                     GLint level,
                                                     GLint internalformat,
                                                     GLsizei width,
                                                     GLsizei height,
                                                     GLint border,
                                                     GLenum format,
                                                     GLenum type)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexImage2DExternalANGLE, "glTexImage2DExternalANGLE",
          "context = %d, target = %s, level = %d, internalformat = %d, width = %d, height = %d, "
          "border = %d, format = %s, type = %s",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), level, internalformat,
          width, height, border, GLenumToString(GLenumGroup::PixelFormat, format),
          GLenumToString(GLenumGroup::PixelType, type));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTexImage2DExternalANGLE(context, targetPacked, level, internalformat, width,
                                             height, border, format, type));
        if (isCallValid)
        {
            context->texImage2DExternal(targetPacked, level, internalformat, width, height, border,
                                        format, type);
        }
        ANGLE_CAPTURE(TexImage2DExternalANGLE, isCallValid, context, targetPacked, level,
                      internalformat, width, height, border, format, type);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY InvalidateTextureANGLEContextANGLE(GLeglContext ctx, GLenum target)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::InvalidateTextureANGLE, "glInvalidateTextureANGLE",
          "context = %d, target = %s", CID(context),
          GLenumToString(GLenumGroup::TextureTarget, target));

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateInvalidateTextureANGLE(context, targetPacked));
        if (isCallValid)
        {
            context->invalidateTexture(targetPacked);
        }
        ANGLE_CAPTURE(InvalidateTextureANGLE, isCallValid, context, targetPacked);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetTexImageANGLEContextANGLE(GLeglContext ctx,
                                              GLenum target,
                                              GLint level,
                                              GLenum format,
                                              GLenum type,
                                              void *pixels)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetTexImageANGLE, "glGetTexImageANGLE",
          "context = %d, target = %s, level = %d, format = %s, type = %s, pixels = 0x%016" PRIxPTR
          "",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), level,
          GLenumToString(GLenumGroup::PixelFormat, format),
          GLenumToString(GLenumGroup::PixelType, type), (uintptr_t)pixels);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureTarget targetPacked                            = FromGL<TextureTarget>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetTexImageANGLE(context, targetPacked, level, format, type, pixels));
        if (isCallValid)
        {
            context->getTexImage(targetPacked, level, format, type, pixels);
        }
        ANGLE_CAPTURE(GetTexImageANGLE, isCallValid, context, targetPacked, level, format, type,
                      pixels);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY GetRenderbufferImageANGLEContextANGLE(GLeglContext ctx,
                                                       GLenum target,
                                                       GLenum format,
                                                       GLenum type,
                                                       void *pixels)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::GetRenderbufferImageANGLE, "glGetRenderbufferImageANGLE",
          "context = %d, target = %s, format = %s, type = %s, pixels = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::RenderbufferTarget, target),
          GLenumToString(GLenumGroup::PixelFormat, format),
          GLenumToString(GLenumGroup::PixelType, type), (uintptr_t)pixels);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetRenderbufferImageANGLE(context, target, format, type, pixels));
        if (isCallValid)
        {
            context->getRenderbufferImage(target, format, type, pixels);
        }
        ANGLE_CAPTURE(GetRenderbufferImageANGLE, isCallValid, context, target, format, type,
                      pixels);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexStorageMemFlags2DANGLEContextANGLE(GLeglContext ctx,
                                                       GLenum target,
                                                       GLsizei levels,
                                                       GLenum internalFormat,
                                                       GLsizei width,
                                                       GLsizei height,
                                                       GLuint memory,
                                                       GLuint64 offset,
                                                       GLbitfield createFlags,
                                                       GLbitfield usageFlags)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexStorageMemFlags2DANGLE, "glTexStorageMemFlags2DANGLE",
          "context = %d, target = %s, levels = %d, internalFormat = %s, width = %d, height = %d, "
          "memory = %u, offset = %llu, createFlags = %s, usageFlags = %s",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), levels,
          GLenumToString(GLenumGroup::DefaultGroup, internalFormat), width, height, memory,
          static_cast<unsigned long long>(offset),
          GLbitfieldToString(GLenumGroup::DefaultGroup, createFlags).c_str(),
          GLbitfieldToString(GLenumGroup::DefaultGroup, usageFlags).c_str());

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        MemoryObjectID memoryPacked                           = FromGL<MemoryObjectID>(memory);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateTexStorageMemFlags2DANGLE(
                                context, targetPacked, levels, internalFormat, width, height,
                                memoryPacked, offset, createFlags, usageFlags));
        if (isCallValid)
        {
            context->texStorageMemFlags2D(targetPacked, levels, internalFormat, width, height,
                                          memoryPacked, offset, createFlags, usageFlags);
        }
        ANGLE_CAPTURE(TexStorageMemFlags2DANGLE, isCallValid, context, targetPacked, levels,
                      internalFormat, width, height, memoryPacked, offset, createFlags, usageFlags);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexStorageMemFlags2DMultisampleANGLEContextANGLE(GLeglContext ctx,
                                                                  GLenum target,
                                                                  GLsizei samples,
                                                                  GLenum internalFormat,
                                                                  GLsizei width,
                                                                  GLsizei height,
                                                                  GLboolean fixedSampleLocations,
                                                                  GLuint memory,
                                                                  GLuint64 offset,
                                                                  GLbitfield createFlags,
                                                                  GLbitfield usageFlags)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(
        context, gl::EntryPoint::TexStorageMemFlags2DMultisampleANGLE,
        "glTexStorageMemFlags2DMultisampleANGLE",
        "context = %d, target = %s, samples = %d, internalFormat = %s, width = %d, height = %d, "
        "fixedSampleLocations = %s, memory = %u, offset = %llu, createFlags = %s, usageFlags = %s",
        CID(context), GLenumToString(GLenumGroup::TextureTarget, target), samples,
        GLenumToString(GLenumGroup::DefaultGroup, internalFormat), width, height,
        GLbooleanToString(fixedSampleLocations), memory, static_cast<unsigned long long>(offset),
        GLbitfieldToString(GLenumGroup::DefaultGroup, createFlags).c_str(),
        GLbitfieldToString(GLenumGroup::DefaultGroup, usageFlags).c_str());

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        MemoryObjectID memoryPacked                           = FromGL<MemoryObjectID>(memory);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTexStorageMemFlags2DMultisampleANGLE(
                 context, targetPacked, samples, internalFormat, width, height,
                 fixedSampleLocations, memoryPacked, offset, createFlags, usageFlags));
        if (isCallValid)
        {
            context->texStorageMemFlags2DMultisample(targetPacked, samples, internalFormat, width,
                                                     height, fixedSampleLocations, memoryPacked,
                                                     offset, createFlags, usageFlags);
        }
        ANGLE_CAPTURE(TexStorageMemFlags2DMultisampleANGLE, isCallValid, context, targetPacked,
                      samples, internalFormat, width, height, fixedSampleLocations, memoryPacked,
                      offset, createFlags, usageFlags);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexStorageMemFlags3DANGLEContextANGLE(GLeglContext ctx,
                                                       GLenum target,
                                                       GLsizei levels,
                                                       GLenum internalFormat,
                                                       GLsizei width,
                                                       GLsizei height,
                                                       GLsizei depth,
                                                       GLuint memory,
                                                       GLuint64 offset,
                                                       GLbitfield createFlags,
                                                       GLbitfield usageFlags)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexStorageMemFlags3DANGLE, "glTexStorageMemFlags3DANGLE",
          "context = %d, target = %s, levels = %d, internalFormat = %s, width = %d, height = %d, "
          "depth = %d, memory = %u, offset = %llu, createFlags = %s, usageFlags = %s",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), levels,
          GLenumToString(GLenumGroup::DefaultGroup, internalFormat), width, height, depth, memory,
          static_cast<unsigned long long>(offset),
          GLbitfieldToString(GLenumGroup::DefaultGroup, createFlags).c_str(),
          GLbitfieldToString(GLenumGroup::DefaultGroup, usageFlags).c_str());

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        MemoryObjectID memoryPacked                           = FromGL<MemoryObjectID>(memory);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateTexStorageMemFlags3DANGLE(
                                context, targetPacked, levels, internalFormat, width, height, depth,
                                memoryPacked, offset, createFlags, usageFlags));
        if (isCallValid)
        {
            context->texStorageMemFlags3D(targetPacked, levels, internalFormat, width, height,
                                          depth, memoryPacked, offset, createFlags, usageFlags);
        }
        ANGLE_CAPTURE(TexStorageMemFlags3DANGLE, isCallValid, context, targetPacked, levels,
                      internalFormat, width, height, depth, memoryPacked, offset, createFlags,
                      usageFlags);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY TexStorageMemFlags3DMultisampleANGLEContextANGLE(GLeglContext ctx,
                                                                  GLenum target,
                                                                  GLsizei samples,
                                                                  GLenum internalFormat,
                                                                  GLsizei width,
                                                                  GLsizei height,
                                                                  GLsizei depth,
                                                                  GLboolean fixedSampleLocations,
                                                                  GLuint memory,
                                                                  GLuint64 offset,
                                                                  GLbitfield createFlags,
                                                                  GLbitfield usageFlags)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::TexStorageMemFlags3DMultisampleANGLE,
          "glTexStorageMemFlags3DMultisampleANGLE",
          "context = %d, target = %s, samples = %d, internalFormat = %s, width = %d, height = %d, "
          "depth = %d, fixedSampleLocations = %s, memory = %u, offset = %llu, createFlags = %s, "
          "usageFlags = %s",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), samples,
          GLenumToString(GLenumGroup::DefaultGroup, internalFormat), width, height, depth,
          GLbooleanToString(fixedSampleLocations), memory, static_cast<unsigned long long>(offset),
          GLbitfieldToString(GLenumGroup::DefaultGroup, createFlags).c_str(),
          GLbitfieldToString(GLenumGroup::DefaultGroup, usageFlags).c_str());

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        TextureType targetPacked                              = FromGL<TextureType>(target);
        MemoryObjectID memoryPacked                           = FromGL<MemoryObjectID>(memory);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTexStorageMemFlags3DMultisampleANGLE(
                 context, targetPacked, samples, internalFormat, width, height, depth,
                 fixedSampleLocations, memoryPacked, offset, createFlags, usageFlags));
        if (isCallValid)
        {
            context->texStorageMemFlags3DMultisample(targetPacked, samples, internalFormat, width,
                                                     height, depth, fixedSampleLocations,
                                                     memoryPacked, offset, createFlags, usageFlags);
        }
        ANGLE_CAPTURE(TexStorageMemFlags3DMultisampleANGLE, isCallValid, context, targetPacked,
                      samples, internalFormat, width, height, depth, fixedSampleLocations,
                      memoryPacked, offset, createFlags, usageFlags);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ImportMemoryZirconHandleANGLEContextANGLE(GLeglContext ctx,
                                                           GLuint memory,
                                                           GLuint64 size,
                                                           GLenum handleType,
                                                           GLuint handle)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ImportMemoryZirconHandleANGLE, "glImportMemoryZirconHandleANGLE",
          "context = %d, memory = %u, size = %llu, handleType = %s, handle = %u", CID(context),
          memory, static_cast<unsigned long long>(size),
          GLenumToString(GLenumGroup::ExternalHandleType, handleType), handle);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        MemoryObjectID memoryPacked                           = FromGL<MemoryObjectID>(memory);
        HandleType handleTypePacked                           = FromGL<HandleType>(handleType);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateImportMemoryZirconHandleANGLE(context, memoryPacked, size,
                                                                  handleTypePacked, handle));
        if (isCallValid)
        {
            context->importMemoryZirconHandle(memoryPacked, size, handleTypePacked, handle);
        }
        ANGLE_CAPTURE(ImportMemoryZirconHandleANGLE, isCallValid, context, memoryPacked, size,
                      handleTypePacked, handle);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}

void GL_APIENTRY ImportSemaphoreZirconHandleANGLEContextANGLE(GLeglContext ctx,
                                                              GLuint semaphore,
                                                              GLenum handleType,
                                                              GLuint handle)
{
    Context *context = static_cast<gl::Context *>(ctx);
    EVENT(context, gl::EntryPoint::ImportSemaphoreZirconHandleANGLE,
          "glImportSemaphoreZirconHandleANGLE",
          "context = %d, semaphore = %u, handleType = %s, handle = %u", CID(context), semaphore,
          GLenumToString(GLenumGroup::ExternalHandleType, handleType), handle);

    if (context && !context->isContextLost())
    {
        ASSERT(context == GetValidGlobalContext());
        SemaphoreID semaphorePacked                           = FromGL<SemaphoreID>(semaphore);
        HandleType handleTypePacked                           = FromGL<HandleType>(handleType);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateImportSemaphoreZirconHandleANGLE(
                                              context, semaphorePacked, handleTypePacked, handle));
        if (isCallValid)
        {
            context->importSemaphoreZirconHandle(semaphorePacked, handleTypePacked, handle);
        }
        ANGLE_CAPTURE(ImportSemaphoreZirconHandleANGLE, isCallValid, context, semaphorePacked,
                      handleTypePacked, handle);
    }
    else
    {
        GenerateContextLostErrorOnContext(context);
    }
}
}  // namespace gl
