//
// Copyright 2013 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.
//

// validationES.h: Validation functions for generic OpenGL ES entry point parameters

#ifndef LIBANGLE_VALIDATION_ES_H_
#define LIBANGLE_VALIDATION_ES_H_

#include "common/PackedEnums.h"
#include "common/mathutil.h"
#include "common/utilities.h"
#include "libANGLE/Context.h"
#include "libANGLE/ErrorStrings.h"
#include "libANGLE/Framebuffer.h"
#include "libANGLE/VertexArray.h"

#include <GLES2/gl2.h>
#include <GLES3/gl3.h>
#include <GLES3/gl31.h>

namespace egl
{
class Display;
class Image;
}  // namespace egl

namespace gl
{
class Context;
struct Format;
class Framebuffer;
struct LinkedUniform;
class Program;
class Shader;

enum class TexImageDimension
{
    _2D,
    _3D,
};

#define ANGLE_VALIDATION_ERROR(errorCode, message) \
    context->getMutableErrorSetForValidation()->validationError(entryPoint, errorCode, message)
#define ANGLE_VALIDATION_ERRORF(errorCode, ...)                                     \
    ANGLE_UNSAFE_TODO(context->getMutableErrorSetForValidation()->validationErrorF( \
        entryPoint, errorCode, __VA_ARGS__))

bool ValidTextureTarget(const Context *context, TextureType type);
bool ValidTexture2DTarget(const Context *context, TextureType type);
bool ValidTexture3DTarget(const Context *context, TextureType target);
bool ValidTextureExternalTarget(const Context *context, TextureType target);
bool ValidTextureExternalTarget(const Context *context, TextureTarget target);
bool ValidTexture2DDestinationTarget(const Context *context, TextureTarget target);
bool ValidTexture3DDestinationTarget(const Context *context, TextureTarget target);
bool ValidFramebufferTarget(const Context *context, GLenum target);
bool ValidMipLevel(const Context *context, TextureType type, GLint level);
bool ValidImageSizeParameters(const Context *context,
                              angle::EntryPoint entryPoint,
                              TextureType target,
                              GLint level,
                              GLsizei width,
                              GLsizei height,
                              GLsizei depth,
                              bool isSubImage);
bool ValidCompressedFormatForTexture2DArray(GLenum format, const Extensions &extensions);
bool ValidCompressedFormatForTexture3D(GLenum format, const Extensions &extensions);
bool ValidCompressedImageSize(const Context *context,
                              GLenum internalFormat,
                              GLint level,
                              GLsizei width,
                              GLsizei height,
                              GLsizei depth);
bool ValidImageDataSize(const Context *context,
                        angle::EntryPoint entryPoint,
                        TextureType texType,
                        GLsizei width,
                        GLsizei height,
                        GLsizei depth,
                        GLenum format,
                        GLenum type,
                        const void *pixels,
                        GLuint *outImageSize);
bool ValidImageAllocationSize(const Context *context,
                              angle::EntryPoint entryPoint,
                              GLsizei width,
                              GLsizei height,
                              GLsizei depth,
                              GLsizei samples,
                              GLenum sizedInternalFormat);

bool ValidQueryType(const Context *context, QueryType queryType);

bool ValidateWebGLVertexAttribPointer(const Context *context,
                                      angle::EntryPoint entryPoint,
                                      VertexAttribType type,
                                      GLboolean normalized,
                                      GLsizei stride,
                                      const void *ptr,
                                      bool pureInteger);

bool ValidateWebGLBufferBinding(const Context *context,
                                angle::EntryPoint entryPoint,
                                BufferBinding target,
                                BufferID buffer);

// Validation of transform feedback buffer output size for various DrawArrays calls.
// `primcounts` can be null for non-instanced calls.
// If this function returns false, an error has been generated.
bool ValidateDrawArraysTransformFeedbackBufferSize(const Context *context,
                                                   angle::EntryPoint entryPoint,
                                                   const GLsizei *counts,
                                                   const GLsizei *primcounts,
                                                   GLsizei drawcount);

// Returns valid program if id is a valid program name
// Errors INVALID_OPERATION if valid shader is given and returns NULL
// Errors INVALID_VALUE otherwise and returns NULL
Program *GetValidProgram(const Context *context, angle::EntryPoint entryPoint, ShaderProgramID id);

// Returns valid shader if id is a valid shader name
// Errors INVALID_OPERATION if valid program is given and returns NULL
// Errors INVALID_VALUE otherwise and returns NULL
Shader *GetValidShader(const Context *context, angle::EntryPoint entryPoint, ShaderProgramID id);

bool ValidateAttachmentTarget(const Context *context,
                              angle::EntryPoint entryPoint,
                              GLenum attachment);

bool ValidateBlitFramebufferParameters(const Context *context,
                                       angle::EntryPoint entryPoint,
                                       GLint srcX0,
                                       GLint srcY0,
                                       GLint srcX1,
                                       GLint srcY1,
                                       GLint dstX0,
                                       GLint dstY0,
                                       GLint dstX1,
                                       GLint dstY1,
                                       GLbitfield mask,
                                       GLenum filter);

bool ValidateBindFramebufferBase(const Context *context,
                                 angle::EntryPoint entryPoint,
                                 GLenum target,
                                 FramebufferID framebuffer);
bool ValidateBindRenderbufferBase(const Context *context,
                                  angle::EntryPoint entryPoint,
                                  GLenum target,
                                  RenderbufferID renderbuffer);
bool ValidateFramebufferParameteriBase(const Context *context,
                                       angle::EntryPoint entryPoint,
                                       GLenum target,
                                       FramebufferParameter pnamePacked,
                                       GLint param);
bool ValidateFramebufferRenderbufferBase(const Context *context,
                                         angle::EntryPoint entryPoint,
                                         GLenum target,
                                         GLenum attachment,
                                         GLenum renderbuffertarget,
                                         RenderbufferID renderbuffer);
bool ValidateFramebufferTextureBase(const Context *context,
                                    angle::EntryPoint entryPoint,
                                    GLenum target,
                                    GLenum attachment,
                                    TextureID texture,
                                    GLint level);
bool ValidateGenerateMipmapBase(const Context *context,
                                angle::EntryPoint entryPoint,
                                TextureType target);

bool ValidateRenderbufferStorageParametersBase(const Context *context,
                                               angle::EntryPoint entryPoint,
                                               GLenum target,
                                               GLsizei samples,
                                               GLenum internalformat,
                                               GLsizei width,
                                               GLsizei height);

bool ValidatePixelPack(const Context *context,
                       angle::EntryPoint entryPoint,
                       GLenum format,
                       GLenum type,
                       GLsizei width,
                       GLsizei height,
                       GLsizei bufSize,
                       const void *pixels);

bool ValidateReadPixelsBase(const Context *context,
                            angle::EntryPoint entryPoint,
                            GLint x,
                            GLint y,
                            GLsizei width,
                            GLsizei height,
                            GLenum format,
                            GLenum type,
                            GLsizei bufSize,
                            const void *pixels);
bool ValidateBeginQueryBase(const Context *context,
                            angle::EntryPoint entryPoint,
                            QueryType target,
                            QueryID id);
bool ValidateEndQueryBase(const Context *context, angle::EntryPoint entryPoint, QueryType target);
bool ValidateGetQueryivBase(const Context *context,
                            angle::EntryPoint entryPoint,
                            QueryType targetPacked,
                            QueryParameter pnamePacked,
                            GLsizei *outNumParams);
bool ValidateGetQueryObjectBase(const Context *context,
                                angle::EntryPoint entryPoint,
                                QueryID idPacked,
                                QueryObjectParameter pnamePacked,
                                GLsizei *outNumParams);

ANGLE_INLINE bool ValidateUniformCommonBase(const Context *context,
                                            angle::EntryPoint entryPoint,
                                            const Program *program,
                                            UniformLocation location,
                                            GLsizei count,
                                            const LinkedUniform **uniformOut)
{
    // TODO(Jiajia): Add image uniform check in future.
    if (ANGLE_UNLIKELY(count < 0))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, err::kNegativeCount);
        return false;
    }

    if (ANGLE_UNLIKELY(!program))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, err::kInvalidProgramName);
        return false;
    }

    if (ANGLE_UNLIKELY(!program->isLinked()))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, err::kProgramNotLinked);
        return false;
    }

    if (location.value == -1)
    {
        return true;  // no-op
    }

    const ProgramExecutable &executable = program->getExecutable();
    const auto &uniformLocations        = executable.getUniformLocations();
    size_t castedLocation               = static_cast<size_t>(location.value);
    if (ANGLE_UNLIKELY(castedLocation >= uniformLocations.size()))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, err::kInvalidUniformLocation);
        return false;
    }

    const auto &uniformLocation = uniformLocations[castedLocation];
    if (uniformLocation.ignored)
    {
        return true;  // no-op
    }

    if (ANGLE_UNLIKELY(!uniformLocation.used()))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, err::kInvalidUniformLocation);
        return false;
    }

    const LinkedUniform &uniform = executable.getUniformByIndex(uniformLocation.index);

    // attempting to write an array to a non-array uniform is an INVALID_OPERATION
    if (ANGLE_UNLIKELY(count > 1) && ANGLE_UNLIKELY(!uniform.isArray()))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, err::kInvalidUniformCount);
        return false;
    }

    *uniformOut = &uniform;
    return true;
}

