// GENERATED FILE - DO NOT EDIT.
// Generated by generate_entry_points.py using data from gl.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_gl_4_autogen.cpp:
//   Defines the Desktop GL 4.x entry points.

#include "libGL/entry_points_gl_4_autogen.h"

#include "libANGLE/Context.h"
#include "libANGLE/Context.inl.h"
#include "libANGLE/entry_points_utils.h"
#include "libANGLE/gl_enum_utils.h"
#include "libANGLE/validationEGL.h"
#include "libANGLE/validationES.h"
#include "libANGLE/validationES1.h"
#include "libANGLE/validationES2.h"
#include "libANGLE/validationES3.h"
#include "libANGLE/validationES31.h"
#include "libANGLE/validationES32.h"
#include "libANGLE/validationESEXT.h"
#include "libANGLE/validationGL4_autogen.h"
#include "libGLESv2/global_state.h"

namespace gl
{

// GL 4.0
void GL_APIENTRY BeginQueryIndexed(GLenum target, GLuint index, GLuint id)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLBeginQueryIndexed, "context = %d, target = %s, index = %u, id = %u",
          CID(context), GLenumToString(GLenumGroup::QueryTarget, target), index, id);

    if (context)
    {
        QueryID idPacked                                      = PackParam<QueryID>(id);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateBeginQueryIndexed(context, target, index, idPacked));
        if (isCallValid)
        {
            context->beginQueryIndexed(target, index, idPacked);
        }
        ANGLE_CAPTURE(BeginQueryIndexed, isCallValid, context, target, index, idPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY BindTransformFeedback(GLenum target, GLuint id)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLBindTransformFeedback, "context = %d, target = %s, id = %u", CID(context),
          GLenumToString(GLenumGroup::BindTransformFeedbackTarget, target), id);

    if (context)
    {
        TransformFeedbackID idPacked                          = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY BlendEquationSeparatei(GLuint buf, GLenum modeRGB, GLenum modeAlpha)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLBlendEquationSeparatei, "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() ||
                            ValidateBlendEquationSeparatei(context, buf, modeRGB, modeAlpha));
        if (isCallValid)
        {
            context->blendEquationSeparatei(buf, modeRGB, modeAlpha);
        }
        ANGLE_CAPTURE(BlendEquationSeparatei, isCallValid, context, buf, modeRGB, modeAlpha);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY BlendEquationi(GLuint buf, GLenum mode)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLBlendEquationi, "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() || ValidateBlendEquationi(context, buf, mode));
        if (isCallValid)
        {
            context->blendEquationi(buf, mode);
        }
        ANGLE_CAPTURE(BlendEquationi, isCallValid, context, buf, mode);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY
BlendFuncSeparatei(GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, 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)
    {
        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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY BlendFunci(GLuint buf, GLenum src, GLenum dst)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLBlendFunci, "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() || ValidateBlendFunci(context, buf, src, dst));
        if (isCallValid)
        {
            context->blendFunci(buf, src, dst);
        }
        ANGLE_CAPTURE(BlendFunci, isCallValid, context, buf, src, dst);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY DeleteTransformFeedbacks(GLsizei n, const GLuint *ids)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLDeleteTransformFeedbacks, "context = %d, n = %d, ids = 0x%016" PRIxPTR "",
          CID(context), n, (uintptr_t)ids);

    if (context)
    {
        const TransformFeedbackID *idsPacked = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY DrawArraysIndirect(GLenum mode, const void *indirect)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLDrawArraysIndirect, "context = %d, mode = %s, indirect = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::PrimitiveType, mode), (uintptr_t)indirect);

    if (context)
    {
        PrimitiveMode modePacked                              = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY DrawElementsIndirect(GLenum mode, GLenum type, const void *indirect)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, 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)
    {
        PrimitiveMode modePacked                              = PackParam<PrimitiveMode>(mode);
        DrawElementsType typePacked                           = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY DrawTransformFeedback(GLenum mode, GLuint id)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLDrawTransformFeedback, "context = %d, mode = %s, id = %u", CID(context),
          GLenumToString(GLenumGroup::PrimitiveType, mode), id);

    if (context)
    {
        TransformFeedbackID idPacked                          = PackParam<TransformFeedbackID>(id);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateDrawTransformFeedback(context, mode, idPacked));
        if (isCallValid)
        {
            context->drawTransformFeedback(mode, idPacked);
        }
        ANGLE_CAPTURE(DrawTransformFeedback, isCallValid, context, mode, idPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY DrawTransformFeedbackStream(GLenum mode, GLuint id, GLuint stream)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLDrawTransformFeedbackStream, "context = %d, mode = %s, id = %u, stream = %u",
          CID(context), GLenumToString(GLenumGroup::PrimitiveType, mode), id, stream);

    if (context)
    {
        TransformFeedbackID idPacked                          = PackParam<TransformFeedbackID>(id);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateDrawTransformFeedbackStream(context, mode, idPacked, stream));
        if (isCallValid)
        {
            context->drawTransformFeedbackStream(mode, idPacked, stream);
        }
        ANGLE_CAPTURE(DrawTransformFeedbackStream, isCallValid, context, mode, idPacked, stream);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY EndQueryIndexed(GLenum target, GLuint index)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLEndQueryIndexed, "context = %d, target = %s, index = %u", CID(context),
          GLenumToString(GLenumGroup::QueryTarget, target), index);

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

void GL_APIENTRY GenTransformFeedbacks(GLsizei n, GLuint *ids)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGenTransformFeedbacks, "context = %d, n = %d, ids = 0x%016" PRIxPTR "",
          CID(context), n, (uintptr_t)ids);

    if (context)
    {
        TransformFeedbackID *idsPacked = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetActiveSubroutineName(GLuint program,
                                         GLenum shadertype,
                                         GLuint index,
                                         GLsizei bufsize,
                                         GLsizei *length,
                                         GLchar *name)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetActiveSubroutineName,
          "context = %d, program = %u, shadertype = %s, index = %u, bufsize = %d, length = "
          "0x%016" PRIxPTR ", name = 0x%016" PRIxPTR "",
          CID(context), program, GLenumToString(GLenumGroup::ShaderType, shadertype), index,
          bufsize, (uintptr_t)length, (uintptr_t)name);

    if (context)
    {
        ShaderProgramID programPacked                         = PackParam<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetActiveSubroutineName(context, programPacked, shadertype,
                                                            index, bufsize, length, name));
        if (isCallValid)
        {
            context->getActiveSubroutineName(programPacked, shadertype, index, bufsize, length,
                                             name);
        }
        ANGLE_CAPTURE(GetActiveSubroutineName, isCallValid, context, programPacked, shadertype,
                      index, bufsize, length, name);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetActiveSubroutineUniformName(GLuint program,
                                                GLenum shadertype,
                                                GLuint index,
                                                GLsizei bufsize,
                                                GLsizei *length,
                                                GLchar *name)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetActiveSubroutineUniformName,
          "context = %d, program = %u, shadertype = %s, index = %u, bufsize = %d, length = "
          "0x%016" PRIxPTR ", name = 0x%016" PRIxPTR "",
          CID(context), program, GLenumToString(GLenumGroup::ShaderType, shadertype), index,
          bufsize, (uintptr_t)length, (uintptr_t)name);

    if (context)
    {
        ShaderProgramID programPacked                         = PackParam<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetActiveSubroutineUniformName(
                                context, programPacked, shadertype, index, bufsize, length, name));
        if (isCallValid)
        {
            context->getActiveSubroutineUniformName(programPacked, shadertype, index, bufsize,
                                                    length, name);
        }
        ANGLE_CAPTURE(GetActiveSubroutineUniformName, isCallValid, context, programPacked,
                      shadertype, index, bufsize, length, name);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetActiveSubroutineUniformiv(GLuint program,
                                              GLenum shadertype,
                                              GLuint index,
                                              GLenum pname,
                                              GLint *values)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetActiveSubroutineUniformiv,
          "context = %d, program = %u, shadertype = %s, index = %u, pname = %s, values = "
          "0x%016" PRIxPTR "",
          CID(context), program, GLenumToString(GLenumGroup::ShaderType, shadertype), index,
          GLenumToString(GLenumGroup::SubroutineParameterName, pname), (uintptr_t)values);

    if (context)
    {
        ShaderProgramID programPacked                         = PackParam<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetActiveSubroutineUniformiv(context, programPacked, shadertype,
                                                                 index, pname, values));
        if (isCallValid)
        {
            context->getActiveSubroutineUniformiv(programPacked, shadertype, index, pname, values);
        }
        ANGLE_CAPTURE(GetActiveSubroutineUniformiv, isCallValid, context, programPacked, shadertype,
                      index, pname, values);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetProgramStageiv(GLuint program, GLenum shadertype, GLenum pname, GLint *values)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetProgramStageiv,
          "context = %d, program = %u, shadertype = %s, pname = %s, values = 0x%016" PRIxPTR "",
          CID(context), program, GLenumToString(GLenumGroup::ShaderType, shadertype),
          GLenumToString(GLenumGroup::ProgramStagePName, pname), (uintptr_t)values);

    if (context)
    {
        ShaderProgramID programPacked                         = PackParam<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetProgramStageiv(context, programPacked, shadertype, pname, values));
        if (isCallValid)
        {
            context->getProgramStageiv(programPacked, shadertype, pname, values);
        }
        ANGLE_CAPTURE(GetProgramStageiv, isCallValid, context, programPacked, shadertype, pname,
                      values);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetQueryIndexediv(GLenum target, GLuint index, GLenum pname, GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetQueryIndexediv,
          "context = %d, target = %s, index = %u, pname = %s, params = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target), index,
          GLenumToString(GLenumGroup::QueryParameterName, pname), (uintptr_t)params);

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

GLuint GL_APIENTRY GetSubroutineIndex(GLuint program, GLenum shadertype, const GLchar *name)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetSubroutineIndex,
          "context = %d, program = %u, shadertype = %s, name = 0x%016" PRIxPTR "", CID(context),
          program, GLenumToString(GLenumGroup::ShaderType, shadertype), (uintptr_t)name);

    GLuint returnValue;
    if (context)
    {
        ShaderProgramID programPacked                         = PackParam<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetSubroutineIndex(context, programPacked, shadertype, name));
        if (isCallValid)
        {
            returnValue = context->getSubroutineIndex(programPacked, shadertype, name);
        }
        else
        {
            returnValue = GetDefaultReturnValue<angle::EntryPoint::GLGetSubroutineIndex, GLuint>();
        }
        ANGLE_CAPTURE(GetSubroutineIndex, isCallValid, context, programPacked, shadertype, name,
                      returnValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
        returnValue = GetDefaultReturnValue<angle::EntryPoint::GLGetSubroutineIndex, GLuint>();
    }
    return returnValue;
}

GLint GL_APIENTRY GetSubroutineUniformLocation(GLuint program,
                                               GLenum shadertype,
                                               const GLchar *name)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetSubroutineUniformLocation,
          "context = %d, program = %u, shadertype = %s, name = 0x%016" PRIxPTR "", CID(context),
          program, GLenumToString(GLenumGroup::ShaderType, shadertype), (uintptr_t)name);

    GLint returnValue;
    if (context)
    {
        ShaderProgramID programPacked                         = PackParam<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetSubroutineUniformLocation(context, programPacked, shadertype, name));
        if (isCallValid)
        {
            returnValue = context->getSubroutineUniformLocation(programPacked, shadertype, name);
        }
        else
        {
            returnValue =
                GetDefaultReturnValue<angle::EntryPoint::GLGetSubroutineUniformLocation, GLint>();
        }
        ANGLE_CAPTURE(GetSubroutineUniformLocation, isCallValid, context, programPacked, shadertype,
                      name, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
        returnValue =
            GetDefaultReturnValue<angle::EntryPoint::GLGetSubroutineUniformLocation, GLint>();
    }
    return returnValue;
}

void GL_APIENTRY GetUniformSubroutineuiv(GLenum shadertype, GLint location, GLuint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetUniformSubroutineuiv,
          "context = %d, shadertype = %s, location = %d, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::ShaderType, shadertype), location, (uintptr_t)params);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetUniformSubroutineuiv(context, shadertype, location, params));
        if (isCallValid)
        {
            context->getUniformSubroutineuiv(shadertype, location, params);
        }
        ANGLE_CAPTURE(GetUniformSubroutineuiv, isCallValid, context, shadertype, location, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetUniformdv(GLuint program, GLint location, GLdouble *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetUniformdv,
          "context = %d, program = %u, location = %d, params = 0x%016" PRIxPTR "", CID(context),
          program, location, (uintptr_t)params);

    if (context)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetUniformdv(context, programPacked, locationPacked, params));
        if (isCallValid)
        {
            context->getUniformdv(programPacked, locationPacked, params);
        }
        ANGLE_CAPTURE(GetUniformdv, isCallValid, context, programPacked, locationPacked, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

GLboolean GL_APIENTRY IsTransformFeedback(GLuint id)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLIsTransformFeedback, "context = %d, id = %u", CID(context), id);

    GLboolean returnValue;
    if (context)
    {
        TransformFeedbackID idPacked                          = PackParam<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<angle::EntryPoint::GLIsTransformFeedback, GLboolean>();
        }
        ANGLE_CAPTURE(IsTransformFeedback, isCallValid, context, idPacked, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
        returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsTransformFeedback, GLboolean>();
    }
    return returnValue;
}

void GL_APIENTRY MinSampleShading(GLfloat value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLMinSampleShading, "context = %d, value = %f", CID(context), value);

    if (context)
    {
        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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY PatchParameterfv(GLenum pname, const GLfloat *values)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLPatchParameterfv, "context = %d, pname = %s, values = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::PatchParameterName, pname), (uintptr_t)values);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidatePatchParameterfv(context, pname, values));
        if (isCallValid)
        {
            context->patchParameterfv(pname, values);
        }
        ANGLE_CAPTURE(PatchParameterfv, isCallValid, context, pname, values);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY PatchParameteri(GLenum pname, GLint value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLPatchParameteri, "context = %d, pname = %s, value = %d", CID(context),
          GLenumToString(GLenumGroup::PatchParameterName, pname), value);

    if (context)
    {
        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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY PauseTransformFeedback()
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLPauseTransformFeedback, "context = %d", CID(context));

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

void GL_APIENTRY ResumeTransformFeedback()
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLResumeTransformFeedback, "context = %d", CID(context));

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

