// GENERATED FILE - DO NOT EDIT.
// Generated by generate_entry_points.py using data from gl.xml.
//
// Copyright 2020 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// entry_points_gl_1_1_autogen.cpp:
//   Defines the GL 1.1 entry points.

#include "libGL/entry_points_gl_1_1_autogen.h"

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

namespace gl
{
GLboolean GL_APIENTRY AreTexturesResident(GLsizei n, const GLuint *textures, GLboolean *residences)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::AreTexturesResident, "glAreTexturesResident",
          "context = %d, n = %d, textures = 0x%016" PRIxPTR ", residences = 0x%016" PRIxPTR "",
          CID(context), n, (uintptr_t)textures, (uintptr_t)residences);

    GLboolean returnValue;
    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateAreTexturesResident(context, n, textures, residences));
        if (isCallValid)
        {
            returnValue = context->areTexturesResident(n, textures, residences);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::AreTexturesResident, GLboolean>();
        }
        ANGLE_CAPTURE(AreTexturesResident, isCallValid, context, n, textures, residences,
                      returnValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
        returnValue = GetDefaultReturnValue<EntryPoint::AreTexturesResident, GLboolean>();
    }
    return returnValue;
}

void GL_APIENTRY ArrayElement(GLint i)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::ArrayElement, "glArrayElement", "context = %d, i = %d",
          CID(context), i);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateArrayElement(context, i));
        if (isCallValid)
        {
            context->arrayElement(i);
        }
        ANGLE_CAPTURE(ArrayElement, isCallValid, context, i);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

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

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

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

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

void GL_APIENTRY CopyTexImage1D(GLenum target,
                                GLint level,
                                GLenum internalformat,
                                GLint x,
                                GLint y,
                                GLsizei width,
                                GLint border)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::CopyTexImage1D, "glCopyTexImage1D",
          "context = %d, target = %s, level = %d, internalformat = %s, x = %d, y = %d, width = %d, "
          "border = %d",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), level,
          GLenumToString(GLenumGroup::InternalFormat, internalformat), x, y, width, border);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateCopyTexImage1D(context, target, level, internalformat, x, y, width, border));
        if (isCallValid)
        {
            context->copyTexImage1D(target, level, internalformat, x, y, width, border);
        }
        ANGLE_CAPTURE(CopyTexImage1D, isCallValid, context, target, level, internalformat, x, y,
                      width, border);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

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

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

void GL_APIENTRY
CopyTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::CopyTexSubImage1D, "glCopyTexSubImage1D",
          "context = %d, target = %s, level = %d, xoffset = %d, x = %d, y = %d, width = %d",
          CID(context), GLenumToString(GLenumGroup::TextureTarget, target), level, xoffset, x, y,
          width);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateCopyTexSubImage1D(context, target, level, xoffset, x, y, width));
        if (isCallValid)
        {
            context->copyTexSubImage1D(target, level, xoffset, x, y, width);
        }
        ANGLE_CAPTURE(CopyTexSubImage1D, isCallValid, context, target, level, xoffset, x, y, width);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

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

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

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

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

void GL_APIENTRY DisableClientState(GLenum array)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::DisableClientState, "glDisableClientState",
          "context = %d, array = %s", CID(context), GLenumToString(GLenumGroup::EnableCap, array));

    if (context)
    {
        ClientVertexArrayType arrayPacked = FromGL<ClientVertexArrayType>(array);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateDisableClientState(context, arrayPacked));
        if (isCallValid)
        {
            context->disableClientState(arrayPacked);
        }
        ANGLE_CAPTURE(DisableClientState, isCallValid, context, arrayPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

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

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

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

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

void GL_APIENTRY EdgeFlagPointer(GLsizei stride, const void *pointer)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::EdgeFlagPointer, "glEdgeFlagPointer",
          "context = %d, stride = %d, pointer = 0x%016" PRIxPTR "", CID(context), stride,
          (uintptr_t)pointer);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateEdgeFlagPointer(context, stride, pointer));
        if (isCallValid)
        {
            context->edgeFlagPointer(stride, pointer);
        }
        ANGLE_CAPTURE(EdgeFlagPointer, isCallValid, context, stride, pointer);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY EnableClientState(GLenum array)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::EnableClientState, "glEnableClientState",
          "context = %d, array = %s", CID(context), GLenumToString(GLenumGroup::EnableCap, array));

    if (context)
    {
        ClientVertexArrayType arrayPacked = FromGL<ClientVertexArrayType>(array);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateEnableClientState(context, arrayPacked));
        if (isCallValid)
        {
            context->enableClientState(arrayPacked);
        }
        ANGLE_CAPTURE(EnableClientState, isCallValid, context, arrayPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

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

    if (context)
    {
        TextureID *texturesPacked                             = FromGL<TextureID *>(textures);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() || ValidateGenTextures(context, n, texturesPacked));
        if (isCallValid)
        {
            context->genTextures(n, texturesPacked);
        }
        ANGLE_CAPTURE(GenTextures, isCallValid, context, n, texturesPacked);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

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

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

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

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

void GL_APIENTRY Indexub(GLubyte c)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::Indexub, "glIndexub", "context = %d, c = %d", CID(context), c);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateIndexub(context, c));
        if (isCallValid)
        {
            context->indexub(c);
        }
        ANGLE_CAPTURE(Indexub, isCallValid, context, c);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY Indexubv(const GLubyte *c)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::Indexubv, "glIndexubv", "context = %d, c = 0x%016" PRIxPTR "",
          CID(context), (uintptr_t)c);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateIndexubv(context, c));
        if (isCallValid)
        {
            context->indexubv(c);
        }
        ANGLE_CAPTURE(Indexubv, isCallValid, context, c);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY InterleavedArrays(GLenum format, GLsizei stride, const void *pointer)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::InterleavedArrays, "glInterleavedArrays",
          "context = %d, format = %s, stride = %d, pointer = 0x%016" PRIxPTR "", CID(context),
          GLenumToString(GLenumGroup::InterleavedArrayFormat, format), stride, (uintptr_t)pointer);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateInterleavedArrays(context, format, stride, pointer));
        if (isCallValid)
        {
            context->interleavedArrays(format, stride, pointer);
        }
        ANGLE_CAPTURE(InterleavedArrays, isCallValid, context, format, stride, pointer);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