bool ValidateUniform1ivValue(const Context *context,
                             angle::EntryPoint entryPoint,
                             GLenum uniformType,
                             GLsizei count,
                             const GLint *value);

ANGLE_INLINE bool ValidateUniformValue(const Context *context,
                                       angle::EntryPoint entryPoint,
                                       GLenum valueType,
                                       GLenum uniformType)
{
    // Check that the value type is compatible with uniform type.
    // Do the cheaper test first, for a little extra speed.
    if (ANGLE_UNLIKELY(valueType != uniformType) &&
        ANGLE_UNLIKELY(VariableBoolVectorType(valueType) != uniformType))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, err::kUniformSizeMismatch);
        return false;
    }
    return true;
}

template <typename ParamType>
ANGLE_INLINE bool ValidateUniformValuePointer(const Context *context,
                                              angle::EntryPoint entryPoint,
                                              const ParamType *value)
{
    if (ANGLE_UNLIKELY(value == nullptr))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, err::kInvalidUniformValuePointer);
        return false;
    }

    return true;
}

template bool ValidateUniformValuePointer(const Context *, angle::EntryPoint, const GLfloat *);
template bool ValidateUniformValuePointer(const Context *, angle::EntryPoint, const GLint *);
template bool ValidateUniformValuePointer(const Context *, angle::EntryPoint, const GLuint *);