void GL_APIENTRY Uniform1d(GLint location, GLdouble x)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLUniform1d, "context = %d, location = %d, x = %f", CID(context), location, x);

    if (context)
    {
        UniformLocation locationPacked = PackParam<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateUniform1d(context, locationPacked, x));
        if (isCallValid)
        {
            context->uniform1d(locationPacked, x);
        }
        ANGLE_CAPTURE(Uniform1d, isCallValid, context, locationPacked, x);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY Uniform1dv(GLint location, GLsizei count, const GLdouble *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLUniform1dv,
          "context = %d, location = %d, count = %d, value = 0x%016" PRIxPTR "", CID(context),
          location, count, (uintptr_t)value);

    if (context)
    {
        UniformLocation locationPacked = PackParam<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateUniform1dv(context, locationPacked, count, value));
        if (isCallValid)
        {
            context->uniform1dv(locationPacked, count, value);
        }
        ANGLE_CAPTURE(Uniform1dv, isCallValid, context, locationPacked, count, value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY Uniform2d(GLint location, GLdouble x, GLdouble y)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLUniform2d, "context = %d, location = %d, x = %f, y = %f", CID(context),
          location, x, y);

    if (context)
    {
        UniformLocation locationPacked = PackParam<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateUniform2d(context, locationPacked, x, y));
        if (isCallValid)
        {
            context->uniform2d(locationPacked, x, y);
        }
        ANGLE_CAPTURE(Uniform2d, isCallValid, context, locationPacked, x, y);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY Uniform2dv(GLint location, GLsizei count, const GLdouble *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLUniform2dv,
          "context = %d, location = %d, count = %d, value = 0x%016" PRIxPTR "", CID(context),
          location, count, (uintptr_t)value);

    if (context)
    {
        UniformLocation locationPacked = PackParam<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateUniform2dv(context, locationPacked, count, value));
        if (isCallValid)
        {
            context->uniform2dv(locationPacked, count, value);
        }
        ANGLE_CAPTURE(Uniform2dv, isCallValid, context, locationPacked, count, value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY Uniform3d(GLint location, GLdouble x, GLdouble y, GLdouble z)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLUniform3d, "context = %d, location = %d, x = %f, y = %f, z = %f", CID(context),
          location, x, y, z);

    if (context)
    {
        UniformLocation locationPacked = PackParam<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateUniform3d(context, locationPacked, x, y, z));
        if (isCallValid)
        {
            context->uniform3d(locationPacked, x, y, z);
        }
        ANGLE_CAPTURE(Uniform3d, isCallValid, context, locationPacked, x, y, z);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY Uniform3dv(GLint location, GLsizei count, const GLdouble *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLUniform3dv,
          "context = %d, location = %d, count = %d, value = 0x%016" PRIxPTR "", CID(context),
          location, count, (uintptr_t)value);

    if (context)
    {
        UniformLocation locationPacked = PackParam<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateUniform3dv(context, locationPacked, count, value));
        if (isCallValid)
        {
            context->uniform3dv(locationPacked, count, value);
        }
        ANGLE_CAPTURE(Uniform3dv, isCallValid, context, locationPacked, count, value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY Uniform4d(GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLUniform4d, "context = %d, location = %d, x = %f, y = %f, z = %f, w = %f",
          CID(context), location, x, y, z, w);

    if (context)
    {
        UniformLocation locationPacked = PackParam<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateUniform4d(context, locationPacked, x, y, z, w));
        if (isCallValid)
        {
            context->uniform4d(locationPacked, x, y, z, w);
        }
        ANGLE_CAPTURE(Uniform4d, isCallValid, context, locationPacked, x, y, z, w);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY Uniform4dv(GLint location, GLsizei count, const GLdouble *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLUniform4dv,
          "context = %d, location = %d, count = %d, value = 0x%016" PRIxPTR "", CID(context),
          location, count, (uintptr_t)value);

    if (context)
    {
        UniformLocation locationPacked = PackParam<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateUniform4dv(context, locationPacked, count, value));
        if (isCallValid)
        {
            context->uniform4dv(locationPacked, count, value);
        }
        ANGLE_CAPTURE(Uniform4dv, isCallValid, context, locationPacked, count, value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY UniformMatrix2dv(GLint location,
                                  GLsizei count,
                                  GLboolean transpose,
                                  const GLdouble *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLUniformMatrix2dv,
          "context = %d, location = %d, count = %d, transpose = %s, value = 0x%016" PRIxPTR "",
          CID(context), location, count, GLbooleanToString(transpose), (uintptr_t)value);

    if (context)
    {
        UniformLocation locationPacked = PackParam<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateUniformMatrix2dv(context, locationPacked, count, transpose, value));
        if (isCallValid)
        {
            context->uniformMatrix2dv(locationPacked, count, transpose, value);
        }
        ANGLE_CAPTURE(UniformMatrix2dv, isCallValid, context, locationPacked, count, transpose,
                      value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY UniformMatrix2x3dv(GLint location,
                                    GLsizei count,
                                    GLboolean transpose,
                                    const GLdouble *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLUniformMatrix2x3dv,
          "context = %d, location = %d, count = %d, transpose = %s, value = 0x%016" PRIxPTR "",
          CID(context), location, count, GLbooleanToString(transpose), (uintptr_t)value);

    if (context)
    {
        UniformLocation locationPacked = PackParam<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateUniformMatrix2x3dv(context, locationPacked, count, transpose, value));
        if (isCallValid)
        {
            context->uniformMatrix2x3dv(locationPacked, count, transpose, value);
        }
        ANGLE_CAPTURE(UniformMatrix2x3dv, isCallValid, context, locationPacked, count, transpose,
                      value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY UniformMatrix2x4dv(GLint location,
                                    GLsizei count,
                                    GLboolean transpose,
                                    const GLdouble *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLUniformMatrix2x4dv,
          "context = %d, location = %d, count = %d, transpose = %s, value = 0x%016" PRIxPTR "",
          CID(context), location, count, GLbooleanToString(transpose), (uintptr_t)value);

    if (context)
    {
        UniformLocation locationPacked = PackParam<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateUniformMatrix2x4dv(context, locationPacked, count, transpose, value));
        if (isCallValid)
        {
            context->uniformMatrix2x4dv(locationPacked, count, transpose, value);
        }
        ANGLE_CAPTURE(UniformMatrix2x4dv, isCallValid, context, locationPacked, count, transpose,
                      value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY UniformMatrix3dv(GLint location,
                                  GLsizei count,
                                  GLboolean transpose,
                                  const GLdouble *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLUniformMatrix3dv,
          "context = %d, location = %d, count = %d, transpose = %s, value = 0x%016" PRIxPTR "",
          CID(context), location, count, GLbooleanToString(transpose), (uintptr_t)value);

    if (context)
    {
        UniformLocation locationPacked = PackParam<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateUniformMatrix3dv(context, locationPacked, count, transpose, value));
        if (isCallValid)
        {
            context->uniformMatrix3dv(locationPacked, count, transpose, value);
        }
        ANGLE_CAPTURE(UniformMatrix3dv, isCallValid, context, locationPacked, count, transpose,
                      value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY UniformMatrix3x2dv(GLint location,
                                    GLsizei count,
                                    GLboolean transpose,
                                    const GLdouble *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLUniformMatrix3x2dv,
          "context = %d, location = %d, count = %d, transpose = %s, value = 0x%016" PRIxPTR "",
          CID(context), location, count, GLbooleanToString(transpose), (uintptr_t)value);

    if (context)
    {
        UniformLocation locationPacked = PackParam<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateUniformMatrix3x2dv(context, locationPacked, count, transpose, value));
        if (isCallValid)
        {
            context->uniformMatrix3x2dv(locationPacked, count, transpose, value);
        }
        ANGLE_CAPTURE(UniformMatrix3x2dv, isCallValid, context, locationPacked, count, transpose,
                      value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY UniformMatrix3x4dv(GLint location,
                                    GLsizei count,
                                    GLboolean transpose,
                                    const GLdouble *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLUniformMatrix3x4dv,
          "context = %d, location = %d, count = %d, transpose = %s, value = 0x%016" PRIxPTR "",
          CID(context), location, count, GLbooleanToString(transpose), (uintptr_t)value);

    if (context)
    {
        UniformLocation locationPacked = PackParam<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateUniformMatrix3x4dv(context, locationPacked, count, transpose, value));
        if (isCallValid)
        {
            context->uniformMatrix3x4dv(locationPacked, count, transpose, value);
        }
        ANGLE_CAPTURE(UniformMatrix3x4dv, isCallValid, context, locationPacked, count, transpose,
                      value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY UniformMatrix4dv(GLint location,
                                  GLsizei count,
                                  GLboolean transpose,
                                  const GLdouble *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLUniformMatrix4dv,
          "context = %d, location = %d, count = %d, transpose = %s, value = 0x%016" PRIxPTR "",
          CID(context), location, count, GLbooleanToString(transpose), (uintptr_t)value);

    if (context)
    {
        UniformLocation locationPacked = PackParam<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateUniformMatrix4dv(context, locationPacked, count, transpose, value));
        if (isCallValid)
        {
            context->uniformMatrix4dv(locationPacked, count, transpose, value);
        }
        ANGLE_CAPTURE(UniformMatrix4dv, isCallValid, context, locationPacked, count, transpose,
                      value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY UniformMatrix4x2dv(GLint location,
                                    GLsizei count,
                                    GLboolean transpose,
                                    const GLdouble *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLUniformMatrix4x2dv,
          "context = %d, location = %d, count = %d, transpose = %s, value = 0x%016" PRIxPTR "",
          CID(context), location, count, GLbooleanToString(transpose), (uintptr_t)value);

    if (context)
    {
        UniformLocation locationPacked = PackParam<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateUniformMatrix4x2dv(context, locationPacked, count, transpose, value));
        if (isCallValid)
        {
            context->uniformMatrix4x2dv(locationPacked, count, transpose, value);
        }
        ANGLE_CAPTURE(UniformMatrix4x2dv, isCallValid, context, locationPacked, count, transpose,
                      value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY UniformMatrix4x3dv(GLint location,
                                    GLsizei count,
                                    GLboolean transpose,
                                    const GLdouble *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLUniformMatrix4x3dv,
          "context = %d, location = %d, count = %d, transpose = %s, value = 0x%016" PRIxPTR "",
          CID(context), location, count, GLbooleanToString(transpose), (uintptr_t)value);

    if (context)
    {
        UniformLocation locationPacked = PackParam<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateUniformMatrix4x3dv(context, locationPacked, count, transpose, value));
        if (isCallValid)
        {
            context->uniformMatrix4x3dv(locationPacked, count, transpose, value);
        }
        ANGLE_CAPTURE(UniformMatrix4x3dv, isCallValid, context, locationPacked, count, transpose,
                      value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY UniformSubroutinesuiv(GLenum shadertype, GLsizei count, const GLuint *indices)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLUniformSubroutinesuiv,
          "context = %d, shadertype = %s, count = %d, indices = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::ShaderType, shadertype), count, (uintptr_t)indices);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateUniformSubroutinesuiv(context, shadertype, count, indices));
        if (isCallValid)
        {
            context->uniformSubroutinesuiv(shadertype, count, indices);
        }
        ANGLE_CAPTURE(UniformSubroutinesuiv, isCallValid, context, shadertype, count, indices);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL 4.1
void GL_APIENTRY ActiveShaderProgram(GLuint pipeline, GLuint program)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLActiveShaderProgram, "context = %d, pipeline = %u, program = %u", CID(context),
          pipeline, program);

    if (context)
    {
        ProgramPipelineID pipelinePacked = PackParam<ProgramPipelineID>(pipeline);
        ShaderProgramID programPacked    = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY BindProgramPipeline(GLuint pipeline)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLBindProgramPipeline, "context = %d, pipeline = %u", CID(context), pipeline);

    if (context)
    {
        ProgramPipelineID pipelinePacked = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ClearDepthf(GLfloat d)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLClearDepthf, "context = %d, d = %f", CID(context), d);

    if (context)
    {
        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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

GLuint GL_APIENTRY CreateShaderProgramv(GLenum type, GLsizei count, const GLchar *const *strings)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, 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)
    {
        ShaderType typePacked                                 = PackParam<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<angle::EntryPoint::GLCreateShaderProgramv, GLuint>();
        }
        ANGLE_CAPTURE(CreateShaderProgramv, isCallValid, context, typePacked, count, strings,
                      returnValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
        returnValue = GetDefaultReturnValue<angle::EntryPoint::GLCreateShaderProgramv, GLuint>();
    }
    return returnValue;
}

void GL_APIENTRY DeleteProgramPipelines(GLsizei n, const GLuint *pipelines)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLDeleteProgramPipelines, "context = %d, n = %d, pipelines = 0x%016" PRIxPTR "",
          CID(context), n, (uintptr_t)pipelines);

    if (context)
    {
        const ProgramPipelineID *pipelinesPacked = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY DepthRangeArrayv(GLuint first, GLsizei count, const GLdouble *v)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLDepthRangeArrayv,
          "context = %d, first = %u, count = %d, v = 0x%016" PRIxPTR "", CID(context), first, count,
          (uintptr_t)v);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateDepthRangeArrayv(context, first, count, v));
        if (isCallValid)
        {
            context->depthRangeArrayv(first, count, v);
        }
        ANGLE_CAPTURE(DepthRangeArrayv, isCallValid, context, first, count, v);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY DepthRangeIndexed(GLuint index, GLdouble n, GLdouble f)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLDepthRangeIndexed, "context = %d, index = %u, n = %f, f = %f", CID(context),
          index, n, f);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateDepthRangeIndexed(context, index, n, f));
        if (isCallValid)
        {
            context->depthRangeIndexed(index, n, f);
        }
        ANGLE_CAPTURE(DepthRangeIndexed, isCallValid, context, index, n, f);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY DepthRangef(GLfloat n, GLfloat f)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLDepthRangef, "context = %d, n = %f, f = %f", CID(context), n, f);

    if (context)
    {
        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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GenProgramPipelines(GLsizei n, GLuint *pipelines)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGenProgramPipelines, "context = %d, n = %d, pipelines = 0x%016" PRIxPTR "",
          CID(context), n, (uintptr_t)pipelines);

    if (context)
    {
        ProgramPipelineID *pipelinesPacked = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetDoublei_v(GLenum target, GLuint index, GLdouble *data)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetDoublei_v,
          "context = %d, target = %s, index = %u, data = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::TypeEnum, target), index, (uintptr_t)data);

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

void GL_APIENTRY GetFloati_v(GLenum target, GLuint index, GLfloat *data)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetFloati_v, "context = %d, target = %s, index = %u, data = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::TypeEnum, target), index, (uintptr_t)data);

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

void GL_APIENTRY GetProgramBinary(GLuint program,
                                  GLsizei bufSize,
                                  GLsizei *length,
                                  GLenum *binaryFormat,
                                  void *binary)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, 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)
    {
        ShaderProgramID programPacked                         = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetProgramPipelineInfoLog(GLuint pipeline,
                                           GLsizei bufSize,
                                           GLsizei *length,
                                           GLchar *infoLog)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, 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)
    {
        ProgramPipelineID pipelinePacked = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetProgramPipelineiv(GLuint pipeline, GLenum pname, GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetProgramPipelineiv,
          "context = %d, pipeline = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          pipeline, GLenumToString(GLenumGroup::PipelineParameterName, pname), (uintptr_t)params);

    if (context)
    {
        ProgramPipelineID pipelinePacked = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetShaderPrecisionFormat(GLenum shadertype,
                                          GLenum precisiontype,
                                          GLint *range,
                                          GLint *precision)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, 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)
    {
        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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetVertexAttribLdv(GLuint index, GLenum pname, GLdouble *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetVertexAttribLdv,
          "context = %d, index = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context), index,
          GLenumToString(GLenumGroup::VertexAttribEnum, pname), (uintptr_t)params);

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

GLboolean GL_APIENTRY IsProgramPipeline(GLuint pipeline)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLIsProgramPipeline, "context = %d, pipeline = %u", CID(context), pipeline);

    GLboolean returnValue;
    if (context)
    {
        ProgramPipelineID pipelinePacked = PackParam<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<angle::EntryPoint::GLIsProgramPipeline, GLboolean>();
        }
        ANGLE_CAPTURE(IsProgramPipeline, isCallValid, context, pipelinePacked, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
        returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsProgramPipeline, GLboolean>();
    }
    return returnValue;
}

void GL_APIENTRY ProgramBinary(GLuint program,
                               GLenum binaryFormat,
                               const void *binary,
                               GLsizei length)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, 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)
    {
        ShaderProgramID programPacked                         = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramParameteri(GLuint program, GLenum pname, GLint value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLProgramParameteri, "context = %d, program = %u, pname = %s, value = %d",
          CID(context), program, GLenumToString(GLenumGroup::ProgramParameterPName, pname), value);

    if (context)
    {
        ShaderProgramID programPacked                         = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniform1d(GLuint program, GLint location, GLdouble v0)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLProgramUniform1d, "context = %d, program = %u, location = %d, v0 = %f",
          CID(context), program, location, v0);

    if (context)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateProgramUniform1d(context, programPacked, locationPacked, v0));
        if (isCallValid)
        {
            context->programUniform1d(programPacked, locationPacked, v0);
        }
        ANGLE_CAPTURE(ProgramUniform1d, isCallValid, context, programPacked, locationPacked, v0);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniform1dv(GLuint program,
                                   GLint location,
                                   GLsizei count,
                                   const GLdouble *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLProgramUniform1dv,
          "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
          CID(context), program, location, count, (uintptr_t)value);

    if (context)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramUniform1dv(context, programPacked, locationPacked, count, value));
        if (isCallValid)
        {
            context->programUniform1dv(programPacked, locationPacked, count, value);
        }
        ANGLE_CAPTURE(ProgramUniform1dv, isCallValid, context, programPacked, locationPacked, count,
                      value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniform1f(GLuint program, GLint location, GLfloat v0)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLProgramUniform1f, "context = %d, program = %u, location = %d, v0 = %f",
          CID(context), program, location, v0);

    if (context)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniform1fv(GLuint program,
                                   GLint location,
                                   GLsizei count,
                                   const GLfloat *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLProgramUniform1fv,
          "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
          CID(context), program, location, count, (uintptr_t)value);

    if (context)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniform1i(GLuint program, GLint location, GLint v0)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLProgramUniform1i, "context = %d, program = %u, location = %d, v0 = %d",
          CID(context), program, location, v0);

    if (context)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniform1iv(GLuint program,
                                   GLint location,
                                   GLsizei count,
                                   const GLint *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLProgramUniform1iv,
          "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
          CID(context), program, location, count, (uintptr_t)value);

    if (context)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniform1ui(GLuint program, GLint location, GLuint v0)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLProgramUniform1ui, "context = %d, program = %u, location = %d, v0 = %u",
          CID(context), program, location, v0);

    if (context)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniform1uiv(GLuint program,
                                    GLint location,
                                    GLsizei count,
                                    const GLuint *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLProgramUniform1uiv,
          "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
          CID(context), program, location, count, (uintptr_t)value);

    if (context)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniform2d(GLuint program, GLint location, GLdouble v0, GLdouble v1)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLProgramUniform2d,
          "context = %d, program = %u, location = %d, v0 = %f, v1 = %f", CID(context), program,
          location, v0, v1);

    if (context)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramUniform2d(context, programPacked, locationPacked, v0, v1));
        if (isCallValid)
        {
            context->programUniform2d(programPacked, locationPacked, v0, v1);
        }
        ANGLE_CAPTURE(ProgramUniform2d, isCallValid, context, programPacked, locationPacked, v0,
                      v1);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniform2dv(GLuint program,
                                   GLint location,
                                   GLsizei count,
                                   const GLdouble *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLProgramUniform2dv,
          "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
          CID(context), program, location, count, (uintptr_t)value);

    if (context)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramUniform2dv(context, programPacked, locationPacked, count, value));
        if (isCallValid)
        {
            context->programUniform2dv(programPacked, locationPacked, count, value);
        }
        ANGLE_CAPTURE(ProgramUniform2dv, isCallValid, context, programPacked, locationPacked, count,
                      value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniform2f(GLuint program, GLint location, GLfloat v0, GLfloat v1)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLProgramUniform2f,
          "context = %d, program = %u, location = %d, v0 = %f, v1 = %f", CID(context), program,
          location, v0, v1);

    if (context)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniform2fv(GLuint program,
                                   GLint location,
                                   GLsizei count,
                                   const GLfloat *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLProgramUniform2fv,
          "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
          CID(context), program, location, count, (uintptr_t)value);

    if (context)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniform2i(GLuint program, GLint location, GLint v0, GLint v1)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLProgramUniform2i,
          "context = %d, program = %u, location = %d, v0 = %d, v1 = %d", CID(context), program,
          location, v0, v1);

    if (context)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniform2iv(GLuint program,
                                   GLint location,
                                   GLsizei count,
                                   const GLint *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLProgramUniform2iv,
          "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
          CID(context), program, location, count, (uintptr_t)value);

    if (context)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniform2ui(GLuint program, GLint location, GLuint v0, GLuint v1)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLProgramUniform2ui,
          "context = %d, program = %u, location = %d, v0 = %u, v1 = %u", CID(context), program,
          location, v0, v1);

    if (context)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniform2uiv(GLuint program,
                                    GLint location,
                                    GLsizei count,
                                    const GLuint *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLProgramUniform2uiv,
          "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
          CID(context), program, location, count, (uintptr_t)value);

    if (context)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY
ProgramUniform3d(GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLProgramUniform3d,
          "context = %d, program = %u, location = %d, v0 = %f, v1 = %f, v2 = %f", CID(context),
          program, location, v0, v1, v2);

    if (context)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramUniform3d(context, programPacked, locationPacked, v0, v1, v2));
        if (isCallValid)
        {
            context->programUniform3d(programPacked, locationPacked, v0, v1, v2);
        }
        ANGLE_CAPTURE(ProgramUniform3d, isCallValid, context, programPacked, locationPacked, v0, v1,
                      v2);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniform3dv(GLuint program,
                                   GLint location,
                                   GLsizei count,
                                   const GLdouble *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLProgramUniform3dv,
          "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
          CID(context), program, location, count, (uintptr_t)value);

    if (context)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramUniform3dv(context, programPacked, locationPacked, count, value));
        if (isCallValid)
        {
            context->programUniform3dv(programPacked, locationPacked, count, value);
        }
        ANGLE_CAPTURE(ProgramUniform3dv, isCallValid, context, programPacked, locationPacked, count,
                      value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY
ProgramUniform3f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLProgramUniform3f,
          "context = %d, program = %u, location = %d, v0 = %f, v1 = %f, v2 = %f", CID(context),
          program, location, v0, v1, v2);

    if (context)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniform3fv(GLuint program,
                                   GLint location,
                                   GLsizei count,
                                   const GLfloat *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLProgramUniform3fv,
          "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
          CID(context), program, location, count, (uintptr_t)value);

    if (context)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniform3i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLProgramUniform3i,
          "context = %d, program = %u, location = %d, v0 = %d, v1 = %d, v2 = %d", CID(context),
          program, location, v0, v1, v2);

    if (context)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniform3iv(GLuint program,
                                   GLint location,
                                   GLsizei count,
                                   const GLint *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLProgramUniform3iv,
          "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
          CID(context), program, location, count, (uintptr_t)value);

    if (context)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniform3ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLProgramUniform3ui,
          "context = %d, program = %u, location = %d, v0 = %u, v1 = %u, v2 = %u", CID(context),
          program, location, v0, v1, v2);

    if (context)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniform3uiv(GLuint program,
                                    GLint location,
                                    GLsizei count,
                                    const GLuint *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLProgramUniform3uiv,
          "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
          CID(context), program, location, count, (uintptr_t)value);

    if (context)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY
ProgramUniform4d(GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLProgramUniform4d,
          "context = %d, program = %u, location = %d, v0 = %f, v1 = %f, v2 = %f, v3 = %f",
          CID(context), program, location, v0, v1, v2, v3);

    if (context)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramUniform4d(context, programPacked, locationPacked, v0, v1, v2, v3));
        if (isCallValid)
        {
            context->programUniform4d(programPacked, locationPacked, v0, v1, v2, v3);
        }
        ANGLE_CAPTURE(ProgramUniform4d, isCallValid, context, programPacked, locationPacked, v0, v1,
                      v2, v3);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniform4dv(GLuint program,
                                   GLint location,
                                   GLsizei count,
                                   const GLdouble *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLProgramUniform4dv,
          "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
          CID(context), program, location, count, (uintptr_t)value);

    if (context)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateProgramUniform4dv(context, programPacked, locationPacked, count, value));
        if (isCallValid)
        {
            context->programUniform4dv(programPacked, locationPacked, count, value);
        }
        ANGLE_CAPTURE(ProgramUniform4dv, isCallValid, context, programPacked, locationPacked, count,
                      value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY
ProgramUniform4f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, 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)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniform4fv(GLuint program,
                                   GLint location,
                                   GLsizei count,
                                   const GLfloat *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLProgramUniform4fv,
          "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
          CID(context), program, location, count, (uintptr_t)value);

    if (context)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY
ProgramUniform4i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, 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)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniform4iv(GLuint program,
                                   GLint location,
                                   GLsizei count,
                                   const GLint *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLProgramUniform4iv,
          "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
          CID(context), program, location, count, (uintptr_t)value);

    if (context)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY
ProgramUniform4ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, 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)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniform4uiv(GLuint program,
                                    GLint location,
                                    GLsizei count,
                                    const GLuint *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLProgramUniform4uiv,
          "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
          CID(context), program, location, count, (uintptr_t)value);

    if (context)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniformMatrix2dv(GLuint program,
                                         GLint location,
                                         GLsizei count,
                                         GLboolean transpose,
                                         const GLdouble *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLProgramUniformMatrix2dv,
          "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)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateProgramUniformMatrix2dv(context, programPacked, locationPacked,
                                                            count, transpose, value));
        if (isCallValid)
        {
            context->programUniformMatrix2dv(programPacked, locationPacked, count, transpose,
                                             value);
        }
        ANGLE_CAPTURE(ProgramUniformMatrix2dv, isCallValid, context, programPacked, locationPacked,
                      count, transpose, value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniformMatrix2fv(GLuint program,
                                         GLint location,
                                         GLsizei count,
                                         GLboolean transpose,
                                         const GLfloat *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, 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)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniformMatrix2x3dv(GLuint program,
                                           GLint location,
                                           GLsizei count,
                                           GLboolean transpose,
                                           const GLdouble *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLProgramUniformMatrix2x3dv,
          "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)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateProgramUniformMatrix2x3dv(
                                context, programPacked, locationPacked, count, transpose, value));
        if (isCallValid)
        {
            context->programUniformMatrix2x3dv(programPacked, locationPacked, count, transpose,
                                               value);
        }
        ANGLE_CAPTURE(ProgramUniformMatrix2x3dv, isCallValid, context, programPacked,
                      locationPacked, count, transpose, value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniformMatrix2x3fv(GLuint program,
                                           GLint location,
                                           GLsizei count,
                                           GLboolean transpose,
                                           const GLfloat *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, 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)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniformMatrix2x4dv(GLuint program,
                                           GLint location,
                                           GLsizei count,
                                           GLboolean transpose,
                                           const GLdouble *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLProgramUniformMatrix2x4dv,
          "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)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateProgramUniformMatrix2x4dv(
                                context, programPacked, locationPacked, count, transpose, value));
        if (isCallValid)
        {
            context->programUniformMatrix2x4dv(programPacked, locationPacked, count, transpose,
                                               value);
        }
        ANGLE_CAPTURE(ProgramUniformMatrix2x4dv, isCallValid, context, programPacked,
                      locationPacked, count, transpose, value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniformMatrix2x4fv(GLuint program,
                                           GLint location,
                                           GLsizei count,
                                           GLboolean transpose,
                                           const GLfloat *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, 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)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniformMatrix3dv(GLuint program,
                                         GLint location,
                                         GLsizei count,
                                         GLboolean transpose,
                                         const GLdouble *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLProgramUniformMatrix3dv,
          "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)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateProgramUniformMatrix3dv(context, programPacked, locationPacked,
                                                            count, transpose, value));
        if (isCallValid)
        {
            context->programUniformMatrix3dv(programPacked, locationPacked, count, transpose,
                                             value);
        }
        ANGLE_CAPTURE(ProgramUniformMatrix3dv, isCallValid, context, programPacked, locationPacked,
                      count, transpose, value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniformMatrix3fv(GLuint program,
                                         GLint location,
                                         GLsizei count,
                                         GLboolean transpose,
                                         const GLfloat *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, 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)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniformMatrix3x2dv(GLuint program,
                                           GLint location,
                                           GLsizei count,
                                           GLboolean transpose,
                                           const GLdouble *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLProgramUniformMatrix3x2dv,
          "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)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateProgramUniformMatrix3x2dv(
                                context, programPacked, locationPacked, count, transpose, value));
        if (isCallValid)
        {
            context->programUniformMatrix3x2dv(programPacked, locationPacked, count, transpose,
                                               value);
        }
        ANGLE_CAPTURE(ProgramUniformMatrix3x2dv, isCallValid, context, programPacked,
                      locationPacked, count, transpose, value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniformMatrix3x2fv(GLuint program,
                                           GLint location,
                                           GLsizei count,
                                           GLboolean transpose,
                                           const GLfloat *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, 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)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniformMatrix3x4dv(GLuint program,
                                           GLint location,
                                           GLsizei count,
                                           GLboolean transpose,
                                           const GLdouble *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLProgramUniformMatrix3x4dv,
          "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)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateProgramUniformMatrix3x4dv(
                                context, programPacked, locationPacked, count, transpose, value));
        if (isCallValid)
        {
            context->programUniformMatrix3x4dv(programPacked, locationPacked, count, transpose,
                                               value);
        }
        ANGLE_CAPTURE(ProgramUniformMatrix3x4dv, isCallValid, context, programPacked,
                      locationPacked, count, transpose, value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniformMatrix3x4fv(GLuint program,
                                           GLint location,
                                           GLsizei count,
                                           GLboolean transpose,
                                           const GLfloat *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, 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)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniformMatrix4dv(GLuint program,
                                         GLint location,
                                         GLsizei count,
                                         GLboolean transpose,
                                         const GLdouble *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLProgramUniformMatrix4dv,
          "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)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateProgramUniformMatrix4dv(context, programPacked, locationPacked,
                                                            count, transpose, value));
        if (isCallValid)
        {
            context->programUniformMatrix4dv(programPacked, locationPacked, count, transpose,
                                             value);
        }
        ANGLE_CAPTURE(ProgramUniformMatrix4dv, isCallValid, context, programPacked, locationPacked,
                      count, transpose, value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniformMatrix4fv(GLuint program,
                                         GLint location,
                                         GLsizei count,
                                         GLboolean transpose,
                                         const GLfloat *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, 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)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniformMatrix4x2dv(GLuint program,
                                           GLint location,
                                           GLsizei count,
                                           GLboolean transpose,
                                           const GLdouble *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLProgramUniformMatrix4x2dv,
          "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)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateProgramUniformMatrix4x2dv(
                                context, programPacked, locationPacked, count, transpose, value));
        if (isCallValid)
        {
            context->programUniformMatrix4x2dv(programPacked, locationPacked, count, transpose,
                                               value);
        }
        ANGLE_CAPTURE(ProgramUniformMatrix4x2dv, isCallValid, context, programPacked,
                      locationPacked, count, transpose, value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniformMatrix4x2fv(GLuint program,
                                           GLint location,
                                           GLsizei count,
                                           GLboolean transpose,
                                           const GLfloat *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, 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)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniformMatrix4x3dv(GLuint program,
                                           GLint location,
                                           GLsizei count,
                                           GLboolean transpose,
                                           const GLdouble *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLProgramUniformMatrix4x3dv,
          "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)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<UniformLocation>(location);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateProgramUniformMatrix4x3dv(
                                context, programPacked, locationPacked, count, transpose, value));
        if (isCallValid)
        {
            context->programUniformMatrix4x3dv(programPacked, locationPacked, count, transpose,
                                               value);
        }
        ANGLE_CAPTURE(ProgramUniformMatrix4x3dv, isCallValid, context, programPacked,
                      locationPacked, count, transpose, value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ProgramUniformMatrix4x3fv(GLuint program,
                                           GLint location,
                                           GLsizei count,
                                           GLboolean transpose,
                                           const GLfloat *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, 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)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ReleaseShaderCompiler()
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLReleaseShaderCompiler, "context = %d", CID(context));

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