GLboolean GL_APIENTRY IsTexture(GLuint texture)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::IsTexture, "glIsTexture", "context = %d, texture = %u",
          CID(context), texture);

    GLboolean returnValue;
    if (context)
    {
        TextureID texturePacked                               = FromGL<TextureID>(texture);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidateIsTexture(context, texturePacked));
        if (isCallValid)
        {
            returnValue = context->isTexture(texturePacked);
        }
        else
        {
            returnValue = GetDefaultReturnValue<EntryPoint::IsTexture, GLboolean>();
        }
        ANGLE_CAPTURE(IsTexture, isCallValid, context, texturePacked, returnValue);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
        returnValue = GetDefaultReturnValue<EntryPoint::IsTexture, GLboolean>();
    }
    return returnValue;
}

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

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

void GL_APIENTRY PolygonOffset(GLfloat factor, GLfloat units)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::PolygonOffset, "glPolygonOffset",
          "context = %d, factor = %f, units = %f", CID(context), factor, units);

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

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

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

void GL_APIENTRY PrioritizeTextures(GLsizei n, const GLuint *textures, const GLfloat *priorities)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::PrioritizeTextures, "glPrioritizeTextures",
          "context = %d, n = %d, textures = 0x%016" PRIxPTR ", priorities = 0x%016" PRIxPTR "",
          CID(context), n, (uintptr_t)textures, (uintptr_t)priorities);

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidatePrioritizeTextures(context, n, textures, priorities));
        if (isCallValid)
        {
            context->prioritizeTextures(n, textures, priorities);
        }
        ANGLE_CAPTURE(PrioritizeTextures, isCallValid, context, n, textures, priorities);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

void GL_APIENTRY PushClientAttrib(GLbitfield mask)
{
    Context *context = GetValidGlobalContext();
    EVENT(context, gl::EntryPoint::PushClientAttrib, "glPushClientAttrib",
          "context = %d, mask = %s", CID(context),
          GLbitfieldToString(GLenumGroup::ClientAttribMask, mask).c_str());

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid = (context->skipValidation() || ValidatePushClientAttrib(context, mask));
        if (isCallValid)
        {
            context->pushClientAttrib(mask);
        }
        ANGLE_CAPTURE(PushClientAttrib, isCallValid, context, mask);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

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

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

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

    if (context)
    {
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid =
            (context->skipValidation() ||
             ValidateTexSubImage1D(context, target, level, xoffset, width, format, type, pixels));
        if (isCallValid)
        {
            context->texSubImage1D(target, level, xoffset, width, format, type, pixels);
        }
        ANGLE_CAPTURE(TexSubImage1D, isCallValid, context, target, level, xoffset, width, format,
                      type, pixels);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}

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

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

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

    if (context)
    {
        VertexAttribType typePacked                           = FromGL<VertexAttribType>(type);
        std::unique_lock<angle::GlobalMutex> shareContextLock = GetShareGroupLock(context);
        bool isCallValid                                      = (context->skipValidation() ||
                            ValidateVertexPointer(context, size, typePacked, stride, pointer));
        if (isCallValid)
        {
            context->vertexPointer(size, typePacked, stride, pointer);
        }
        ANGLE_CAPTURE(VertexPointer, isCallValid, context, size, typePacked, stride, pointer);
    }
    else
    {
        GenerateContextLostErrorOnCurrentGlobalContext();
    }
}
}  // namespace gl