bool ValidateUniformMatrixValue(const Context *context,
                                angle::EntryPoint entryPoint,
                                GLenum valueType,
                                GLenum uniformType);
bool ValidateUniform(const Context *context,
                     angle::EntryPoint entryPoint,
                     GLenum uniformType,
                     UniformLocation location,
                     GLsizei count);
bool ValidateUniformMatrix(const Context *context,
                           angle::EntryPoint entryPoint,
                           GLenum matrixType,
                           UniformLocation location,
                           GLsizei count,
                           GLboolean transpose);
bool ValidateStateQuery(const Context *context,
                        angle::EntryPoint entryPoint,
                        GLenum pname,
                        const void *data,
                        GLsizei *outNumParams);
bool ValidateRobustStateQuery(const Context *context,
                              angle::EntryPoint entryPoint,
                              GLenum pname,
                              GLsizei paramCount,
                              const void *data);

bool ValidateCopyImageSubDataBase(const Context *context,
                                  angle::EntryPoint entryPoint,
                                  GLuint srcName,
                                  GLenum srcTarget,
                                  GLint srcLevel,
                                  GLint srcX,
                                  GLint srcY,
                                  GLint srcZ,
                                  GLuint dstName,
                                  GLenum dstTarget,
                                  GLint dstLevel,
                                  GLint dstX,
                                  GLint dstY,
                                  GLint dstZ,
                                  GLsizei srcWidth,
                                  GLsizei srcHeight,
                                  GLsizei srcDepth);

bool ValidateCopyTexImageParametersBase(const Context *context,
                                        angle::EntryPoint entryPoint,
                                        TextureTarget target,
                                        GLint level,
                                        GLenum internalformat,
                                        bool isSubImage,
                                        GLint xoffset,
                                        GLint yoffset,
                                        GLint zoffset,
                                        GLint x,
                                        GLint y,
                                        GLsizei width,
                                        GLsizei height,
                                        GLint border,
                                        Format *textureFormatOut);

void RecordDrawModeError(const Context *context, angle::EntryPoint entryPoint, PrimitiveMode mode);
const char *ValidateDrawElementsStates(const Context *context);

ANGLE_INLINE bool ValidateDrawBase(const Context *context,
                                   angle::EntryPoint entryPoint,
                                   PrimitiveMode mode)
{
    intptr_t drawStatesError = context->getStateCache().getBasicDrawStatesErrorString(
        context, &context->getPrivateStateCache());
    if (ANGLE_UNLIKELY(drawStatesError))
    {
        const char *errorMessage = reinterpret_cast<const char *>(drawStatesError);
        GLenum errorCode         = context->getStateCache().getBasicDrawElementsErrorCode();
        ANGLE_VALIDATION_ERROR(errorCode, errorMessage);
        return false;
    }

    if (ANGLE_UNLIKELY(!context->getStateCache().isValidDrawMode(mode)))
    {
        RecordDrawModeError(context, entryPoint, mode);
        return false;
    }

    return true;
}

bool ValidateDrawArraysInstancedBase(const Context *context,
                                     angle::EntryPoint entryPoint,
                                     PrimitiveMode mode,
                                     GLint first,
                                     GLsizei count,
                                     GLsizei primcount,
                                     GLuint baseinstance);

bool ValidateDrawElementsInstancedBase(const Context *context,
                                       angle::EntryPoint entryPoint,
                                       PrimitiveMode mode,
                                       GLsizei count,
                                       DrawElementsType type,
                                       const void *indices,
                                       GLsizei primcount,
                                       GLuint baseinstance);

bool ValidateDrawInstancedANGLE(const Context *context, angle::EntryPoint entryPoint);

bool ValidateGetUniformBase(const Context *context,
                            angle::EntryPoint entryPoint,
                            ShaderProgramID programPacked,
                            UniformLocation locationPacked);
bool ValidateSizedGetUniform(const Context *context,
                             angle::EntryPoint entryPoint,
                             ShaderProgramID programPacked,
                             UniformLocation locationPacked,
                             GLsizei bufSize);

bool ValidateDiscardFramebufferBase(const Context *context,
                                    angle::EntryPoint entryPoint,
                                    GLenum target,
                                    GLsizei numAttachments,
                                    const GLenum *attachments,
                                    bool defaultFramebuffer);

bool ValidateEGLImageObject(const Context *context,
                            angle::EntryPoint entryPoint,
                            TextureType type,
                            egl::ImageID image);

bool ValidateProgramBinaryBase(const Context *context,
                               angle::EntryPoint entryPoint,
                               ShaderProgramID program,
                               GLenum binaryFormat,
                               const void *binary,
                               GLint length);
bool ValidateGetProgramBinaryBase(const Context *context,
                                  angle::EntryPoint entryPoint,
                                  ShaderProgramID program,
                                  GLsizei bufSize,
                                  const GLsizei *length,
                                  const GLenum *binaryFormat,
                                  const void *binary);

bool ValidateDrawBuffersBase(const Context *context,
                             angle::EntryPoint entryPoint,
                             GLsizei n,
                             const GLenum *bufs);

bool ValidateGetBufferPointervBase(const Context *context,
                                   angle::EntryPoint entryPoint,
                                   BufferBinding targetPacked,
                                   GLenum pname,
                                   GLsizei *outNumParams);
bool ValidateUnmapBufferBase(const Context *context,
                             angle::EntryPoint entryPoint,
                             BufferBinding target);