void GL_APIENTRY ScissorArrayv(GLuint first, GLsizei count, const GLint *v)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLScissorArrayv, "context = %d, first = %u, count = %d, v = 0x%016" PRIxPTR "",
          CID(context), first, count, (uintptr_t)v);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateScissorArrayv(context, first, count, v));
        if (isCallValid)
        {
            context->scissorArrayv(first, count, v);
        }
        ANGLE_CAPTURE(ScissorArrayv, isCallValid, context, first, count, v);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY
ScissorIndexed(GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLScissorIndexed,
          "context = %d, index = %u, left = %d, bottom = %d, width = %d, height = %d", CID(context),
          index, left, bottom, width, height);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateScissorIndexed(context, index, left, bottom, width, height));
        if (isCallValid)
        {
            context->scissorIndexed(index, left, bottom, width, height);
        }
        ANGLE_CAPTURE(ScissorIndexed, isCallValid, context, index, left, bottom, width, height);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ScissorIndexedv(GLuint index, const GLint *v)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLScissorIndexedv, "context = %d, index = %u, v = 0x%016" PRIxPTR "",
          CID(context), index, (uintptr_t)v);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateScissorIndexedv(context, index, v));
        if (isCallValid)
        {
            context->scissorIndexedv(index, v);
        }
        ANGLE_CAPTURE(ScissorIndexedv, isCallValid, context, index, v);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ShaderBinary(GLsizei count,
                              const GLuint *shaders,
                              GLenum binaryformat,
                              const void *binary,
                              GLsizei length)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, 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)
    {
        const ShaderProgramID *shadersPacked = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY UseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLUseProgramStages, "context = %d, pipeline = %u, stages = %s, program = %u",
          CID(context), pipeline,
          GLbitfieldToString(GLenumGroup::UseProgramStageMask, stages).c_str(), program);

    if (context)
    {
        ProgramPipelineID pipelinePacked = PackParam<ProgramPipelineID>(pipeline);
        ShaderProgramID programPacked    = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ValidateProgramPipeline(GLuint pipeline)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLValidateProgramPipeline, "context = %d, pipeline = %u", CID(context),
          pipeline);

    if (context)
    {
        ProgramPipelineID pipelinePacked = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY VertexAttribL1d(GLuint index, GLdouble x)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLVertexAttribL1d, "context = %d, index = %u, x = %f", CID(context), index, x);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateVertexAttribL1d(context, index, x));
        if (isCallValid)
        {
            context->vertexAttribL1d(index, x);
        }
        ANGLE_CAPTURE(VertexAttribL1d, isCallValid, context, index, x);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY VertexAttribL1dv(GLuint index, const GLdouble *v)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLVertexAttribL1dv, "context = %d, index = %u, v = 0x%016" PRIxPTR "",
          CID(context), index, (uintptr_t)v);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateVertexAttribL1dv(context, index, v));
        if (isCallValid)
        {
            context->vertexAttribL1dv(index, v);
        }
        ANGLE_CAPTURE(VertexAttribL1dv, isCallValid, context, index, v);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY VertexAttribL2d(GLuint index, GLdouble x, GLdouble y)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLVertexAttribL2d, "context = %d, index = %u, x = %f, y = %f", CID(context),
          index, x, y);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateVertexAttribL2d(context, index, x, y));
        if (isCallValid)
        {
            context->vertexAttribL2d(index, x, y);
        }
        ANGLE_CAPTURE(VertexAttribL2d, isCallValid, context, index, x, y);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY VertexAttribL2dv(GLuint index, const GLdouble *v)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLVertexAttribL2dv, "context = %d, index = %u, v = 0x%016" PRIxPTR "",
          CID(context), index, (uintptr_t)v);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateVertexAttribL2dv(context, index, v));
        if (isCallValid)
        {
            context->vertexAttribL2dv(index, v);
        }
        ANGLE_CAPTURE(VertexAttribL2dv, isCallValid, context, index, v);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY VertexAttribL3d(GLuint index, GLdouble x, GLdouble y, GLdouble z)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLVertexAttribL3d, "context = %d, index = %u, x = %f, y = %f, z = %f",
          CID(context), index, x, y, z);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateVertexAttribL3d(context, index, x, y, z));
        if (isCallValid)
        {
            context->vertexAttribL3d(index, x, y, z);
        }
        ANGLE_CAPTURE(VertexAttribL3d, isCallValid, context, index, x, y, z);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY VertexAttribL3dv(GLuint index, const GLdouble *v)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLVertexAttribL3dv, "context = %d, index = %u, v = 0x%016" PRIxPTR "",
          CID(context), index, (uintptr_t)v);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateVertexAttribL3dv(context, index, v));
        if (isCallValid)
        {
            context->vertexAttribL3dv(index, v);
        }
        ANGLE_CAPTURE(VertexAttribL3dv, isCallValid, context, index, v);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY VertexAttribL4d(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLVertexAttribL4d, "context = %d, index = %u, x = %f, y = %f, z = %f, w = %f",
          CID(context), index, x, y, z, w);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateVertexAttribL4d(context, index, x, y, z, w));
        if (isCallValid)
        {
            context->vertexAttribL4d(index, x, y, z, w);
        }
        ANGLE_CAPTURE(VertexAttribL4d, isCallValid, context, index, x, y, z, w);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY VertexAttribL4dv(GLuint index, const GLdouble *v)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLVertexAttribL4dv, "context = %d, index = %u, v = 0x%016" PRIxPTR "",
          CID(context), index, (uintptr_t)v);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateVertexAttribL4dv(context, index, v));
        if (isCallValid)
        {
            context->vertexAttribL4dv(index, v);
        }
        ANGLE_CAPTURE(VertexAttribL4dv, isCallValid, context, index, v);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY
VertexAttribLPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLVertexAttribLPointer,
          "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)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateVertexAttribLPointer(context, index, size, type, stride, pointer));
        if (isCallValid)
        {
            context->vertexAttribLPointer(index, size, type, stride, pointer);
        }
        ANGLE_CAPTURE(VertexAttribLPointer, isCallValid, context, index, size, type, stride,
                      pointer);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ViewportArrayv(GLuint first, GLsizei count, const GLfloat *v)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLViewportArrayv, "context = %d, first = %u, count = %d, v = 0x%016" PRIxPTR "",
          CID(context), first, count, (uintptr_t)v);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateViewportArrayv(context, first, count, v));
        if (isCallValid)
        {
            context->viewportArrayv(first, count, v);
        }
        ANGLE_CAPTURE(ViewportArrayv, isCallValid, context, first, count, v);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ViewportIndexedf(GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLViewportIndexedf, "context = %d, index = %u, x = %f, y = %f, w = %f, h = %f",
          CID(context), index, x, y, w, h);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateViewportIndexedf(context, index, x, y, w, h));
        if (isCallValid)
        {
            context->viewportIndexedf(index, x, y, w, h);
        }
        ANGLE_CAPTURE(ViewportIndexedf, isCallValid, context, index, x, y, w, h);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ViewportIndexedfv(GLuint index, const GLfloat *v)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLViewportIndexedfv, "context = %d, index = %u, v = 0x%016" PRIxPTR "",
          CID(context), index, (uintptr_t)v);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateViewportIndexedfv(context, index, v));
        if (isCallValid)
        {
            context->viewportIndexedfv(index, v);
        }
        ANGLE_CAPTURE(ViewportIndexedfv, isCallValid, context, index, v);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL 4.2
void GL_APIENTRY BindImageTexture(GLuint unit,
                                  GLuint texture,
                                  GLint level,
                                  GLboolean layered,
                                  GLint layer,
                                  GLenum access,
                                  GLenum format)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, 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)
    {
        TextureID texturePacked                               = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY DrawArraysInstancedBaseInstance(GLenum mode,
                                                 GLint first,
                                                 GLsizei count,
                                                 GLsizei instancecount,
                                                 GLuint baseinstance)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLDrawArraysInstancedBaseInstance,
          "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                              = PackParam<PrimitiveMode>(mode);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateDrawArraysInstancedBaseInstance(
                                context, modePacked, first, count, instancecount, baseinstance));
        if (isCallValid)
        {
            context->drawArraysInstancedBaseInstance(modePacked, first, count, instancecount,
                                                     baseinstance);
        }
        ANGLE_CAPTURE(DrawArraysInstancedBaseInstance, isCallValid, context, modePacked, first,
                      count, instancecount, baseinstance);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY DrawElementsInstancedBaseInstance(GLenum mode,
                                                   GLsizei count,
                                                   GLenum type,
                                                   const void *indices,
                                                   GLsizei instancecount,
                                                   GLuint baseinstance)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLDrawElementsInstancedBaseInstance,
          "context = %d, mode = %s, count = %d, type = %s, indices = 0x%016" PRIxPTR
          ", instancecount = %d, baseinstance = %u",
          CID(context), GLenumToString(GLenumGroup::PrimitiveType, mode), count,
          GLenumToString(GLenumGroup::PrimitiveType, type), (uintptr_t)indices, instancecount,
          baseinstance);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateDrawElementsInstancedBaseInstance(
                                context, mode, count, type, indices, instancecount, baseinstance));
        if (isCallValid)
        {
            context->drawElementsInstancedBaseInstance(mode, count, type, indices, instancecount,
                                                       baseinstance);
        }
        ANGLE_CAPTURE(DrawElementsInstancedBaseInstance, isCallValid, context, mode, count, type,
                      indices, instancecount, baseinstance);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY DrawElementsInstancedBaseVertexBaseInstance(GLenum mode,
                                                             GLsizei count,
                                                             GLenum type,
                                                             const void *indices,
                                                             GLsizei instancecount,
                                                             GLint basevertex,
                                                             GLuint baseinstance)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLDrawElementsInstancedBaseVertexBaseInstance,
          "context = %d, mode = %s, count = %d, type = %s, indices = 0x%016" PRIxPTR
          ", instancecount = %d, basevertex = %d, baseinstance = %u",
          CID(context), GLenumToString(GLenumGroup::PrimitiveType, mode), count,
          GLenumToString(GLenumGroup::PrimitiveType, type), (uintptr_t)indices, instancecount,
          basevertex, baseinstance);

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

void GL_APIENTRY DrawTransformFeedbackInstanced(GLenum mode, GLuint id, GLsizei instancecount)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLDrawTransformFeedbackInstanced,
          "context = %d, mode = %s, id = %u, instancecount = %d", CID(context),
          GLenumToString(GLenumGroup::PrimitiveType, mode), id, instancecount);

    if (context)
    {
        TransformFeedbackID idPacked                          = PackParam<TransformFeedbackID>(id);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateDrawTransformFeedbackInstanced(context, mode, idPacked, instancecount));
        if (isCallValid)
        {
            context->drawTransformFeedbackInstanced(mode, idPacked, instancecount);
        }
        ANGLE_CAPTURE(DrawTransformFeedbackInstanced, isCallValid, context, mode, idPacked,
                      instancecount);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY DrawTransformFeedbackStreamInstanced(GLenum mode,
                                                      GLuint id,
                                                      GLuint stream,
                                                      GLsizei instancecount)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLDrawTransformFeedbackStreamInstanced,
          "context = %d, mode = %s, id = %u, stream = %u, instancecount = %d", CID(context),
          GLenumToString(GLenumGroup::PrimitiveType, mode), id, stream, instancecount);

    if (context)
    {
        TransformFeedbackID idPacked                          = PackParam<TransformFeedbackID>(id);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateDrawTransformFeedbackStreamInstanced(
                                              context, mode, idPacked, stream, instancecount));
        if (isCallValid)
        {
            context->drawTransformFeedbackStreamInstanced(mode, idPacked, stream, instancecount);
        }
        ANGLE_CAPTURE(DrawTransformFeedbackStreamInstanced, isCallValid, context, mode, idPacked,
                      stream, instancecount);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetActiveAtomicCounterBufferiv(GLuint program,
                                                GLuint bufferIndex,
                                                GLenum pname,
                                                GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetActiveAtomicCounterBufferiv,
          "context = %d, program = %u, bufferIndex = %u, pname = %s, params = 0x%016" PRIxPTR "",
          CID(context), program, bufferIndex,
          GLenumToString(GLenumGroup::AtomicCounterBufferPName, pname), (uintptr_t)params);

    if (context)
    {
        ShaderProgramID programPacked                         = PackParam<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetActiveAtomicCounterBufferiv(
                                              context, programPacked, bufferIndex, pname, params));
        if (isCallValid)
        {
            context->getActiveAtomicCounterBufferiv(programPacked, bufferIndex, pname, params);
        }
        ANGLE_CAPTURE(GetActiveAtomicCounterBufferiv, isCallValid, context, programPacked,
                      bufferIndex, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetInternalformativ(GLenum target,
                                     GLenum internalformat,
                                     GLenum pname,
                                     GLsizei bufSize,
                                     GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, 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)
    {
        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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY MemoryBarrier(GLbitfield barriers)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLMemoryBarrier, "context = %d, barriers = %s", CID(context),
          GLbitfieldToString(GLenumGroup::MemoryBarrierMask, barriers).c_str());

    if (context)
    {
        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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TexStorage1D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLTexStorage1D,
          "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() ||
                            ValidateTexStorage1D(context, target, levels, internalformat, width));
        if (isCallValid)
        {
            context->texStorage1D(target, levels, internalformat, width);
        }
        ANGLE_CAPTURE(TexStorage1D, isCallValid, context, target, levels, internalformat, width);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY
TexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, 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)
    {
        TextureType targetPacked                              = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TexStorage3D(GLenum target,
                              GLsizei levels,
                              GLenum internalformat,
                              GLsizei width,
                              GLsizei height,
                              GLsizei depth)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, 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)
    {
        TextureType targetPacked                              = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL 4.3
void GL_APIENTRY BindVertexBuffer(GLuint bindingindex,
                                  GLuint buffer,
                                  GLintptr offset,
                                  GLsizei stride)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLBindVertexBuffer,
          "context = %d, bindingindex = %u, buffer = %u, offset = %llu, stride = %d", CID(context),
          bindingindex, buffer, static_cast<unsigned long long>(offset), stride);

    if (context)
    {
        BufferID bufferPacked                                 = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY
ClearBufferData(GLenum target, GLenum internalformat, GLenum format, GLenum type, const void *data)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLClearBufferData,
          "context = %d, target = %s, internalformat = %s, format = %s, type = %s, data = "
          "0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::BufferStorageTarget, target),
          GLenumToString(GLenumGroup::InternalFormat, internalformat),
          GLenumToString(GLenumGroup::PixelFormat, format),
          GLenumToString(GLenumGroup::PixelType, type), (uintptr_t)data);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateClearBufferData(context, target, internalformat, format, type, data));
        if (isCallValid)
        {
            context->clearBufferData(target, internalformat, format, type, data);
        }
        ANGLE_CAPTURE(ClearBufferData, isCallValid, context, target, internalformat, format, type,
                      data);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ClearBufferSubData(GLenum target,
                                    GLenum internalformat,
                                    GLintptr offset,
                                    GLsizeiptr size,
                                    GLenum format,
                                    GLenum type,
                                    const void *data)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLClearBufferSubData,
          "context = %d, target = %s, internalformat = %s, offset = %llu, size = %llu, format = "
          "%s, type = %s, data = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::DefaultGroup, target),
          GLenumToString(GLenumGroup::InternalFormat, internalformat),
          static_cast<unsigned long long>(offset), static_cast<unsigned long long>(size),
          GLenumToString(GLenumGroup::PixelFormat, format),
          GLenumToString(GLenumGroup::PixelType, type), (uintptr_t)data);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateClearBufferSubData(context, target, internalformat, offset,
                                                       size, format, type, data));
        if (isCallValid)
        {
            context->clearBufferSubData(target, internalformat, offset, size, format, type, data);
        }
        ANGLE_CAPTURE(ClearBufferSubData, isCallValid, context, target, internalformat, offset,
                      size, format, type, data);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY CopyImageSubData(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, 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)
    {
        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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY DebugMessageCallback(GLDEBUGPROC callback, const void *userParam)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLDebugMessageCallback,
          "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() ||
                            ValidateDebugMessageCallback(context, callback, userParam));
        if (isCallValid)
        {
            context->debugMessageCallback(callback, userParam);
        }
        ANGLE_CAPTURE(DebugMessageCallback, isCallValid, context, callback, userParam);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY DebugMessageControl(GLenum source,
                                     GLenum type,
                                     GLenum severity,
                                     GLsizei count,
                                     const GLuint *ids,
                                     GLboolean enabled)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, 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)
    {
        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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY DebugMessageInsert(GLenum source,
                                    GLenum type,
                                    GLuint id,
                                    GLenum severity,
                                    GLsizei length,
                                    const GLchar *buf)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, 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)
    {
        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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY DispatchCompute(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, 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)
    {
        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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY DispatchComputeIndirect(GLintptr indirect)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLDispatchComputeIndirect, "context = %d, indirect = %llu", CID(context),
          static_cast<unsigned long long>(indirect));

    if (context)
    {
        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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY FramebufferParameteri(GLenum target, GLenum pname, GLint param)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLFramebufferParameteri, "context = %d, target = %s, pname = %s, param = %d",
          CID(context), GLenumToString(GLenumGroup::FramebufferTarget, target),
          GLenumToString(GLenumGroup::FramebufferParameterName, pname), param);

    if (context)
    {
        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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

GLuint GL_APIENTRY GetDebugMessageLog(GLuint count,
                                      GLsizei bufSize,
                                      GLenum *sources,
                                      GLenum *types,
                                      GLuint *ids,
                                      GLenum *severities,
                                      GLsizei *lengths,
                                      GLchar *messageLog)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, 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)
    {
        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<angle::EntryPoint::GLGetDebugMessageLog, GLuint>();
        }
        ANGLE_CAPTURE(GetDebugMessageLog, isCallValid, context, count, bufSize, sources, types, ids,
                      severities, lengths, messageLog, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
        returnValue = GetDefaultReturnValue<angle::EntryPoint::GLGetDebugMessageLog, GLuint>();
    }
    return returnValue;
}

void GL_APIENTRY GetFramebufferParameteriv(GLenum target, GLenum pname, GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, 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)
    {
        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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetInternalformati64v(GLenum target,
                                       GLenum internalformat,
                                       GLenum pname,
                                       GLsizei bufSize,
                                       GLint64 *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetInternalformati64v,
          "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)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetInternalformati64v(context, target, internalformat, pname,
                                                          bufSize, params));
        if (isCallValid)
        {
            context->getInternalformati64v(target, internalformat, pname, bufSize, params);
        }
        ANGLE_CAPTURE(GetInternalformati64v, isCallValid, context, target, internalformat, pname,
                      bufSize, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY
GetObjectLabel(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, 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)
    {
        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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetObjectPtrLabel(const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, 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)
    {
        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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetProgramInterfaceiv(GLuint program,
                                       GLenum programInterface,
                                       GLenum pname,
                                       GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, 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)
    {
        ShaderProgramID programPacked                         = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

GLuint GL_APIENTRY GetProgramResourceIndex(GLuint program,
                                           GLenum programInterface,
                                           const GLchar *name)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, 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)
    {
        ShaderProgramID programPacked                         = PackParam<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<angle::EntryPoint::GLGetProgramResourceIndex, GLuint>();
        }
        ANGLE_CAPTURE(GetProgramResourceIndex, isCallValid, context, programPacked,
                      programInterface, name, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
        returnValue = GetDefaultReturnValue<angle::EntryPoint::GLGetProgramResourceIndex, GLuint>();
    }
    return returnValue;
}

GLint GL_APIENTRY GetProgramResourceLocation(GLuint program,
                                             GLenum programInterface,
                                             const GLchar *name)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, 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)
    {
        ShaderProgramID programPacked                         = PackParam<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<angle::EntryPoint::GLGetProgramResourceLocation, GLint>();
        }
        ANGLE_CAPTURE(GetProgramResourceLocation, isCallValid, context, programPacked,
                      programInterface, name, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
        returnValue =
            GetDefaultReturnValue<angle::EntryPoint::GLGetProgramResourceLocation, GLint>();
    }
    return returnValue;
}

