// 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_gles_3_0_autogen.cpp:
//   Defines the GLES 3.0 entry points.

#include "libGLESv2/entry_points_gles_3_0_autogen.h"

#include "common/entry_points_enum_autogen.h"
#include "common/gl_enum_utils.h"
#include "libANGLE/Context.h"
#include "libANGLE/Context.inl.h"
#include "libANGLE/capture/capture_gles_3_0_autogen.h"
#include "libANGLE/context_private_call_gles_autogen.h"
#include "libANGLE/entry_points_utils.h"
#include "libANGLE/validationES3.h"
#include "libGLESv2/global_state.h"

using namespace gl;

extern "C" {
void GL_APIENTRY GL_BeginQuery(GLenum target, GLuint id)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLBeginQuery, "context = %d, target = %s, id = %u", CID(context),
          GLenumToString(GLESEnum::QueryTarget, target), id);

    if (context)
    {
        QueryType targetPacked = PackParam<QueryType>(target);
        QueryID idPacked       = PackParam<QueryID>(id);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             (ValidatePixelLocalStorageInactive(context->getPrivateState(),
                                                context->getMutableErrorSetForValidation(),
                                                angle::EntryPoint::GLBeginQuery) &&
              ValidateBeginQuery(context, angle::EntryPoint::GLBeginQuery, targetPacked,
                                 idPacked)));
        if (isCallValid)
        {
            context->beginQuery(targetPacked, idPacked);
        }
        ANGLE_CAPTURE_GL(BeginQuery, isCallValid, context, targetPacked, idPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_BeginTransformFeedback(GLenum primitiveMode)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLBeginTransformFeedback, "context = %d, primitiveMode = %s", CID(context),
          GLenumToString(GLESEnum::PrimitiveType, primitiveMode));

    if (context)
    {
        PrimitiveMode primitiveModePacked = PackParam<PrimitiveMode>(primitiveMode);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             (ValidatePixelLocalStorageInactive(context->getPrivateState(),
                                                context->getMutableErrorSetForValidation(),
                                                angle::EntryPoint::GLBeginTransformFeedback) &&
              ValidateBeginTransformFeedback(context, angle::EntryPoint::GLBeginTransformFeedback,
                                             primitiveModePacked)));
        if (isCallValid)
        {
            context->beginTransformFeedback(primitiveModePacked);
        }
        ANGLE_CAPTURE_GL(BeginTransformFeedback, isCallValid, context, primitiveModePacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_BindBufferBase(GLenum target, GLuint index, GLuint buffer)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLBindBufferBase, "context = %d, target = %s, index = %u, buffer = %u",
          CID(context), GLenumToString(GLESEnum::BufferTargetARB, target), index, buffer);

    if (context)
    {
        BufferBinding targetPacked = PackParam<BufferBinding>(target);
        BufferID bufferPacked      = PackParam<BufferID>(buffer);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid = (context->skipValidation() ||
                            ValidateBindBufferBase(context, angle::EntryPoint::GLBindBufferBase,
                                                   targetPacked, index, bufferPacked));
        if (isCallValid)
        {
            context->bindBufferBase(targetPacked, index, bufferPacked);
        }
        ANGLE_CAPTURE_GL(BindBufferBase, isCallValid, context, targetPacked, index, bufferPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY
GL_BindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLBindBufferRange,
          "context = %d, target = %s, index = %u, buffer = %u, offset = %llu, size = %llu",
          CID(context), GLenumToString(GLESEnum::BufferTargetARB, target), index, buffer,
          static_cast<unsigned long long>(offset), static_cast<unsigned long long>(size));

    if (context)
    {
        BufferBinding targetPacked = PackParam<BufferBinding>(target);
        BufferID bufferPacked      = PackParam<BufferID>(buffer);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateBindBufferRange(context, angle::EntryPoint::GLBindBufferRange, targetPacked,
                                     index, bufferPacked, offset, size));
        if (isCallValid)
        {
            context->bindBufferRange(targetPacked, index, bufferPacked, offset, size);
        }
        ANGLE_CAPTURE_GL(BindBufferRange, isCallValid, context, targetPacked, index, bufferPacked,
                         offset, size);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_BindSampler(GLuint unit, GLuint sampler)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLBindSampler, "context = %d, unit = %u, sampler = %u", CID(context), unit,
          sampler);

    if (context)
    {
        SamplerID samplerPacked = PackParam<SamplerID>(sampler);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateBindSampler(context, angle::EntryPoint::GLBindSampler, unit, samplerPacked));
        if (isCallValid)
        {
            context->bindSampler(unit, samplerPacked);
        }
        ANGLE_CAPTURE_GL(BindSampler, isCallValid, context, unit, samplerPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

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

    if (context)
    {
        TransformFeedbackID idPacked = PackParam<TransformFeedbackID>(id);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             (ValidatePixelLocalStorageInactive(context->getPrivateState(),
                                                context->getMutableErrorSetForValidation(),
                                                angle::EntryPoint::GLBindTransformFeedback) &&
              ValidateBindTransformFeedback(context, angle::EntryPoint::GLBindTransformFeedback,
                                            target, idPacked)));
        if (isCallValid)
        {
            context->bindTransformFeedback(target, idPacked);
        }
        ANGLE_CAPTURE_GL(BindTransformFeedback, isCallValid, context, target, idPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_BindVertexArray(GLuint array)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLBindVertexArray, "context = %d, array = %u", CID(context), array);

    if (context)
    {
        VertexArrayID arrayPacked = PackParam<VertexArrayID>(array);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateBindVertexArray(context, angle::EntryPoint::GLBindVertexArray, arrayPacked));
        if (isCallValid)
        {
            context->bindVertexArray(arrayPacked);
        }
        ANGLE_CAPTURE_GL(BindVertexArray, isCallValid, context, arrayPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_BlitFramebuffer(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, GLBlitFramebuffer,
          "context = %d, srcX0 = %d, srcY0 = %d, srcX1 = %d, srcY1 = %d, dstX0 = %d, dstY0 = %d, "
          "dstX1 = %d, dstY1 = %d, mask = %s, filter = %s",
          CID(context), srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1,
          GLbitfieldToString(GLESEnum::ClearBufferMask, mask).c_str(),
          GLenumToString(GLESEnum::BlitFramebufferFilter, filter));

    if (context)
    {
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             (ValidatePixelLocalStorageInactive(context->getPrivateState(),
                                                context->getMutableErrorSetForValidation(),
                                                angle::EntryPoint::GLBlitFramebuffer) &&
              ValidateBlitFramebuffer(context, angle::EntryPoint::GLBlitFramebuffer, srcX0, srcY0,
                                      srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter)));
        if (isCallValid)
        {
            context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask,
                                     filter);
        }
        ANGLE_CAPTURE_GL(BlitFramebuffer, isCallValid, context, srcX0, srcY0, srcX1, srcY1, dstX0,
                         dstY0, dstX1, dstY1, mask, filter);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_ClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLClearBufferfi,
          "context = %d, buffer = %s, drawbuffer = %d, depth = %f, stencil = %d", CID(context),
          GLenumToString(GLESEnum::Buffer, buffer), drawbuffer, depth, stencil);

    if (context)
    {
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid = (context->skipValidation() ||
                            ValidateClearBufferfi(context, angle::EntryPoint::GLClearBufferfi,
                                                  buffer, drawbuffer, depth, stencil));
        if (isCallValid)
        {
            context->clearBufferfi(buffer, drawbuffer, depth, stencil);
        }
        ANGLE_CAPTURE_GL(ClearBufferfi, isCallValid, context, buffer, drawbuffer, depth, stencil);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLClearBufferfv,
          "context = %d, buffer = %s, drawbuffer = %d, value = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLESEnum::Buffer, buffer), drawbuffer, (uintptr_t)value);

    if (context)
    {
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid = (context->skipValidation() ||
                            ValidateClearBufferfv(context, angle::EntryPoint::GLClearBufferfv,
                                                  buffer, drawbuffer, value));
        if (isCallValid)
        {
            context->clearBufferfv(buffer, drawbuffer, value);
        }
        ANGLE_CAPTURE_GL(ClearBufferfv, isCallValid, context, buffer, drawbuffer, value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLClearBufferiv,
          "context = %d, buffer = %s, drawbuffer = %d, value = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLESEnum::Buffer, buffer), drawbuffer, (uintptr_t)value);

    if (context)
    {
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid = (context->skipValidation() ||
                            ValidateClearBufferiv(context, angle::EntryPoint::GLClearBufferiv,
                                                  buffer, drawbuffer, value));
        if (isCallValid)
        {
            context->clearBufferiv(buffer, drawbuffer, value);
        }
        ANGLE_CAPTURE_GL(ClearBufferiv, isCallValid, context, buffer, drawbuffer, value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

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

    if (context)
    {
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid = (context->skipValidation() ||
                            ValidateClearBufferuiv(context, angle::EntryPoint::GLClearBufferuiv,
                                                   buffer, drawbuffer, value));
        if (isCallValid)
        {
            context->clearBufferuiv(buffer, drawbuffer, value);
        }
        ANGLE_CAPTURE_GL(ClearBufferuiv, isCallValid, context, buffer, drawbuffer, value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

GLenum GL_APIENTRY GL_ClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLClientWaitSync,
          "context = %d, sync = 0x%016" PRIxPTR ", flags = %s, timeout = %llu", CID(context),
          (uintptr_t)sync, GLbitfieldToString(GLESEnum::SyncObjectMask, flags).c_str(),
          static_cast<unsigned long long>(timeout));

    GLenum returnValue;
    if (context)
    {
        SyncID syncPacked = PackParam<SyncID>(sync);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             (ValidatePixelLocalStorageInactive(context->getPrivateState(),
                                                context->getMutableErrorSetForValidation(),
                                                angle::EntryPoint::GLClientWaitSync) &&
              ValidateClientWaitSync(context, angle::EntryPoint::GLClientWaitSync, syncPacked,
                                     flags, timeout)));
        if (isCallValid)
        {
            returnValue = context->clientWaitSync(syncPacked, flags, timeout);
        }
        else
        {
            returnValue = GetDefaultReturnValue<angle::EntryPoint::GLClientWaitSync, GLenum>();
        }
        ANGLE_CAPTURE_GL(ClientWaitSync, isCallValid, context, syncPacked, flags, timeout,
                         returnValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
        returnValue = GetDefaultReturnValue<angle::EntryPoint::GLClientWaitSync, GLenum>();
    }
    egl::Display::GetCurrentThreadUnlockedTailCall()->run(&returnValue);
    return returnValue;
}

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

    if (context)
    {
        TextureTarget targetPacked = PackParam<TextureTarget>(target);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             (ValidatePixelLocalStorageInactive(context->getPrivateState(),
                                                context->getMutableErrorSetForValidation(),
                                                angle::EntryPoint::GLCompressedTexImage3D) &&
              ValidateCompressedTexImage3D(context, angle::EntryPoint::GLCompressedTexImage3D,
                                           targetPacked, level, internalformat, width, height,
                                           depth, border, imageSize, data)));
        if (isCallValid)
        {
            context->compressedTexImage3D(targetPacked, level, internalformat, width, height, depth,
                                          border, imageSize, data);
        }
        ANGLE_CAPTURE_GL(CompressedTexImage3D, isCallValid, context, targetPacked, level,
                         internalformat, width, height, depth, border, imageSize, data);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    egl::Display::GetCurrentThreadUnlockedTailCall()->run(nullptr);
}

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

    if (context)
    {
        TextureTarget targetPacked = PackParam<TextureTarget>(target);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             (ValidatePixelLocalStorageInactive(context->getPrivateState(),
                                                context->getMutableErrorSetForValidation(),
                                                angle::EntryPoint::GLCompressedTexSubImage3D) &&
              ValidateCompressedTexSubImage3D(context, angle::EntryPoint::GLCompressedTexSubImage3D,
                                              targetPacked, level, xoffset, yoffset, zoffset, width,
                                              height, depth, format, imageSize, data)));
        if (isCallValid)
        {
            context->compressedTexSubImage3D(targetPacked, level, xoffset, yoffset, zoffset, width,
                                             height, depth, format, imageSize, data);
        }
        ANGLE_CAPTURE_GL(CompressedTexSubImage3D, isCallValid, context, targetPacked, level,
                         xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    egl::Display::GetCurrentThreadUnlockedTailCall()->run(nullptr);
}

void GL_APIENTRY GL_CopyBufferSubData(GLenum readTarget,
                                      GLenum writeTarget,
                                      GLintptr readOffset,
                                      GLintptr writeOffset,
                                      GLsizeiptr size)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLCopyBufferSubData,
          "context = %d, readTarget = %s, writeTarget = %s, readOffset = %llu, writeOffset = %llu, "
          "size = %llu",
          CID(context), GLenumToString(GLESEnum::CopyBufferSubDataTarget, readTarget),
          GLenumToString(GLESEnum::CopyBufferSubDataTarget, writeTarget),
          static_cast<unsigned long long>(readOffset), static_cast<unsigned long long>(writeOffset),
          static_cast<unsigned long long>(size));

    if (context)
    {
        BufferBinding readTargetPacked  = PackParam<BufferBinding>(readTarget);
        BufferBinding writeTargetPacked = PackParam<BufferBinding>(writeTarget);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             (ValidatePixelLocalStorageInactive(context->getPrivateState(),
                                                context->getMutableErrorSetForValidation(),
                                                angle::EntryPoint::GLCopyBufferSubData) &&
              ValidateCopyBufferSubData(context, angle::EntryPoint::GLCopyBufferSubData,
                                        readTargetPacked, writeTargetPacked, readOffset,
                                        writeOffset, size)));
        if (isCallValid)
        {
            context->copyBufferSubData(readTargetPacked, writeTargetPacked, readOffset, writeOffset,
                                       size);
        }
        ANGLE_CAPTURE_GL(CopyBufferSubData, isCallValid, context, readTargetPacked,
                         writeTargetPacked, readOffset, writeOffset, size);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_CopyTexSubImage3D(GLenum target,
                                      GLint level,
                                      GLint xoffset,
                                      GLint yoffset,
                                      GLint zoffset,
                                      GLint x,
                                      GLint y,
                                      GLsizei width,
                                      GLsizei height)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLCopyTexSubImage3D,
          "context = %d, target = %s, level = %d, xoffset = %d, yoffset = %d, zoffset = %d, x = "
          "%d, y = %d, width = %d, height = %d",
          CID(context), GLenumToString(GLESEnum::TextureTarget, target), level, xoffset, yoffset,
          zoffset, x, y, width, height);

    if (context)
    {
        TextureTarget targetPacked = PackParam<TextureTarget>(target);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             (ValidatePixelLocalStorageInactive(context->getPrivateState(),
                                                context->getMutableErrorSetForValidation(),
                                                angle::EntryPoint::GLCopyTexSubImage3D) &&
              ValidateCopyTexSubImage3D(context, angle::EntryPoint::GLCopyTexSubImage3D,
                                        targetPacked, level, xoffset, yoffset, zoffset, x, y, width,
                                        height)));
        if (isCallValid)
        {
            context->copyTexSubImage3D(targetPacked, level, xoffset, yoffset, zoffset, x, y, width,
                                       height);
        }
        ANGLE_CAPTURE_GL(CopyTexSubImage3D, isCallValid, context, targetPacked, level, xoffset,
                         yoffset, zoffset, x, y, width, height);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

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

    if (context)
    {
        const QueryID *idsPacked = PackParam<const QueryID *>(ids);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateDeleteQueries(context, angle::EntryPoint::GLDeleteQueries, n, idsPacked));
        if (isCallValid)
        {
            context->deleteQueries(n, idsPacked);
        }
        ANGLE_CAPTURE_GL(DeleteQueries, isCallValid, context, n, idsPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

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

    if (context)
    {
        const SamplerID *samplersPacked = PackParam<const SamplerID *>(samplers);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid = (context->skipValidation() ||
                            ValidateDeleteSamplers(context, angle::EntryPoint::GLDeleteSamplers,
                                                   count, samplersPacked));
        if (isCallValid)
        {
            context->deleteSamplers(count, samplersPacked);
        }
        ANGLE_CAPTURE_GL(DeleteSamplers, isCallValid, context, count, samplersPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_DeleteSync(GLsync sync)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLDeleteSync, "context = %d, sync = 0x%016" PRIxPTR "", CID(context),
          (uintptr_t)sync);

    if (context)
    {
        SyncID syncPacked = PackParam<SyncID>(sync);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateDeleteSync(context, angle::EntryPoint::GLDeleteSync, syncPacked));
        if (isCallValid)
        {
            context->deleteSync(syncPacked);
        }
        ANGLE_CAPTURE_GL(DeleteSync, isCallValid, context, syncPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_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);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateDeleteTransformFeedbacks(
                 context, angle::EntryPoint::GLDeleteTransformFeedbacks, n, idsPacked));
        if (isCallValid)
        {
            context->deleteTransformFeedbacks(n, idsPacked);
        }
        ANGLE_CAPTURE_GL(DeleteTransformFeedbacks, isCallValid, context, n, idsPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

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

    if (context)
    {
        const VertexArrayID *arraysPacked = PackParam<const VertexArrayID *>(arrays);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid = (context->skipValidation() ||
                            ValidateDeleteVertexArrays(
                                context, angle::EntryPoint::GLDeleteVertexArrays, n, arraysPacked));
        if (isCallValid)
        {
            context->deleteVertexArrays(n, arraysPacked);
        }
        ANGLE_CAPTURE_GL(DeleteVertexArrays, isCallValid, context, n, arraysPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_DrawArraysInstanced(GLenum mode,
                                        GLint first,
                                        GLsizei count,
                                        GLsizei instancecount)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLDrawArraysInstanced,
          "context = %d, mode = %s, first = %d, count = %d, instancecount = %d", CID(context),
          GLenumToString(GLESEnum::PrimitiveType, mode), first, count, instancecount);

    if (context)
    {
        PrimitiveMode modePacked = PackParam<PrimitiveMode>(mode);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateDrawArraysInstanced(context, angle::EntryPoint::GLDrawArraysInstanced,
                                         modePacked, first, count, instancecount));
        if (isCallValid)
        {
            context->drawArraysInstanced(modePacked, first, count, instancecount);
        }
        ANGLE_CAPTURE_GL(DrawArraysInstanced, isCallValid, context, modePacked, first, count,
                         instancecount);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_DrawBuffers(GLsizei n, const GLenum *bufs)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLDrawBuffers, "context = %d, n = %d, bufs = 0x%016" PRIxPTR "", CID(context), n,
          (uintptr_t)bufs);

    if (context)
    {
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             (ValidatePixelLocalStorageInactive(context->getPrivateState(),
                                                context->getMutableErrorSetForValidation(),
                                                angle::EntryPoint::GLDrawBuffers) &&
              ValidateDrawBuffers(context, angle::EntryPoint::GLDrawBuffers, n, bufs)));
        if (isCallValid)
        {
            context->drawBuffers(n, bufs);
        }
        ANGLE_CAPTURE_GL(DrawBuffers, isCallValid, context, n, bufs);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_DrawElementsInstanced(GLenum mode,
                                          GLsizei count,
                                          GLenum type,
                                          const void *indices,
                                          GLsizei instancecount)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLDrawElementsInstanced,
          "context = %d, mode = %s, count = %d, type = %s, indices = 0x%016" PRIxPTR
          ", instancecount = %d",
          CID(context), GLenumToString(GLESEnum::PrimitiveType, mode), count,
          GLenumToString(GLESEnum::DrawElementsType, type), (uintptr_t)indices, instancecount);

    if (context)
    {
        PrimitiveMode modePacked    = PackParam<PrimitiveMode>(mode);
        DrawElementsType typePacked = PackParam<DrawElementsType>(type);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateDrawElementsInstanced(context, angle::EntryPoint::GLDrawElementsInstanced,
                                           modePacked, count, typePacked, indices, instancecount));
        if (isCallValid)
        {
            context->drawElementsInstanced(modePacked, count, typePacked, indices, instancecount);
        }
        ANGLE_CAPTURE_GL(DrawElementsInstanced, isCallValid, context, modePacked, count, typePacked,
                         indices, instancecount);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_DrawRangeElements(GLenum mode,
                                      GLuint start,
                                      GLuint end,
                                      GLsizei count,
                                      GLenum type,
                                      const void *indices)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLDrawRangeElements,
          "context = %d, mode = %s, start = %u, end = %u, count = %d, type = %s, indices = "
          "0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLESEnum::PrimitiveType, mode), start, end, count,
          GLenumToString(GLESEnum::DrawElementsType, type), (uintptr_t)indices);

    if (context)
    {
        PrimitiveMode modePacked    = PackParam<PrimitiveMode>(mode);
        DrawElementsType typePacked = PackParam<DrawElementsType>(type);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateDrawRangeElements(context, angle::EntryPoint::GLDrawRangeElements, modePacked,
                                       start, end, count, typePacked, indices));
        if (isCallValid)
        {
            context->drawRangeElements(modePacked, start, end, count, typePacked, indices);
        }
        ANGLE_CAPTURE_GL(DrawRangeElements, isCallValid, context, modePacked, start, end, count,
                         typePacked, indices);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_EndQuery(GLenum target)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLEndQuery, "context = %d, target = %s", CID(context),
          GLenumToString(GLESEnum::QueryTarget, target));

    if (context)
    {
        QueryType targetPacked = PackParam<QueryType>(target);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             (ValidatePixelLocalStorageInactive(context->getPrivateState(),
                                                context->getMutableErrorSetForValidation(),
                                                angle::EntryPoint::GLEndQuery) &&
              ValidateEndQuery(context, angle::EntryPoint::GLEndQuery, targetPacked)));
        if (isCallValid)
        {
            context->endQuery(targetPacked);
        }
        ANGLE_CAPTURE_GL(EndQuery, isCallValid, context, targetPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

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

    if (context)
    {
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             (ValidatePixelLocalStorageInactive(context->getPrivateState(),
                                                context->getMutableErrorSetForValidation(),
                                                angle::EntryPoint::GLEndTransformFeedback) &&
              ValidateEndTransformFeedback(context, angle::EntryPoint::GLEndTransformFeedback)));
        if (isCallValid)
        {
            context->endTransformFeedback();
        }
        ANGLE_CAPTURE_GL(EndTransformFeedback, isCallValid, context);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

GLsync GL_APIENTRY GL_FenceSync(GLenum condition, GLbitfield flags)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLFenceSync, "context = %d, condition = %s, flags = %s", CID(context),
          GLenumToString(GLESEnum::SyncCondition, condition),
          GLbitfieldToString(GLESEnum::SyncBehaviorFlags, flags).c_str());

    GLsync returnValue;
    if (context)
    {
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateFenceSync(context, angle::EntryPoint::GLFenceSync, condition, flags));
        if (isCallValid)
        {
            returnValue = context->fenceSync(condition, flags);
        }
        else
        {
            returnValue = GetDefaultReturnValue<angle::EntryPoint::GLFenceSync, GLsync>();
        }
        ANGLE_CAPTURE_GL(FenceSync, isCallValid, context, condition, flags, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
        returnValue = GetDefaultReturnValue<angle::EntryPoint::GLFenceSync, GLsync>();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
    return returnValue;
}

void GL_APIENTRY GL_FlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLFlushMappedBufferRange,
          "context = %d, target = %s, offset = %llu, length = %llu", CID(context),
          GLenumToString(GLESEnum::BufferTargetARB, target),
          static_cast<unsigned long long>(offset), static_cast<unsigned long long>(length));

    if (context)
    {
        BufferBinding targetPacked = PackParam<BufferBinding>(target);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateFlushMappedBufferRange(context, angle::EntryPoint::GLFlushMappedBufferRange,
                                            targetPacked, offset, length));
        if (isCallValid)
        {
            context->flushMappedBufferRange(targetPacked, offset, length);
        }
        ANGLE_CAPTURE_GL(FlushMappedBufferRange, isCallValid, context, targetPacked, offset,
                         length);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_FramebufferTextureLayer(GLenum target,
                                            GLenum attachment,
                                            GLuint texture,
                                            GLint level,
                                            GLint layer)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLFramebufferTextureLayer,
          "context = %d, target = %s, attachment = %s, texture = %u, level = %d, layer = %d",
          CID(context), GLenumToString(GLESEnum::FramebufferTarget, target),
          GLenumToString(GLESEnum::FramebufferAttachment, attachment), texture, level, layer);

    if (context)
    {
        TextureID texturePacked = PackParam<TextureID>(texture);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             (ValidatePixelLocalStorageInactive(context->getPrivateState(),
                                                context->getMutableErrorSetForValidation(),
                                                angle::EntryPoint::GLFramebufferTextureLayer) &&
              ValidateFramebufferTextureLayer(context, angle::EntryPoint::GLFramebufferTextureLayer,
                                              target, attachment, texturePacked, level, layer)));
        if (isCallValid)
        {
            context->framebufferTextureLayer(target, attachment, texturePacked, level, layer);
        }
        ANGLE_CAPTURE_GL(FramebufferTextureLayer, isCallValid, context, target, attachment,
                         texturePacked, level, layer);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

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

    if (context)
    {
        QueryID *idsPacked = PackParam<QueryID *>(ids);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGenQueries(context, angle::EntryPoint::GLGenQueries, n, idsPacked));
        if (isCallValid)
        {
            context->genQueries(n, idsPacked);
        }
        ANGLE_CAPTURE_GL(GenQueries, isCallValid, context, n, idsPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

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

    if (context)
    {
        SamplerID *samplersPacked = PackParam<SamplerID *>(samplers);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGenSamplers(context, angle::EntryPoint::GLGenSamplers, count, samplersPacked));
        if (isCallValid)
        {
            context->genSamplers(count, samplersPacked);
        }
        ANGLE_CAPTURE_GL(GenSamplers, isCallValid, context, count, samplersPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_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);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid = (context->skipValidation() ||
                            ValidateGenTransformFeedbacks(
                                context, angle::EntryPoint::GLGenTransformFeedbacks, n, idsPacked));
        if (isCallValid)
        {
            context->genTransformFeedbacks(n, idsPacked);
        }
        ANGLE_CAPTURE_GL(GenTransformFeedbacks, isCallValid, context, n, idsPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

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

    if (context)
    {
        VertexArrayID *arraysPacked = PackParam<VertexArrayID *>(arrays);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid = (context->skipValidation() ||
                            ValidateGenVertexArrays(context, angle::EntryPoint::GLGenVertexArrays,
                                                    n, arraysPacked));
        if (isCallValid)
        {
            context->genVertexArrays(n, arraysPacked);
        }
        ANGLE_CAPTURE_GL(GenVertexArrays, isCallValid, context, n, arraysPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_GetActiveUniformBlockName(GLuint program,
                                              GLuint uniformBlockIndex,
                                              GLsizei bufSize,
                                              GLsizei *length,
                                              GLchar *uniformBlockName)
{
    Context *context = GetValidGlobalContext();
    EVENT(
        context, GLGetActiveUniformBlockName,
        "context = %d, program = %u, uniformBlockIndex = %u, bufSize = %d, length = 0x%016" PRIxPTR
        ", uniformBlockName = 0x%016" PRIxPTR "",
        CID(context), program, uniformBlockIndex, bufSize, (uintptr_t)length,
        (uintptr_t)uniformBlockName);

    if (context)
    {
        ShaderProgramID programPacked             = PackParam<ShaderProgramID>(program);
        UniformBlockIndex uniformBlockIndexPacked = PackParam<UniformBlockIndex>(uniformBlockIndex);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetActiveUniformBlockName(
                 context, angle::EntryPoint::GLGetActiveUniformBlockName, programPacked,
                 uniformBlockIndexPacked, bufSize, length, uniformBlockName));
        if (isCallValid)
        {
            context->getActiveUniformBlockName(programPacked, uniformBlockIndexPacked, bufSize,
                                               length, uniformBlockName);
        }
        ANGLE_CAPTURE_GL(GetActiveUniformBlockName, isCallValid, context, programPacked,
                         uniformBlockIndexPacked, bufSize, length, uniformBlockName);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_GetActiveUniformBlockiv(GLuint program,
                                            GLuint uniformBlockIndex,
                                            GLenum pname,
                                            GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetActiveUniformBlockiv,
          "context = %d, program = %u, uniformBlockIndex = %u, pname = %s, params = 0x%016" PRIxPTR
          "",
          CID(context), program, uniformBlockIndex,
          GLenumToString(GLESEnum::UniformBlockPName, pname), (uintptr_t)params);

    if (context)
    {
        ShaderProgramID programPacked             = PackParam<ShaderProgramID>(program);
        UniformBlockIndex uniformBlockIndexPacked = PackParam<UniformBlockIndex>(uniformBlockIndex);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid = (context->skipValidation() ||
                            ValidateGetActiveUniformBlockiv(
                                context, angle::EntryPoint::GLGetActiveUniformBlockiv,
                                programPacked, uniformBlockIndexPacked, pname, params));
        if (isCallValid)
        {
            context->getActiveUniformBlockiv(programPacked, uniformBlockIndexPacked, pname, params);
        }
        ANGLE_CAPTURE_GL(GetActiveUniformBlockiv, isCallValid, context, programPacked,
                         uniformBlockIndexPacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_GetActiveUniformsiv(GLuint program,
                                        GLsizei uniformCount,
                                        const GLuint *uniformIndices,
                                        GLenum pname,
                                        GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetActiveUniformsiv,
          "context = %d, program = %u, uniformCount = %d, uniformIndices = 0x%016" PRIxPTR
          ", pname = %s, params = 0x%016" PRIxPTR "",
          CID(context), program, uniformCount, (uintptr_t)uniformIndices,
          GLenumToString(GLESEnum::UniformPName, pname), (uintptr_t)params);

    if (context)
    {
        ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid = (context->skipValidation() ||
                            ValidateGetActiveUniformsiv(
                                context, angle::EntryPoint::GLGetActiveUniformsiv, programPacked,
                                uniformCount, uniformIndices, pname, params));
        if (isCallValid)
        {
            context->getActiveUniformsiv(programPacked, uniformCount, uniformIndices, pname,
                                         params);
        }
        ANGLE_CAPTURE_GL(GetActiveUniformsiv, isCallValid, context, programPacked, uniformCount,
                         uniformIndices, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_GetBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetBufferParameteri64v,
          "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLESEnum::BufferTargetARB, target),
          GLenumToString(GLESEnum::AllEnums, pname), (uintptr_t)params);

    if (context)
    {
        BufferBinding targetPacked = PackParam<BufferBinding>(target);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetBufferParameteri64v(context, angle::EntryPoint::GLGetBufferParameteri64v,
                                            targetPacked, pname, params));
        if (isCallValid)
        {
            context->getBufferParameteri64v(targetPacked, pname, params);
        }
        ANGLE_CAPTURE_GL(GetBufferParameteri64v, isCallValid, context, targetPacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_GetBufferPointerv(GLenum target, GLenum pname, void **params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetBufferPointerv,
          "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLESEnum::BufferTargetARB, target),
          GLenumToString(GLESEnum::AllEnums, pname), (uintptr_t)params);

    if (context)
    {
        BufferBinding targetPacked = PackParam<BufferBinding>(target);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetBufferPointerv(context, angle::EntryPoint::GLGetBufferPointerv,
                                       targetPacked, pname, params));
        if (isCallValid)
        {
            context->getBufferPointerv(targetPacked, pname, params);
        }
        ANGLE_CAPTURE_GL(GetBufferPointerv, isCallValid, context, targetPacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

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

    GLint returnValue;
    if (context)
    {
        ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetFragDataLocation(context, angle::EntryPoint::GLGetFragDataLocation,
                                         programPacked, name));
        if (isCallValid)
        {
            returnValue = context->getFragDataLocation(programPacked, name);
        }
        else
        {
            returnValue = GetDefaultReturnValue<angle::EntryPoint::GLGetFragDataLocation, GLint>();
        }
        ANGLE_CAPTURE_GL(GetFragDataLocation, isCallValid, context, programPacked, name,
                         returnValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
        returnValue = GetDefaultReturnValue<angle::EntryPoint::GLGetFragDataLocation, GLint>();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
    return returnValue;
}

void GL_APIENTRY GL_GetInteger64i_v(GLenum target, GLuint index, GLint64 *data)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetInteger64i_v,
          "context = %d, target = %s, index = %u, data = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLESEnum::GetPName, target), index, (uintptr_t)data);

    if (context)
    {
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid = (context->skipValidation() ||
                            ValidateGetInteger64i_v(context, angle::EntryPoint::GLGetInteger64i_v,
                                                    target, index, data));
        if (isCallValid)
        {
            context->getInteger64i_v(target, index, data);
        }
        ANGLE_CAPTURE_GL(GetInteger64i_v, isCallValid, context, target, index, data);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_GetInteger64v(GLenum pname, GLint64 *data)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetInteger64v, "context = %d, pname = %s, data = 0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLESEnum::GetPName, pname), (uintptr_t)data);

    if (context)
    {
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetInteger64v(context, angle::EntryPoint::GLGetInteger64v, pname, data));
        if (isCallValid)
        {
            context->getInteger64v(pname, data);
        }
        ANGLE_CAPTURE_GL(GetInteger64v, isCallValid, context, pname, data);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_GetIntegeri_v(GLenum target, GLuint index, GLint *data)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetIntegeri_v,
          "context = %d, target = %s, index = %u, data = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLESEnum::GetPName, target), index, (uintptr_t)data);

    if (context)
    {
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid = (context->skipValidation() ||
                            ValidateGetIntegeri_v(context, angle::EntryPoint::GLGetIntegeri_v,
                                                  target, index, data));
        if (isCallValid)
        {
            context->getIntegeri_v(target, index, data);
        }
        ANGLE_CAPTURE_GL(GetIntegeri_v, isCallValid, context, target, index, data);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_GetInternalformativ(GLenum target,
                                        GLenum internalformat,
                                        GLenum pname,
                                        GLsizei count,
                                        GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetInternalformativ,
          "context = %d, target = %s, internalformat = %s, pname = %s, count = %d, params = "
          "0x%016" PRIxPTR "",
          CID(context), GLenumToString(GLESEnum::TextureTarget, target),
          GLenumToString(GLESEnum::InternalFormat, internalformat),
          GLenumToString(GLESEnum::InternalFormatPName, pname), count, (uintptr_t)params);

    if (context)
    {
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetInternalformativ(context, angle::EntryPoint::GLGetInternalformativ, target,
                                         internalformat, pname, count, params));
        if (isCallValid)
        {
            context->getInternalformativ(target, internalformat, pname, count, params);
        }
        ANGLE_CAPTURE_GL(GetInternalformativ, isCallValid, context, target, internalformat, pname,
                         count, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_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);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetProgramBinary(context, angle::EntryPoint::GLGetProgramBinary, programPacked,
                                      bufSize, length, binaryFormat, binary));
        if (isCallValid)
        {
            context->getProgramBinary(programPacked, bufSize, length, binaryFormat, binary);
        }
        ANGLE_CAPTURE_GL(GetProgramBinary, isCallValid, context, programPacked, bufSize, length,
                         binaryFormat, binary);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

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

    if (context)
    {
        QueryID idPacked = PackParam<QueryID>(id);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetQueryObjectuiv(context, angle::EntryPoint::GLGetQueryObjectuiv, idPacked,
                                       pname, params));
        if (isCallValid)
        {
            context->getQueryObjectuiv(idPacked, pname, params);
        }
        ANGLE_CAPTURE_GL(GetQueryObjectuiv, isCallValid, context, idPacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

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

    if (context)
    {
        QueryType targetPacked = PackParam<QueryType>(target);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid = (context->skipValidation() ||
                            ValidateGetQueryiv(context, angle::EntryPoint::GLGetQueryiv,
                                               targetPacked, pname, params));
        if (isCallValid)
        {
            context->getQueryiv(targetPacked, pname, params);
        }
        ANGLE_CAPTURE_GL(GetQueryiv, isCallValid, context, targetPacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_GetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetSamplerParameterfv,
          "context = %d, sampler = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          sampler, GLenumToString(GLESEnum::SamplerParameterF, pname), (uintptr_t)params);

    if (context)
    {
        SamplerID samplerPacked = PackParam<SamplerID>(sampler);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetSamplerParameterfv(context, angle::EntryPoint::GLGetSamplerParameterfv,
                                           samplerPacked, pname, params));
        if (isCallValid)
        {
            context->getSamplerParameterfv(samplerPacked, pname, params);
        }
        ANGLE_CAPTURE_GL(GetSamplerParameterfv, isCallValid, context, samplerPacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_GetSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetSamplerParameteriv,
          "context = %d, sampler = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
          sampler, GLenumToString(GLESEnum::SamplerParameterI, pname), (uintptr_t)params);

    if (context)
    {
        SamplerID samplerPacked = PackParam<SamplerID>(sampler);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetSamplerParameteriv(context, angle::EntryPoint::GLGetSamplerParameteriv,
                                           samplerPacked, pname, params));
        if (isCallValid)
        {
            context->getSamplerParameteriv(samplerPacked, pname, params);
        }
        ANGLE_CAPTURE_GL(GetSamplerParameteriv, isCallValid, context, samplerPacked, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

const GLubyte *GL_APIENTRY GL_GetStringi(GLenum name, GLuint index)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetStringi, "context = %d, name = %s, index = %u", CID(context),
          GLenumToString(GLESEnum::StringName, name), index);

    const GLubyte *returnValue;
    if (context)
    {
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetStringi(context, angle::EntryPoint::GLGetStringi, name, index));
        if (isCallValid)
        {
            returnValue = context->getStringi(name, index);
        }
        else
        {
            returnValue = GetDefaultReturnValue<angle::EntryPoint::GLGetStringi, const GLubyte *>();
        }
        ANGLE_CAPTURE_GL(GetStringi, isCallValid, context, name, index, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
        returnValue = GetDefaultReturnValue<angle::EntryPoint::GLGetStringi, const GLubyte *>();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
    return returnValue;
}

void GL_APIENTRY
GL_GetSynciv(GLsync sync, GLenum pname, GLsizei count, GLsizei *length, GLint *values)
{
    Context *context = GetGlobalContext();
    EVENT(context, GLGetSynciv,
          "context = %d, sync = 0x%016" PRIxPTR ", pname = %s, count = %d, length = 0x%016" PRIxPTR
          ", values = 0x%016" PRIxPTR "",
          CID(context), (uintptr_t)sync, GLenumToString(GLESEnum::SyncParameterName, pname), count,
          (uintptr_t)length, (uintptr_t)values);

    if (context)
    {
        SyncID syncPacked = PackParam<SyncID>(sync);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid = (context->skipValidation() ||
                            ValidateGetSynciv(context, angle::EntryPoint::GLGetSynciv, syncPacked,
                                              pname, count, length, values));
        if (isCallValid)
        {
            context->getSynciv(syncPacked, pname, count, length, values);
        }
        ANGLE_CAPTURE_GL(GetSynciv, isCallValid, context, syncPacked, pname, count, length, values);
    }
    else
    {
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_GetTransformFeedbackVarying(GLuint program,
                                                GLuint index,
                                                GLsizei bufSize,
                                                GLsizei *length,
                                                GLsizei *size,
                                                GLenum *type,
                                                GLchar *name)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetTransformFeedbackVarying,
          "context = %d, program = %u, index = %u, bufSize = %d, length = 0x%016" PRIxPTR
          ", size = 0x%016" PRIxPTR ", type = 0x%016" PRIxPTR ", name = 0x%016" PRIxPTR "",
          CID(context), program, index, bufSize, (uintptr_t)length, (uintptr_t)size,
          (uintptr_t)type, (uintptr_t)name);

    if (context)
    {
        ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid = (context->skipValidation() ||
                            ValidateGetTransformFeedbackVarying(
                                context, angle::EntryPoint::GLGetTransformFeedbackVarying,
                                programPacked, index, bufSize, length, size, type, name));
        if (isCallValid)
        {
            context->getTransformFeedbackVarying(programPacked, index, bufSize, length, size, type,
                                                 name);
        }
        ANGLE_CAPTURE_GL(GetTransformFeedbackVarying, isCallValid, context, programPacked, index,
                         bufSize, length, size, type, name);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

GLuint GL_APIENTRY GL_GetUniformBlockIndex(GLuint program, const GLchar *uniformBlockName)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetUniformBlockIndex,
          "context = %d, program = %u, uniformBlockName = 0x%016" PRIxPTR "", CID(context), program,
          (uintptr_t)uniformBlockName);

    GLuint returnValue;
    if (context)
    {
        ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetUniformBlockIndex(context, angle::EntryPoint::GLGetUniformBlockIndex,
                                          programPacked, uniformBlockName));
        if (isCallValid)
        {
            returnValue = context->getUniformBlockIndex(programPacked, uniformBlockName);
        }
        else
        {
            returnValue =
                GetDefaultReturnValue<angle::EntryPoint::GLGetUniformBlockIndex, GLuint>();
        }
        ANGLE_CAPTURE_GL(GetUniformBlockIndex, isCallValid, context, programPacked,
                         uniformBlockName, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
        returnValue = GetDefaultReturnValue<angle::EntryPoint::GLGetUniformBlockIndex, GLuint>();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
    return returnValue;
}

void GL_APIENTRY GL_GetUniformIndices(GLuint program,
                                      GLsizei uniformCount,
                                      const GLchar *const *uniformNames,
                                      GLuint *uniformIndices)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetUniformIndices,
          "context = %d, program = %u, uniformCount = %d, uniformNames = 0x%016" PRIxPTR
          ", uniformIndices = 0x%016" PRIxPTR "",
          CID(context), program, uniformCount, (uintptr_t)uniformNames, (uintptr_t)uniformIndices);

    if (context)
    {
        ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetUniformIndices(context, angle::EntryPoint::GLGetUniformIndices,
                                       programPacked, uniformCount, uniformNames, uniformIndices));
        if (isCallValid)
        {
            context->getUniformIndices(programPacked, uniformCount, uniformNames, uniformIndices);
        }
        ANGLE_CAPTURE_GL(GetUniformIndices, isCallValid, context, programPacked, uniformCount,
                         uniformNames, uniformIndices);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_GetUniformuiv(GLuint program, GLint location, GLuint *params)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLGetUniformuiv,
          "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);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid = (context->skipValidation() ||
                            ValidateGetUniformuiv(context, angle::EntryPoint::GLGetUniformuiv,
                                                  programPacked, locationPacked, params));
        if (isCallValid)
        {
            context->getUniformuiv(programPacked, locationPacked, params);
        }
        ANGLE_CAPTURE_GL(GetUniformuiv, isCallValid, context, programPacked, locationPacked,
                         params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

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

    if (context)
    {
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetVertexAttribIiv(context, angle::EntryPoint::GLGetVertexAttribIiv, index,
                                        pname, params));
        if (isCallValid)
        {
            context->getVertexAttribIiv(index, pname, params);
        }
        ANGLE_CAPTURE_GL(GetVertexAttribIiv, isCallValid, context, index, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

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

    if (context)
    {
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateGetVertexAttribIuiv(context, angle::EntryPoint::GLGetVertexAttribIuiv, index,
                                         pname, params));
        if (isCallValid)
        {
            context->getVertexAttribIuiv(index, pname, params);
        }
        ANGLE_CAPTURE_GL(GetVertexAttribIuiv, isCallValid, context, index, pname, params);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_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(GLESEnum::FramebufferTarget, target), numAttachments,
          (uintptr_t)attachments);

    if (context)
    {
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             (ValidatePixelLocalStorageInactive(context->getPrivateState(),
                                                context->getMutableErrorSetForValidation(),
                                                angle::EntryPoint::GLInvalidateFramebuffer) &&
              ValidateInvalidateFramebuffer(context, angle::EntryPoint::GLInvalidateFramebuffer,
                                            target, numAttachments, attachments)));
        if (isCallValid)
        {
            context->invalidateFramebuffer(target, numAttachments, attachments);
        }
        ANGLE_CAPTURE_GL(InvalidateFramebuffer, isCallValid, context, target, numAttachments,
                         attachments);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_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(GLESEnum::FramebufferTarget, target), numAttachments,
          (uintptr_t)attachments, x, y, width, height);

    if (context)
    {
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             (ValidatePixelLocalStorageInactive(context->getPrivateState(),
                                                context->getMutableErrorSetForValidation(),
                                                angle::EntryPoint::GLInvalidateSubFramebuffer) &&
              ValidateInvalidateSubFramebuffer(
                  context, angle::EntryPoint::GLInvalidateSubFramebuffer, target, numAttachments,
                  attachments, x, y, width, height)));
        if (isCallValid)
        {
            context->invalidateSubFramebuffer(target, numAttachments, attachments, x, y, width,
                                              height);
        }
        ANGLE_CAPTURE_GL(InvalidateSubFramebuffer, isCallValid, context, target, numAttachments,
                         attachments, x, y, width, height);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

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

    GLboolean returnValue;
    if (context)
    {
        QueryID idPacked = PackParam<QueryID>(id);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid = (context->skipValidation() ||
                            ValidateIsQuery(context, angle::EntryPoint::GLIsQuery, idPacked));
        if (isCallValid)
        {
            returnValue = context->isQuery(idPacked);
        }
        else
        {
            returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsQuery, GLboolean>();
        }
        ANGLE_CAPTURE_GL(IsQuery, isCallValid, context, idPacked, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
        returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsQuery, GLboolean>();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
    return returnValue;
}

GLboolean GL_APIENTRY GL_IsSampler(GLuint sampler)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLIsSampler, "context = %d, sampler = %u", CID(context), sampler);

    GLboolean returnValue;
    if (context)
    {
        SamplerID samplerPacked = PackParam<SamplerID>(sampler);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateIsSampler(context, angle::EntryPoint::GLIsSampler, samplerPacked));
        if (isCallValid)
        {
            returnValue = context->isSampler(samplerPacked);
        }
        else
        {
            returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsSampler, GLboolean>();
        }
        ANGLE_CAPTURE_GL(IsSampler, isCallValid, context, samplerPacked, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
        returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsSampler, GLboolean>();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
    return returnValue;
}

GLboolean GL_APIENTRY GL_IsSync(GLsync sync)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLIsSync, "context = %d, sync = 0x%016" PRIxPTR "", CID(context),
          (uintptr_t)sync);

    GLboolean returnValue;
    if (context)
    {
        SyncID syncPacked = PackParam<SyncID>(sync);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid = (context->skipValidation() ||
                            ValidateIsSync(context, angle::EntryPoint::GLIsSync, syncPacked));
        if (isCallValid)
        {
            returnValue = context->isSync(syncPacked);
        }
        else
        {
            returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsSync, GLboolean>();
        }
        ANGLE_CAPTURE_GL(IsSync, isCallValid, context, syncPacked, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
        returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsSync, GLboolean>();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
    return returnValue;
}

GLboolean GL_APIENTRY GL_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);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid = (context->skipValidation() ||
                            ValidateIsTransformFeedback(
                                context, angle::EntryPoint::GLIsTransformFeedback, idPacked));
        if (isCallValid)
        {
            returnValue = context->isTransformFeedback(idPacked);
        }
        else
        {
            returnValue =
                GetDefaultReturnValue<angle::EntryPoint::GLIsTransformFeedback, GLboolean>();
        }
        ANGLE_CAPTURE_GL(IsTransformFeedback, isCallValid, context, idPacked, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
        returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsTransformFeedback, GLboolean>();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
    return returnValue;
}

GLboolean GL_APIENTRY GL_IsVertexArray(GLuint array)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLIsVertexArray, "context = %d, array = %u", CID(context), array);

    GLboolean returnValue;
    if (context)
    {
        VertexArrayID arrayPacked = PackParam<VertexArrayID>(array);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateIsVertexArray(context, angle::EntryPoint::GLIsVertexArray, arrayPacked));
        if (isCallValid)
        {
            returnValue = context->isVertexArray(arrayPacked);
        }
        else
        {
            returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsVertexArray, GLboolean>();
        }
        ANGLE_CAPTURE_GL(IsVertexArray, isCallValid, context, arrayPacked, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
        returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsVertexArray, GLboolean>();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
    return returnValue;
}

void *GL_APIENTRY GL_MapBufferRange(GLenum target,
                                    GLintptr offset,
                                    GLsizeiptr length,
                                    GLbitfield access)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLMapBufferRange,
          "context = %d, target = %s, offset = %llu, length = %llu, access = %s", CID(context),
          GLenumToString(GLESEnum::BufferTargetARB, target),
          static_cast<unsigned long long>(offset), static_cast<unsigned long long>(length),
          GLbitfieldToString(GLESEnum::MapBufferAccessMask, access).c_str());

    void *returnValue;
    if (context)
    {
        BufferBinding targetPacked = PackParam<BufferBinding>(target);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid = (context->skipValidation() ||
                            ValidateMapBufferRange(context, angle::EntryPoint::GLMapBufferRange,
                                                   targetPacked, offset, length, access));
        if (isCallValid)
        {
            returnValue = context->mapBufferRange(targetPacked, offset, length, access);
        }
        else
        {
            returnValue = GetDefaultReturnValue<angle::EntryPoint::GLMapBufferRange, void *>();
        }
        ANGLE_CAPTURE_GL(MapBufferRange, isCallValid, context, targetPacked, offset, length, access,
                         returnValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
        returnValue = GetDefaultReturnValue<angle::EntryPoint::GLMapBufferRange, void *>();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
    return returnValue;
}

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

    if (context)
    {
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             (ValidatePixelLocalStorageInactive(context->getPrivateState(),
                                                context->getMutableErrorSetForValidation(),
                                                angle::EntryPoint::GLPauseTransformFeedback) &&
              ValidatePauseTransformFeedback(context,
                                             angle::EntryPoint::GLPauseTransformFeedback)));
        if (isCallValid)
        {
            context->pauseTransformFeedback();
        }
        ANGLE_CAPTURE_GL(PauseTransformFeedback, isCallValid, context);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_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(GLESEnum::AllEnums, binaryFormat),
          (uintptr_t)binary, length);

    if (context)
    {
        ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             (ValidatePixelLocalStorageInactive(context->getPrivateState(),
                                                context->getMutableErrorSetForValidation(),
                                                angle::EntryPoint::GLProgramBinary) &&
              ValidateProgramBinary(context, angle::EntryPoint::GLProgramBinary, programPacked,
                                    binaryFormat, binary, length)));
        if (isCallValid)
        {
            context->programBinary(programPacked, binaryFormat, binary, length);
        }
        ANGLE_CAPTURE_GL(ProgramBinary, isCallValid, context, programPacked, binaryFormat, binary,
                         length);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_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(GLESEnum::ProgramParameterPName, pname), value);

    if (context)
    {
        ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             (ValidatePixelLocalStorageInactive(context->getPrivateState(),
                                                context->getMutableErrorSetForValidation(),
                                                angle::EntryPoint::GLProgramParameteri) &&
              ValidateProgramParameteri(context, angle::EntryPoint::GLProgramParameteri,
                                        programPacked, pname, value)));
        if (isCallValid)
        {
            context->programParameteri(programPacked, pname, value);
        }
        ANGLE_CAPTURE_GL(ProgramParameteri, isCallValid, context, programPacked, pname, value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_ReadBuffer(GLenum src)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLReadBuffer, "context = %d, src = %s", CID(context),
          GLenumToString(GLESEnum::ReadBufferMode, src));

    if (context)
    {
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             (ValidatePixelLocalStorageInactive(context->getPrivateState(),
                                                context->getMutableErrorSetForValidation(),
                                                angle::EntryPoint::GLReadBuffer) &&
              ValidateReadBuffer(context, angle::EntryPoint::GLReadBuffer, src)));
        if (isCallValid)
        {
            context->readBuffer(src);
        }
        ANGLE_CAPTURE_GL(ReadBuffer, isCallValid, context, src);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_RenderbufferStorageMultisample(GLenum target,
                                                   GLsizei samples,
                                                   GLenum internalformat,
                                                   GLsizei width,
                                                   GLsizei height)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLRenderbufferStorageMultisample,
          "context = %d, target = %s, samples = %d, internalformat = %s, width = %d, height = %d",
          CID(context), GLenumToString(GLESEnum::RenderbufferTarget, target), samples,
          GLenumToString(GLESEnum::InternalFormat, internalformat), width, height);

    if (context)
    {
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             (ValidatePixelLocalStorageInactive(
                  context->getPrivateState(), context->getMutableErrorSetForValidation(),
                  angle::EntryPoint::GLRenderbufferStorageMultisample) &&
              ValidateRenderbufferStorageMultisample(
                  context, angle::EntryPoint::GLRenderbufferStorageMultisample, target, samples,
                  internalformat, width, height)));
        if (isCallValid)
        {
            context->renderbufferStorageMultisample(target, samples, internalformat, width, height);
        }
        ANGLE_CAPTURE_GL(RenderbufferStorageMultisample, isCallValid, context, target, samples,
                         internalformat, width, height);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

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

    if (context)
    {
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             (ValidatePixelLocalStorageInactive(context->getPrivateState(),
                                                context->getMutableErrorSetForValidation(),
                                                angle::EntryPoint::GLResumeTransformFeedback) &&
              ValidateResumeTransformFeedback(context,
                                              angle::EntryPoint::GLResumeTransformFeedback)));
        if (isCallValid)
        {
            context->resumeTransformFeedback();
        }
        ANGLE_CAPTURE_GL(ResumeTransformFeedback, isCallValid, context);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLSamplerParameterf, "context = %d, sampler = %u, pname = %s, param = %f",
          CID(context), sampler, GLenumToString(GLESEnum::SamplerParameterF, pname), param);

    if (context)
    {
        SamplerID samplerPacked = PackParam<SamplerID>(sampler);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateSamplerParameterf(context, angle::EntryPoint::GLSamplerParameterf,
                                       samplerPacked, pname, param));
        if (isCallValid)
        {
            context->samplerParameterf(samplerPacked, pname, param);
        }
        ANGLE_CAPTURE_GL(SamplerParameterf, isCallValid, context, samplerPacked, pname, param);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_SamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLSamplerParameterfv,
          "context = %d, sampler = %u, pname = %s, param = 0x%016" PRIxPTR "", CID(context),
          sampler, GLenumToString(GLESEnum::SamplerParameterF, pname), (uintptr_t)param);

    if (context)
    {
        SamplerID samplerPacked = PackParam<SamplerID>(sampler);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateSamplerParameterfv(context, angle::EntryPoint::GLSamplerParameterfv,
                                        samplerPacked, pname, param));
        if (isCallValid)
        {
            context->samplerParameterfv(samplerPacked, pname, param);
        }
        ANGLE_CAPTURE_GL(SamplerParameterfv, isCallValid, context, samplerPacked, pname, param);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_SamplerParameteri(GLuint sampler, GLenum pname, GLint param)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLSamplerParameteri, "context = %d, sampler = %u, pname = %s, param = %d",
          CID(context), sampler, GLenumToString(GLESEnum::SamplerParameterI, pname), param);

    if (context)
    {
        SamplerID samplerPacked = PackParam<SamplerID>(sampler);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateSamplerParameteri(context, angle::EntryPoint::GLSamplerParameteri,
                                       samplerPacked, pname, param));
        if (isCallValid)
        {
            context->samplerParameteri(samplerPacked, pname, param);
        }
        ANGLE_CAPTURE_GL(SamplerParameteri, isCallValid, context, samplerPacked, pname, param);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_SamplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLSamplerParameteriv,
          "context = %d, sampler = %u, pname = %s, param = 0x%016" PRIxPTR "", CID(context),
          sampler, GLenumToString(GLESEnum::SamplerParameterI, pname), (uintptr_t)param);

    if (context)
    {
        SamplerID samplerPacked = PackParam<SamplerID>(sampler);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateSamplerParameteriv(context, angle::EntryPoint::GLSamplerParameteriv,
                                        samplerPacked, pname, param));
        if (isCallValid)
        {
            context->samplerParameteriv(samplerPacked, pname, param);
        }
        ANGLE_CAPTURE_GL(SamplerParameteriv, isCallValid, context, samplerPacked, pname, param);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

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

    if (context)
    {
        TextureTarget targetPacked = PackParam<TextureTarget>(target);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             (ValidatePixelLocalStorageInactive(context->getPrivateState(),
                                                context->getMutableErrorSetForValidation(),
                                                angle::EntryPoint::GLTexImage3D) &&
              ValidateTexImage3D(context, angle::EntryPoint::GLTexImage3D, targetPacked, level,
                                 internalformat, width, height, depth, border, format, type,
                                 pixels)));
        if (isCallValid)
        {
            context->texImage3D(targetPacked, level, internalformat, width, height, depth, border,
                                format, type, pixels);
        }
        ANGLE_CAPTURE_GL(TexImage3D, isCallValid, context, targetPacked, level, internalformat,
                         width, height, depth, border, format, type, pixels);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    egl::Display::GetCurrentThreadUnlockedTailCall()->run(nullptr);
}

void GL_APIENTRY
GL_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(GLESEnum::TextureTarget, target), levels,
          GLenumToString(GLESEnum::SizedInternalFormat, internalformat), width, height);

    if (context)
    {
        TextureType targetPacked = PackParam<TextureType>(target);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             (ValidatePixelLocalStorageInactive(context->getPrivateState(),
                                                context->getMutableErrorSetForValidation(),
                                                angle::EntryPoint::GLTexStorage2D) &&
              ValidateTexStorage2D(context, angle::EntryPoint::GLTexStorage2D, targetPacked, levels,
                                   internalformat, width, height)));
        if (isCallValid)
        {
            context->texStorage2D(targetPacked, levels, internalformat, width, height);
        }
        ANGLE_CAPTURE_GL(TexStorage2D, isCallValid, context, targetPacked, levels, internalformat,
                         width, height);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_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(GLESEnum::TextureTarget, target), levels,
          GLenumToString(GLESEnum::SizedInternalFormat, internalformat), width, height, depth);

    if (context)
    {
        TextureType targetPacked = PackParam<TextureType>(target);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             (ValidatePixelLocalStorageInactive(context->getPrivateState(),
                                                context->getMutableErrorSetForValidation(),
                                                angle::EntryPoint::GLTexStorage3D) &&
              ValidateTexStorage3D(context, angle::EntryPoint::GLTexStorage3D, targetPacked, levels,
                                   internalformat, width, height, depth)));
        if (isCallValid)
        {
            context->texStorage3D(targetPacked, levels, internalformat, width, height, depth);
        }
        ANGLE_CAPTURE_GL(TexStorage3D, isCallValid, context, targetPacked, levels, internalformat,
                         width, height, depth);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

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

    if (context)
    {
        TextureTarget targetPacked = PackParam<TextureTarget>(target);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             (ValidatePixelLocalStorageInactive(context->getPrivateState(),
                                                context->getMutableErrorSetForValidation(),
                                                angle::EntryPoint::GLTexSubImage3D) &&
              ValidateTexSubImage3D(context, angle::EntryPoint::GLTexSubImage3D, targetPacked,
                                    level, xoffset, yoffset, zoffset, width, height, depth, format,
                                    type, pixels)));
        if (isCallValid)
        {
            context->texSubImage3D(targetPacked, level, xoffset, yoffset, zoffset, width, height,
                                   depth, format, type, pixels);
        }
        ANGLE_CAPTURE_GL(TexSubImage3D, isCallValid, context, targetPacked, level, xoffset, yoffset,
                         zoffset, width, height, depth, format, type, pixels);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    egl::Display::GetCurrentThreadUnlockedTailCall()->run(nullptr);
}