bool ValidateMapBufferRangeBase(const Context *context,
                                angle::EntryPoint entryPoint,
                                BufferBinding target,
                                GLintptr offset,
                                GLsizeiptr length,
                                GLbitfield access);
bool ValidateFlushMappedBufferRangeBase(const Context *context,
                                        angle::EntryPoint entryPoint,
                                        BufferBinding target,
                                        GLintptr offset,
                                        GLsizeiptr length);

bool ValidateGenOrDelete(ErrorSet *errors, angle::EntryPoint entryPoint, GLint n, const void *ids);

bool ValidateRobustTexImage(const Context *context,
                            angle::EntryPoint entryPoint,
                            const void *pixels,
                            GLuint imageSize,
                            GLsizei bufSize);
bool ValidateRobustParamCount(const Context *context,
                              angle::EntryPoint entryPoint,
                              GLsizei paramCount,
                              GLsizei numParams);

bool ValidateGetFramebufferAttachmentParameterivBase(const Context *context,
                                                     angle::EntryPoint entryPoint,
                                                     GLenum target,
                                                     GLenum attachment,
                                                     GLenum pname,
                                                     GLsizei *outNumParams);

bool ValidateGetFramebufferParameterivBase(const Context *context,
                                           angle::EntryPoint entryPoint,
                                           GLenum target,
                                           FramebufferParameter pnamePacked,
                                           const GLint *params);

bool ValidateGetBufferParameterBase(const Context *context,
                                    angle::EntryPoint entryPoint,
                                    BufferBinding targetPacked,
                                    BufferParam pnamePacked,
                                    GLsizei *outNumParams);

bool ValidateGetProgramivBase(const Context *context,
                              angle::EntryPoint entryPoint,
                              ShaderProgramID programPacked,
                              GLenum pname,
                              GLsizei *outNumParams);

bool ValidateGetRenderbufferParameterivBase(const Context *context,
                                            angle::EntryPoint entryPoint,
                                            GLenum target,
                                            GLenum pname,
                                            GLsizei *outNumParams);

bool ValidateGetShaderivBase(const Context *context,
                             angle::EntryPoint entryPoint,
                             ShaderProgramID shaderPacked,
                             ShaderParameter pnamePacked,
                             const GLint *params,
                             GLsizei *outNumParams);

bool ValidateGetTexParameterBase(const Context *context,
                                 angle::EntryPoint entryPoint,
                                 TextureType targetPacked,
                                 GLenum pname,
                                 GLsizei *outNumParams);

template <typename ParamType>
bool ValidateTexParameterBase(const Context *context,
                              angle::EntryPoint entryPoint,
                              TextureType targetPacked,
                              GLenum pname,
                              const ParamType *params);

bool ValidateGetVertexAttribBase(const Context *context,
                                 angle::EntryPoint entryPoint,
                                 GLuint index,
                                 GLenum pname,
                                 GLsizei *outNumParams);

bool ValidateGetVertexAttribPointerBase(const Context *context,
                                        angle::EntryPoint entryPoint,
                                        GLuint index,
                                        GLenum pname,
                                        GLsizei *outNumParams);

ANGLE_INLINE bool ValidateVertexFormat(const PrivateState &privateState,
                                       ErrorSet *errors,
                                       angle::EntryPoint entryPoint,
                                       GLuint index,
                                       GLint size,
                                       VertexAttribTypeCase validation)
{
    const Caps &caps = privateState.getCaps();
    if (ANGLE_UNLIKELY(index >= static_cast<GLuint>(caps.maxVertexAttributes)))
    {
        errors->validationError(entryPoint, GL_INVALID_VALUE, err::kIndexExceedsMaxVertexAttribute);
        return false;
    }

    switch (validation)
    {
        case VertexAttribTypeCase::Invalid:
            errors->validationError(entryPoint, GL_INVALID_ENUM, err::kInvalidType);
            return false;
        case VertexAttribTypeCase::Valid:
            if (size < 1 || size > 4)
            {
                errors->validationError(entryPoint, GL_INVALID_VALUE, err::kInvalidVertexAttrSize);
                return false;
            }
            break;
        case VertexAttribTypeCase::ValidSize4Only:
            if (size != 4)
            {
                errors->validationError(entryPoint, GL_INVALID_OPERATION,
                                        err::kInvalidVertexAttribSize2101010);
                return false;
            }
            break;
        case VertexAttribTypeCase::ValidSize3or4:
            if (size != 3 && size != 4)
            {
                errors->validationError(entryPoint, GL_INVALID_OPERATION,
                                        err::kInvalidVertexAttribSize1010102);
                return false;
            }
            break;
    }

    return true;
}

// Note: These byte, short, and int types are all converted to float for the shader.
ANGLE_INLINE bool ValidateFloatVertexFormat(const PrivateState &privateState,
                                            const PrivateStateCache &privateStateCache,
                                            ErrorSet *errors,
                                            angle::EntryPoint entryPoint,
                                            GLuint index,
                                            GLint size,
                                            VertexAttribType type)
{
    return ValidateVertexFormat(privateState, errors, entryPoint, index, size,
                                privateStateCache.getVertexAttribTypeValidation(type));
}