GLint GL_APIENTRY GetProgramResourceLocationIndex(GLuint program,
                                                  GLenum programInterface,
                                                  const GLchar *name)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetProgramResourceLocationIndex,
          "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                         = PackParam<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetProgramResourceLocationIndex(
                                              context, programPacked, programInterface, name));
        if (isCallValid)
        {
            returnValue =
                context->getProgramResourceLocationIndex(programPacked, programInterface, name);
        }
        else
        {
            returnValue =
                GetDefaultReturnValue<angle::EntryPoint::GLGetProgramResourceLocationIndex,
                                      GLint>();
        }
        ANGLE_CAPTURE(GetProgramResourceLocationIndex, isCallValid, context, programPacked,
                      programInterface, name, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
        returnValue =
            GetDefaultReturnValue<angle::EntryPoint::GLGetProgramResourceLocationIndex, GLint>();
    }
    return returnValue;
}

void GL_APIENTRY GetProgramResourceName(GLuint program,
                                        GLenum programInterface,
                                        GLuint index,
                                        GLsizei bufSize,
                                        GLsizei *length,
                                        GLchar *name)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, 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)
    {
        ShaderProgramID programPacked                         = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetProgramResourceiv(GLuint program,
                                      GLenum programInterface,
                                      GLuint index,
                                      GLsizei propCount,
                                      const GLenum *props,
                                      GLsizei bufSize,
                                      GLsizei *length,
                                      GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, 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)
    {
        ShaderProgramID programPacked                         = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY InvalidateBufferData(GLuint buffer)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLInvalidateBufferData, "context = %d, buffer = %u", CID(context), buffer);

    if (context)
    {
        BufferID bufferPacked                                 = PackParam<BufferID>(buffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateInvalidateBufferData(context, bufferPacked));
        if (isCallValid)
        {
            context->invalidateBufferData(bufferPacked);
        }
        ANGLE_CAPTURE(InvalidateBufferData, isCallValid, context, bufferPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY InvalidateBufferSubData(GLuint buffer, GLintptr offset, GLsizeiptr length)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLInvalidateBufferSubData,
          "context = %d, buffer = %u, offset = %llu, length = %llu", CID(context), buffer,
          static_cast<unsigned long long>(offset), static_cast<unsigned long long>(length));

    if (context)
    {
        BufferID bufferPacked                                 = PackParam<BufferID>(buffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateInvalidateBufferSubData(context, bufferPacked, offset, length));
        if (isCallValid)
        {
            context->invalidateBufferSubData(bufferPacked, offset, length);
        }
        ANGLE_CAPTURE(InvalidateBufferSubData, isCallValid, context, bufferPacked, offset, length);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY InvalidateFramebuffer(GLenum target,
                                       GLsizei numAttachments,
                                       const GLenum *attachments)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLInvalidateFramebuffer,
          "context = %d, target = %s, numAttachments = %d, attachments = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::FramebufferTarget, target), numAttachments,
          (uintptr_t)attachments);

    if (context)
    {
        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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY InvalidateSubFramebuffer(GLenum target,
                                          GLsizei numAttachments,
                                          const GLenum *attachments,
                                          GLint x,
                                          GLint y,
                                          GLsizei width,
                                          GLsizei height)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, 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)
    {
        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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY InvalidateTexImage(GLuint texture, GLint level)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLInvalidateTexImage, "context = %d, texture = %u, level = %d", CID(context),
          texture, level);

    if (context)
    {
        TextureID texturePacked                               = PackParam<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateInvalidateTexImage(context, texturePacked, level));
        if (isCallValid)
        {
            context->invalidateTexImage(texturePacked, level);
        }
        ANGLE_CAPTURE(InvalidateTexImage, isCallValid, context, texturePacked, level);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY InvalidateTexSubImage(GLuint texture,
                                       GLint level,
                                       GLint xoffset,
                                       GLint yoffset,
                                       GLint zoffset,
                                       GLsizei width,
                                       GLsizei height,
                                       GLsizei depth)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLInvalidateTexSubImage,
          "context = %d, texture = %u, level = %d, xoffset = %d, yoffset = %d, zoffset = %d, width "
          "= %d, height = %d, depth = %d",
          CID(context), texture, level, xoffset, yoffset, zoffset, width, height, depth);

    if (context)
    {
        TextureID texturePacked                               = PackParam<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateInvalidateTexSubImage(context, texturePacked, level, xoffset,
                                                          yoffset, zoffset, width, height, depth));
        if (isCallValid)
        {
            context->invalidateTexSubImage(texturePacked, level, xoffset, yoffset, zoffset, width,
                                           height, depth);
        }
        ANGLE_CAPTURE(InvalidateTexSubImage, isCallValid, context, texturePacked, level, xoffset,
                      yoffset, zoffset, width, height, depth);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY MultiDrawArraysIndirect(GLenum mode,
                                         const void *indirect,
                                         GLsizei drawcount,
                                         GLsizei stride)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLMultiDrawArraysIndirect,
          "context = %d, mode = %s, indirect = 0x%016" PRIxPTR ", drawcount = %d, stride = %d",
          CID(context), GLenumToString(GLenumGroup::PrimitiveType, mode), (uintptr_t)indirect,
          drawcount, stride);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateMultiDrawArraysIndirect(context, mode, indirect, drawcount, stride));
        if (isCallValid)
        {
            context->multiDrawArraysIndirect(mode, indirect, drawcount, stride);
        }
        ANGLE_CAPTURE(MultiDrawArraysIndirect, isCallValid, context, mode, indirect, drawcount,
                      stride);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY MultiDrawElementsIndirect(GLenum mode,
                                           GLenum type,
                                           const void *indirect,
                                           GLsizei drawcount,
                                           GLsizei stride)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLMultiDrawElementsIndirect,
          "context = %d, mode = %s, type = %s, indirect = 0x%016" PRIxPTR
          ", drawcount = %d, stride = %d",
          CID(context), GLenumToString(GLenumGroup::PrimitiveType, mode),
          GLenumToString(GLenumGroup::DrawElementsType, type), (uintptr_t)indirect, drawcount,
          stride);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateMultiDrawElementsIndirect(context, mode, type, indirect, drawcount, stride));
        if (isCallValid)
        {
            context->multiDrawElementsIndirect(mode, type, indirect, drawcount, stride);
        }
        ANGLE_CAPTURE(MultiDrawElementsIndirect, isCallValid, context, mode, type, indirect,
                      drawcount, stride);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ObjectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, 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)
    {
        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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ObjectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLObjectPtrLabel,
          "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() || ValidateObjectPtrLabel(context, ptr, length, label));
        if (isCallValid)
        {
            context->objectPtrLabel(ptr, length, label);
        }
        ANGLE_CAPTURE(ObjectPtrLabel, isCallValid, context, ptr, length, label);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY PopDebugGroup()
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLPopDebugGroup, "context = %d", CID(context));

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

void GL_APIENTRY PushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, 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)
    {
        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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ShaderStorageBlockBinding(GLuint program,
                                           GLuint storageBlockIndex,
                                           GLuint storageBlockBinding)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLShaderStorageBlockBinding,
          "context = %d, program = %u, storageBlockIndex = %u, storageBlockBinding = %u",
          CID(context), program, storageBlockIndex, storageBlockBinding);

    if (context)
    {
        ShaderProgramID programPacked                         = PackParam<ShaderProgramID>(program);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateShaderStorageBlockBinding(
                                context, programPacked, storageBlockIndex, storageBlockBinding));
        if (isCallValid)
        {
            context->shaderStorageBlockBinding(programPacked, storageBlockIndex,
                                               storageBlockBinding);
        }
        ANGLE_CAPTURE(ShaderStorageBlockBinding, isCallValid, context, programPacked,
                      storageBlockIndex, storageBlockBinding);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TexBufferRange(GLenum target,
                                GLenum internalformat,
                                GLuint buffer,
                                GLintptr offset,
                                GLsizeiptr size)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, 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)
    {
        TextureType targetPacked                              = PackParam<TextureType>(target);
        BufferID bufferPacked                                 = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TexStorage2DMultisample(GLenum target,
                                         GLsizei samples,
                                         GLenum internalformat,
                                         GLsizei width,
                                         GLsizei height,
                                         GLboolean fixedsamplelocations)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, 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)
    {
        TextureType targetPacked                              = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TexStorage3DMultisample(GLenum target,
                                         GLsizei samples,
                                         GLenum internalformat,
                                         GLsizei width,
                                         GLsizei height,
                                         GLsizei depth,
                                         GLboolean fixedsamplelocations)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, 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)
    {
        TextureType targetPacked                              = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TextureView(GLuint texture,
                             GLenum target,
                             GLuint origtexture,
                             GLenum internalformat,
                             GLuint minlevel,
                             GLuint numlevels,
                             GLuint minlayer,
                             GLuint numlayers)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLTextureView,
          "context = %d, texture = %u, target = %s, origtexture = %u, internalformat = %s, "
          "minlevel = %u, numlevels = %u, minlayer = %u, numlayers = %u",
          CID(context), texture, GLenumToString(GLenumGroup::TextureTarget, target), origtexture,
          GLenumToString(GLenumGroup::InternalFormat, internalformat), minlevel, numlevels,
          minlayer, numlayers);

    if (context)
    {
        TextureID texturePacked                               = PackParam<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTextureView(context, texturePacked, target, origtexture, internalformat,
                                 minlevel, numlevels, minlayer, numlayers));
        if (isCallValid)
        {
            context->textureView(texturePacked, target, origtexture, internalformat, minlevel,
                                 numlevels, minlayer, numlayers);
        }
        ANGLE_CAPTURE(TextureView, isCallValid, context, texturePacked, target, origtexture,
                      internalformat, minlevel, numlevels, minlayer, numlayers);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY VertexAttribBinding(GLuint attribindex, GLuint bindingindex)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLVertexAttribBinding, "context = %d, attribindex = %u, bindingindex = %u",
          CID(context), attribindex, bindingindex);

    if (context)
    {
        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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY VertexAttribFormat(GLuint attribindex,
                                    GLint size,
                                    GLenum type,
                                    GLboolean normalized,
                                    GLuint relativeoffset)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, 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)
    {
        VertexAttribType typePacked                           = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY VertexAttribIFormat(GLuint attribindex,
                                     GLint size,
                                     GLenum type,
                                     GLuint relativeoffset)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLVertexAttribIFormat,
          "context = %d, attribindex = %u, size = %d, type = %s, relativeoffset = %u", CID(context),
          attribindex, size, GLenumToString(GLenumGroup::DefaultGroup, type), relativeoffset);

    if (context)
    {
        VertexAttribType typePacked                           = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY VertexAttribLFormat(GLuint attribindex,
                                     GLint size,
                                     GLenum type,
                                     GLuint relativeoffset)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLVertexAttribLFormat,
          "context = %d, attribindex = %u, size = %d, type = %s, relativeoffset = %u", CID(context),
          attribindex, size, GLenumToString(GLenumGroup::VertexAttribType, type), relativeoffset);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateVertexAttribLFormat(context, attribindex, size, type, relativeoffset));
        if (isCallValid)
        {
            context->vertexAttribLFormat(attribindex, size, type, relativeoffset);
        }
        ANGLE_CAPTURE(VertexAttribLFormat, isCallValid, context, attribindex, size, type,
                      relativeoffset);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY VertexBindingDivisor(GLuint bindingindex, GLuint divisor)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLVertexBindingDivisor, "context = %d, bindingindex = %u, divisor = %u",
          CID(context), bindingindex, divisor);

    if (context)
    {
        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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL 4.4
void GL_APIENTRY BindBuffersBase(GLenum target, GLuint first, GLsizei count, const GLuint *buffers)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLBindBuffersBase,
          "context = %d, target = %s, first = %u, count = %d, buffers = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::BufferTargetARB, target), first, count,
          (uintptr_t)buffers);

    if (context)
    {
        const BufferID *buffersPacked = PackParam<const BufferID *>(buffers);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateBindBuffersBase(context, target, first, count, buffersPacked));
        if (isCallValid)
        {
            context->bindBuffersBase(target, first, count, buffersPacked);
        }
        ANGLE_CAPTURE(BindBuffersBase, isCallValid, context, target, first, count, buffersPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY BindBuffersRange(GLenum target,
                                  GLuint first,
                                  GLsizei count,
                                  const GLuint *buffers,
                                  const GLintptr *offsets,
                                  const GLsizeiptr *sizes)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLBindBuffersRange,
          "context = %d, target = %s, first = %u, count = %d, buffers = 0x%016" PRIxPTR
          ", offsets = 0x%016" PRIxPTR ", sizes = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::BufferTargetARB, target), first, count,
          (uintptr_t)buffers, (uintptr_t)offsets, (uintptr_t)sizes);

    if (context)
    {
        const BufferID *buffersPacked = PackParam<const BufferID *>(buffers);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateBindBuffersRange(context, target, first, count,
                                                                   buffersPacked, offsets, sizes));
        if (isCallValid)
        {
            context->bindBuffersRange(target, first, count, buffersPacked, offsets, sizes);
        }
        ANGLE_CAPTURE(BindBuffersRange, isCallValid, context, target, first, count, buffersPacked,
                      offsets, sizes);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY BindImageTextures(GLuint first, GLsizei count, const GLuint *textures)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLBindImageTextures,
          "context = %d, first = %u, count = %d, textures = 0x%016" PRIxPTR "", CID(context), first,
          count, (uintptr_t)textures);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateBindImageTextures(context, first, count, textures));
        if (isCallValid)
        {
            context->bindImageTextures(first, count, textures);
        }
        ANGLE_CAPTURE(BindImageTextures, isCallValid, context, first, count, textures);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY BindSamplers(GLuint first, GLsizei count, const GLuint *samplers)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLBindSamplers,
          "context = %d, first = %u, count = %d, samplers = 0x%016" PRIxPTR "", CID(context), first,
          count, (uintptr_t)samplers);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateBindSamplers(context, first, count, samplers));
        if (isCallValid)
        {
            context->bindSamplers(first, count, samplers);
        }
        ANGLE_CAPTURE(BindSamplers, isCallValid, context, first, count, samplers);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY BindTextures(GLuint first, GLsizei count, const GLuint *textures)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLBindTextures,
          "context = %d, first = %u, count = %d, textures = 0x%016" PRIxPTR "", CID(context), first,
          count, (uintptr_t)textures);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateBindTextures(context, first, count, textures));
        if (isCallValid)
        {
            context->bindTextures(first, count, textures);
        }
        ANGLE_CAPTURE(BindTextures, isCallValid, context, first, count, textures);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY BindVertexBuffers(GLuint first,
                                   GLsizei count,
                                   const GLuint *buffers,
                                   const GLintptr *offsets,
                                   const GLsizei *strides)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLBindVertexBuffers,
          "context = %d, first = %u, count = %d, buffers = 0x%016" PRIxPTR
          ", offsets = 0x%016" PRIxPTR ", strides = 0x%016" PRIxPTR "",
          CID(context), first, count, (uintptr_t)buffers, (uintptr_t)offsets, (uintptr_t)strides);

    if (context)
    {
        const BufferID *buffersPacked = PackParam<const BufferID *>(buffers);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateBindVertexBuffers(context, first, count, buffersPacked, offsets, strides));
        if (isCallValid)
        {
            context->bindVertexBuffers(first, count, buffersPacked, offsets, strides);
        }
        ANGLE_CAPTURE(BindVertexBuffers, isCallValid, context, first, count, buffersPacked, offsets,
                      strides);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY BufferStorage(GLenum target, GLsizeiptr size, const void *data, GLbitfield flags)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLBufferStorage,
          "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                            = PackParam<BufferBinding>(target);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateBufferStorage(context, targetPacked, size, data, flags));
        if (isCallValid)
        {
            context->bufferStorage(targetPacked, size, data, flags);
        }
        ANGLE_CAPTURE(BufferStorage, isCallValid, context, targetPacked, size, data, flags);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY
ClearTexImage(GLuint texture, GLint level, GLenum format, GLenum type, const void *data)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLClearTexImage,
          "context = %d, texture = %u, level = %d, format = %s, type = %s, data = 0x%016" PRIxPTR
          "",
          CID(context), texture, level, GLenumToString(GLenumGroup::PixelFormat, format),
          GLenumToString(GLenumGroup::PixelType, type), (uintptr_t)data);

    if (context)
    {
        TextureID texturePacked                               = PackParam<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateClearTexImage(context, texturePacked, level, format, type, data));
        if (isCallValid)
        {
            context->clearTexImage(texturePacked, level, format, type, data);
        }
        ANGLE_CAPTURE(ClearTexImage, isCallValid, context, texturePacked, level, format, type,
                      data);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ClearTexSubImage(GLuint texture,
                                  GLint level,
                                  GLint xoffset,
                                  GLint yoffset,
                                  GLint zoffset,
                                  GLsizei width,
                                  GLsizei height,
                                  GLsizei depth,
                                  GLenum format,
                                  GLenum type,
                                  const void *data)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLClearTexSubImage,
          "context = %d, texture = %u, level = %d, xoffset = %d, yoffset = %d, zoffset = %d, width "
          "= %d, height = %d, depth = %d, format = %s, type = %s, data = 0x%016" PRIxPTR "",
          CID(context), texture, level, xoffset, yoffset, zoffset, width, height, depth,
          GLenumToString(GLenumGroup::PixelFormat, format),
          GLenumToString(GLenumGroup::PixelType, type), (uintptr_t)data);

    if (context)
    {
        TextureID texturePacked                               = PackParam<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateClearTexSubImage(context, texturePacked, level, xoffset, yoffset, zoffset,
                                      width, height, depth, format, type, data));
        if (isCallValid)
        {
            context->clearTexSubImage(texturePacked, level, xoffset, yoffset, zoffset, width,
                                      height, depth, format, type, data);
        }
        ANGLE_CAPTURE(ClearTexSubImage, isCallValid, context, texturePacked, level, xoffset,
                      yoffset, zoffset, width, height, depth, format, type, data);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL 4.5