void GL_APIENTRY GL_TransformFeedbackVaryings(GLuint program,
                                              GLsizei count,
                                              const GLchar *const *varyings,
                                              GLenum bufferMode)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLTransformFeedbackVaryings,
          "context = %d, program = %u, count = %d, varyings = 0x%016" PRIxPTR ", bufferMode = %s",
          CID(context), program, count, (uintptr_t)varyings,
          GLenumToString(GLESEnum::TransformFeedbackBufferMode, bufferMode));

    if (context)
    {
        ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             (ValidatePixelLocalStorageInactive(context->getPrivateState(),
                                                context->getMutableErrorSetForValidation(),
                                                angle::EntryPoint::GLTransformFeedbackVaryings) &&
              ValidateTransformFeedbackVaryings(context,
                                                angle::EntryPoint::GLTransformFeedbackVaryings,
                                                programPacked, count, varyings, bufferMode)));
        if (isCallValid)
        {
            context->transformFeedbackVaryings(programPacked, count, varyings, bufferMode);
        }
        ANGLE_CAPTURE_GL(TransformFeedbackVaryings, isCallValid, context, programPacked, count,
                         varyings, bufferMode);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

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

    if (context)
    {
        UniformLocation locationPacked = PackParam<UniformLocation>(location);

        bool isCallValid =
            (context->skipValidation() ||
             ValidateUniform1ui(context, angle::EntryPoint::GLUniform1ui, locationPacked, v0));
        if (isCallValid)
        {
            context->uniform1ui(locationPacked, v0);
        }
        ANGLE_CAPTURE_GL(Uniform1ui, isCallValid, context, locationPacked, v0);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

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

    if (context)
    {
        UniformLocation locationPacked = PackParam<UniformLocation>(location);

        bool isCallValid = (context->skipValidation() ||
                            ValidateUniform1uiv(context, angle::EntryPoint::GLUniform1uiv,
                                                locationPacked, count, value));
        if (isCallValid)
        {
            context->uniform1uiv(locationPacked, count, value);
        }
        ANGLE_CAPTURE_GL(Uniform1uiv, isCallValid, context, locationPacked, count, value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

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

    if (context)
    {
        UniformLocation locationPacked = PackParam<UniformLocation>(location);

        bool isCallValid =
            (context->skipValidation() ||
             ValidateUniform2ui(context, angle::EntryPoint::GLUniform2ui, locationPacked, v0, v1));
        if (isCallValid)
        {
            context->uniform2ui(locationPacked, v0, v1);
        }
        ANGLE_CAPTURE_GL(Uniform2ui, isCallValid, context, locationPacked, v0, v1);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

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

    if (context)
    {
        UniformLocation locationPacked = PackParam<UniformLocation>(location);

        bool isCallValid = (context->skipValidation() ||
                            ValidateUniform2uiv(context, angle::EntryPoint::GLUniform2uiv,
                                                locationPacked, count, value));
        if (isCallValid)
        {
            context->uniform2uiv(locationPacked, count, value);
        }
        ANGLE_CAPTURE_GL(Uniform2uiv, isCallValid, context, locationPacked, count, value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

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

    if (context)
    {
        UniformLocation locationPacked = PackParam<UniformLocation>(location);

        bool isCallValid = (context->skipValidation() ||
                            ValidateUniform3ui(context, angle::EntryPoint::GLUniform3ui,
                                               locationPacked, v0, v1, v2));
        if (isCallValid)
        {
            context->uniform3ui(locationPacked, v0, v1, v2);
        }
        ANGLE_CAPTURE_GL(Uniform3ui, isCallValid, context, locationPacked, v0, v1, v2);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

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

    if (context)
    {
        UniformLocation locationPacked = PackParam<UniformLocation>(location);

        bool isCallValid = (context->skipValidation() ||
                            ValidateUniform3uiv(context, angle::EntryPoint::GLUniform3uiv,
                                                locationPacked, count, value));
        if (isCallValid)
        {
            context->uniform3uiv(locationPacked, count, value);
        }
        ANGLE_CAPTURE_GL(Uniform3uiv, isCallValid, context, locationPacked, count, value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

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

    if (context)
    {
        UniformLocation locationPacked = PackParam<UniformLocation>(location);

        bool isCallValid = (context->skipValidation() ||
                            ValidateUniform4ui(context, angle::EntryPoint::GLUniform4ui,
                                               locationPacked, v0, v1, v2, v3));
        if (isCallValid)
        {
            context->uniform4ui(locationPacked, v0, v1, v2, v3);
        }
        ANGLE_CAPTURE_GL(Uniform4ui, isCallValid, context, locationPacked, v0, v1, v2, v3);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

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

    if (context)
    {
        UniformLocation locationPacked = PackParam<UniformLocation>(location);

        bool isCallValid = (context->skipValidation() ||
                            ValidateUniform4uiv(context, angle::EntryPoint::GLUniform4uiv,
                                                locationPacked, count, value));
        if (isCallValid)
        {
            context->uniform4uiv(locationPacked, count, value);
        }
        ANGLE_CAPTURE_GL(Uniform4uiv, isCallValid, context, locationPacked, count, value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_UniformBlockBinding(GLuint program,
                                        GLuint uniformBlockIndex,
                                        GLuint uniformBlockBinding)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLUniformBlockBinding,
          "context = %d, program = %u, uniformBlockIndex = %u, uniformBlockBinding = %u",
          CID(context), program, uniformBlockIndex, uniformBlockBinding);

    if (context)
    {
        ShaderProgramID programPacked             = PackParam<ShaderProgramID>(program);
        UniformBlockIndex uniformBlockIndexPacked = PackParam<UniformBlockIndex>(uniformBlockIndex);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid = (context->skipValidation() ||
                            ValidateUniformBlockBinding(
                                context, angle::EntryPoint::GLUniformBlockBinding, programPacked,
                                uniformBlockIndexPacked, uniformBlockBinding));
        if (isCallValid)
        {
            context->uniformBlockBinding(programPacked, uniformBlockIndexPacked,
                                         uniformBlockBinding);
        }
        ANGLE_CAPTURE_GL(UniformBlockBinding, isCallValid, context, programPacked,
                         uniformBlockIndexPacked, uniformBlockBinding);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_UniformMatrix2x3fv(GLint location,
                                       GLsizei count,
                                       GLboolean transpose,
                                       const GLfloat *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLUniformMatrix2x3fv,
          "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);

        bool isCallValid =
            (context->skipValidation() ||
             ValidateUniformMatrix2x3fv(context, angle::EntryPoint::GLUniformMatrix2x3fv,
                                        locationPacked, count, transpose, value));
        if (isCallValid)
        {
            context->uniformMatrix2x3fv(locationPacked, count, transpose, value);
        }
        ANGLE_CAPTURE_GL(UniformMatrix2x3fv, isCallValid, context, locationPacked, count, transpose,
                         value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_UniformMatrix2x4fv(GLint location,
                                       GLsizei count,
                                       GLboolean transpose,
                                       const GLfloat *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLUniformMatrix2x4fv,
          "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);

        bool isCallValid =
            (context->skipValidation() ||
             ValidateUniformMatrix2x4fv(context, angle::EntryPoint::GLUniformMatrix2x4fv,
                                        locationPacked, count, transpose, value));
        if (isCallValid)
        {
            context->uniformMatrix2x4fv(locationPacked, count, transpose, value);
        }
        ANGLE_CAPTURE_GL(UniformMatrix2x4fv, isCallValid, context, locationPacked, count, transpose,
                         value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_UniformMatrix3x2fv(GLint location,
                                       GLsizei count,
                                       GLboolean transpose,
                                       const GLfloat *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLUniformMatrix3x2fv,
          "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);

        bool isCallValid =
            (context->skipValidation() ||
             ValidateUniformMatrix3x2fv(context, angle::EntryPoint::GLUniformMatrix3x2fv,
                                        locationPacked, count, transpose, value));
        if (isCallValid)
        {
            context->uniformMatrix3x2fv(locationPacked, count, transpose, value);
        }
        ANGLE_CAPTURE_GL(UniformMatrix3x2fv, isCallValid, context, locationPacked, count, transpose,
                         value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_UniformMatrix3x4fv(GLint location,
                                       GLsizei count,
                                       GLboolean transpose,
                                       const GLfloat *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLUniformMatrix3x4fv,
          "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);

        bool isCallValid =
            (context->skipValidation() ||
             ValidateUniformMatrix3x4fv(context, angle::EntryPoint::GLUniformMatrix3x4fv,
                                        locationPacked, count, transpose, value));
        if (isCallValid)
        {
            context->uniformMatrix3x4fv(locationPacked, count, transpose, value);
        }
        ANGLE_CAPTURE_GL(UniformMatrix3x4fv, isCallValid, context, locationPacked, count, transpose,
                         value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_UniformMatrix4x2fv(GLint location,
                                       GLsizei count,
                                       GLboolean transpose,
                                       const GLfloat *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLUniformMatrix4x2fv,
          "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);

        bool isCallValid =
            (context->skipValidation() ||
             ValidateUniformMatrix4x2fv(context, angle::EntryPoint::GLUniformMatrix4x2fv,
                                        locationPacked, count, transpose, value));
        if (isCallValid)
        {
            context->uniformMatrix4x2fv(locationPacked, count, transpose, value);
        }
        ANGLE_CAPTURE_GL(UniformMatrix4x2fv, isCallValid, context, locationPacked, count, transpose,
                         value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_UniformMatrix4x3fv(GLint location,
                                       GLsizei count,
                                       GLboolean transpose,
                                       const GLfloat *value)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLUniformMatrix4x3fv,
          "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);

        bool isCallValid =
            (context->skipValidation() ||
             ValidateUniformMatrix4x3fv(context, angle::EntryPoint::GLUniformMatrix4x3fv,
                                        locationPacked, count, transpose, value));
        if (isCallValid)
        {
            context->uniformMatrix4x3fv(locationPacked, count, transpose, value);
        }
        ANGLE_CAPTURE_GL(UniformMatrix4x3fv, isCallValid, context, locationPacked, count, transpose,
                         value);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

GLboolean GL_APIENTRY GL_UnmapBuffer(GLenum target)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLUnmapBuffer, "context = %d, target = %s", CID(context),
          GLenumToString(GLESEnum::BufferTargetARB, target));

    GLboolean returnValue;
    if (context)
    {
        BufferBinding targetPacked = PackParam<BufferBinding>(target);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateUnmapBuffer(context, angle::EntryPoint::GLUnmapBuffer, targetPacked));
        if (isCallValid)
        {
            returnValue = context->unmapBuffer(targetPacked);
        }
        else
        {
            returnValue = GetDefaultReturnValue<angle::EntryPoint::GLUnmapBuffer, GLboolean>();
        }
        ANGLE_CAPTURE_GL(UnmapBuffer, isCallValid, context, targetPacked, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
        returnValue = GetDefaultReturnValue<angle::EntryPoint::GLUnmapBuffer, GLboolean>();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
    return returnValue;
}

void GL_APIENTRY GL_VertexAttribDivisor(GLuint index, GLuint divisor)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLVertexAttribDivisor, "context = %d, index = %u, divisor = %u", CID(context),
          index, divisor);

    if (context)
    {
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid = (context->skipValidation() ||
                            ValidateVertexAttribDivisor(
                                context, angle::EntryPoint::GLVertexAttribDivisor, index, divisor));
        if (isCallValid)
        {
            context->vertexAttribDivisor(index, divisor);
        }
        ANGLE_CAPTURE_GL(VertexAttribDivisor, isCallValid, context, index, divisor);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_VertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLVertexAttribI4i, "context = %d, index = %u, x = %d, y = %d, z = %d, w = %d",
          CID(context), index, x, y, z, w);

    if (context)
    {
        bool isCallValid =
            (context->skipValidation() ||
             ValidateVertexAttribI4i(context->getPrivateState(),
                                     context->getMutableErrorSetForValidation(),
                                     angle::EntryPoint::GLVertexAttribI4i, index, x, y, z, w));
        if (isCallValid)
        {
            ContextPrivateVertexAttribI4i(context->getMutablePrivateState(),
                                          context->getMutablePrivateStateCache(), index, x, y, z,
                                          w);
        }
        ANGLE_CAPTURE_GL(VertexAttribI4i, isCallValid, context, index, x, y, z, w);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

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

    if (context)
    {
        bool isCallValid =
            (context->skipValidation() ||
             ValidateVertexAttribI4iv(context->getPrivateState(),
                                      context->getMutableErrorSetForValidation(),
                                      angle::EntryPoint::GLVertexAttribI4iv, index, v));
        if (isCallValid)
        {
            ContextPrivateVertexAttribI4iv(context->getMutablePrivateState(),
                                           context->getMutablePrivateStateCache(), index, v);
        }
        ANGLE_CAPTURE_GL(VertexAttribI4iv, isCallValid, context, index, v);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

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

    if (context)
    {
        bool isCallValid =
            (context->skipValidation() ||
             ValidateVertexAttribI4ui(context->getPrivateState(),
                                      context->getMutableErrorSetForValidation(),
                                      angle::EntryPoint::GLVertexAttribI4ui, index, x, y, z, w));
        if (isCallValid)
        {
            ContextPrivateVertexAttribI4ui(context->getMutablePrivateState(),
                                           context->getMutablePrivateStateCache(), index, x, y, z,
                                           w);
        }
        ANGLE_CAPTURE_GL(VertexAttribI4ui, isCallValid, context, index, x, y, z, w);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

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

    if (context)
    {
        bool isCallValid =
            (context->skipValidation() ||
             ValidateVertexAttribI4uiv(context->getPrivateState(),
                                       context->getMutableErrorSetForValidation(),
                                       angle::EntryPoint::GLVertexAttribI4uiv, index, v));
        if (isCallValid)
        {
            ContextPrivateVertexAttribI4uiv(context->getMutablePrivateState(),
                                            context->getMutablePrivateStateCache(), index, v);
        }
        ANGLE_CAPTURE_GL(VertexAttribI4uiv, isCallValid, context, index, v);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY
GL_VertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLVertexAttribIPointer,
          "context = %d, index = %u, size = %d, type = %s, stride = %d, pointer = 0x%016" PRIxPTR
          "",
          CID(context), index, size, GLenumToString(GLESEnum::VertexAttribIType, type), stride,
          (uintptr_t)pointer);

    if (context)
    {
        VertexAttribType typePacked = PackParam<VertexAttribType>(type);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateVertexAttribIPointer(context, angle::EntryPoint::GLVertexAttribIPointer, index,
                                          size, typePacked, stride, pointer));
        if (isCallValid)
        {
            context->vertexAttribIPointer(index, size, typePacked, stride, pointer);
        }
        ANGLE_CAPTURE_GL(VertexAttribIPointer, isCallValid, context, index, size, typePacked,
                         stride, pointer);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

void GL_APIENTRY GL_WaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, GLWaitSync, "context = %d, sync = 0x%016" PRIxPTR ", flags = %s, timeout = %llu",
          CID(context), (uintptr_t)sync,
          GLbitfieldToString(GLESEnum::SyncBehaviorFlags, flags).c_str(),
          static_cast<unsigned long long>(timeout));

    if (context)
    {
        SyncID syncPacked = PackParam<SyncID>(sync);
        SCOPED_SHARE_CONTEXT_LOCK(context);
        bool isCallValid =
            (context->skipValidation() ||
             (ValidatePixelLocalStorageInactive(context->getPrivateState(),
                                                context->getMutableErrorSetForValidation(),
                                                angle::EntryPoint::GLWaitSync) &&
              ValidateWaitSync(context, angle::EntryPoint::GLWaitSync, syncPacked, flags,
                               timeout)));
        if (isCallValid)
        {
            context->waitSync(syncPacked, flags, timeout);
        }
        ANGLE_CAPTURE_GL(WaitSync, isCallValid, context, syncPacked, flags, timeout);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
    ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());
}

}  // extern "C"