ANGLE_INLINE bool ValidateIntegerVertexFormat(const PrivateState &privateState,
                                              const PrivateStateCache &privateStateCache,
                                              ErrorSet *errors,
                                              angle::EntryPoint entryPoint,
                                              GLuint index,
                                              GLint size,
                                              VertexAttribType type)
{
    return ValidateVertexFormat(privateState, errors, entryPoint, index, size,
                                privateStateCache.getIntegerVertexAttribTypeValidation(type));
}

ANGLE_INLINE bool ValidateColorMasksForSharedExponentColorBuffers(const BlendStateExt &blendState,
                                                                  const Framebuffer *framebuffer)
{
    // Get a mask of draw buffers that have color writemasks
    // incompatible with shared exponent color buffers.
    // The compatible writemasks are RGBA and 0000.
    const DrawBufferMask incompatibleDiffMask =
        BlendStateExt::ColorMaskStorage::GetDiffMask(blendState.getColorMaskBits(), 0) &
        BlendStateExt::ColorMaskStorage::GetDiffMask(blendState.getColorMaskBits(),
                                                     blendState.getAllColorMaskBits());

    const DrawBufferMask sharedExponentBufferMask =
        framebuffer->getActiveSharedExponentColorAttachmentDrawBufferMask();
    return (sharedExponentBufferMask & incompatibleDiffMask).none();
}

bool ValidateVertexAttribIndex(const PrivateState &state,
                               ErrorSet *errors,
                               angle::EntryPoint entryPoint,
                               GLuint index);

bool ValidateGetActiveUniformBlockivBase(const Context *context,
                                         angle::EntryPoint entryPoint,
                                         ShaderProgramID programPacked,
                                         UniformBlockIndex uniformBlockIndexPacked,
                                         UniformBlockParameter pnamePacked,
                                         GLsizei *outNumParams);

bool ValidateGetSamplerParameterBase(const Context *context,
                                     angle::EntryPoint entryPoint,
                                     SamplerID samplerPacked,
                                     SamplerParameter pnamePacked,
                                     const void *params,
                                     GLsizei *outNumParams);

template <typename ParamType>
bool ValidateSamplerParameterBase(const Context *context,
                                  angle::EntryPoint entryPoint,
                                  SamplerID samplerPacked,
                                  SamplerParameter pnamePacked,
                                  const ParamType *params);

bool ValidateGetInternalFormativBase(const Context *context,
                                     angle::EntryPoint entryPoint,
                                     GLenum target,
                                     GLenum internalformat,
                                     GLenum pname,
                                     GLsizei count,
                                     GLsizei *outNumParams);

bool ValidateFramebufferNotMultisampled(const Context *context,
                                        angle::EntryPoint entryPoint,
                                        const Framebuffer *framebuffer,
                                        bool checkReadBufferResourceSamples);

bool ValidateMultitextureUnit(const PrivateState &state,
                              ErrorSet *errors,
                              angle::EntryPoint entryPoint,
                              GLenum texture);

bool ValidateTransformFeedbackPrimitiveMode(const Context *context,
                                            angle::EntryPoint entryPoint,
                                            PrimitiveMode transformFeedbackPrimitiveMode,
                                            PrimitiveMode renderPrimitiveMode);

bool ValidateTexStorage(const Context *context,
                        angle::EntryPoint entryPoint,
                        TextureType targetPacked,
                        GLsizei levels,
                        GLenum internalformat,
                        GLsizei width,
                        GLsizei height,
                        GLsizei depth,
                        TexImageDimension texImageDimension);

// Common validation for 2D and 3D variants of TexStorage*Multisample.
bool ValidateTexStorageMultisample(const Context *context,
                                   angle::EntryPoint entryPoint,
                                   TextureType target,
                                   GLsizei samples,
                                   GLint internalFormat,
                                   GLsizei width,
                                   GLsizei height,
                                   GLsizei depth);

bool ValidateTexStorage2DMultisampleBase(const Context *context,
                                         angle::EntryPoint entryPoint,
                                         TextureType target,
                                         GLsizei samples,
                                         GLint internalFormat,
                                         GLsizei width,
                                         GLsizei height);

bool ValidateTexStorage3DMultisampleBase(const Context *context,
                                         angle::EntryPoint entryPoint,
                                         TextureType target,
                                         GLsizei samples,
                                         GLenum internalformat,
                                         GLsizei width,
                                         GLsizei height,
                                         GLsizei depth);

bool ValidateGetTexLevelParameterBase(const Context *context,
                                      angle::EntryPoint entryPoint,
                                      TextureTarget targetPacked,
                                      GLint level,
                                      TextureImageParameter pnamePacked,
                                      GLsizei *outNumParams);

bool ValidateMapBufferBase(const Context *context,
                           angle::EntryPoint entryPoint,
                           BufferBinding target);
bool ValidateIndexedStateQuery(const Context *context,
                               angle::EntryPoint entryPoint,
                               GLenum pname,
                               GLuint index,
                               const void *data,
                               GLsizei *outNumParams);
bool ValidateES3TexImage2DParameters(const Context *context,
                                     angle::EntryPoint entryPoint,
                                     TextureTarget target,
                                     GLint level,
                                     GLenum internalformat,
                                     bool isSubImage,
                                     GLint xoffset,
                                     GLint yoffset,
                                     GLint zoffset,
                                     GLsizei width,
                                     GLsizei height,
                                     GLsizei depth,
                                     GLint border,
                                     GLenum format,
                                     GLenum type,
                                     const void *pixels,
                                     GLuint *outImageSize);