void GL_APIENTRY BindTextureUnit(GLuint unit, GLuint texture)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLBindTextureUnit, "context = %d, unit = %u, texture = %u", CID(context), unit,
          texture);

    if (context)
    {
        TextureID texturePacked                               = PackParam<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateBindTextureUnit(context, unit, texturePacked));
        if (isCallValid)
        {
            context->bindTextureUnit(unit, texturePacked);
        }
        ANGLE_CAPTURE(BindTextureUnit, isCallValid, context, unit, texturePacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY BlitNamedFramebuffer(GLuint readFramebuffer,
                                      GLuint drawFramebuffer,
                                      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, GLBlitNamedFramebuffer,
        "context = %d, readFramebuffer = %u, drawFramebuffer = %u, srcX0 = %d, srcY0 = %d, srcX1 = "
        "%d, srcY1 = %d, dstX0 = %d, dstY0 = %d, dstX1 = %d, dstY1 = %d, mask = %s, filter = %s",
        CID(context), readFramebuffer, drawFramebuffer, 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() ||
             ValidateBlitNamedFramebuffer(context, readFramebuffer, drawFramebuffer, srcX0, srcY0,
                                          srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter));
        if (isCallValid)
        {
            context->blitNamedFramebuffer(readFramebuffer, drawFramebuffer, srcX0, srcY0, srcX1,
                                          srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
        }
        ANGLE_CAPTURE(BlitNamedFramebuffer, isCallValid, context, readFramebuffer, drawFramebuffer,
                      srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

GLenum GL_APIENTRY CheckNamedFramebufferStatus(GLuint framebuffer, GLenum target)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLCheckNamedFramebufferStatus, "context = %d, framebuffer = %u, target = %s",
          CID(context), framebuffer, GLenumToString(GLenumGroup::FramebufferTarget, target));

    GLenum returnValue;
    if (context)
    {
        FramebufferID framebufferPacked = PackParam<FramebufferID>(framebuffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateCheckNamedFramebufferStatus(
                                                             context, framebufferPacked, target));
        if (isCallValid)
        {
            returnValue = context->checkNamedFramebufferStatus(framebufferPacked, target);
        }
        else
        {
            returnValue =
                GetDefaultReturnValue<angle::EntryPoint::GLCheckNamedFramebufferStatus, GLenum>();
        }
        ANGLE_CAPTURE(CheckNamedFramebufferStatus, isCallValid, context, framebufferPacked, target,
                      returnValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
        returnValue =
            GetDefaultReturnValue<angle::EntryPoint::GLCheckNamedFramebufferStatus, GLenum>();
    }
    return returnValue;
}

void GL_APIENTRY ClearNamedBufferData(GLuint buffer,
                                      GLenum internalformat,
                                      GLenum format,
                                      GLenum type,
                                      const void *data)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLClearNamedBufferData,
          "context = %d, buffer = %u, internalformat = %s, format = %s, type = %s, data = "
          "0x%016" PRIxPTR "",
          CID(context), buffer, GLenumToString(GLenumGroup::InternalFormat, internalformat),
          GLenumToString(GLenumGroup::PixelFormat, format),
          GLenumToString(GLenumGroup::PixelType, type), (uintptr_t)data);

    if (context)
    {
        BufferID bufferPacked                                 = PackParam<BufferID>(buffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateClearNamedBufferData(context, bufferPacked, internalformat,
                                                         format, type, data));
        if (isCallValid)
        {
            context->clearNamedBufferData(bufferPacked, internalformat, format, type, data);
        }
        ANGLE_CAPTURE(ClearNamedBufferData, isCallValid, context, bufferPacked, internalformat,
                      format, type, data);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ClearNamedBufferSubData(GLuint buffer,
                                         GLenum internalformat,
                                         GLintptr offset,
                                         GLsizeiptr size,
                                         GLenum format,
                                         GLenum type,
                                         const void *data)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLClearNamedBufferSubData,
          "context = %d, buffer = %u, internalformat = %s, offset = %llu, size = %llu, format = "
          "%s, type = %s, data = 0x%016" PRIxPTR "",
          CID(context), buffer, GLenumToString(GLenumGroup::InternalFormat, internalformat),
          static_cast<unsigned long long>(offset), static_cast<unsigned long long>(size),
          GLenumToString(GLenumGroup::PixelFormat, format),
          GLenumToString(GLenumGroup::PixelType, type), (uintptr_t)data);

    if (context)
    {
        BufferID bufferPacked                                 = PackParam<BufferID>(buffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateClearNamedBufferSubData(context, bufferPacked, internalformat,
                                                            offset, size, format, type, data));
        if (isCallValid)
        {
            context->clearNamedBufferSubData(bufferPacked, internalformat, offset, size, format,
                                             type, data);
        }
        ANGLE_CAPTURE(ClearNamedBufferSubData, isCallValid, context, bufferPacked, internalformat,
                      offset, size, format, type, data);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ClearNamedFramebufferfi(GLuint framebuffer,
                                         GLenum buffer,
                                         GLint drawbuffer,
                                         GLfloat depth,
                                         GLint stencil)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLClearNamedFramebufferfi,
          "context = %d, framebuffer = %u, buffer = %s, drawbuffer = %d, depth = %f, stencil = %d",
          CID(context), framebuffer, GLenumToString(GLenumGroup::Buffer, buffer), drawbuffer, depth,
          stencil);

    if (context)
    {
        FramebufferID framebufferPacked = PackParam<FramebufferID>(framebuffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateClearNamedFramebufferfi(context, framebufferPacked, buffer,
                                                            drawbuffer, depth, stencil));
        if (isCallValid)
        {
            context->clearNamedFramebufferfi(framebufferPacked, buffer, drawbuffer, depth, stencil);
        }
        ANGLE_CAPTURE(ClearNamedFramebufferfi, isCallValid, context, framebufferPacked, buffer,
                      drawbuffer, depth, stencil);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ClearNamedFramebufferfv(GLuint framebuffer,
                                         GLenum buffer,
                                         GLint drawbuffer,
                                         const GLfloat *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLClearNamedFramebufferfv,
          "context = %d, framebuffer = %u, buffer = %s, drawbuffer = %d, value = 0x%016" PRIxPTR "",
          CID(context), framebuffer, GLenumToString(GLenumGroup::Buffer, buffer), drawbuffer,
          (uintptr_t)value);

    if (context)
    {
        FramebufferID framebufferPacked = PackParam<FramebufferID>(framebuffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateClearNamedFramebufferfv(context, framebufferPacked, buffer,
                                                            drawbuffer, value));
        if (isCallValid)
        {
            context->clearNamedFramebufferfv(framebufferPacked, buffer, drawbuffer, value);
        }
        ANGLE_CAPTURE(ClearNamedFramebufferfv, isCallValid, context, framebufferPacked, buffer,
                      drawbuffer, value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ClearNamedFramebufferiv(GLuint framebuffer,
                                         GLenum buffer,
                                         GLint drawbuffer,
                                         const GLint *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLClearNamedFramebufferiv,
          "context = %d, framebuffer = %u, buffer = %s, drawbuffer = %d, value = 0x%016" PRIxPTR "",
          CID(context), framebuffer, GLenumToString(GLenumGroup::Buffer, buffer), drawbuffer,
          (uintptr_t)value);

    if (context)
    {
        FramebufferID framebufferPacked = PackParam<FramebufferID>(framebuffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateClearNamedFramebufferiv(context, framebufferPacked, buffer,
                                                            drawbuffer, value));
        if (isCallValid)
        {
            context->clearNamedFramebufferiv(framebufferPacked, buffer, drawbuffer, value);
        }
        ANGLE_CAPTURE(ClearNamedFramebufferiv, isCallValid, context, framebufferPacked, buffer,
                      drawbuffer, value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ClearNamedFramebufferuiv(GLuint framebuffer,
                                          GLenum buffer,
                                          GLint drawbuffer,
                                          const GLuint *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLClearNamedFramebufferuiv,
          "context = %d, framebuffer = %u, buffer = %s, drawbuffer = %d, value = 0x%016" PRIxPTR "",
          CID(context), framebuffer, GLenumToString(GLenumGroup::Buffer, buffer), drawbuffer,
          (uintptr_t)value);

    if (context)
    {
        FramebufferID framebufferPacked = PackParam<FramebufferID>(framebuffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateClearNamedFramebufferuiv(context, framebufferPacked, buffer,
                                                             drawbuffer, value));
        if (isCallValid)
        {
            context->clearNamedFramebufferuiv(framebufferPacked, buffer, drawbuffer, value);
        }
        ANGLE_CAPTURE(ClearNamedFramebufferuiv, isCallValid, context, framebufferPacked, buffer,
                      drawbuffer, value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ClipControl(GLenum origin, GLenum depth)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLClipControl, "context = %d, origin = %s, depth = %s", CID(context),
          GLenumToString(GLenumGroup::ClipControlOrigin, origin),
          GLenumToString(GLenumGroup::ClipControlDepth, depth));

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateClipControl(context, origin, depth));
        if (isCallValid)
        {
            context->clipControl(origin, depth);
        }
        ANGLE_CAPTURE(ClipControl, isCallValid, context, origin, depth);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY CompressedTextureSubImage1D(GLuint texture,
                                             GLint level,
                                             GLint xoffset,
                                             GLsizei width,
                                             GLenum format,
                                             GLsizei imageSize,
                                             const void *data)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLCompressedTextureSubImage1D,
          "context = %d, texture = %u, level = %d, xoffset = %d, width = %d, format = %s, "
          "imageSize = %d, data = 0x%016" PRIxPTR "",
          CID(context), texture, level, xoffset, width,
          GLenumToString(GLenumGroup::PixelFormat, format), imageSize, (uintptr_t)data);

    if (context)
    {
        TextureID texturePacked                               = PackParam<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateCompressedTextureSubImage1D(
                                                             context, texturePacked, level, xoffset,
                                                             width, format, imageSize, data));
        if (isCallValid)
        {
            context->compressedTextureSubImage1D(texturePacked, level, xoffset, width, format,
                                                 imageSize, data);
        }
        ANGLE_CAPTURE(CompressedTextureSubImage1D, isCallValid, context, texturePacked, level,
                      xoffset, width, format, imageSize, data);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY CompressedTextureSubImage2D(GLuint texture,
                                             GLint level,
                                             GLint xoffset,
                                             GLint yoffset,
                                             GLsizei width,
                                             GLsizei height,
                                             GLenum format,
                                             GLsizei imageSize,
                                             const void *data)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLCompressedTextureSubImage2D,
          "context = %d, texture = %u, level = %d, xoffset = %d, yoffset = %d, width = %d, height "
          "= %d, format = %s, imageSize = %d, data = 0x%016" PRIxPTR "",
          CID(context), texture, level, xoffset, yoffset, width, height,
          GLenumToString(GLenumGroup::PixelFormat, format), imageSize, (uintptr_t)data);

    if (context)
    {
        TextureID texturePacked                               = PackParam<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateCompressedTextureSubImage2D(context, texturePacked, level, xoffset, yoffset,
                                                 width, height, format, imageSize, data));
        if (isCallValid)
        {
            context->compressedTextureSubImage2D(texturePacked, level, xoffset, yoffset, width,
                                                 height, format, imageSize, data);
        }
        ANGLE_CAPTURE(CompressedTextureSubImage2D, isCallValid, context, texturePacked, level,
                      xoffset, yoffset, width, height, format, imageSize, data);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY CompressedTextureSubImage3D(GLuint texture,
                                             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, GLCompressedTextureSubImage3D,
          "context = %d, texture = %u, level = %d, xoffset = %d, yoffset = %d, zoffset = %d, width "
          "= %d, height = %d, depth = %d, format = %s, imageSize = %d, data = 0x%016" PRIxPTR "",
          CID(context), texture, level, xoffset, yoffset, zoffset, width, height, depth,
          GLenumToString(GLenumGroup::PixelFormat, format), imageSize, (uintptr_t)data);

    if (context)
    {
        TextureID texturePacked                               = PackParam<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateCompressedTextureSubImage3D(
                                context, texturePacked, level, xoffset, yoffset, zoffset, width,
                                height, depth, format, imageSize, data));
        if (isCallValid)
        {
            context->compressedTextureSubImage3D(texturePacked, level, xoffset, yoffset, zoffset,
                                                 width, height, depth, format, imageSize, data);
        }
        ANGLE_CAPTURE(CompressedTextureSubImage3D, isCallValid, context, texturePacked, level,
                      xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY CopyNamedBufferSubData(GLuint readBuffer,
                                        GLuint writeBuffer,
                                        GLintptr readOffset,
                                        GLintptr writeOffset,
                                        GLsizeiptr size)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLCopyNamedBufferSubData,
          "context = %d, readBuffer = %u, writeBuffer = %u, readOffset = %llu, writeOffset = %llu, "
          "size = %llu",
          CID(context), readBuffer, writeBuffer, static_cast<unsigned long long>(readOffset),
          static_cast<unsigned long long>(writeOffset), static_cast<unsigned long long>(size));

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateCopyNamedBufferSubData(context, readBuffer, writeBuffer,
                                                           readOffset, writeOffset, size));
        if (isCallValid)
        {
            context->copyNamedBufferSubData(readBuffer, writeBuffer, readOffset, writeOffset, size);
        }
        ANGLE_CAPTURE(CopyNamedBufferSubData, isCallValid, context, readBuffer, writeBuffer,
                      readOffset, writeOffset, size);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY
CopyTextureSubImage1D(GLuint texture, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLCopyTextureSubImage1D,
          "context = %d, texture = %u, level = %d, xoffset = %d, x = %d, y = %d, width = %d",
          CID(context), texture, level, xoffset, x, y, width);

    if (context)
    {
        TextureID texturePacked                               = PackParam<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateCopyTextureSubImage1D(context, texturePacked, level, xoffset, x, y, width));
        if (isCallValid)
        {
            context->copyTextureSubImage1D(texturePacked, level, xoffset, x, y, width);
        }
        ANGLE_CAPTURE(CopyTextureSubImage1D, isCallValid, context, texturePacked, level, xoffset, x,
                      y, width);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY CopyTextureSubImage2D(GLuint texture,
                                       GLint level,
                                       GLint xoffset,
                                       GLint yoffset,
                                       GLint x,
                                       GLint y,
                                       GLsizei width,
                                       GLsizei height)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLCopyTextureSubImage2D,
          "context = %d, texture = %u, level = %d, xoffset = %d, yoffset = %d, x = %d, y = %d, "
          "width = %d, height = %d",
          CID(context), texture, level, xoffset, yoffset, x, y, width, height);

    if (context)
    {
        TextureID texturePacked                               = PackParam<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateCopyTextureSubImage2D(context, texturePacked, level, xoffset,
                                                          yoffset, x, y, width, height));
        if (isCallValid)
        {
            context->copyTextureSubImage2D(texturePacked, level, xoffset, yoffset, x, y, width,
                                           height);
        }
        ANGLE_CAPTURE(CopyTextureSubImage2D, isCallValid, context, texturePacked, level, xoffset,
                      yoffset, x, y, width, height);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY CopyTextureSubImage3D(GLuint texture,
                                       GLint level,
                                       GLint xoffset,
                                       GLint yoffset,
                                       GLint zoffset,
                                       GLint x,
                                       GLint y,
                                       GLsizei width,
                                       GLsizei height)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLCopyTextureSubImage3D,
          "context = %d, texture = %u, level = %d, xoffset = %d, yoffset = %d, zoffset = %d, x = "
          "%d, y = %d, width = %d, height = %d",
          CID(context), texture, level, xoffset, yoffset, zoffset, x, y, width, height);

    if (context)
    {
        TextureID texturePacked                               = PackParam<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateCopyTextureSubImage3D(context, texturePacked, level, xoffset,
                                                          yoffset, zoffset, x, y, width, height));
        if (isCallValid)
        {
            context->copyTextureSubImage3D(texturePacked, level, xoffset, yoffset, zoffset, x, y,
                                           width, height);
        }
        ANGLE_CAPTURE(CopyTextureSubImage3D, isCallValid, context, texturePacked, level, xoffset,
                      yoffset, zoffset, x, y, width, height);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY CreateBuffers(GLsizei n, GLuint *buffers)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLCreateBuffers, "context = %d, n = %d, buffers = 0x%016" PRIxPTR "",
          CID(context), n, (uintptr_t)buffers);

    if (context)
    {
        BufferID *buffersPacked                               = PackParam<BufferID *>(buffers);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateCreateBuffers(context, n, buffersPacked));
        if (isCallValid)
        {
            context->createBuffers(n, buffersPacked);
        }
        ANGLE_CAPTURE(CreateBuffers, isCallValid, context, n, buffersPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY CreateFramebuffers(GLsizei n, GLuint *framebuffers)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLCreateFramebuffers, "context = %d, n = %d, framebuffers = 0x%016" PRIxPTR "",
          CID(context), n, (uintptr_t)framebuffers);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateCreateFramebuffers(context, n, framebuffers));
        if (isCallValid)
        {
            context->createFramebuffers(n, framebuffers);
        }
        ANGLE_CAPTURE(CreateFramebuffers, isCallValid, context, n, framebuffers);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY CreateProgramPipelines(GLsizei n, GLuint *pipelines)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLCreateProgramPipelines, "context = %d, n = %d, pipelines = 0x%016" PRIxPTR "",
          CID(context), n, (uintptr_t)pipelines);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateCreateProgramPipelines(context, n, pipelines));
        if (isCallValid)
        {
            context->createProgramPipelines(n, pipelines);
        }
        ANGLE_CAPTURE(CreateProgramPipelines, isCallValid, context, n, pipelines);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY CreateQueries(GLenum target, GLsizei n, GLuint *ids)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLCreateQueries, "context = %d, target = %s, n = %d, ids = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::QueryTarget, target), n, (uintptr_t)ids);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateCreateQueries(context, target, n, ids));
        if (isCallValid)
        {
            context->createQueries(target, n, ids);
        }
        ANGLE_CAPTURE(CreateQueries, isCallValid, context, target, n, ids);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY CreateRenderbuffers(GLsizei n, GLuint *renderbuffers)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLCreateRenderbuffers, "context = %d, n = %d, renderbuffers = 0x%016" PRIxPTR "",
          CID(context), n, (uintptr_t)renderbuffers);

    if (context)
    {
        RenderbufferID *renderbuffersPacked = PackParam<RenderbufferID *>(renderbuffers);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateCreateRenderbuffers(context, n, renderbuffersPacked));
        if (isCallValid)
        {
            context->createRenderbuffers(n, renderbuffersPacked);
        }
        ANGLE_CAPTURE(CreateRenderbuffers, isCallValid, context, n, renderbuffersPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY CreateSamplers(GLsizei n, GLuint *samplers)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLCreateSamplers, "context = %d, n = %d, samplers = 0x%016" PRIxPTR "",
          CID(context), n, (uintptr_t)samplers);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateCreateSamplers(context, n, samplers));
        if (isCallValid)
        {
            context->createSamplers(n, samplers);
        }
        ANGLE_CAPTURE(CreateSamplers, isCallValid, context, n, samplers);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY CreateTextures(GLenum target, GLsizei n, GLuint *textures)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLCreateTextures,
          "context = %d, target = %s, n = %d, textures = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::TextureTarget, target), n, (uintptr_t)textures);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateCreateTextures(context, target, n, textures));
        if (isCallValid)
        {
            context->createTextures(target, n, textures);
        }
        ANGLE_CAPTURE(CreateTextures, isCallValid, context, target, n, textures);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY CreateTransformFeedbacks(GLsizei n, GLuint *ids)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLCreateTransformFeedbacks, "context = %d, n = %d, ids = 0x%016" PRIxPTR "",
          CID(context), n, (uintptr_t)ids);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateCreateTransformFeedbacks(context, n, ids));
        if (isCallValid)
        {
            context->createTransformFeedbacks(n, ids);
        }
        ANGLE_CAPTURE(CreateTransformFeedbacks, isCallValid, context, n, ids);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY CreateVertexArrays(GLsizei n, GLuint *arrays)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLCreateVertexArrays, "context = %d, n = %d, arrays = 0x%016" PRIxPTR "",
          CID(context), n, (uintptr_t)arrays);

    if (context)
    {
        VertexArrayID *arraysPacked                           = PackParam<VertexArrayID *>(arrays);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateCreateVertexArrays(context, n, arraysPacked));
        if (isCallValid)
        {
            context->createVertexArrays(n, arraysPacked);
        }
        ANGLE_CAPTURE(CreateVertexArrays, isCallValid, context, n, arraysPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY DisableVertexArrayAttrib(GLuint vaobj, GLuint index)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLDisableVertexArrayAttrib, "context = %d, vaobj = %u, index = %u", CID(context),
          vaobj, index);

    if (context)
    {
        VertexArrayID vaobjPacked                             = PackParam<VertexArrayID>(vaobj);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateDisableVertexArrayAttrib(context, vaobjPacked, index));
        if (isCallValid)
        {
            context->disableVertexArrayAttrib(vaobjPacked, index);
        }
        ANGLE_CAPTURE(DisableVertexArrayAttrib, isCallValid, context, vaobjPacked, index);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY EnableVertexArrayAttrib(GLuint vaobj, GLuint index)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLEnableVertexArrayAttrib, "context = %d, vaobj = %u, index = %u", CID(context),
          vaobj, index);

    if (context)
    {
        VertexArrayID vaobjPacked                             = PackParam<VertexArrayID>(vaobj);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateEnableVertexArrayAttrib(context, vaobjPacked, index));
        if (isCallValid)
        {
            context->enableVertexArrayAttrib(vaobjPacked, index);
        }
        ANGLE_CAPTURE(EnableVertexArrayAttrib, isCallValid, context, vaobjPacked, index);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY FlushMappedNamedBufferRange(GLuint buffer, GLintptr offset, GLsizeiptr length)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLFlushMappedNamedBufferRange,
          "context = %d, buffer = %u, offset = %llu, length = %llu", CID(context), buffer,
          static_cast<unsigned long long>(offset), static_cast<unsigned long long>(length));

    if (context)
    {
        BufferID bufferPacked                                 = PackParam<BufferID>(buffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateFlushMappedNamedBufferRange(context, bufferPacked, offset, length));
        if (isCallValid)
        {
            context->flushMappedNamedBufferRange(bufferPacked, offset, length);
        }
        ANGLE_CAPTURE(FlushMappedNamedBufferRange, isCallValid, context, bufferPacked, offset,
                      length);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GenerateTextureMipmap(GLuint texture)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGenerateTextureMipmap, "context = %d, texture = %u", CID(context), texture);

    if (context)
    {
        TextureID texturePacked                               = PackParam<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGenerateTextureMipmap(context, texturePacked));
        if (isCallValid)
        {
            context->generateTextureMipmap(texturePacked);
        }
        ANGLE_CAPTURE(GenerateTextureMipmap, isCallValid, context, texturePacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetCompressedTextureImage(GLuint texture,
                                           GLint level,
                                           GLsizei bufSize,
                                           void *pixels)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetCompressedTextureImage,
          "context = %d, texture = %u, level = %d, bufSize = %d, pixels = 0x%016" PRIxPTR "",
          CID(context), texture, level, bufSize, (uintptr_t)pixels);

    if (context)
    {
        TextureID texturePacked                               = PackParam<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetCompressedTextureImage(context, texturePacked, level, bufSize, pixels));
        if (isCallValid)
        {
            context->getCompressedTextureImage(texturePacked, level, bufSize, pixels);
        }
        ANGLE_CAPTURE(GetCompressedTextureImage, isCallValid, context, texturePacked, level,
                      bufSize, pixels);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetCompressedTextureSubImage(GLuint texture,
                                              GLint level,
                                              GLint xoffset,
                                              GLint yoffset,
                                              GLint zoffset,
                                              GLsizei width,
                                              GLsizei height,
                                              GLsizei depth,
                                              GLsizei bufSize,
                                              void *pixels)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetCompressedTextureSubImage,
          "context = %d, texture = %u, level = %d, xoffset = %d, yoffset = %d, zoffset = %d, width "
          "= %d, height = %d, depth = %d, bufSize = %d, pixels = 0x%016" PRIxPTR "",
          CID(context), texture, level, xoffset, yoffset, zoffset, width, height, depth, bufSize,
          (uintptr_t)pixels);

    if (context)
    {
        TextureID texturePacked                               = PackParam<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetCompressedTextureSubImage(context, texturePacked, level, xoffset, yoffset,
                                                  zoffset, width, height, depth, bufSize, pixels));
        if (isCallValid)
        {
            context->getCompressedTextureSubImage(texturePacked, level, xoffset, yoffset, zoffset,
                                                  width, height, depth, bufSize, pixels);
        }
        ANGLE_CAPTURE(GetCompressedTextureSubImage, isCallValid, context, texturePacked, level,
                      xoffset, yoffset, zoffset, width, height, depth, bufSize, pixels);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