bool ValidateES3CopyTexImage2DParameters(const Context *context,
                                         angle::EntryPoint entryPoint,
                                         TextureTarget target,
                                         GLint level,
                                         GLenum internalformat,
                                         bool isSubImage,
                                         GLint xoffset,
                                         GLint yoffset,
                                         GLint zoffset,
                                         GLint x,
                                         GLint y,
                                         GLsizei width,
                                         GLsizei height,
                                         GLint border);

bool ValidateGetMultisamplefvBase(const Context *context,
                                  angle::EntryPoint entryPoint,
                                  GLenum pname,
                                  GLuint index,
                                  GLsizei *outNumParams);

bool ValidateSampleMaskiBase(const PrivateState &state,
                             ErrorSet *errors,
                             angle::EntryPoint entryPoint,
                             GLuint maskNumber,
                             GLbitfield mask);

bool ValidateProgramExecutableXFBBuffersPresent(const Context *context,
                                                const ProgramExecutable *programExecutable);

// We should check with Khronos if returning INVALID_FRAMEBUFFER_OPERATION is OK when querying
// implementation format info for incomplete framebuffers. It seems like these queries are
// incongruent with the other errors.
// Inlined for speed.
template <GLenum ErrorCode = GL_INVALID_FRAMEBUFFER_OPERATION>
ANGLE_INLINE bool ValidateFramebufferComplete(const Context *context,
                                              angle::EntryPoint entryPoint,
                                              const Framebuffer *framebuffer)
{
    const FramebufferStatus &framebufferStatus = framebuffer->checkStatus(context);
    if (ANGLE_UNLIKELY(!framebufferStatus.isComplete()))
    {
        ASSERT(framebufferStatus.reason != nullptr);
        ANGLE_VALIDATION_ERROR(ErrorCode, framebufferStatus.reason);
        return false;
    }

    return true;
}

const char *ValidateProgramPipelineDrawStates(const State &state,
                                              const Extensions &extensions,
                                              ProgramPipeline *programPipeline);
const char *ValidateProgramPipelineAttachedPrograms(ProgramPipeline *programPipeline);
const char *ValidateDrawStates(const Context *context, GLenum *outErrorCode);
const char *ValidateProgramPipeline(const Context *context);

void RecordDrawAttribsError(const Context *context, angle::EntryPoint entryPoint);

ANGLE_INLINE bool ValidateDrawAttribs(const Context *context,
                                      angle::EntryPoint entryPoint,
                                      int64_t maxVertex)
{
    // For non-instanced attributes, the maximum vertex must be accessible in the attribute buffers.
    // For instanced attributes, in non-instanced draw calls only attribute 0 is accessed.  In
    // instanced draw calls, the instance limit is checked in ValidateDrawInstancedAttribs.
    if (ANGLE_UNLIKELY(maxVertex >= context->getNonInstancedVertexElementLimit()) ||
        ANGLE_UNLIKELY(context->getInstancedVertexElementLimit() < 1))
    {
        RecordDrawAttribsError(context, entryPoint);
        return false;
    }

    return true;
}

ANGLE_INLINE bool ValidateDrawArraysAttribs(const Context *context,
                                            angle::EntryPoint entryPoint,
                                            GLint first,
                                            GLsizei count)
{
    if (!context->isBufferAccessValidationEnabled())
    {
        return true;
    }

    // Check the computation of maxVertex doesn't overflow.
    // - first < 0 has been checked as an error condition.
    // - if count <= 0, skip validating no-op draw calls.
    // From this we know maxVertex will be positive, and only need to check if it overflows GLint.
    ASSERT(first >= 0);
    ASSERT(count > 0);
    int64_t maxVertex = static_cast<int64_t>(first) + static_cast<int64_t>(count) - 1;
    if (ANGLE_UNLIKELY(maxVertex > static_cast<int64_t>(std::numeric_limits<GLint>::max())))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, err::kIntegerOverflow);
        return false;
    }

    return ValidateDrawAttribs(context, entryPoint, maxVertex);
}

ANGLE_INLINE bool ValidateDrawInstancedAttribs(const Context *context,
                                               angle::EntryPoint entryPoint,
                                               GLint primcount,
                                               GLuint baseinstance)
{
    if (ANGLE_LIKELY(!context->isBufferAccessValidationEnabled()))
    {
        return true;
    }

    // For each instance, attribute element index = floor(instance / attrib.divisor) + baseinstance.
    // The instance runs [0..primcount - 1], so max instance is primcount - 1.
    // For all attribs with attrib.divisor != 0, check max element index < attrib.elementIndex:
    //    floor((primcount - 1) / attrib.divisor) + baseinstance < attrib.elementLimit.

    if (ANGLE_LIKELY(baseinstance == 0))
    {
        // Fast path when baseinstance == 0:
        // for all attribs: floor((primcount - 1) / attrib.divisor) < attrib.elementLimit
        // ->
        // primcount <= min(for all attribs: attrib.elementLimit * attrib.divisor)
        const GLint64 limit = context->getInstancedVertexElementLimit();
        if (primcount > limit)
        {
            RecordDrawAttribsError(context, entryPoint);
            return false;
        }
        return true;
    }

    const VertexArray *vao = context->getState().getVertexArray();
    if (!vao)
    {
        return true;
    }

    const auto &vertexAttribs  = vao->getVertexAttributes();
    const auto &vertexBindings = vao->getVertexBindings();

    for (size_t attributeIndex : context->getActiveBufferedAttribsMask())
    {
        const VertexAttribute &attrib = vertexAttribs[attributeIndex];
        const VertexBinding &binding  = vertexBindings[attrib.bindingIndex];

        GLuint divisor = binding.getDivisor();
        if (divisor == 0)
        {
            // Non-instanced attributes are validated by ValidateDrawAttribs.
            continue;
        }

        GLint64 elementLimit = attrib.getCachedElementLimit();
        if (elementLimit == VertexAttribute::kIntegerOverflow || elementLimit < 0)
        {
            RecordDrawAttribsError(context, entryPoint);
            return false;
        }
        // Compute max instance attribute index = floor(instance / divisor) + baseinstance.
        GLint64 lastIndex =
            static_cast<GLint64>((static_cast<GLuint>(primcount) - 1u) / divisor) + baseinstance;

        if (lastIndex >= elementLimit)
        {
            RecordDrawAttribsError(context, entryPoint);
            return false;
        }
    }

    return true;
}