GLenum GL_APIENTRY GetGraphicsResetStatus()
{
    Context *context = GetGlobalContext();
    EVENT(context, GLGetGraphicsResetStatus, "context = %d", CID(context));

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

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

void GL_APIENTRY GetNamedBufferParameteri64v(GLuint buffer, GLenum pname, GLint64 *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetNamedBufferParameteri64v,
          "context = %d, buffer = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context), buffer,
          GLenumToString(GLenumGroup::VertexBufferObjectParameter, pname), (uintptr_t)params);

    if (context)
    {
        BufferID bufferPacked                                 = PackParam<BufferID>(buffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateGetNamedBufferParameteri64v(
                                                             context, bufferPacked, pname, params));
        if (isCallValid)
        {
            context->getNamedBufferParameteri64v(bufferPacked, pname, params);
        }
        ANGLE_CAPTURE(GetNamedBufferParameteri64v, isCallValid, context, bufferPacked, pname,
                      params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetNamedBufferParameteriv(GLuint buffer, GLenum pname, GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetNamedBufferParameteriv,
          "context = %d, buffer = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context), buffer,
          GLenumToString(GLenumGroup::VertexBufferObjectParameter, pname), (uintptr_t)params);

    if (context)
    {
        BufferID bufferPacked                                 = PackParam<BufferID>(buffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateGetNamedBufferParameteriv(
                                                             context, bufferPacked, pname, params));
        if (isCallValid)
        {
            context->getNamedBufferParameteriv(bufferPacked, pname, params);
        }
        ANGLE_CAPTURE(GetNamedBufferParameteriv, isCallValid, context, bufferPacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetNamedBufferPointerv(GLuint buffer, GLenum pname, void **params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetNamedBufferPointerv,
          "context = %d, buffer = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context), buffer,
          GLenumToString(GLenumGroup::VertexBufferObjectParameter, pname), (uintptr_t)params);

    if (context)
    {
        BufferID bufferPacked                                 = PackParam<BufferID>(buffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetNamedBufferPointerv(context, bufferPacked, pname, params));
        if (isCallValid)
        {
            context->getNamedBufferPointerv(bufferPacked, pname, params);
        }
        ANGLE_CAPTURE(GetNamedBufferPointerv, isCallValid, context, bufferPacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetNamedBufferSubData(GLuint buffer, GLintptr offset, GLsizeiptr size, void *data)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetNamedBufferSubData,
          "context = %d, buffer = %u, offset = %llu, size = %llu, data = 0x%016" PRIxPTR "",
          CID(context), buffer, static_cast<unsigned long long>(offset),
          static_cast<unsigned long long>(size), (uintptr_t)data);

    if (context)
    {
        BufferID bufferPacked                                 = PackParam<BufferID>(buffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetNamedBufferSubData(context, bufferPacked, offset, size, data));
        if (isCallValid)
        {
            context->getNamedBufferSubData(bufferPacked, offset, size, data);
        }
        ANGLE_CAPTURE(GetNamedBufferSubData, isCallValid, context, bufferPacked, offset, size,
                      data);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetNamedFramebufferAttachmentParameteriv(GLuint framebuffer,
                                                          GLenum attachment,
                                                          GLenum pname,
                                                          GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetNamedFramebufferAttachmentParameteriv,
          "context = %d, framebuffer = %u, attachment = %s, pname = %s, params = 0x%016" PRIxPTR "",
          CID(context), framebuffer, GLenumToString(GLenumGroup::FramebufferAttachment, attachment),
          GLenumToString(GLenumGroup::FramebufferAttachmentParameterName, pname),
          (uintptr_t)params);

    if (context)
    {
        FramebufferID framebufferPacked = PackParam<FramebufferID>(framebuffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetNamedFramebufferAttachmentParameteriv(
                                context, framebufferPacked, attachment, pname, params));
        if (isCallValid)
        {
            context->getNamedFramebufferAttachmentParameteriv(framebufferPacked, attachment, pname,
                                                              params);
        }
        ANGLE_CAPTURE(GetNamedFramebufferAttachmentParameteriv, isCallValid, context,
                      framebufferPacked, attachment, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetNamedFramebufferParameteriv(GLuint framebuffer, GLenum pname, GLint *param)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetNamedFramebufferParameteriv,
          "context = %d, framebuffer = %u, pname = %s, param = 0x%016" PRIxPTR "", CID(context),
          framebuffer, GLenumToString(GLenumGroup::GetFramebufferParameter, pname),
          (uintptr_t)param);

    if (context)
    {
        FramebufferID framebufferPacked = PackParam<FramebufferID>(framebuffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetNamedFramebufferParameteriv(context, framebufferPacked, pname, param));
        if (isCallValid)
        {
            context->getNamedFramebufferParameteriv(framebufferPacked, pname, param);
        }
        ANGLE_CAPTURE(GetNamedFramebufferParameteriv, isCallValid, context, framebufferPacked,
                      pname, param);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetNamedRenderbufferParameteriv(GLuint renderbuffer, GLenum pname, GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetNamedRenderbufferParameteriv,
          "context = %d, renderbuffer = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          renderbuffer, GLenumToString(GLenumGroup::RenderbufferParameterName, pname),
          (uintptr_t)params);

    if (context)
    {
        RenderbufferID renderbufferPacked = PackParam<RenderbufferID>(renderbuffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetNamedRenderbufferParameteriv(context, renderbufferPacked, pname, params));
        if (isCallValid)
        {
            context->getNamedRenderbufferParameteriv(renderbufferPacked, pname, params);
        }
        ANGLE_CAPTURE(GetNamedRenderbufferParameteriv, isCallValid, context, renderbufferPacked,
                      pname, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetQueryBufferObjecti64v(GLuint id, GLuint buffer, GLenum pname, GLintptr offset)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetQueryBufferObjecti64v,
          "context = %d, id = %u, buffer = %u, pname = %s, offset = %llu", CID(context), id, buffer,
          GLenumToString(GLenumGroup::QueryObjectParameterName, pname),
          static_cast<unsigned long long>(offset));

    if (context)
    {
        BufferID bufferPacked                                 = PackParam<BufferID>(buffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetQueryBufferObjecti64v(context, id, bufferPacked, pname, offset));
        if (isCallValid)
        {
            context->getQueryBufferObjecti64v(id, bufferPacked, pname, offset);
        }
        ANGLE_CAPTURE(GetQueryBufferObjecti64v, isCallValid, context, id, bufferPacked, pname,
                      offset);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetQueryBufferObjectiv(GLuint id, GLuint buffer, GLenum pname, GLintptr offset)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetQueryBufferObjectiv,
          "context = %d, id = %u, buffer = %u, pname = %s, offset = %llu", CID(context), id, buffer,
          GLenumToString(GLenumGroup::QueryObjectParameterName, pname),
          static_cast<unsigned long long>(offset));

    if (context)
    {
        BufferID bufferPacked                                 = PackParam<BufferID>(buffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetQueryBufferObjectiv(context, id, bufferPacked, pname, offset));
        if (isCallValid)
        {
            context->getQueryBufferObjectiv(id, bufferPacked, pname, offset);
        }
        ANGLE_CAPTURE(GetQueryBufferObjectiv, isCallValid, context, id, bufferPacked, pname,
                      offset);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetQueryBufferObjectui64v(GLuint id, GLuint buffer, GLenum pname, GLintptr offset)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetQueryBufferObjectui64v,
          "context = %d, id = %u, buffer = %u, pname = %s, offset = %llu", CID(context), id, buffer,
          GLenumToString(GLenumGroup::QueryObjectParameterName, pname),
          static_cast<unsigned long long>(offset));

    if (context)
    {
        BufferID bufferPacked                                 = PackParam<BufferID>(buffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetQueryBufferObjectui64v(context, id, bufferPacked, pname, offset));
        if (isCallValid)
        {
            context->getQueryBufferObjectui64v(id, bufferPacked, pname, offset);
        }
        ANGLE_CAPTURE(GetQueryBufferObjectui64v, isCallValid, context, id, bufferPacked, pname,
                      offset);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetQueryBufferObjectuiv(GLuint id, GLuint buffer, GLenum pname, GLintptr offset)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetQueryBufferObjectuiv,
          "context = %d, id = %u, buffer = %u, pname = %s, offset = %llu", CID(context), id, buffer,
          GLenumToString(GLenumGroup::QueryObjectParameterName, pname),
          static_cast<unsigned long long>(offset));

    if (context)
    {
        BufferID bufferPacked                                 = PackParam<BufferID>(buffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetQueryBufferObjectuiv(context, id, bufferPacked, pname, offset));
        if (isCallValid)
        {
            context->getQueryBufferObjectuiv(id, bufferPacked, pname, offset);
        }
        ANGLE_CAPTURE(GetQueryBufferObjectuiv, isCallValid, context, id, bufferPacked, pname,
                      offset);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetTextureImage(GLuint texture,
                                 GLint level,
                                 GLenum format,
                                 GLenum type,
                                 GLsizei bufSize,
                                 void *pixels)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetTextureImage,
          "context = %d, texture = %u, level = %d, format = %s, type = %s, bufSize = %d, pixels = "
          "0x%016" PRIxPTR "",
          CID(context), texture, level, GLenumToString(GLenumGroup::PixelFormat, format),
          GLenumToString(GLenumGroup::PixelType, type), bufSize, (uintptr_t)pixels);

    if (context)
    {
        TextureID texturePacked                               = PackParam<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetTextureImage(context, texturePacked, level, format, type, bufSize, pixels));
        if (isCallValid)
        {
            context->getTextureImage(texturePacked, level, format, type, bufSize, pixels);
        }
        ANGLE_CAPTURE(GetTextureImage, isCallValid, context, texturePacked, level, format, type,
                      bufSize, pixels);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetTextureLevelParameterfv(GLuint texture,
                                            GLint level,
                                            GLenum pname,
                                            GLfloat *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetTextureLevelParameterfv,
          "context = %d, texture = %u, level = %d, pname = %s, params = 0x%016" PRIxPTR "",
          CID(context), texture, level, GLenumToString(GLenumGroup::GetTextureParameter, pname),
          (uintptr_t)params);

    if (context)
    {
        TextureID texturePacked                               = PackParam<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetTextureLevelParameterfv(context, texturePacked, level, pname, params));
        if (isCallValid)
        {
            context->getTextureLevelParameterfv(texturePacked, level, pname, params);
        }
        ANGLE_CAPTURE(GetTextureLevelParameterfv, isCallValid, context, texturePacked, level, pname,
                      params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetTextureLevelParameteriv(GLuint texture,
                                            GLint level,
                                            GLenum pname,
                                            GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetTextureLevelParameteriv,
          "context = %d, texture = %u, level = %d, pname = %s, params = 0x%016" PRIxPTR "",
          CID(context), texture, level, GLenumToString(GLenumGroup::GetTextureParameter, pname),
          (uintptr_t)params);

    if (context)
    {
        TextureID texturePacked                               = PackParam<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetTextureLevelParameteriv(context, texturePacked, level, pname, params));
        if (isCallValid)
        {
            context->getTextureLevelParameteriv(texturePacked, level, pname, params);
        }
        ANGLE_CAPTURE(GetTextureLevelParameteriv, isCallValid, context, texturePacked, level, pname,
                      params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetTextureParameterIiv(GLuint texture, GLenum pname, GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetTextureParameterIiv,
          "context = %d, texture = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          texture, GLenumToString(GLenumGroup::GetTextureParameter, pname), (uintptr_t)params);

    if (context)
    {
        TextureID texturePacked                               = PackParam<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetTextureParameterIiv(context, texturePacked, pname, params));
        if (isCallValid)
        {
            context->getTextureParameterIiv(texturePacked, pname, params);
        }
        ANGLE_CAPTURE(GetTextureParameterIiv, isCallValid, context, texturePacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetTextureParameterIuiv(GLuint texture, GLenum pname, GLuint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetTextureParameterIuiv,
          "context = %d, texture = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          texture, GLenumToString(GLenumGroup::GetTextureParameter, pname), (uintptr_t)params);

    if (context)
    {
        TextureID texturePacked                               = PackParam<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetTextureParameterIuiv(context, texturePacked, pname, params));
        if (isCallValid)
        {
            context->getTextureParameterIuiv(texturePacked, pname, params);
        }
        ANGLE_CAPTURE(GetTextureParameterIuiv, isCallValid, context, texturePacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetTextureParameterfv(GLuint texture, GLenum pname, GLfloat *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetTextureParameterfv,
          "context = %d, texture = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          texture, GLenumToString(GLenumGroup::GetTextureParameter, pname), (uintptr_t)params);

    if (context)
    {
        TextureID texturePacked                               = PackParam<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetTextureParameterfv(context, texturePacked, pname, params));
        if (isCallValid)
        {
            context->getTextureParameterfv(texturePacked, pname, params);
        }
        ANGLE_CAPTURE(GetTextureParameterfv, isCallValid, context, texturePacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetTextureParameteriv(GLuint texture, GLenum pname, GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetTextureParameteriv,
          "context = %d, texture = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          texture, GLenumToString(GLenumGroup::GetTextureParameter, pname), (uintptr_t)params);

    if (context)
    {
        TextureID texturePacked                               = PackParam<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetTextureParameteriv(context, texturePacked, pname, params));
        if (isCallValid)
        {
            context->getTextureParameteriv(texturePacked, pname, params);
        }
        ANGLE_CAPTURE(GetTextureParameteriv, isCallValid, context, texturePacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetTextureSubImage(GLuint texture,
                                    GLint level,
                                    GLint xoffset,
                                    GLint yoffset,
                                    GLint zoffset,
                                    GLsizei width,
                                    GLsizei height,
                                    GLsizei depth,
                                    GLenum format,
                                    GLenum type,
                                    GLsizei bufSize,
                                    void *pixels)
{
    Context *context = GetValidGlobalContext();
    EVENT(
        context, GLGetTextureSubImage,
        "context = %d, texture = %u, 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), texture, level, xoffset, yoffset, zoffset, width, height, depth,
        GLenumToString(GLenumGroup::PixelFormat, format),
        GLenumToString(GLenumGroup::PixelType, type), bufSize, (uintptr_t)pixels);

    if (context)
    {
        TextureID texturePacked                               = PackParam<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetTextureSubImage(context, texturePacked, level, xoffset, yoffset, zoffset,
                                        width, height, depth, format, type, bufSize, pixels));
        if (isCallValid)
        {
            context->getTextureSubImage(texturePacked, level, xoffset, yoffset, zoffset, width,
                                        height, depth, format, type, bufSize, pixels);
        }
        ANGLE_CAPTURE(GetTextureSubImage, isCallValid, context, texturePacked, level, xoffset,
                      yoffset, zoffset, width, height, depth, format, type, bufSize, pixels);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetTransformFeedbacki64_v(GLuint xfb, GLenum pname, GLuint index, GLint64 *param)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetTransformFeedbacki64_v,
          "context = %d, xfb = %u, pname = %s, index = %u, param = 0x%016" PRIxPTR "", CID(context),
          xfb, GLenumToString(GLenumGroup::TransformFeedbackPName, pname), index, (uintptr_t)param);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetTransformFeedbacki64_v(context, xfb, pname, index, param));
        if (isCallValid)
        {
            context->getTransformFeedbacki64_v(xfb, pname, index, param);
        }
        ANGLE_CAPTURE(GetTransformFeedbacki64_v, isCallValid, context, xfb, pname, index, param);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetTransformFeedbacki_v(GLuint xfb, GLenum pname, GLuint index, GLint *param)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetTransformFeedbacki_v,
          "context = %d, xfb = %u, pname = %s, index = %u, param = 0x%016" PRIxPTR "", CID(context),
          xfb, GLenumToString(GLenumGroup::TransformFeedbackPName, pname), index, (uintptr_t)param);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetTransformFeedbacki_v(context, xfb, pname, index, param));
        if (isCallValid)
        {
            context->getTransformFeedbacki_v(xfb, pname, index, param);
        }
        ANGLE_CAPTURE(GetTransformFeedbacki_v, isCallValid, context, xfb, pname, index, param);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetTransformFeedbackiv(GLuint xfb, GLenum pname, GLint *param)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetTransformFeedbackiv,
          "context = %d, xfb = %u, pname = %s, param = 0x%016" PRIxPTR "", CID(context), xfb,
          GLenumToString(GLenumGroup::TransformFeedbackPName, pname), (uintptr_t)param);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetTransformFeedbackiv(context, xfb, pname, param));
        if (isCallValid)
        {
            context->getTransformFeedbackiv(xfb, pname, param);
        }
        ANGLE_CAPTURE(GetTransformFeedbackiv, isCallValid, context, xfb, pname, param);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetVertexArrayIndexed64iv(GLuint vaobj, GLuint index, GLenum pname, GLint64 *param)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetVertexArrayIndexed64iv,
          "context = %d, vaobj = %u, index = %u, pname = %s, param = 0x%016" PRIxPTR "",
          CID(context), vaobj, index, GLenumToString(GLenumGroup::VertexArrayPName, pname),
          (uintptr_t)param);

    if (context)
    {
        VertexArrayID vaobjPacked                             = PackParam<VertexArrayID>(vaobj);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetVertexArrayIndexed64iv(context, vaobjPacked, index, pname, param));
        if (isCallValid)
        {
            context->getVertexArrayIndexed64iv(vaobjPacked, index, pname, param);
        }
        ANGLE_CAPTURE(GetVertexArrayIndexed64iv, isCallValid, context, vaobjPacked, index, pname,
                      param);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetVertexArrayIndexediv(GLuint vaobj, GLuint index, GLenum pname, GLint *param)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetVertexArrayIndexediv,
          "context = %d, vaobj = %u, index = %u, pname = %s, param = 0x%016" PRIxPTR "",
          CID(context), vaobj, index, GLenumToString(GLenumGroup::VertexArrayPName, pname),
          (uintptr_t)param);

    if (context)
    {
        VertexArrayID vaobjPacked                             = PackParam<VertexArrayID>(vaobj);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetVertexArrayIndexediv(context, vaobjPacked, index, pname, param));
        if (isCallValid)
        {
            context->getVertexArrayIndexediv(vaobjPacked, index, pname, param);
        }
        ANGLE_CAPTURE(GetVertexArrayIndexediv, isCallValid, context, vaobjPacked, index, pname,
                      param);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetVertexArrayiv(GLuint vaobj, GLenum pname, GLint *param)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetVertexArrayiv,
          "context = %d, vaobj = %u, pname = %s, param = 0x%016" PRIxPTR "", CID(context), vaobj,
          GLenumToString(GLenumGroup::VertexArrayPName, pname), (uintptr_t)param);

    if (context)
    {
        VertexArrayID vaobjPacked                             = PackParam<VertexArrayID>(vaobj);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetVertexArrayiv(context, vaobjPacked, pname, param));
        if (isCallValid)
        {
            context->getVertexArrayiv(vaobjPacked, pname, param);
        }
        ANGLE_CAPTURE(GetVertexArrayiv, isCallValid, context, vaobjPacked, pname, param);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY
GetnColorTable(GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *table)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetnColorTable,
          "context = %d, target = %s, format = %s, type = %s, bufSize = %d, table = 0x%016" PRIxPTR
          "",
          CID(context), GLenumToString(GLenumGroup::ColorTableTarget, target),
          GLenumToString(GLenumGroup::PixelFormat, format),
          GLenumToString(GLenumGroup::PixelType, type), bufSize, (uintptr_t)table);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetnColorTable(context, target, format, type, bufSize, table));
        if (isCallValid)
        {
            context->getnColorTable(target, format, type, bufSize, table);
        }
        ANGLE_CAPTURE(GetnColorTable, isCallValid, context, target, format, type, bufSize, table);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetnCompressedTexImage(GLenum target, GLint lod, GLsizei bufSize, void *pixels)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetnCompressedTexImage,
          "context = %d, target = %s, lod = %d, bufSize = %d, pixels = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), lod, bufSize,
          (uintptr_t)pixels);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetnCompressedTexImage(context, target, lod, bufSize, pixels));
        if (isCallValid)
        {
            context->getnCompressedTexImage(target, lod, bufSize, pixels);
        }
        ANGLE_CAPTURE(GetnCompressedTexImage, isCallValid, context, target, lod, bufSize, pixels);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY
GetnConvolutionFilter(GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *image)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetnConvolutionFilter,
          "context = %d, target = %s, format = %s, type = %s, bufSize = %d, image = 0x%016" PRIxPTR
          "",
          CID(context), GLenumToString(GLenumGroup::ConvolutionTarget, target),
          GLenumToString(GLenumGroup::PixelFormat, format),
          GLenumToString(GLenumGroup::PixelType, type), bufSize, (uintptr_t)image);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetnConvolutionFilter(context, target, format, type, bufSize, image));
        if (isCallValid)
        {
            context->getnConvolutionFilter(target, format, type, bufSize, image);
        }
        ANGLE_CAPTURE(GetnConvolutionFilter, isCallValid, context, target, format, type, bufSize,
                      image);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetnHistogram(GLenum target,
                               GLboolean reset,
                               GLenum format,
                               GLenum type,
                               GLsizei bufSize,
                               void *values)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetnHistogram,
          "context = %d, target = %s, reset = %s, format = %s, type = %s, bufSize = %d, values = "
          "0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::HistogramTargetEXT, target),
          GLbooleanToString(reset), GLenumToString(GLenumGroup::PixelFormat, format),
          GLenumToString(GLenumGroup::PixelType, type), bufSize, (uintptr_t)values);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetnHistogram(context, target, reset, format, type, bufSize, values));
        if (isCallValid)
        {
            context->getnHistogram(target, reset, format, type, bufSize, values);
        }
        ANGLE_CAPTURE(GetnHistogram, isCallValid, context, target, reset, format, type, bufSize,
                      values);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetnMapdv(GLenum target, GLenum query, GLsizei bufSize, GLdouble *v)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetnMapdv,
          "context = %d, target = %s, query = %s, bufSize = %d, v = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::MapTarget, target),
          GLenumToString(GLenumGroup::MapQuery, query), bufSize, (uintptr_t)v);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetnMapdv(context, target, query, bufSize, v));
        if (isCallValid)
        {
            context->getnMapdv(target, query, bufSize, v);
        }
        ANGLE_CAPTURE(GetnMapdv, isCallValid, context, target, query, bufSize, v);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetnMapfv(GLenum target, GLenum query, GLsizei bufSize, GLfloat *v)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetnMapfv,
          "context = %d, target = %s, query = %s, bufSize = %d, v = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::MapTarget, target),
          GLenumToString(GLenumGroup::MapQuery, query), bufSize, (uintptr_t)v);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetnMapfv(context, target, query, bufSize, v));
        if (isCallValid)
        {
            context->getnMapfv(target, query, bufSize, v);
        }
        ANGLE_CAPTURE(GetnMapfv, isCallValid, context, target, query, bufSize, v);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetnMapiv(GLenum target, GLenum query, GLsizei bufSize, GLint *v)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetnMapiv,
          "context = %d, target = %s, query = %s, bufSize = %d, v = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::MapTarget, target),
          GLenumToString(GLenumGroup::MapQuery, query), bufSize, (uintptr_t)v);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetnMapiv(context, target, query, bufSize, v));
        if (isCallValid)
        {
            context->getnMapiv(target, query, bufSize, v);
        }
        ANGLE_CAPTURE(GetnMapiv, isCallValid, context, target, query, bufSize, v);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetnMinmax(GLenum target,
                            GLboolean reset,
                            GLenum format,
                            GLenum type,
                            GLsizei bufSize,
                            void *values)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetnMinmax,
          "context = %d, target = %s, reset = %s, format = %s, type = %s, bufSize = %d, values = "
          "0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::MinmaxTargetEXT, target),
          GLbooleanToString(reset), GLenumToString(GLenumGroup::PixelFormat, format),
          GLenumToString(GLenumGroup::PixelType, type), bufSize, (uintptr_t)values);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetnMinmax(context, target, reset, format, type, bufSize, values));
        if (isCallValid)
        {
            context->getnMinmax(target, reset, format, type, bufSize, values);
        }
        ANGLE_CAPTURE(GetnMinmax, isCallValid, context, target, reset, format, type, bufSize,
                      values);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetnPixelMapfv(GLenum map, GLsizei bufSize, GLfloat *values)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetnPixelMapfv,
          "context = %d, map = %s, bufSize = %d, values = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::PixelMap, map), bufSize, (uintptr_t)values);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetnPixelMapfv(context, map, bufSize, values));
        if (isCallValid)
        {
            context->getnPixelMapfv(map, bufSize, values);
        }
        ANGLE_CAPTURE(GetnPixelMapfv, isCallValid, context, map, bufSize, values);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetnPixelMapuiv(GLenum map, GLsizei bufSize, GLuint *values)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetnPixelMapuiv,
          "context = %d, map = %s, bufSize = %d, values = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::PixelMap, map), bufSize, (uintptr_t)values);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetnPixelMapuiv(context, map, bufSize, values));
        if (isCallValid)
        {
            context->getnPixelMapuiv(map, bufSize, values);
        }
        ANGLE_CAPTURE(GetnPixelMapuiv, isCallValid, context, map, bufSize, values);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetnPixelMapusv(GLenum map, GLsizei bufSize, GLushort *values)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetnPixelMapusv,
          "context = %d, map = %s, bufSize = %d, values = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::PixelMap, map), bufSize, (uintptr_t)values);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetnPixelMapusv(context, map, bufSize, values));
        if (isCallValid)
        {
            context->getnPixelMapusv(map, bufSize, values);
        }
        ANGLE_CAPTURE(GetnPixelMapusv, isCallValid, context, map, bufSize, values);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetnPolygonStipple(GLsizei bufSize, GLubyte *pattern)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetnPolygonStipple, "context = %d, bufSize = %d, pattern = 0x%016" PRIxPTR "",
          CID(context), bufSize, (uintptr_t)pattern);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGetnPolygonStipple(context, bufSize, pattern));
        if (isCallValid)
        {
            context->getnPolygonStipple(bufSize, pattern);
        }
        ANGLE_CAPTURE(GetnPolygonStipple, isCallValid, context, bufSize, pattern);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetnSeparableFilter(GLenum target,
                                     GLenum format,
                                     GLenum type,
                                     GLsizei rowBufSize,
                                     void *row,
                                     GLsizei columnBufSize,
                                     void *column,
                                     void *span)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetnSeparableFilter,
          "context = %d, target = %s, format = %s, type = %s, rowBufSize = %d, row = 0x%016" PRIxPTR
          ", columnBufSize = %d, column = 0x%016" PRIxPTR ", span = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::SeparableTargetEXT, target),
          GLenumToString(GLenumGroup::PixelFormat, format),
          GLenumToString(GLenumGroup::PixelType, type), rowBufSize, (uintptr_t)row, columnBufSize,
          (uintptr_t)column, (uintptr_t)span);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateGetnSeparableFilter(context, target, format, type, rowBufSize,
                                                        row, columnBufSize, column, span));
        if (isCallValid)
        {
            context->getnSeparableFilter(target, format, type, rowBufSize, row, columnBufSize,
                                         column, span);
        }
        ANGLE_CAPTURE(GetnSeparableFilter, isCallValid, context, target, format, type, rowBufSize,
                      row, columnBufSize, column, span);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY
GetnTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *pixels)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetnTexImage,
          "context = %d, target = %s, level = %d, format = %s, type = %s, bufSize = %d, pixels = "
          "0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), level,
          GLenumToString(GLenumGroup::PixelFormat, format),
          GLenumToString(GLenumGroup::PixelType, type), bufSize, (uintptr_t)pixels);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetnTexImage(context, target, level, format, type, bufSize, pixels));
        if (isCallValid)
        {
            context->getnTexImage(target, level, format, type, bufSize, pixels);
        }
        ANGLE_CAPTURE(GetnTexImage, isCallValid, context, target, level, format, type, bufSize,
                      pixels);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY GetnUniformdv(GLuint program, GLint location, GLsizei bufSize, GLdouble *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetnUniformdv,
          "context = %d, program = %u, location = %d, bufSize = %d, params = 0x%016" PRIxPTR "",
          CID(context), program, location, bufSize, (uintptr_t)params);

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

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

    if (context)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

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

    if (context)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

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

    if (context)
    {
        ShaderProgramID programPacked  = PackParam<ShaderProgramID>(program);
        UniformLocation locationPacked = PackParam<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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY InvalidateNamedFramebufferData(GLuint framebuffer,
                                                GLsizei numAttachments,
                                                const GLenum *attachments)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLInvalidateNamedFramebufferData,
          "context = %d, framebuffer = %u, numAttachments = %d, attachments = 0x%016" PRIxPTR "",
          CID(context), framebuffer, numAttachments, (uintptr_t)attachments);

    if (context)
    {
        FramebufferID framebufferPacked = PackParam<FramebufferID>(framebuffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateInvalidateNamedFramebufferData(context, framebufferPacked,
                                                                   numAttachments, attachments));
        if (isCallValid)
        {
            context->invalidateNamedFramebufferData(framebufferPacked, numAttachments, attachments);
        }
        ANGLE_CAPTURE(InvalidateNamedFramebufferData, isCallValid, context, framebufferPacked,
                      numAttachments, attachments);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY InvalidateNamedFramebufferSubData(GLuint framebuffer,
                                                   GLsizei numAttachments,
                                                   const GLenum *attachments,
                                                   GLint x,
                                                   GLint y,
                                                   GLsizei width,
                                                   GLsizei height)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLInvalidateNamedFramebufferSubData,
          "context = %d, framebuffer = %u, numAttachments = %d, attachments = 0x%016" PRIxPTR
          ", x = %d, y = %d, width = %d, height = %d",
          CID(context), framebuffer, numAttachments, (uintptr_t)attachments, x, y, width, height);

    if (context)
    {
        FramebufferID framebufferPacked = PackParam<FramebufferID>(framebuffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateInvalidateNamedFramebufferSubData(context, framebufferPacked, numAttachments,
                                                       attachments, x, y, width, height));
        if (isCallValid)
        {
            context->invalidateNamedFramebufferSubData(framebufferPacked, numAttachments,
                                                       attachments, x, y, width, height);
        }
        ANGLE_CAPTURE(InvalidateNamedFramebufferSubData, isCallValid, context, framebufferPacked,
                      numAttachments, attachments, x, y, width, height);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void *GL_APIENTRY MapNamedBuffer(GLuint buffer, GLenum access)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLMapNamedBuffer, "context = %d, buffer = %u, access = %s", CID(context), buffer,
          GLenumToString(GLenumGroup::BufferAccessARB, access));

    void *returnValue;
    if (context)
    {
        BufferID bufferPacked                                 = PackParam<BufferID>(buffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateMapNamedBuffer(context, bufferPacked, access));
        if (isCallValid)
        {
            returnValue = context->mapNamedBuffer(bufferPacked, access);
        }
        else
        {
            returnValue = GetDefaultReturnValue<angle::EntryPoint::GLMapNamedBuffer, void *>();
        }
        ANGLE_CAPTURE(MapNamedBuffer, isCallValid, context, bufferPacked, access, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
        returnValue = GetDefaultReturnValue<angle::EntryPoint::GLMapNamedBuffer, void *>();
    }
    return returnValue;
}

void *GL_APIENTRY MapNamedBufferRange(GLuint buffer,
                                      GLintptr offset,
                                      GLsizeiptr length,
                                      GLbitfield access)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLMapNamedBufferRange,
          "context = %d, buffer = %u, offset = %llu, length = %llu, access = %s", CID(context),
          buffer, static_cast<unsigned long long>(offset), static_cast<unsigned long long>(length),
          GLbitfieldToString(GLenumGroup::BufferAccessMask, access).c_str());

    void *returnValue;
    if (context)
    {
        BufferID bufferPacked                                 = PackParam<BufferID>(buffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateMapNamedBufferRange(context, bufferPacked, offset, length, access));
        if (isCallValid)
        {
            returnValue = context->mapNamedBufferRange(bufferPacked, offset, length, access);
        }
        else
        {
            returnValue = GetDefaultReturnValue<angle::EntryPoint::GLMapNamedBufferRange, void *>();
        }
        ANGLE_CAPTURE(MapNamedBufferRange, isCallValid, context, bufferPacked, offset, length,
                      access, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
        returnValue = GetDefaultReturnValue<angle::EntryPoint::GLMapNamedBufferRange, void *>();
    }
    return returnValue;
}

void GL_APIENTRY MemoryBarrierByRegion(GLbitfield barriers)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLMemoryBarrierByRegion, "context = %d, barriers = %s", CID(context),
          GLbitfieldToString(GLenumGroup::MemoryBarrierMask, barriers).c_str());

    if (context)
    {
        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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY NamedBufferData(GLuint buffer, GLsizeiptr size, const void *data, GLenum usage)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLNamedBufferData,
          "context = %d, buffer = %u, size = %llu, data = 0x%016" PRIxPTR ", usage = %s",
          CID(context), buffer, static_cast<unsigned long long>(size), (uintptr_t)data,
          GLenumToString(GLenumGroup::VertexBufferObjectUsage, usage));

    if (context)
    {
        BufferID bufferPacked                                 = PackParam<BufferID>(buffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateNamedBufferData(context, bufferPacked, size, data, usage));
        if (isCallValid)
        {
            context->namedBufferData(bufferPacked, size, data, usage);
        }
        ANGLE_CAPTURE(NamedBufferData, isCallValid, context, bufferPacked, size, data, usage);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY NamedBufferStorage(GLuint buffer,
                                    GLsizeiptr size,
                                    const void *data,
                                    GLbitfield flags)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLNamedBufferStorage,
          "context = %d, buffer = %u, size = %llu, data = 0x%016" PRIxPTR ", flags = %s",
          CID(context), buffer, static_cast<unsigned long long>(size), (uintptr_t)data,
          GLbitfieldToString(GLenumGroup::MapBufferUsageMask, flags).c_str());

    if (context)
    {
        BufferID bufferPacked                                 = PackParam<BufferID>(buffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateNamedBufferStorage(context, bufferPacked, size, data, flags));
        if (isCallValid)
        {
            context->namedBufferStorage(bufferPacked, size, data, flags);
        }
        ANGLE_CAPTURE(NamedBufferStorage, isCallValid, context, bufferPacked, size, data, flags);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY NamedBufferSubData(GLuint buffer,
                                    GLintptr offset,
                                    GLsizeiptr size,
                                    const void *data)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLNamedBufferSubData,
          "context = %d, buffer = %u, offset = %llu, size = %llu, data = 0x%016" PRIxPTR "",
          CID(context), buffer, static_cast<unsigned long long>(offset),
          static_cast<unsigned long long>(size), (uintptr_t)data);

    if (context)
    {
        BufferID bufferPacked                                 = PackParam<BufferID>(buffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateNamedBufferSubData(context, bufferPacked, offset, size, data));
        if (isCallValid)
        {
            context->namedBufferSubData(bufferPacked, offset, size, data);
        }
        ANGLE_CAPTURE(NamedBufferSubData, isCallValid, context, bufferPacked, offset, size, data);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY NamedFramebufferDrawBuffer(GLuint framebuffer, GLenum buf)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLNamedFramebufferDrawBuffer, "context = %d, framebuffer = %u, buf = %s",
          CID(context), framebuffer, GLenumToString(GLenumGroup::ColorBuffer, buf));

    if (context)
    {
        FramebufferID framebufferPacked = PackParam<FramebufferID>(framebuffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateNamedFramebufferDrawBuffer(context, framebufferPacked, buf));
        if (isCallValid)
        {
            context->namedFramebufferDrawBuffer(framebufferPacked, buf);
        }
        ANGLE_CAPTURE(NamedFramebufferDrawBuffer, isCallValid, context, framebufferPacked, buf);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY NamedFramebufferDrawBuffers(GLuint framebuffer, GLsizei n, const GLenum *bufs)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLNamedFramebufferDrawBuffers,
          "context = %d, framebuffer = %u, n = %d, bufs = 0x%016" PRIxPTR "", CID(context),
          framebuffer, n, (uintptr_t)bufs);

    if (context)
    {
        FramebufferID framebufferPacked = PackParam<FramebufferID>(framebuffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateNamedFramebufferDrawBuffers(
                                                             context, framebufferPacked, n, bufs));
        if (isCallValid)
        {
            context->namedFramebufferDrawBuffers(framebufferPacked, n, bufs);
        }
        ANGLE_CAPTURE(NamedFramebufferDrawBuffers, isCallValid, context, framebufferPacked, n,
                      bufs);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY NamedFramebufferParameteri(GLuint framebuffer, GLenum pname, GLint param)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLNamedFramebufferParameteri,
          "context = %d, framebuffer = %u, pname = %s, param = %d", CID(context), framebuffer,
          GLenumToString(GLenumGroup::FramebufferParameterName, pname), param);

    if (context)
    {
        FramebufferID framebufferPacked = PackParam<FramebufferID>(framebuffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateNamedFramebufferParameteri(context, framebufferPacked, pname, param));
        if (isCallValid)
        {
            context->namedFramebufferParameteri(framebufferPacked, pname, param);
        }
        ANGLE_CAPTURE(NamedFramebufferParameteri, isCallValid, context, framebufferPacked, pname,
                      param);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY NamedFramebufferReadBuffer(GLuint framebuffer, GLenum src)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLNamedFramebufferReadBuffer, "context = %d, framebuffer = %u, src = %s",
          CID(context), framebuffer, GLenumToString(GLenumGroup::ColorBuffer, src));

    if (context)
    {
        FramebufferID framebufferPacked = PackParam<FramebufferID>(framebuffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateNamedFramebufferReadBuffer(context, framebufferPacked, src));
        if (isCallValid)
        {
            context->namedFramebufferReadBuffer(framebufferPacked, src);
        }
        ANGLE_CAPTURE(NamedFramebufferReadBuffer, isCallValid, context, framebufferPacked, src);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY NamedFramebufferRenderbuffer(GLuint framebuffer,
                                              GLenum attachment,
                                              GLenum renderbuffertarget,
                                              GLuint renderbuffer)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLNamedFramebufferRenderbuffer,
          "context = %d, framebuffer = %u, attachment = %s, renderbuffertarget = %s, renderbuffer "
          "= %u",
          CID(context), framebuffer, GLenumToString(GLenumGroup::FramebufferAttachment, attachment),
          GLenumToString(GLenumGroup::RenderbufferTarget, renderbuffertarget), renderbuffer);

    if (context)
    {
        FramebufferID framebufferPacked   = PackParam<FramebufferID>(framebuffer);
        RenderbufferID renderbufferPacked = PackParam<RenderbufferID>(renderbuffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateNamedFramebufferRenderbuffer(context, framebufferPacked, attachment,
                                                  renderbuffertarget, renderbufferPacked));
        if (isCallValid)
        {
            context->namedFramebufferRenderbuffer(framebufferPacked, attachment, renderbuffertarget,
                                                  renderbufferPacked);
        }
        ANGLE_CAPTURE(NamedFramebufferRenderbuffer, isCallValid, context, framebufferPacked,
                      attachment, renderbuffertarget, renderbufferPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY NamedFramebufferTexture(GLuint framebuffer,
                                         GLenum attachment,
                                         GLuint texture,
                                         GLint level)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLNamedFramebufferTexture,
          "context = %d, framebuffer = %u, attachment = %s, texture = %u, level = %d", CID(context),
          framebuffer, GLenumToString(GLenumGroup::FramebufferAttachment, attachment), texture,
          level);

    if (context)
    {
        FramebufferID framebufferPacked = PackParam<FramebufferID>(framebuffer);
        TextureID texturePacked         = PackParam<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateNamedFramebufferTexture(context, framebufferPacked, attachment,
                                                            texturePacked, level));
        if (isCallValid)
        {
            context->namedFramebufferTexture(framebufferPacked, attachment, texturePacked, level);
        }
        ANGLE_CAPTURE(NamedFramebufferTexture, isCallValid, context, framebufferPacked, attachment,
                      texturePacked, level);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY NamedFramebufferTextureLayer(GLuint framebuffer,
                                              GLenum attachment,
                                              GLuint texture,
                                              GLint level,
                                              GLint layer)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLNamedFramebufferTextureLayer,
          "context = %d, framebuffer = %u, attachment = %s, texture = %u, level = %d, layer = %d",
          CID(context), framebuffer, GLenumToString(GLenumGroup::FramebufferAttachment, attachment),
          texture, level, layer);

    if (context)
    {
        FramebufferID framebufferPacked = PackParam<FramebufferID>(framebuffer);
        TextureID texturePacked         = PackParam<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateNamedFramebufferTextureLayer(
                                                             context, framebufferPacked, attachment,
                                                             texturePacked, level, layer));
        if (isCallValid)
        {
            context->namedFramebufferTextureLayer(framebufferPacked, attachment, texturePacked,
                                                  level, layer);
        }
        ANGLE_CAPTURE(NamedFramebufferTextureLayer, isCallValid, context, framebufferPacked,
                      attachment, texturePacked, level, layer);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY NamedRenderbufferStorage(GLuint renderbuffer,
                                          GLenum internalformat,
                                          GLsizei width,
                                          GLsizei height)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLNamedRenderbufferStorage,
          "context = %d, renderbuffer = %u, internalformat = %s, width = %d, height = %d",
          CID(context), renderbuffer, GLenumToString(GLenumGroup::InternalFormat, internalformat),
          width, height);

    if (context)
    {
        RenderbufferID renderbufferPacked = PackParam<RenderbufferID>(renderbuffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateNamedRenderbufferStorage(context, renderbufferPacked,
                                                             internalformat, width, height));
        if (isCallValid)
        {
            context->namedRenderbufferStorage(renderbufferPacked, internalformat, width, height);
        }
        ANGLE_CAPTURE(NamedRenderbufferStorage, isCallValid, context, renderbufferPacked,
                      internalformat, width, height);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY NamedRenderbufferStorageMultisample(GLuint renderbuffer,
                                                     GLsizei samples,
                                                     GLenum internalformat,
                                                     GLsizei width,
                                                     GLsizei height)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLNamedRenderbufferStorageMultisample,
          "context = %d, renderbuffer = %u, samples = %d, internalformat = %s, width = %d, height "
          "= %d",
          CID(context), renderbuffer, samples,
          GLenumToString(GLenumGroup::InternalFormat, internalformat), width, height);

    if (context)
    {
        RenderbufferID renderbufferPacked = PackParam<RenderbufferID>(renderbuffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateNamedRenderbufferStorageMultisample(context, renderbufferPacked, samples,
                                                         internalformat, width, height));
        if (isCallValid)
        {
            context->namedRenderbufferStorageMultisample(renderbufferPacked, samples,
                                                         internalformat, width, height);
        }
        ANGLE_CAPTURE(NamedRenderbufferStorageMultisample, isCallValid, context, renderbufferPacked,
                      samples, internalformat, width, height);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY ReadnPixels(GLint x,
                             GLint y,
                             GLsizei width,
                             GLsizei height,
                             GLenum format,
                             GLenum type,
                             GLsizei bufSize,
                             void *data)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, 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)
    {
        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
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TextureBarrier()
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLTextureBarrier, "context = %d", CID(context));

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