ANGLE_INLINE bool ValidateDrawInstancedCounts(const Context *context,
                                              angle::EntryPoint entryPoint,
                                              GLsizei primcount,
                                              GLuint baseinstance)
{
    angle::CheckedNumeric<GLuint> checkedSum = baseinstance;
    checkedSum += primcount - 1;

    if (ANGLE_UNLIKELY(!checkedSum.IsValid()))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, err::kInstanceIdOverflow);
        return false;
    }

    return true;
}

ANGLE_INLINE bool ValidateDrawArraysCommon(const Context *context,
                                           angle::EntryPoint entryPoint,
                                           PrimitiveMode mode,
                                           GLint first,
                                           GLsizei count,
                                           GLsizei primcount)
{
    if (ANGLE_UNLIKELY(first < 0))
    {
        ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, err::kNegativeStart);
        return false;
    }

    if (count <= 0)
    {
        if (ANGLE_UNLIKELY(count < 0))
        {
            ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, err::kNegativeCount);
            return false;
        }

        // Early exit.
        return ValidateDrawBase(context, entryPoint, mode);
    }

    if (primcount <= 0)
    {
        if (ANGLE_UNLIKELY(primcount < 0))
        {
            ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, err::kNegativeCount);
            return false;
        }
        // Early exit.
        return ValidateDrawBase(context, entryPoint, mode);
    }

    if (ANGLE_UNLIKELY(!ValidateDrawBase(context, entryPoint, mode)))
    {
        return false;
    }

    return ValidateDrawArraysAttribs(context, entryPoint, first, count);
}

ANGLE_INLINE bool ValidateDrawElementsBase(const Context *context,
                                           angle::EntryPoint entryPoint,
                                           PrimitiveMode mode,
                                           DrawElementsType type)
{
    if (ANGLE_UNLIKELY(!context->getStateCache().isValidDrawElementsType(type)))
    {
        if (type == DrawElementsType::UnsignedInt)
        {
            ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, err::kTypeNotUnsignedShortByte);
            return false;
        }

        ASSERT(type == DrawElementsType::InvalidEnum);
        ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, err::kEnumInvalid);
        return false;
    }

    intptr_t drawElementsError;
    if (!context->getPrivateStateCache().isCachedBasicDrawElementsErrorValid())
    {
        context->getPrivateStateCache().updateBasicDrawElementsError(
            reinterpret_cast<intptr_t>(ValidateDrawElementsStates(context)));
    }
    drawElementsError = context->getPrivateStateCache().getBasicDrawElementsError();

    if (ANGLE_UNLIKELY(drawElementsError))
    {
        // All errors from ValidateDrawElementsStates return INVALID_OPERATION.
        const char *errorMessage = reinterpret_cast<const char *>(drawElementsError);
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, errorMessage);
        return false;
    }

    // Note that we are missing overflow checks for active transform feedback buffers.
    return true;
}