void GL_APIENTRY TextureBuffer(GLuint texture, GLenum internalformat, GLuint buffer)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLTextureBuffer, "context = %d, texture = %u, internalformat = %s, buffer = %u",
          CID(context), texture, GLenumToString(GLenumGroup::InternalFormat, internalformat),
          buffer);

    if (context)
    {
        TextureID texturePacked                               = PackParam<TextureID>(texture);
        BufferID bufferPacked                                 = PackParam<BufferID>(buffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTextureBuffer(context, texturePacked, internalformat, bufferPacked));
        if (isCallValid)
        {
            context->textureBuffer(texturePacked, internalformat, bufferPacked);
        }
        ANGLE_CAPTURE(TextureBuffer, isCallValid, context, texturePacked, internalformat,
                      bufferPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

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

    if (context)
    {
        TextureID texturePacked                               = PackParam<TextureID>(texture);
        BufferID bufferPacked                                 = PackParam<BufferID>(buffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateTextureBufferRange(context, texturePacked, internalformat,
                                                       bufferPacked, offset, size));
        if (isCallValid)
        {
            context->textureBufferRange(texturePacked, internalformat, bufferPacked, offset, size);
        }
        ANGLE_CAPTURE(TextureBufferRange, isCallValid, context, texturePacked, internalformat,
                      bufferPacked, offset, size);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TextureParameterIiv(GLuint texture, GLenum pname, const GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLTextureParameterIiv,
          "context = %d, texture = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          texture, GLenumToString(GLenumGroup::TextureParameterName, pname), (uintptr_t)params);

    if (context)
    {
        TextureID texturePacked                               = PackParam<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateTextureParameterIiv(context, texturePacked, pname, params));
        if (isCallValid)
        {
            context->textureParameterIiv(texturePacked, pname, params);
        }
        ANGLE_CAPTURE(TextureParameterIiv, isCallValid, context, texturePacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TextureParameterIuiv(GLuint texture, GLenum pname, const GLuint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLTextureParameterIuiv,
          "context = %d, texture = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          texture, GLenumToString(GLenumGroup::TextureParameterName, pname), (uintptr_t)params);

    if (context)
    {
        TextureID texturePacked                               = PackParam<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateTextureParameterIuiv(context, texturePacked, pname, params));
        if (isCallValid)
        {
            context->textureParameterIuiv(texturePacked, pname, params);
        }
        ANGLE_CAPTURE(TextureParameterIuiv, isCallValid, context, texturePacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TextureParameterf(GLuint texture, GLenum pname, GLfloat param)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLTextureParameterf, "context = %d, texture = %u, pname = %s, param = %f",
          CID(context), texture, GLenumToString(GLenumGroup::TextureParameterName, pname), param);

    if (context)
    {
        TextureID texturePacked                               = PackParam<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateTextureParameterf(context, texturePacked, pname, param));
        if (isCallValid)
        {
            context->textureParameterf(texturePacked, pname, param);
        }
        ANGLE_CAPTURE(TextureParameterf, isCallValid, context, texturePacked, pname, param);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TextureParameterfv(GLuint texture, GLenum pname, const GLfloat *param)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLTextureParameterfv,
          "context = %d, texture = %u, pname = %s, param = 0x%016" PRIxPTR "", CID(context),
          texture, GLenumToString(GLenumGroup::TextureParameterName, pname), (uintptr_t)param);

    if (context)
    {
        TextureID texturePacked                               = PackParam<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateTextureParameterfv(context, texturePacked, pname, param));
        if (isCallValid)
        {
            context->textureParameterfv(texturePacked, pname, param);
        }
        ANGLE_CAPTURE(TextureParameterfv, isCallValid, context, texturePacked, pname, param);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TextureParameteri(GLuint texture, GLenum pname, GLint param)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLTextureParameteri, "context = %d, texture = %u, pname = %s, param = %d",
          CID(context), texture, GLenumToString(GLenumGroup::TextureParameterName, pname), param);

    if (context)
    {
        TextureID texturePacked                               = PackParam<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateTextureParameteri(context, texturePacked, pname, param));
        if (isCallValid)
        {
            context->textureParameteri(texturePacked, pname, param);
        }
        ANGLE_CAPTURE(TextureParameteri, isCallValid, context, texturePacked, pname, param);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TextureParameteriv(GLuint texture, GLenum pname, const GLint *param)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLTextureParameteriv,
          "context = %d, texture = %u, pname = %s, param = 0x%016" PRIxPTR "", CID(context),
          texture, GLenumToString(GLenumGroup::TextureParameterName, pname), (uintptr_t)param);

    if (context)
    {
        TextureID texturePacked                               = PackParam<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateTextureParameteriv(context, texturePacked, pname, param));
        if (isCallValid)
        {
            context->textureParameteriv(texturePacked, pname, param);
        }
        ANGLE_CAPTURE(TextureParameteriv, isCallValid, context, texturePacked, pname, param);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TextureStorage1D(GLuint texture,
                                  GLsizei levels,
                                  GLenum internalformat,
                                  GLsizei width)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLTextureStorage1D,
          "context = %d, texture = %u, levels = %d, internalformat = %s, width = %d", CID(context),
          texture, levels, GLenumToString(GLenumGroup::InternalFormat, internalformat), width);

    if (context)
    {
        TextureID texturePacked                               = PackParam<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTextureStorage1D(context, texturePacked, levels, internalformat, width));
        if (isCallValid)
        {
            context->textureStorage1D(texturePacked, levels, internalformat, width);
        }
        ANGLE_CAPTURE(TextureStorage1D, isCallValid, context, texturePacked, levels, internalformat,
                      width);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TextureStorage2D(GLuint texture,
                                  GLsizei levels,
                                  GLenum internalformat,
                                  GLsizei width,
                                  GLsizei height)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLTextureStorage2D,
          "context = %d, texture = %u, levels = %d, internalformat = %s, width = %d, height = %d",
          CID(context), texture, levels,
          GLenumToString(GLenumGroup::InternalFormat, internalformat), width, height);

    if (context)
    {
        TextureID texturePacked                               = PackParam<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateTextureStorage2D(context, texturePacked, levels,
                                                                   internalformat, width, height));
        if (isCallValid)
        {
            context->textureStorage2D(texturePacked, levels, internalformat, width, height);
        }
        ANGLE_CAPTURE(TextureStorage2D, isCallValid, context, texturePacked, levels, internalformat,
                      width, height);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TextureStorage2DMultisample(GLuint texture,
                                             GLsizei samples,
                                             GLenum internalformat,
                                             GLsizei width,
                                             GLsizei height,
                                             GLboolean fixedsamplelocations)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLTextureStorage2DMultisample,
          "context = %d, texture = %u, samples = %d, internalformat = %s, width = %d, height = %d, "
          "fixedsamplelocations = %s",
          CID(context), texture, samples,
          GLenumToString(GLenumGroup::InternalFormat, internalformat), width, height,
          GLbooleanToString(fixedsamplelocations));

    if (context)
    {
        TextureID texturePacked                               = PackParam<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTextureStorage2DMultisample(context, texturePacked, samples, internalformat,
                                                 width, height, fixedsamplelocations));
        if (isCallValid)
        {
            context->textureStorage2DMultisample(texturePacked, samples, internalformat, width,
                                                 height, fixedsamplelocations);
        }
        ANGLE_CAPTURE(TextureStorage2DMultisample, isCallValid, context, texturePacked, samples,
                      internalformat, width, height, fixedsamplelocations);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TextureStorage3D(GLuint texture,
                                  GLsizei levels,
                                  GLenum internalformat,
                                  GLsizei width,
                                  GLsizei height,
                                  GLsizei depth)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLTextureStorage3D,
          "context = %d, texture = %u, levels = %d, internalformat = %s, width = %d, height = %d, "
          "depth = %d",
          CID(context), texture, levels,
          GLenumToString(GLenumGroup::InternalFormat, internalformat), width, height, depth);

    if (context)
    {
        TextureID texturePacked                               = PackParam<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateTextureStorage3D(context, texturePacked, levels, internalformat,
                                                     width, height, depth));
        if (isCallValid)
        {
            context->textureStorage3D(texturePacked, levels, internalformat, width, height, depth);
        }
        ANGLE_CAPTURE(TextureStorage3D, isCallValid, context, texturePacked, levels, internalformat,
                      width, height, depth);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TextureStorage3DMultisample(GLuint texture,
                                             GLsizei samples,
                                             GLenum internalformat,
                                             GLsizei width,
                                             GLsizei height,
                                             GLsizei depth,
                                             GLboolean fixedsamplelocations)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLTextureStorage3DMultisample,
          "context = %d, texture = %u, samples = %d, internalformat = %s, width = %d, height = %d, "
          "depth = %d, fixedsamplelocations = %s",
          CID(context), texture, samples,
          GLenumToString(GLenumGroup::InternalFormat, internalformat), width, height, depth,
          GLbooleanToString(fixedsamplelocations));

    if (context)
    {
        TextureID texturePacked                               = PackParam<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTextureStorage3DMultisample(context, texturePacked, samples, internalformat,
                                                 width, height, depth, fixedsamplelocations));
        if (isCallValid)
        {
            context->textureStorage3DMultisample(texturePacked, samples, internalformat, width,
                                                 height, depth, fixedsamplelocations);
        }
        ANGLE_CAPTURE(TextureStorage3DMultisample, isCallValid, context, texturePacked, samples,
                      internalformat, width, height, depth, fixedsamplelocations);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TextureSubImage1D(GLuint texture,
                                   GLint level,
                                   GLint xoffset,
                                   GLsizei width,
                                   GLenum format,
                                   GLenum type,
                                   const void *pixels)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLTextureSubImage1D,
          "context = %d, texture = %u, level = %d, xoffset = %d, width = %d, format = %s, type = "
          "%s, pixels = 0x%016" PRIxPTR "",
          CID(context), texture, level, xoffset, width,
          GLenumToString(GLenumGroup::PixelFormat, format),
          GLenumToString(GLenumGroup::PixelType, type), (uintptr_t)pixels);

    if (context)
    {
        TextureID texturePacked                               = PackParam<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateTextureSubImage1D(context, texturePacked, level, xoffset, width,
                                                      format, type, pixels));
        if (isCallValid)
        {
            context->textureSubImage1D(texturePacked, level, xoffset, width, format, type, pixels);
        }
        ANGLE_CAPTURE(TextureSubImage1D, isCallValid, context, texturePacked, level, xoffset, width,
                      format, type, pixels);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TextureSubImage2D(GLuint texture,
                                   GLint level,
                                   GLint xoffset,
                                   GLint yoffset,
                                   GLsizei width,
                                   GLsizei height,
                                   GLenum format,
                                   GLenum type,
                                   const void *pixels)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLTextureSubImage2D,
          "context = %d, texture = %u, level = %d, xoffset = %d, yoffset = %d, width = %d, height "
          "= %d, format = %s, type = %s, pixels = 0x%016" PRIxPTR "",
          CID(context), texture, level, xoffset, yoffset, width, height,
          GLenumToString(GLenumGroup::PixelFormat, format),
          GLenumToString(GLenumGroup::PixelType, type), (uintptr_t)pixels);

    if (context)
    {
        TextureID texturePacked                               = PackParam<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTextureSubImage2D(context, texturePacked, level, xoffset, yoffset, width,
                                       height, format, type, pixels));
        if (isCallValid)
        {
            context->textureSubImage2D(texturePacked, level, xoffset, yoffset, width, height,
                                       format, type, pixels);
        }
        ANGLE_CAPTURE(TextureSubImage2D, isCallValid, context, texturePacked, level, xoffset,
                      yoffset, width, height, format, type, pixels);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TextureSubImage3D(GLuint texture,
                                   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, GLTextureSubImage3D,
          "context = %d, texture = %u, level = %d, xoffset = %d, yoffset = %d, zoffset = %d, width "
          "= %d, height = %d, depth = %d, format = %s, type = %s, pixels = 0x%016" PRIxPTR "",
          CID(context), texture, level, xoffset, yoffset, zoffset, width, height, depth,
          GLenumToString(GLenumGroup::PixelFormat, format),
          GLenumToString(GLenumGroup::PixelType, type), (uintptr_t)pixels);

    if (context)
    {
        TextureID texturePacked                               = PackParam<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTextureSubImage3D(context, texturePacked, level, xoffset, yoffset, zoffset,
                                       width, height, depth, format, type, pixels));
        if (isCallValid)
        {
            context->textureSubImage3D(texturePacked, level, xoffset, yoffset, zoffset, width,
                                       height, depth, format, type, pixels);
        }
        ANGLE_CAPTURE(TextureSubImage3D, isCallValid, context, texturePacked, level, xoffset,
                      yoffset, zoffset, width, height, depth, format, type, pixels);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TransformFeedbackBufferBase(GLuint xfb, GLuint index, GLuint buffer)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLTransformFeedbackBufferBase, "context = %d, xfb = %u, index = %u, buffer = %u",
          CID(context), xfb, index, buffer);

    if (context)
    {
        BufferID bufferPacked                                 = PackParam<BufferID>(buffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateTransformFeedbackBufferBase(context, xfb, index, bufferPacked));
        if (isCallValid)
        {
            context->transformFeedbackBufferBase(xfb, index, bufferPacked);
        }
        ANGLE_CAPTURE(TransformFeedbackBufferBase, isCallValid, context, xfb, index, bufferPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY TransformFeedbackBufferRange(GLuint xfb,
                                              GLuint index,
                                              GLuint buffer,
                                              GLintptr offset,
                                              GLsizeiptr size)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLTransformFeedbackBufferRange,
          "context = %d, xfb = %u, index = %u, buffer = %u, offset = %llu, size = %llu",
          CID(context), xfb, index, buffer, static_cast<unsigned long long>(offset),
          static_cast<unsigned long long>(size));

    if (context)
    {
        BufferID bufferPacked                                 = PackParam<BufferID>(buffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTransformFeedbackBufferRange(context, xfb, index, bufferPacked, offset, size));
        if (isCallValid)
        {
            context->transformFeedbackBufferRange(xfb, index, bufferPacked, offset, size);
        }
        ANGLE_CAPTURE(TransformFeedbackBufferRange, isCallValid, context, xfb, index, bufferPacked,
                      offset, size);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

GLboolean GL_APIENTRY UnmapNamedBuffer(GLuint buffer)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLUnmapNamedBuffer, "context = %d, buffer = %u", CID(context), buffer);

    GLboolean returnValue;
    if (context)
    {
        BufferID bufferPacked                                 = PackParam<BufferID>(buffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateUnmapNamedBuffer(context, bufferPacked));
        if (isCallValid)
        {
            returnValue = context->unmapNamedBuffer(bufferPacked);
        }
        else
        {
            returnValue = GetDefaultReturnValue<angle::EntryPoint::GLUnmapNamedBuffer, GLboolean>();
        }
        ANGLE_CAPTURE(UnmapNamedBuffer, isCallValid, context, bufferPacked, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
        returnValue = GetDefaultReturnValue<angle::EntryPoint::GLUnmapNamedBuffer, GLboolean>();
    }
    return returnValue;
}

void GL_APIENTRY VertexArrayAttribBinding(GLuint vaobj, GLuint attribindex, GLuint bindingindex)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLVertexArrayAttribBinding,
          "context = %d, vaobj = %u, attribindex = %u, bindingindex = %u", CID(context), vaobj,
          attribindex, bindingindex);

    if (context)
    {
        VertexArrayID vaobjPacked                             = PackParam<VertexArrayID>(vaobj);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateVertexArrayAttribBinding(context, vaobjPacked, attribindex, bindingindex));
        if (isCallValid)
        {
            context->vertexArrayAttribBinding(vaobjPacked, attribindex, bindingindex);
        }
        ANGLE_CAPTURE(VertexArrayAttribBinding, isCallValid, context, vaobjPacked, attribindex,
                      bindingindex);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY VertexArrayAttribFormat(GLuint vaobj,
                                         GLuint attribindex,
                                         GLint size,
                                         GLenum type,
                                         GLboolean normalized,
                                         GLuint relativeoffset)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLVertexArrayAttribFormat,
          "context = %d, vaobj = %u, attribindex = %u, size = %d, type = %s, normalized = %s, "
          "relativeoffset = %u",
          CID(context), vaobj, attribindex, size,
          GLenumToString(GLenumGroup::VertexAttribType, type), GLbooleanToString(normalized),
          relativeoffset);

    if (context)
    {
        VertexArrayID vaobjPacked                             = PackParam<VertexArrayID>(vaobj);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateVertexArrayAttribFormat(context, vaobjPacked, attribindex, size,
                                                            type, normalized, relativeoffset));
        if (isCallValid)
        {
            context->vertexArrayAttribFormat(vaobjPacked, attribindex, size, type, normalized,
                                             relativeoffset);
        }
        ANGLE_CAPTURE(VertexArrayAttribFormat, isCallValid, context, vaobjPacked, attribindex, size,
                      type, normalized, relativeoffset);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY VertexArrayAttribIFormat(GLuint vaobj,
                                          GLuint attribindex,
                                          GLint size,
                                          GLenum type,
                                          GLuint relativeoffset)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLVertexArrayAttribIFormat,
          "context = %d, vaobj = %u, attribindex = %u, size = %d, type = %s, relativeoffset = %u",
          CID(context), vaobj, attribindex, size,
          GLenumToString(GLenumGroup::VertexAttribType, type), relativeoffset);

    if (context)
    {
        VertexArrayID vaobjPacked                             = PackParam<VertexArrayID>(vaobj);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateVertexArrayAttribIFormat(context, vaobjPacked, attribindex,
                                                             size, type, relativeoffset));
        if (isCallValid)
        {
            context->vertexArrayAttribIFormat(vaobjPacked, attribindex, size, type, relativeoffset);
        }
        ANGLE_CAPTURE(VertexArrayAttribIFormat, isCallValid, context, vaobjPacked, attribindex,
                      size, type, relativeoffset);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY VertexArrayAttribLFormat(GLuint vaobj,
                                          GLuint attribindex,
                                          GLint size,
                                          GLenum type,
                                          GLuint relativeoffset)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLVertexArrayAttribLFormat,
          "context = %d, vaobj = %u, attribindex = %u, size = %d, type = %s, relativeoffset = %u",
          CID(context), vaobj, attribindex, size,
          GLenumToString(GLenumGroup::VertexAttribType, type), relativeoffset);

    if (context)
    {
        VertexArrayID vaobjPacked                             = PackParam<VertexArrayID>(vaobj);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateVertexArrayAttribLFormat(context, vaobjPacked, attribindex,
                                                             size, type, relativeoffset));
        if (isCallValid)
        {
            context->vertexArrayAttribLFormat(vaobjPacked, attribindex, size, type, relativeoffset);
        }
        ANGLE_CAPTURE(VertexArrayAttribLFormat, isCallValid, context, vaobjPacked, attribindex,
                      size, type, relativeoffset);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY VertexArrayBindingDivisor(GLuint vaobj, GLuint bindingindex, GLuint divisor)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLVertexArrayBindingDivisor,
          "context = %d, vaobj = %u, bindingindex = %u, divisor = %u", CID(context), vaobj,
          bindingindex, divisor);

    if (context)
    {
        VertexArrayID vaobjPacked                             = PackParam<VertexArrayID>(vaobj);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateVertexArrayBindingDivisor(context, vaobjPacked, bindingindex, divisor));
        if (isCallValid)
        {
            context->vertexArrayBindingDivisor(vaobjPacked, bindingindex, divisor);
        }
        ANGLE_CAPTURE(VertexArrayBindingDivisor, isCallValid, context, vaobjPacked, bindingindex,
                      divisor);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY VertexArrayElementBuffer(GLuint vaobj, GLuint buffer)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLVertexArrayElementBuffer, "context = %d, vaobj = %u, buffer = %u",
          CID(context), vaobj, buffer);

    if (context)
    {
        VertexArrayID vaobjPacked                             = PackParam<VertexArrayID>(vaobj);
        BufferID bufferPacked                                 = PackParam<BufferID>(buffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateVertexArrayElementBuffer(context, vaobjPacked, bufferPacked));
        if (isCallValid)
        {
            context->vertexArrayElementBuffer(vaobjPacked, bufferPacked);
        }
        ANGLE_CAPTURE(VertexArrayElementBuffer, isCallValid, context, vaobjPacked, bufferPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY VertexArrayVertexBuffer(GLuint vaobj,
                                         GLuint bindingindex,
                                         GLuint buffer,
                                         GLintptr offset,
                                         GLsizei stride)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLVertexArrayVertexBuffer,
          "context = %d, vaobj = %u, bindingindex = %u, buffer = %u, offset = %llu, stride = %d",
          CID(context), vaobj, bindingindex, buffer, static_cast<unsigned long long>(offset),
          stride);

    if (context)
    {
        VertexArrayID vaobjPacked                             = PackParam<VertexArrayID>(vaobj);
        BufferID bufferPacked                                 = PackParam<BufferID>(buffer);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateVertexArrayVertexBuffer(context, vaobjPacked, bindingindex,
                                                            bufferPacked, offset, stride));
        if (isCallValid)
        {
            context->vertexArrayVertexBuffer(vaobjPacked, bindingindex, bufferPacked, offset,
                                             stride);
        }
        ANGLE_CAPTURE(VertexArrayVertexBuffer, isCallValid, context, vaobjPacked, bindingindex,
                      bufferPacked, offset, stride);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY VertexArrayVertexBuffers(GLuint vaobj,
                                          GLuint first,
                                          GLsizei count,
                                          const GLuint *buffers,
                                          const GLintptr *offsets,
                                          const GLsizei *strides)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLVertexArrayVertexBuffers,
          "context = %d, vaobj = %u, first = %u, count = %d, buffers = 0x%016" PRIxPTR
          ", offsets = 0x%016" PRIxPTR ", strides = 0x%016" PRIxPTR "",
          CID(context), vaobj, first, count, (uintptr_t)buffers, (uintptr_t)offsets,
          (uintptr_t)strides);

    if (context)
    {
        VertexArrayID vaobjPacked     = PackParam<VertexArrayID>(vaobj);
        const BufferID *buffersPacked = PackParam<const BufferID *>(buffers);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateVertexArrayVertexBuffers(context, vaobjPacked, first, count,
                                                             buffersPacked, offsets, strides));
        if (isCallValid)
        {
            context->vertexArrayVertexBuffers(vaobjPacked, first, count, buffersPacked, offsets,
                                              strides);
        }
        ANGLE_CAPTURE(VertexArrayVertexBuffers, isCallValid, context, vaobjPacked, first, count,
                      buffersPacked, offsets, strides);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

// GL 4.6
void GL_APIENTRY MultiDrawArraysIndirectCount(GLenum mode,
                                              const void *indirect,
                                              GLintptr drawcount,
                                              GLsizei maxdrawcount,
                                              GLsizei stride)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLMultiDrawArraysIndirectCount,
          "context = %d, mode = %s, indirect = 0x%016" PRIxPTR
          ", drawcount = %llu, maxdrawcount = %d, stride = %d",
          CID(context), GLenumToString(GLenumGroup::PrimitiveType, mode), (uintptr_t)indirect,
          static_cast<unsigned long long>(drawcount), maxdrawcount, stride);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateMultiDrawArraysIndirectCount(context, mode, indirect, drawcount,
                                                                 maxdrawcount, stride));
        if (isCallValid)
        {
            context->multiDrawArraysIndirectCount(mode, indirect, drawcount, maxdrawcount, stride);
        }
        ANGLE_CAPTURE(MultiDrawArraysIndirectCount, isCallValid, context, mode, indirect, drawcount,
                      maxdrawcount, stride);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY MultiDrawElementsIndirectCount(GLenum mode,
                                                GLenum type,
                                                const void *indirect,
                                                GLintptr drawcount,
                                                GLsizei maxdrawcount,
                                                GLsizei stride)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLMultiDrawElementsIndirectCount,
          "context = %d, mode = %s, type = %s, indirect = 0x%016" PRIxPTR
          ", drawcount = %llu, maxdrawcount = %d, stride = %d",
          CID(context), GLenumToString(GLenumGroup::PrimitiveType, mode),
          GLenumToString(GLenumGroup::DefaultGroup, type), (uintptr_t)indirect,
          static_cast<unsigned long long>(drawcount), maxdrawcount, stride);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateMultiDrawElementsIndirectCount(
                                context, mode, type, indirect, drawcount, maxdrawcount, stride));
        if (isCallValid)
        {
            context->multiDrawElementsIndirectCount(mode, type, indirect, drawcount, maxdrawcount,
                                                    stride);
        }
        ANGLE_CAPTURE(MultiDrawElementsIndirectCount, isCallValid, context, mode, type, indirect,
                      drawcount, maxdrawcount, stride);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY PolygonOffsetClamp(GLfloat factor, GLfloat units, GLfloat clamp)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLPolygonOffsetClamp, "context = %d, factor = %f, units = %f, clamp = %f",
          CID(context), factor, units, clamp);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidatePolygonOffsetClamp(context, factor, units, clamp));
        if (isCallValid)
        {
            context->polygonOffsetClamp(factor, units, clamp);
        }
        ANGLE_CAPTURE(PolygonOffsetClamp, isCallValid, context, factor, units, clamp);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY SpecializeShader(GLuint shader,
                                  const GLchar *pEntryPoint,
                                  GLuint numSpecializationConstants,
                                  const GLuint *pConstantIndex,
                                  const GLuint *pConstantValue)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLSpecializeShader,
          "context = %d, shader = %u, pEntryPoint = 0x%016" PRIxPTR
          ", numSpecializationConstants = %u, pConstantIndex = 0x%016" PRIxPTR
          ", pConstantValue = 0x%016" PRIxPTR "",
          CID(context), shader, (uintptr_t)pEntryPoint, numSpecializationConstants,
          (uintptr_t)pConstantIndex, (uintptr_t)pConstantValue);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateSpecializeShader(context, shader, pEntryPoint, numSpecializationConstants,
                                      pConstantIndex, pConstantValue));
        if (isCallValid)
        {
            context->specializeShader(shader, pEntryPoint, numSpecializationConstants,
                                      pConstantIndex, pConstantValue);
        }
        ANGLE_CAPTURE(SpecializeShader, isCallValid, context, shader, pEntryPoint,
                      numSpecializationConstants, pConstantIndex, pConstantValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}
}  // namespace gl