ANGLE_INLINE bool ValidateDrawElementsCommon(const Context *context,
                                             angle::EntryPoint entryPoint,
                                             PrimitiveMode mode,
                                             GLsizei count,
                                             DrawElementsType type,
                                             const void *indices,
                                             GLsizei primcount)
{
    if (ANGLE_UNLIKELY(!ValidateDrawElementsBase(context, entryPoint, mode, type)))
    {
        return false;
    }

    ASSERT(isPow2(GetDrawElementsTypeSize(type)) && GetDrawElementsTypeSize(type) > 0);

    const State &state         = context->getState();
    const VertexArray *vao     = state.getVertexArray();
    Buffer *elementArrayBuffer = vao->getElementArrayBuffer();
    GLuint typeBytes           = GetDrawElementsTypeSize(type);

    if (elementArrayBuffer != nullptr)
    {
        if (ANGLE_UNLIKELY((reinterpret_cast<uintptr_t>(indices) &
                            static_cast<uintptr_t>(typeBytes - 1)) != 0))
        {
            // [WebGL 1.0] Section 6.4 Buffer Offset and Stride Requirements:
            // The offset arguments to drawElements and [...], must be a multiple of the size of the
            // data type passed to the call, or an INVALID_OPERATION error is generated.
            // [GLES 3.2] Section 6.3:
            // Clients must align data elements consistently with the requirements of the
            // client platform, with an additional base-level requirement that an offset within a
            // buffer to a datum comprising N basic machine units be a multiple of N.
            ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, err::kOffsetMustBeMultipleOfType);
            return false;
        }

        // [WebGL 1.0] Section 6.4 Buffer Offset and Stride Requirements
        // In addition the offset argument to drawElements must be non-negative or an INVALID_VALUE
        // error is generated.
        if (ANGLE_UNLIKELY(reinterpret_cast<intptr_t>(indices) < 0))
        {
            ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, err::kNegativeOffset);
            return false;
        }
    }

    if (count <= 0)
    {
        if (ANGLE_UNLIKELY(count < 0))
        {
            ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, err::kNegativeCount);
            return false;
        }

        // Early exit.
        return ValidateDrawBase(context, entryPoint, mode);
    }

    if (ANGLE_UNLIKELY(!ValidateDrawBase(context, entryPoint, mode)))
    {
        return false;
    }

    if (!elementArrayBuffer)
    {
        if (ANGLE_UNLIKELY(!indices))
        {
            // This is an application error that would normally result in a crash, but we catch
            // it and return an error
            ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, err::kElementArrayNoBufferOrPointer);
            return false;
        }
    }
    else
    {
        // The max possible type size is 8 and count is on 32 bits so doing the multiplication
        // in a 64 bit integer is safe. Also we are guaranteed that here count > 0.
        static_assert(std::is_same<int, GLsizei>::value, "GLsizei isn't the expected type");
        constexpr uint64_t kMaxTypeSize = 8;
        constexpr uint64_t kIntMax      = std::numeric_limits<int>::max();
        constexpr uint64_t kUint64Max   = std::numeric_limits<uint64_t>::max();
        static_assert(kIntMax < kUint64Max / kMaxTypeSize, "");

        uint64_t elementCount = static_cast<uint64_t>(count);
        ASSERT(elementCount > 0 && GetDrawElementsTypeSize(type) <= kMaxTypeSize);

        // Doing the multiplication here is overflow-safe
        uint64_t elementDataSizeNoOffset = elementCount << GetDrawElementsTypeShift(type);

        // The offset can be any value, check for overflows
        uint64_t offset = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(indices));
        uint64_t elementDataSizeWithOffset = elementDataSizeNoOffset + offset;
        if (ANGLE_UNLIKELY(elementDataSizeWithOffset < elementDataSizeNoOffset))
        {
            ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, err::kIntegerOverflow);
            return false;
        }

        // Related to possible test bug: https://github.com/KhronosGroup/WebGL/issues/3064
        if (ANGLE_UNLIKELY(elementDataSizeWithOffset >
                           static_cast<uint64_t>(elementArrayBuffer->getSize())) &&
            ANGLE_UNLIKELY(primcount > 0))
        {
            ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, err::kInsufficientBufferSize);
            return false;
        }
    }

    if (ANGLE_UNLIKELY(context->isBufferAccessValidationEnabled()) && ANGLE_UNLIKELY(primcount > 0))
    {
        // Use the parameter buffer to retrieve and cache the index range.
        // TODO: this calculation should take basevertex into account for
        // glDrawElementsInstancedBaseVertexBaseInstanceEXT.  http://anglebug.com/41481166
        IndexRange indexRange{IndexRange::Undefined()};
        ANGLE_VALIDATION_TRY(vao->getIndexRange(context, type, count, indices,
                                                context->getState().isPrimitiveRestartEnabled(),
                                                &indexRange));

        // No op if there are no real indices in the index data (all are primitive restart).
        if (!indexRange.isEmpty())
        {
            // If we use an index greater than our maximum supported index range, return an error.
            // The ES3 spec does not specify behaviour here, it is undefined, but ANGLE should
            // always return an error if possible here.
            if (static_cast<GLint64>(indexRange.end()) >= context->getCaps().maxElementIndex)
            {
                ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, err::kExceedsMaxElement);
                return false;
            }

            if (!ValidateDrawAttribs(context, entryPoint, static_cast<GLint64>(indexRange.end())))
            {
                return false;
            }
        }
    }

    return true;
}

ANGLE_INLINE bool ValidateBindVertexArrayBase(const Context *context,
                                              angle::EntryPoint entryPoint,
                                              VertexArrayID array)
{
    if (ANGLE_UNLIKELY(!context->getPrivateState().isVertexArrayGenerated(array)))
    {
        // The default VAO should always exist
        ASSERT(array.value != 0);
        ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, err::kInvalidVertexArray);
        return false;
    }

    return true;
}

ANGLE_INLINE bool ValidateVertexAttribIndex(const PrivateState &state,
                                            ErrorSet *errors,
                                            angle::EntryPoint entryPoint,
                                            GLuint index)
{
    if (ANGLE_UNLIKELY(index >= static_cast<GLuint>(state.getCaps().maxVertexAttributes)))
    {
        errors->validationError(entryPoint, GL_INVALID_VALUE, err::kIndexExceedsMaxVertexAttribute);
        return false;
    }

    return true;
}

bool ValidateLogicOpCommon(const PrivateState &state,
                           ErrorSet *errors,
                           angle::EntryPoint entryPoint,
                           LogicalOperation opcodePacked);

bool ValidateNoActivePLSConflict(const Context *context,
                                 angle::EntryPoint entryPoint,
                                 TextureID textureId);
bool ValidateNoActivePLSConflict(const Context *context,
                                 angle::EntryPoint entryPoint,
                                 RenderbufferID renderbufferId);
}  // namespace gl

#endif  // LIBANGLE_VALIDATION_ES_H_
