/*
 * Copyright (C) 2015-2021 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */

#pragma once

#if ENABLE(WEBGL)

#include "ActivityStateChangeObserver.h"
#include "ExceptionOr.h"
#include "GPUBasedCanvasRenderingContext.h"
#include "GraphicsContextGL.h"
#include "ImageBuffer.h"
#include "SuspendableTimer.h"
#include "Timer.h"
#include "WebGLAny.h"
#include "WebGLBuffer.h"
#include "WebGLContextAttributes.h"
#include "WebGLFramebuffer.h"
#include "WebGLProgram.h"
#include "WebGLRenderbuffer.h"
#include "WebGLStateTracker.h"
#include "WebGLTexture.h"
#include "WebGLVertexArrayObjectOES.h"
#include <JavaScriptCore/ArrayBufferView.h>
#include <JavaScriptCore/ConsoleTypes.h>
#include <limits>
#include <memory>
#include <wtf/CheckedArithmetic.h>
#include <wtf/Lock.h>

#if ENABLE(WEBGL2)
#include "WebGLSampler.h"
#include "WebGLTransformFeedback.h"
#include "WebGLVertexArrayObject.h"
#endif

#if ENABLE(WEBXR)
#include "JSDOMPromiseDeferred.h"
#endif

namespace JSC {
class AbstractSlotVisitor;
}

namespace WTF {
class AbstractLocker;
}

namespace WebCore {

class ANGLEInstancedArrays;
class EXTBlendMinMax;
class EXTColorBufferFloat;
class EXTColorBufferHalfFloat;
class EXTFloatBlend;
class EXTTextureCompressionRGTC;
class EXTTextureFilterAnisotropic;
class EXTShaderTextureLOD;
class EXTsRGB;
class EXTFragDepth;
class HTMLImageElement;
class ImageData;
class IntSize;
class KHRParallelShaderCompile;
class OESStandardDerivatives;
class OESTextureFloat;
class OESTextureFloatLinear;
class OESTextureHalfFloat;
class OESTextureHalfFloatLinear;
class OESVertexArrayObject;
class OESElementIndexUint;
class OESFBORenderMipmap;
#if ENABLE(OFFSCREEN_CANVAS)
class OffscreenCanvas;
#endif
class WebGLActiveInfo;
class WebGLColorBufferFloat;
class WebGLCompressedTextureASTC;
class WebGLCompressedTextureATC;
class WebGLCompressedTextureETC;
class WebGLCompressedTextureETC1;
class WebGLCompressedTexturePVRTC;
class WebGLCompressedTextureS3TC;
class WebGLCompressedTextureS3TCsRGB;
class WebGLContextGroup;
class WebGLContextObject;
class WebGLDebugRendererInfo;
class WebGLDebugShaders;
class WebGLDepthTexture;
class WebGLDrawBuffers;
class WebGLExtension;
class WebGLLoseContext;
class WebGLMultiDraw;
class WebGLObject;
class WebGLShader;
class WebGLSharedObject;
class WebGLShaderPrecisionFormat;
class WebGLUniformLocation;

#if ENABLE(VIDEO)
class HTMLVideoElement;
#endif

#if ENABLE(OFFSCREEN_CANVAS)
using WebGLCanvas = std::variant<RefPtr<HTMLCanvasElement>, RefPtr<OffscreenCanvas>>;
#else
using WebGLCanvas = std::variant<RefPtr<HTMLCanvasElement>>;
#endif

#if ENABLE(MEDIA_STREAM)
class MediaSample;
#endif

class WebGLRenderingContextBase : public GraphicsContextGL::Client, public GPUBasedCanvasRenderingContext, private ActivityStateChangeObserver {
    WTF_MAKE_ISO_ALLOCATED(WebGLRenderingContextBase);
public:
    using WebGLVersion = GraphicsContextGLWebGLVersion;
    static std::unique_ptr<WebGLRenderingContextBase> create(CanvasBase&, WebGLContextAttributes&, WebGLVersion);
    virtual ~WebGLRenderingContextBase();

    WebGLCanvas canvas();

    int drawingBufferWidth() const;
    int drawingBufferHeight() const;

    void activeTexture(GCGLenum texture);
    void attachShader(WebGLProgram&, WebGLShader&);
    void bindAttribLocation(WebGLProgram&, GCGLuint index, const String& name);
    void bindBuffer(GCGLenum target, WebGLBuffer*);
    virtual void bindFramebuffer(GCGLenum target, WebGLFramebuffer*);
    void bindRenderbuffer(GCGLenum target, WebGLRenderbuffer*);
    void bindTexture(GCGLenum target, WebGLTexture*);
    void blendColor(GCGLfloat red, GCGLfloat green, GCGLfloat blue, GCGLfloat alpha);
    void blendEquation(GCGLenum mode);
    void blendEquationSeparate(GCGLenum modeRGB, GCGLenum modeAlpha);
    void blendFunc(GCGLenum sfactor, GCGLenum dfactor);
    void blendFuncSeparate(GCGLenum srcRGB, GCGLenum dstRGB, GCGLenum srcAlpha, GCGLenum dstAlpha);

    using BufferDataSource = std::variant<RefPtr<ArrayBuffer>, RefPtr<ArrayBufferView>>;
    void bufferData(GCGLenum target, long long size, GCGLenum usage);
    void bufferData(GCGLenum target, std::optional<BufferDataSource>&&, GCGLenum usage);
    void bufferSubData(GCGLenum target, long long offset, BufferDataSource&&);

    GCGLenum checkFramebufferStatus(GCGLenum target);
    void clear(GCGLbitfield mask);
    void clearColor(GCGLfloat red, GCGLfloat green, GCGLfloat blue, GCGLfloat alpha);
    void clearDepth(GCGLfloat);
    void clearStencil(GCGLint);
    void colorMask(GCGLboolean red, GCGLboolean green, GCGLboolean blue, GCGLboolean alpha);
    void compileShader(WebGLShader&);

    void compressedTexImage2D(GCGLenum target, GCGLint level, GCGLenum internalformat, GCGLsizei width, GCGLsizei height, GCGLint border, ArrayBufferView& data);
    void compressedTexSubImage2D(GCGLenum target, GCGLint level, GCGLint xoffset, GCGLint yoffset, GCGLsizei width, GCGLsizei height, GCGLenum format, ArrayBufferView& data);

    void copyTexImage2D(GCGLenum target, GCGLint level, GCGLenum internalformat, GCGLint x, GCGLint y, GCGLsizei width, GCGLsizei height, GCGLint border);
    void copyTexSubImage2D(GCGLenum target, GCGLint level, GCGLint xoffset, GCGLint yoffset, GCGLint x, GCGLint y, GCGLsizei width, GCGLsizei height);

    RefPtr<WebGLBuffer> createBuffer();
    RefPtr<WebGLFramebuffer> createFramebuffer();
    RefPtr<WebGLProgram> createProgram();
    RefPtr<WebGLRenderbuffer> createRenderbuffer();
    RefPtr<WebGLShader> createShader(GCGLenum type);
    RefPtr<WebGLTexture> createTexture();

    void cullFace(GCGLenum mode);

    void deleteBuffer(WebGLBuffer*);
    virtual void deleteFramebuffer(WebGLFramebuffer*);
    void deleteProgram(WebGLProgram*);
    void deleteRenderbuffer(WebGLRenderbuffer*);
    void deleteShader(WebGLShader*);
    void deleteTexture(WebGLTexture*);

    void depthFunc(GCGLenum);
    void depthMask(GCGLboolean);
    void depthRange(GCGLfloat zNear, GCGLfloat zFar);
    void detachShader(WebGLProgram&, WebGLShader&);
    void disable(GCGLenum cap);
    void disableVertexAttribArray(GCGLuint index);
    void drawArrays(GCGLenum mode, GCGLint first, GCGLsizei count);
    void drawElements(GCGLenum mode, GCGLsizei count, GCGLenum type, long long offset);

    void enable(GCGLenum cap);
    void enableVertexAttribArray(GCGLuint index);
    void finish();
    void flush();
    void framebufferRenderbuffer(GCGLenum target, GCGLenum attachment, GCGLenum renderbuffertarget, WebGLRenderbuffer*);
    void framebufferTexture2D(GCGLenum target, GCGLenum attachment, GCGLenum textarget, WebGLTexture*, GCGLint level);
    void frontFace(GCGLenum mode);
    void generateMipmap(GCGLenum target);

    RefPtr<WebGLActiveInfo> getActiveAttrib(WebGLProgram&, GCGLuint index);
    RefPtr<WebGLActiveInfo> getActiveUniform(WebGLProgram&, GCGLuint index);
    std::optional<Vector<RefPtr<WebGLShader>>> getAttachedShaders(WebGLProgram&);
    GCGLint getAttribLocation(WebGLProgram&, const String& name);
    WebGLAny getBufferParameter(GCGLenum target, GCGLenum pname);
    WEBCORE_EXPORT std::optional<WebGLContextAttributes> getContextAttributes();
    GCGLenum getError();
    virtual WebGLExtension* getExtension(const String& name) = 0;
    virtual WebGLAny getFramebufferAttachmentParameter(GCGLenum target, GCGLenum attachment, GCGLenum pname) = 0;
    virtual WebGLAny getParameter(GCGLenum pname);
    WebGLAny getProgramParameter(WebGLProgram&, GCGLenum pname);
    String getProgramInfoLog(WebGLProgram&);
    WebGLAny getRenderbufferParameter(GCGLenum target, GCGLenum pname);
    WebGLAny getShaderParameter(WebGLShader&, GCGLenum pname);
    String getShaderInfoLog(WebGLShader&);
    RefPtr<WebGLShaderPrecisionFormat> getShaderPrecisionFormat(GCGLenum shaderType, GCGLenum precisionType);
    String getShaderSource(WebGLShader&);
    virtual std::optional<Vector<String>> getSupportedExtensions() = 0;
    virtual WebGLAny getTexParameter(GCGLenum target, GCGLenum pname);
    WebGLAny getUniform(WebGLProgram&, const WebGLUniformLocation&);
    RefPtr<WebGLUniformLocation> getUniformLocation(WebGLProgram&, const String&);
    WebGLAny getVertexAttrib(GCGLuint index, GCGLenum pname);
    long long getVertexAttribOffset(GCGLuint index, GCGLenum pname);

    bool extensionIsEnabled(const String&);

    bool isPreservingDrawingBuffer() const { return m_attributes.preserveDrawingBuffer; }

    bool preventBufferClearForInspector() const { return m_preventBufferClearForInspector; }
    void setPreventBufferClearForInspector(bool value) { m_preventBufferClearForInspector = value; }

    void hint(GCGLenum target, GCGLenum mode);
    GCGLboolean isBuffer(WebGLBuffer*);
    bool isContextLost() const;
    GCGLboolean isEnabled(GCGLenum cap);
    GCGLboolean isFramebuffer(WebGLFramebuffer*);
    GCGLboolean isProgram(WebGLProgram*);
    GCGLboolean isRenderbuffer(WebGLRenderbuffer*);
    GCGLboolean isShader(WebGLShader*);
    GCGLboolean isTexture(WebGLTexture*);

    void lineWidth(GCGLfloat);
    void linkProgram(WebGLProgram&);
    bool linkProgramWithoutInvalidatingAttribLocations(WebGLProgram*);
    virtual void pixelStorei(GCGLenum pname, GCGLint param);
#if ENABLE(WEBXR)
    using MakeXRCompatiblePromise = DOMPromiseDeferred<void>;
    void makeXRCompatible(MakeXRCompatiblePromise&&);
    bool isXRCompatible() const { return m_isXRCompatible; }
#endif
    void polygonOffset(GCGLfloat factor, GCGLfloat units);
    // This must be virtual so more validation can be added in WebGL 2.0.
    virtual void readPixels(GCGLint x, GCGLint y, GCGLsizei width, GCGLsizei height, GCGLenum format, GCGLenum type, ArrayBufferView& pixels);
    void renderbufferStorage(GCGLenum target, GCGLenum internalformat, GCGLsizei width, GCGLsizei height);
    virtual void renderbufferStorageImpl(GCGLenum target, GCGLsizei samples, GCGLenum internalformat, GCGLsizei width, GCGLsizei height, const char* functionName);
    void sampleCoverage(GCGLfloat value, GCGLboolean invert);
    void scissor(GCGLint x, GCGLint y, GCGLsizei width, GCGLsizei height);
    void shaderSource(WebGLShader&, const String&);
    void stencilFunc(GCGLenum func, GCGLint ref, GCGLuint mask);
    void stencilFuncSeparate(GCGLenum face, GCGLenum func, GCGLint ref, GCGLuint mask);
    void stencilMask(GCGLuint);
    void stencilMaskSeparate(GCGLenum face, GCGLuint mask);
    void stencilOp(GCGLenum fail, GCGLenum zfail, GCGLenum zpass);
    void stencilOpSeparate(GCGLenum face, GCGLenum fail, GCGLenum zfail, GCGLenum zpass);

    // These must be virtual so more validation can be added in WebGL 2.0.
    virtual void texImage2D(GCGLenum target, GCGLint level, GCGLenum internalformat, GCGLsizei width, GCGLsizei height, GCGLint border, GCGLenum format, GCGLenum type, RefPtr<ArrayBufferView>&&);

#if ENABLE(VIDEO)
    using TexImageSource = std::variant<RefPtr<ImageBitmap>, RefPtr<ImageData>, RefPtr<HTMLImageElement>, RefPtr<HTMLCanvasElement>, RefPtr<HTMLVideoElement>>;
#else
    using TexImageSource = std::variant<RefPtr<ImageBitmap>, RefPtr<ImageData>, RefPtr<HTMLImageElement>, RefPtr<HTMLCanvasElement>>;
#endif

    virtual ExceptionOr<void> texImage2D(GCGLenum target, GCGLint level, GCGLenum internalformat, GCGLenum format, GCGLenum type, std::optional<TexImageSource>);

    void texParameterf(GCGLenum target, GCGLenum pname, GCGLfloat param);
    void texParameteri(GCGLenum target, GCGLenum pname, GCGLint param);

    // These must be virtual so more validation can be added in WebGL 2.0.
    virtual void texSubImage2D(GCGLenum target, GCGLint level, GCGLint xoffset, GCGLint yoffset, GCGLsizei width, GCGLsizei height, GCGLenum format, GCGLenum type, RefPtr<ArrayBufferView>&&);
    virtual ExceptionOr<void> texSubImage2D(GCGLenum target, GCGLint level, GCGLint xoffset, GCGLint yoffset, GCGLenum format, GCGLenum type, std::optional<TexImageSource>&&);

    template <class TypedArray, class DataType>
    class TypedList {
    public:
        using VariantType = std::variant<RefPtr<TypedArray>, Vector<DataType>>;

        TypedList(VariantType&& variant)
            : m_variant(WTFMove(variant))
        {
        }

        const DataType* data() const
        {
            return WTF::switchOn(m_variant,
                [] (const RefPtr<TypedArray>& typedArray) -> const DataType* { return typedArray->data(); },
                [] (const Vector<DataType>& vector) -> const DataType* { return vector.data(); }
            );
        }

        GCGLsizei length() const
        {
            return WTF::switchOn(m_variant,
                [] (const RefPtr<TypedArray>& typedArray) -> GCGLsizei { return typedArray->length(); },
                [] (const Vector<DataType>& vector) -> GCGLsizei { return vector.size(); }
            );
        }

    private:
        VariantType m_variant;
    };

    using Float32List = TypedList<Float32Array, float>;
    using Int32List = TypedList<Int32Array, int>;
    using Uint32List = TypedList<Uint32Array, uint32_t>;

    void uniform1f(const WebGLUniformLocation*, GCGLfloat x);
    void uniform2f(const WebGLUniformLocation*, GCGLfloat x, GCGLfloat y);
    void uniform3f(const WebGLUniformLocation*, GCGLfloat x, GCGLfloat y, GCGLfloat z);
    void uniform4f(const WebGLUniformLocation*, GCGLfloat x, GCGLfloat y, GCGLfloat z, GCGLfloat w);

    void uniform1i(const WebGLUniformLocation*, GCGLint x);
    void uniform2i(const WebGLUniformLocation*, GCGLint x, GCGLint y);
    void uniform3i(const WebGLUniformLocation*, GCGLint x, GCGLint y, GCGLint z);
    void uniform4i(const WebGLUniformLocation*, GCGLint x, GCGLint y, GCGLint z, GCGLint w);

    void uniform1fv(const WebGLUniformLocation*, Float32List&&);
    void uniform2fv(const WebGLUniformLocation*, Float32List&&);
    void uniform3fv(const WebGLUniformLocation*, Float32List&&);
    void uniform4fv(const WebGLUniformLocation*, Float32List&&);

    void uniform1iv(const WebGLUniformLocation*, Int32List&&);
    void uniform2iv(const WebGLUniformLocation*, Int32List&&);
    void uniform3iv(const WebGLUniformLocation*, Int32List&&);
    void uniform4iv(const WebGLUniformLocation*, Int32List&&);

    void uniformMatrix2fv(const WebGLUniformLocation*, GCGLboolean transpose, Float32List&&);
    void uniformMatrix3fv(const WebGLUniformLocation*, GCGLboolean transpose, Float32List&&);
    void uniformMatrix4fv(const WebGLUniformLocation*, GCGLboolean transpose, Float32List&&);

    void useProgram(WebGLProgram*);
    void validateProgram(WebGLProgram&);

    void vertexAttrib1f(GCGLuint index, GCGLfloat x);
    void vertexAttrib2f(GCGLuint index, GCGLfloat x, GCGLfloat y);
    void vertexAttrib3f(GCGLuint index, GCGLfloat x, GCGLfloat y, GCGLfloat z);
    void vertexAttrib4f(GCGLuint index, GCGLfloat x, GCGLfloat y, GCGLfloat z, GCGLfloat w);

    void vertexAttrib1fv(GCGLuint index, Float32List&&);
    void vertexAttrib2fv(GCGLuint index, Float32List&&);
    void vertexAttrib3fv(GCGLuint index, Float32List&&);
    void vertexAttrib4fv(GCGLuint index, Float32List&&);

    void vertexAttribPointer(GCGLuint index, GCGLint size, GCGLenum type, GCGLboolean normalized,
        GCGLsizei stride, long long offset);

    void viewport(GCGLint x, GCGLint y, GCGLsizei width, GCGLsizei height);

    // WEBKIT_lose_context support
    enum LostContextMode {
        // Lost context occurred at the graphics system level.
        RealLostContext,

        // Lost context provoked by WEBKIT_lose_context.
        SyntheticLostContext
    };
    void forceLostContext(LostContextMode);
    void forceRestoreContext();
    void loseContextImpl(LostContextMode);
    using SimulatedEventForTesting = GraphicsContextGL::SimulatedEventForTesting;
    WEBCORE_EXPORT void simulateEventForTesting(SimulatedEventForTesting);

    GraphicsContextGL* graphicsContextGL() const { return m_context.get(); }
    WebGLContextGroup* contextGroup() const { return m_contextGroup.get(); }
    PlatformLayer* platformLayer() const override;

    void reshape(int width, int height) override;

    void prepareForDisplayWithPaint() final;
    void paintRenderingResultsToCanvas() final;
    std::optional<PixelBuffer> paintRenderingResultsToPixelBuffer();
#if ENABLE(MEDIA_STREAM)
    RefPtr<MediaSample> paintCompositedResultsToMediaSample();
#endif

    void removeSharedObject(WebGLSharedObject&);
    void removeContextObject(WebGLContextObject&);
    
    unsigned getMaxVertexAttribs() const { return m_maxVertexAttribs; }

    bool isContextUnrecoverablyLost() const;

    // Instanced Array helper functions.
    void drawArraysInstanced(GCGLenum mode, GCGLint first, GCGLsizei count, GCGLsizei primcount);
    void drawElementsInstanced(GCGLenum mode, GCGLsizei count, GCGLenum type, long long offset, GCGLsizei primcount);
    void vertexAttribDivisor(GCGLuint index, GCGLuint divisor);

    // GraphicsContextGL::Client
    void didComposite() override;
    void forceContextLost() override;
    void recycleContext() override;
    void dispatchContextChangedNotification() override;

    virtual void addMembersToOpaqueRoots(JSC::AbstractSlotVisitor&);
    // This lock must be held across all mutations of containers like
    // Vectors, HashSets, etc. which contain RefPtr<WebGLObject>, and
    // which are traversed by addMembersToOpaqueRoots() or any of the
    // similarly-named methods in WebGLObject subclasses.
    //
    // FIXME: consider changing this mechanism to instead record when
    // individual WebGLObjects are latched / unlatched in the
    // context's state, either directly, or indirectly through
    // container objects. If that were done, then the
    // "GenerateIsReachable=Impl" in various WebGL objects' IDL files
    // would need to be changed to instead query whether the object is
    // currently latched into the context - without traversing all of
    // the latched objects to find the current one, which would be
    // prohibitively expensive.
    Lock& objectGraphLock() WTF_RETURNS_LOCK(m_objectGraphLock);

protected:
    WebGLRenderingContextBase(CanvasBase&, WebGLContextAttributes);
    WebGLRenderingContextBase(CanvasBase&, Ref<GraphicsContextGL>&&, WebGLContextAttributes);

    friend class EXTTextureCompressionRGTC;
    friend class WebGLDrawBuffers;
    friend class WebGLFramebuffer;
    friend class WebGLObject;
    friend class OESVertexArrayObject;
    friend class WebGLDebugShaders;
    friend class WebGLCompressedTextureASTC;
    friend class WebGLCompressedTextureATC;
    friend class WebGLCompressedTextureETC;
    friend class WebGLCompressedTextureETC1;
    friend class WebGLCompressedTexturePVRTC;
    friend class WebGLCompressedTextureS3TC;
    friend class WebGLCompressedTextureS3TCsRGB;
    friend class WebGLMultiDraw;
    friend class WebGLRenderingContextErrorMessageCallback;
    friend class WebGLVertexArrayObjectOES;
    friend class WebGLVertexArrayObject;
    friend class WebGLVertexArrayObjectBase;
    friend class WebGLSync;

    // Implementation helpers.
    friend class ScopedUnpackParametersResetRestore;

    virtual void initializeNewContext();
    virtual void initializeVertexArrayObjects() = 0;
    void setupFlags();

    // ActiveDOMObject
    void stop() override;
    const char* activeDOMObjectName() const override;
    void suspend(ReasonForSuspension) override;
    void resume() override;

    void addSharedObject(WebGLSharedObject&);
    void addContextObject(WebGLContextObject&);
    void detachAndRemoveAllObjects();

    void destroyGraphicsContextGL();
    void markContextChanged();
    void markContextChangedAndNotifyCanvasObserver();

    void addActivityStateChangeObserverIfNecessary();
    void removeActivityStateChangeObserver();

    // Query whether it is built on top of compliant GLES2 implementation.
    bool isGLES2Compliant() { return m_isGLES2Compliant; }
    // Query if the GL implementation is NPOT strict.
    bool isGLES2NPOTStrict() { return m_isGLES2NPOTStrict; }
    // Query if depth_stencil buffer is supported.
    bool isDepthStencilSupported() { return m_isDepthStencilSupported; }

    // Helper to return the size in bytes of OpenGL data types
    // like GL_FLOAT, GL_INT, etc.
    unsigned sizeInBytes(GCGLenum type);

    // Basic validation of count and offset against number of elements in element array buffer
    bool validateElementArraySize(GCGLsizei count, GCGLenum type, GCGLintptr offset);

    // Conservative but quick index validation
    virtual bool validateIndexArrayConservative(GCGLenum type, unsigned& numElementsRequired) = 0;

    // Precise but slow index validation -- only done if conservative checks fail
    bool validateIndexArrayPrecise(GCGLsizei count, GCGLenum type, GCGLintptr offset, unsigned& numElementsRequired);
    bool validateVertexAttributes(unsigned elementCount, unsigned primitiveCount = 0);

    // Validates the incoming WebGL object, which is assumed to be non-null.
    // Checks that the object belongs to this context and that it's not marked for
    // deletion. Performs a context lost check internally.
    bool validateWebGLObject(const char*, WebGLObject*);

    // Validates the incoming WebGL program or shader, which is assumed to be
    // non-null. OpenGL ES's validation rules differ for these types of objects
    // compared to others. Performs a context lost check internally.
    bool validateWebGLProgramOrShader(const char*, WebGLObject*);

#if !USE(ANGLE)
    bool validateDrawArrays(const char* functionName, GCGLenum mode, GCGLint first, GCGLsizei count, GCGLsizei primcount);
    bool validateDrawElements(const char* functionName, GCGLenum mode, GCGLsizei count, GCGLenum type, long long offset, unsigned& numElements, GCGLsizei primcount);
    bool validateNPOTTextureLevel(GCGLsizei width, GCGLsizei height, GCGLint level, const char* functionName);
#endif
    bool validateVertexArrayObject(const char* functionName);

    // Adds a compressed texture format.
    void addCompressedTextureFormat(GCGLenum);

    // Set UNPACK_ALIGNMENT to 1, all other parameters to 0.
    virtual void resetUnpackParameters();
    // Restore the client unpack parameters.
    virtual void restoreUnpackParameters();

    RefPtr<Image> drawImageIntoBuffer(Image&, int width, int height, int deviceScaleFactor, const char* functionName);

#if ENABLE(VIDEO)
    RefPtr<Image> videoFrameToImage(HTMLVideoElement*, BackingStoreCopy, const char* functionName);
#endif

    WebGLTexture::TextureExtensionFlag textureExtensionFlags() const;

    bool enableSupportedExtension(ASCIILiteral extensionNameLiteral);
    void loseExtensions(LostContextMode);

    virtual void uncacheDeletedBuffer(const WTF::AbstractLocker&, WebGLBuffer*);

    bool compositingResultsNeedUpdating() const final { return m_compositingResultsNeedUpdating; }
    bool needsPreparationForDisplay() const final { return true; }
    void prepareForDisplay() final;

    RefPtr<GraphicsContextGL> m_context;
    RefPtr<WebGLContextGroup> m_contextGroup;
    Lock m_objectGraphLock;

    bool m_restoreAllowed { false };
    SuspendableTimer m_restoreTimer;

    bool m_needsUpdate;
    bool m_markedCanvasDirty;
    HashSet<WebGLContextObject*> m_contextObjects;

    // List of bound VBO's. Used to maintain info about sizes for ARRAY_BUFFER and stored values for ELEMENT_ARRAY_BUFFER
    RefPtr<WebGLBuffer> m_boundArrayBuffer;

    RefPtr<WebGLVertexArrayObjectBase> m_defaultVertexArrayObject;
    RefPtr<WebGLVertexArrayObjectBase> m_boundVertexArrayObject;

    void setBoundVertexArrayObject(const WTF::AbstractLocker&, WebGLVertexArrayObjectBase*);
    
    class VertexAttribValue {
    public:
        VertexAttribValue()
        {
            initValue();
        }
        
        void initValue()
        {
            type = GraphicsContextGL::FLOAT;
            fValue[0] = 0.0f;
            fValue[1] = 0.0f;
            fValue[2] = 0.0f;
            fValue[3] = 1.0f;
        }
        
        GCGLenum type;
        union {
            GCGLfloat fValue[4];
            GCGLint iValue[4];
            GCGLuint uiValue[4];
        };
    };
    Vector<VertexAttribValue> m_vertexAttribValue;
    unsigned m_maxVertexAttribs;
#if !USE(ANGLE)
    RefPtr<WebGLBuffer> m_vertexAttrib0Buffer;
    long m_vertexAttrib0BufferSize { 0 };
    GCGLfloat m_vertexAttrib0BufferValue[4];
    bool m_forceAttrib0BufferRefill { true };
    bool m_vertexAttrib0UsedBefore { false };
#endif

    RefPtr<WebGLProgram> m_currentProgram;
    RefPtr<WebGLFramebuffer> m_framebufferBinding;
    RefPtr<WebGLRenderbuffer> m_renderbufferBinding;
    struct TextureUnitState {
        RefPtr<WebGLTexture> texture2DBinding;
        RefPtr<WebGLTexture> textureCubeMapBinding;
        RefPtr<WebGLTexture> texture3DBinding;
        RefPtr<WebGLTexture> texture2DArrayBinding;
    };
    Vector<TextureUnitState> m_textureUnits;
#if !USE(ANGLE)
    HashSet<unsigned, DefaultHash<unsigned>, WTF::UnsignedWithZeroKeyHashTraits<unsigned>> m_unrenderableTextureUnits;
#endif
    unsigned long m_activeTextureUnit;

    RefPtr<WebGLTexture> m_blackTexture2D;
    RefPtr<WebGLTexture> m_blackTextureCubeMap;

    Vector<GCGLenum> m_compressedTextureFormats;

    // Fixed-size cache of reusable image buffers for video texImage2D calls.
    class LRUImageBufferCache {
    public:
        LRUImageBufferCache(int capacity);
        // Returns pointer to a cleared image buffer that is owned by the cache. The pointer is valid until next call.
        // Using fillOperator == CompositeOperator::Copy can be used to omit the clear of the buffer.
        ImageBuffer* imageBuffer(const IntSize&, CompositeOperator fillOperator = CompositeOperator::SourceOver);
    private:
        void bubbleToFront(size_t idx);
        Vector<RefPtr<ImageBuffer>> m_buffers;
    };
    LRUImageBufferCache m_generatedImageCache { 0 };

    GCGLint m_maxTextureSize;
    GCGLint m_maxCubeMapTextureSize;
    GCGLint m_maxRenderbufferSize;
    GCGLint m_maxViewportDims[2] { 0, 0 };
    GCGLint m_maxTextureLevel;
    GCGLint m_maxCubeMapTextureLevel;

    GCGLint m_maxDrawBuffers;
    GCGLint m_maxColorAttachments;
    GCGLenum m_backDrawBuffer;
    bool m_drawBuffersWebGLRequirementsChecked;
    bool m_drawBuffersSupported;

    GCGLint m_packAlignment;
    GCGLint m_unpackAlignment;
    bool m_unpackFlipY;
    bool m_unpackPremultiplyAlpha;
    GCGLenum m_unpackColorspaceConversion;

    bool m_contextLost { false };
    LostContextMode m_contextLostMode { SyntheticLostContext };
    WebGLContextAttributes m_attributes;

    bool m_layerCleared;
    GCGLfloat m_clearColor[4];
    bool m_scissorEnabled;
    GCGLfloat m_clearDepth;
    GCGLint m_clearStencil;
    GCGLboolean m_colorMask[4];
    GCGLboolean m_depthMask;

    bool m_stencilEnabled;
    GCGLuint m_stencilMask, m_stencilMaskBack;
    GCGLint m_stencilFuncRef, m_stencilFuncRefBack; // Note that these are the user specified values, not the internal clamped value.
    GCGLuint m_stencilFuncMask, m_stencilFuncMaskBack;

    bool m_rasterizerDiscardEnabled { false };

    bool m_isGLES2Compliant;
    bool m_isGLES2NPOTStrict;
    bool m_isDepthStencilSupported;
    bool m_isRobustnessEXTSupported;

    bool m_synthesizedErrorsToConsole { true };
    int m_numGLErrorsToConsoleAllowed;

    bool m_preventBufferClearForInspector { false };

    // A WebGLRenderingContext can be created in a state where it appears as
    // a valid and active context, but will not execute any important operations
    // until its load policy is completely resolved.
    bool m_isPendingPolicyResolution { false };
    bool m_hasRequestedPolicyResolution { false };
    bool isContextLostOrPending();

    bool m_compositingResultsNeedUpdating { false };
    bool m_isDisplayingWithPaint { false };

    // Enabled extension objects.
    // FIXME: Move some of these to WebGLRenderingContext, the ones not needed for WebGL2
    RefPtr<EXTFragDepth> m_extFragDepth;
    RefPtr<EXTBlendMinMax> m_extBlendMinMax;
    RefPtr<EXTsRGB> m_extsRGB;
    RefPtr<EXTTextureCompressionRGTC> m_extTextureCompressionRGTC;
    RefPtr<EXTTextureFilterAnisotropic> m_extTextureFilterAnisotropic;
    RefPtr<EXTShaderTextureLOD> m_extShaderTextureLOD;
    RefPtr<KHRParallelShaderCompile> m_khrParallelShaderCompile;
    RefPtr<OESTextureFloat> m_oesTextureFloat;
    RefPtr<OESTextureFloatLinear> m_oesTextureFloatLinear;
    RefPtr<OESTextureHalfFloat> m_oesTextureHalfFloat;
    RefPtr<OESTextureHalfFloatLinear> m_oesTextureHalfFloatLinear;
    RefPtr<OESStandardDerivatives> m_oesStandardDerivatives;
    RefPtr<OESVertexArrayObject> m_oesVertexArrayObject;
    RefPtr<OESElementIndexUint> m_oesElementIndexUint;
    RefPtr<OESFBORenderMipmap> m_oesFBORenderMipmap;
    RefPtr<WebGLLoseContext> m_webglLoseContext;
    RefPtr<WebGLDebugRendererInfo> m_webglDebugRendererInfo;
    RefPtr<WebGLDebugShaders> m_webglDebugShaders;
    RefPtr<WebGLCompressedTextureASTC> m_webglCompressedTextureASTC;
    RefPtr<WebGLCompressedTextureATC> m_webglCompressedTextureATC;
    RefPtr<WebGLCompressedTextureETC> m_webglCompressedTextureETC;
    RefPtr<WebGLCompressedTextureETC1> m_webglCompressedTextureETC1;
    RefPtr<WebGLCompressedTexturePVRTC> m_webglCompressedTexturePVRTC;
    RefPtr<WebGLCompressedTextureS3TC> m_webglCompressedTextureS3TC;
    RefPtr<WebGLCompressedTextureS3TCsRGB> m_webglCompressedTextureS3TCsRGB;
    RefPtr<WebGLDepthTexture> m_webglDepthTexture;
    RefPtr<WebGLDrawBuffers> m_webglDrawBuffers;
    RefPtr<ANGLEInstancedArrays> m_angleInstancedArrays;
    RefPtr<EXTColorBufferHalfFloat> m_extColorBufferHalfFloat;
    RefPtr<EXTFloatBlend> m_extFloatBlend;
    RefPtr<WebGLColorBufferFloat> m_webglColorBufferFloat;
    RefPtr<EXTColorBufferFloat> m_extColorBufferFloat;
    RefPtr<WebGLMultiDraw> m_webglMultiDraw;

    bool m_areWebGL2TexImageSourceFormatsAndTypesAdded { false };
    bool m_areOESTextureFloatFormatsAndTypesAdded { false };
    bool m_areOESTextureHalfFloatFormatsAndTypesAdded { false };
    bool m_areEXTsRGBFormatsAndTypesAdded { false };

    HashSet<GCGLenum> m_supportedTexImageSourceInternalFormats;
    HashSet<GCGLenum> m_supportedTexImageSourceFormats;
    HashSet<GCGLenum> m_supportedTexImageSourceTypes;

    // Helpers for getParameter and other similar functions.
    bool getBooleanParameter(GCGLenum);
    Vector<bool> getBooleanArrayParameter(GCGLenum);
    float getFloatParameter(GCGLenum);
    int getIntParameter(GCGLenum);
    unsigned getUnsignedIntParameter(GCGLenum);
    RefPtr<Float32Array> getWebGLFloatArrayParameter(GCGLenum);
    RefPtr<Int32Array> getWebGLIntArrayParameter(GCGLenum);

    enum ClearCaller {
        // Caller of ClearIfComposited is a user-level draw or clear call.
        ClearCallerDrawOrClear,
        // Caller of ClearIfComposited is anything else, including
        // readbacks or copies.
        ClearCallerOther,
    };
    // Clear the backbuffer if it was composited since the last operation.
    // clearMask is set to the bitfield of any clear that would happen anyway at this time
    // and the function returns true if that clear is now unnecessary.
    bool clearIfComposited(ClearCaller, GCGLbitfield clearMask = 0);

    // Helper to restore state that clearing the framebuffer may destroy.
    void restoreStateAfterClear();

    enum class TexImageFunctionType {
        TexImage,
        TexSubImage,
        CopyTexImage,
        CompressedTexImage
    };

    enum class TexImageFunctionID {
        TexImage2D,
        TexSubImage2D,
        TexImage3D,
        TexSubImage3D
    };

    enum class TexImageDimension {
        Tex2D,
        Tex3D
    };

    enum TexFuncValidationSourceType {
        SourceArrayBufferView,
        SourceImageBitmap,
        SourceImageData,
        SourceHTMLImageElement,
        SourceHTMLCanvasElement,
#if ENABLE(VIDEO)
        SourceHTMLVideoElement,
#endif
        // WebGL 2.0.
        SourceUnpackBuffer,
    };

    enum NullDisposition {
        NullAllowed,
        NullNotAllowed,
        NullNotReachable
    };

    template <typename T> IntRect getTextureSourceSize(T* textureSource)
    {
        return IntRect(0, 0, textureSource->width(), textureSource->height());
    }
    template <typename T> bool validateTexImageSubRectangle(const char* functionName,
        TexImageFunctionID functionID,
        T* image,
        const IntRect& subRect,
        GCGLsizei depth,
        GCGLint unpackImageHeight,
        bool* selectingSubRectangle)
    {
        ASSERT(functionName);
        ASSERT(selectingSubRectangle);
        if (!image) {
            // Probably indicates a failure to allocate the image.
            synthesizeGLError(GraphicsContextGL::OUT_OF_MEMORY, functionName, "out of memory");
            return false;
        }

        int imageWidth = static_cast<int>(image->width());
        int imageHeight = static_cast<int>(image->height());
        *selectingSubRectangle = !(!subRect.x() && !subRect.y() && subRect.width() == imageWidth && subRect.height() == imageHeight);
        // If the source image rect selects anything except the entire
        // contents of the image, assert that we're running WebGL 2.0,
        // since this should never happen for WebGL 1.0 (even though
        // the code could support it). If the image is null, that will
        // be signaled as an error later.
        ASSERT(!*selectingSubRectangle || isWebGL2());

        if (!subRect.isValid() || subRect.x() < 0 || subRect.y() < 0
            || subRect.maxX() > imageWidth || subRect.maxY() > imageHeight
            || subRect.width() < 0 || subRect.height() < 0) {
            synthesizeGLError(GraphicsContextGL::INVALID_OPERATION, functionName,
                "source sub-rectangle specified via pixel unpack parameters is invalid");
            return false;
        }

        if (functionID == TexImageFunctionID::TexImage3D || functionID == TexImageFunctionID::TexSubImage3D) {
            ASSERT(unpackImageHeight >= 0);

            if (depth < 1) {
                synthesizeGLError(GraphicsContextGL::INVALID_OPERATION, functionName,
                    "Can't define a 3D texture with depth < 1");
                return false;
            }

            // According to the WebGL 2.0 spec, specifying depth > 1 means
            // to select multiple rectangles stacked vertically.
            Checked<GCGLint, RecordOverflow> maxYAccessed;
            if (unpackImageHeight)
                maxYAccessed = unpackImageHeight;
            else
                maxYAccessed = subRect.height();
            maxYAccessed *= depth - 1;
            maxYAccessed += subRect.height();
            maxYAccessed += subRect.y();

            if (maxYAccessed.hasOverflowed()) {
                synthesizeGLError(GraphicsContextGL::INVALID_OPERATION, functionName,
                    "Out-of-range parameters passed for 3D texture upload");
                return false;
            }

            if (maxYAccessed > imageHeight) {
                synthesizeGLError(GraphicsContextGL::INVALID_OPERATION, functionName,
                    "Not enough data supplied to upload to a 3D texture with depth > 1");
                return false;
            }
        } else {
            ASSERT(depth >= 1);
            ASSERT(!unpackImageHeight);
        }
        return true;
    }
    IntRect sentinelEmptyRect();
    IntRect safeGetImageSize(Image*);
    IntRect getImageDataSize(ImageData*);
    IntRect getTexImageSourceSize(TexImageSource&);

    ExceptionOr<void> texImageSourceHelper(TexImageFunctionID, GCGLenum target, GCGLint level, GCGLint internalformat, GCGLint border, GCGLenum format, GCGLenum type, GCGLint xoffset, GCGLint yoffset, GCGLint zoffset, const IntRect& sourceImageRect, GCGLsizei depth, GCGLint unpackImageHeight, TexImageSource&&);
    // Helper function for tex(Sub)Image2D && texSubImage3D.
    void texImageArrayBufferViewHelper(TexImageFunctionID, GCGLenum target, GCGLint level, GCGLint internalformat, GCGLsizei width, GCGLsizei height, GCGLsizei depth, GCGLint border, GCGLenum format, GCGLenum type, GCGLint xoffset, GCGLint yoffset, GCGLint zoffset, RefPtr<ArrayBufferView>&& pixels, NullDisposition, GCGLuint srcOffset);
    void texImageImpl(TexImageFunctionID, GCGLenum target, GCGLint level, GCGLenum internalformat, GCGLint xoffset, GCGLint yoffset, GCGLint zoffset, GCGLenum format, GCGLenum type, Image*, GraphicsContextGL::DOMSource, bool flipY, bool premultiplyAlpha, bool ignoreNativeImageAlphaPremultiplication, const IntRect&, GCGLsizei depth, GCGLint unpackImageHeight);
    void texImage2DBase(GCGLenum target, GCGLint level, GCGLenum internalformat, GCGLsizei width, GCGLsizei height, GCGLint border, GCGLenum format, GCGLenum type, GCGLsizei byteLength, const void* pixels);
    void texSubImage2DBase(GCGLenum target, GCGLint level, GCGLint xoffset, GCGLint yoffset, GCGLsizei width, GCGLsizei height, GCGLenum internalformat, GCGLenum format, GCGLenum type, GCGLsizei byteLength, const void* pixels);
    static const char* getTexImageFunctionName(TexImageFunctionID);
    using PixelStoreParams = GraphicsContextGL::PixelStoreParams;
    virtual PixelStoreParams getPackPixelStoreParams() const;
    virtual PixelStoreParams getUnpackPixelStoreParams(TexImageDimension) const;

#if !USE(ANGLE)
    bool checkTextureCompleteness(const char*, bool);

    void createFallbackBlackTextures1x1();

    // Helper function for copyTex{Sub}Image, check whether the internalformat
    // and the color buffer format of the current bound framebuffer combination
    // is valid.
    bool isTexInternalFormatColorBufferCombinationValid(GCGLenum texInternalFormat, GCGLenum colorBufferFormat);

    // Helper function to get the bound read framebuffer's color buffer format.
    GCGLenum getBoundReadFramebufferColorFormat();

    // Helper function to get the bound read framebuffer's width.
    int getBoundReadFramebufferWidth();

    // Helper function to get the bound read framebuffer's height.
    int getBoundReadFramebufferHeight();
#endif

    // Helper function to verify limits on the length of uniform and attribute locations.
    bool validateLocationLength(const char* functionName, const String&);

    // Helper function to check if size is non-negative.
    // Generate GL error and return false for negative inputs; otherwise, return true.
    bool validateSize(const char* functionName, GCGLint x, GCGLint y, GCGLint z = 0);

    // Helper function to check if all characters in the string belong to the
    // ASCII subset as defined in GLSL ES 1.0 spec section 3.1.
    bool validateString(const char* functionName, const String&);

    // Helper function to check target and texture bound to the target.
    // Generate GL errors and return 0 if target is invalid or texture bound is
    // null.  Otherwise, return the texture bound to the target.
    RefPtr<WebGLTexture> validateTextureBinding(const char* functionName, GCGLenum target);

    // Wrapper function for validateTexture2D(3D)Binding, used in texImageSourceHelper.
    virtual RefPtr<WebGLTexture> validateTexImageBinding(const char*, TexImageFunctionID, GCGLenum);

    // Helper function to check texture 2D target and texture bound to the target.
    // Generate GL errors and return 0 if target is invalid or texture bound is
    // null. Otherwise, return the texture bound to the target.
    RefPtr<WebGLTexture> validateTexture2DBinding(const char*, GCGLenum);

    void addExtensionSupportedFormatsAndTypes();
    void addExtensionSupportedFormatsAndTypesWebGL2();

    // Helper function to check input internalformat/format/type for functions
    // Tex{Sub}Image taking TexImageSource source data. Generates GL error and
    // returns false if parameters are invalid.
    bool validateTexImageSourceFormatAndType(const char* functionName, TexImageFunctionType, GCGLenum internalformat, GCGLenum format, GCGLenum type);

    // Helper function to check input format/type for functions {copy}Tex{Sub}Image.
    // Generates GL error and returns false if parameters are invalid.
    bool validateTexFuncFormatAndType(const char* functionName, GCGLenum internalformat, GCGLenum format, GCGLenum type, GCGLint level);

    // Helper function to check input level for functions {copy}Tex{Sub}Image.
    // Generates GL error and returns false if level is invalid.
    bool validateTexFuncLevel(const char* functionName, GCGLenum target, GCGLint level);
    virtual GCGLint maxTextureLevelForTarget(GCGLenum target);

    // Helper function for tex{Sub}Image{2|3}D to check if the input format/type/level/target/width/height/depth/border/xoffset/yoffset/zoffset are valid.
    // Otherwise, it would return quickly without doing other work.
    bool validateTexFunc(const char* functionName, TexImageFunctionType, TexFuncValidationSourceType, GCGLenum target, GCGLint level, GCGLenum internalformat, GCGLsizei width,
        GCGLsizei height, GCGLsizei depth, GCGLint border, GCGLenum format, GCGLenum type, GCGLint xoffset, GCGLint yoffset, GCGLint zoffset);

    // Helper function to check input parameters for functions {copy}Tex{Sub}Image.
    // Generates GL error and returns false if parameters are invalid.
    bool validateTexFuncParameters(const char* functionName,
        TexImageFunctionType,
        TexFuncValidationSourceType,
        GCGLenum target, GCGLint level,
        GCGLenum internalformat,
        GCGLsizei width, GCGLsizei height, GCGLsizei depth,
        GCGLint border,
        GCGLenum format, GCGLenum type);

    // Helper function to validate that the given ArrayBufferView
    // is of the correct type and contains enough data for the texImage call.
    // Generates GL error and returns false if parameters are invalid.
    bool validateTexFuncData(const char* functionName, TexImageDimension,
        GCGLsizei width, GCGLsizei height, GCGLsizei depth,
        GCGLenum format, GCGLenum type,
        ArrayBufferView* pixels,
        NullDisposition,
        GCGLuint srcOffset);

    // Helper function to validate a given texture format is settable as in
    // you can supply data to texImage2D, or call texImage2D, copyTexImage2D and
    // copyTexSubImage2D.
    // Generates GL error and returns false if the format is not settable.
    bool validateSettableTexInternalFormat(const char* functionName, GCGLenum format);

#if !USE(ANGLE)
    // Helper function to validate compressed texture data is correct size
    // for the given format and dimensions.
    bool validateCompressedTexFuncData(const char* functionName, GCGLsizei width, GCGLsizei height, GCGLenum format, ArrayBufferView& pixels);
#endif
    // Helper function for validating compressed texture formats.
    bool validateCompressedTexFormat(const char* functionName, GCGLenum format);

#if !USE(ANGLE)
    // Helper function to validate compressed texture dimensions are valid for
    // the given format.
    bool validateCompressedTexDimensions(const char* functionName, GCGLenum target, GCGLint level, GCGLsizei width, GCGLsizei height, GCGLenum format);

    // Helper function to validate compressed texture dimensions are valid for
    // the given format.
    bool validateCompressedTexSubDimensions(const char* functionName, GCGLenum target, GCGLint level, GCGLint xoffset, GCGLint yoffset,
        GCGLsizei width, GCGLsizei height, GCGLenum format, WebGLTexture*);
#endif

    // Helper function to validate mode for draw{Arrays/Elements}.
    bool validateDrawMode(const char* functionName, GCGLenum);

    // Helper function to validate if front/back stencilMask and stencilFunc settings are the same.
    bool validateStencilSettings(const char* functionName);

    // Helper function to validate stencil func.
    bool validateStencilFunc(const char* functionName, GCGLenum);

    // Helper function for texParameterf and texParameteri.
    void texParameter(GCGLenum target, GCGLenum pname, GCGLfloat parami, GCGLint paramf, bool isFloat);

    // Helper function to print errors and warnings to console.
    void printToConsole(MessageLevel, const String&);

    // Helper function to validate the target for checkFramebufferStatus and
    // validateFramebufferFuncParameters.
    virtual bool validateFramebufferTarget(GCGLenum target);

    // Get the framebuffer bound to the given target.
    virtual WebGLFramebuffer* getFramebufferBinding(GCGLenum target);

    virtual WebGLFramebuffer* getReadFramebufferBinding();

    // Helper function to validate input parameters for framebuffer functions.
    // Generate GL error if parameters are illegal.
    bool validateFramebufferFuncParameters(const char* functionName, GCGLenum target, GCGLenum attachment);

    // Helper function to validate blend equation mode.
    virtual bool validateBlendEquation(const char* functionName, GCGLenum) = 0;

    // Helper function to validate blend func factors.
    bool validateBlendFuncFactors(const char* functionName, GCGLenum src, GCGLenum dst);

    // Helper function to validate a GL capability.
    virtual bool validateCapability(const char* functionName, GCGLenum);

    // Helper function to validate input parameters for uniform functions.
    bool validateUniformLocation(const char* functionName, const WebGLUniformLocation*);
    template<typename T, typename TypedListType>
    std::optional<GCGLSpan<const T>> validateUniformParameters(const char* functionName, const WebGLUniformLocation* location, const TypedList<TypedListType, T>& values, GCGLsizei requiredMinSize, GCGLuint srcOffset = 0, GCGLuint srcLength = 0)
    {
        return validateUniformMatrixParameters(functionName, location, false, values, requiredMinSize, srcOffset, srcLength);
    }
    template<typename T, typename TypedListType>
    std::optional<GCGLSpan<const T>> validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation*, GCGLboolean transpose, const TypedList<TypedListType, T>&, GCGLsizei requiredMinSize, GCGLuint srcOffset = 0, GCGLuint srcLength = 0);

    // Helper function to validate parameters for bufferData.
    // Return the current bound buffer to target, or 0 if parameters are invalid.
    virtual WebGLBuffer* validateBufferDataParameters(const char* functionName, GCGLenum target, GCGLenum usage);

    // Helper function for tex{Sub}Image2D to make sure image is ready.
    ExceptionOr<bool> validateHTMLImageElement(const char* functionName, HTMLImageElement*);
    ExceptionOr<bool> validateHTMLCanvasElement(const char* functionName, HTMLCanvasElement*);
#if ENABLE(VIDEO)
    ExceptionOr<bool> validateHTMLVideoElement(const char* functionName, HTMLVideoElement*);
#endif
    ExceptionOr<bool> validateImageBitmap(const char* functionName, ImageBitmap*);

    // Helper functions for vertexAttribNf{v}.
    void vertexAttribfImpl(const char* functionName, GCGLuint index, GCGLsizei expectedSize, GCGLfloat, GCGLfloat, GCGLfloat, GCGLfloat);
    void vertexAttribfvImpl(const char* functionName, GCGLuint index, Float32List&&, GCGLsizei expectedSize);

    // Helper function for delete* (deleteBuffer, deleteProgram, etc) functions.
    // Return false if caller should return without further processing.
    bool deleteObject(const WTF::AbstractLocker&, WebGLObject*);

    // Helper function for APIs which can legally receive null objects, including
    // the bind* calls (bindBuffer, bindTexture, etc.) and useProgram. Checks that
    // the object belongs to this context and that it's not marked for deletion.
    // Returns false if the caller should return without further processing.
    // Performs a context lost check internally.
    // This returns true for null WebGLObject arguments!
    bool validateNullableWebGLObject(const char* functionName, WebGLObject*);

    // Helper function to validate the target for bufferData and
    // getBufferParameter.
    virtual bool validateBufferTarget(const char* functionName, GCGLenum target);

    // Helper function to validate the target for bufferData.
    // Return the current bound buffer to target, or 0 if the target is invalid.
    virtual WebGLBuffer* validateBufferDataTarget(const char* functionName, GCGLenum target);

    virtual bool validateAndCacheBufferBinding(const WTF::AbstractLocker&, const char* functionName, GCGLenum target, WebGLBuffer*);

#if !USE(ANGLE)
    // Helpers for simulating vertexAttrib0.
    void initVertexAttrib0();
    std::optional<bool> simulateVertexAttrib0(GCGLuint numVertex);
    bool validateSimulatedVertexAttrib0(GCGLuint numVertex);
    void restoreStatesAfterVertexAttrib0Simulation();
#endif

    // Wrapper for GraphicsContextGLOpenGL::synthesizeGLError that sends a message to the JavaScript console.
    enum ConsoleDisplayPreference { DisplayInConsole, DontDisplayInConsole };
    void synthesizeGLError(GCGLenum, const char* functionName, const char* description, ConsoleDisplayPreference = DisplayInConsole);

    String ensureNotNull(const String&) const;

    // Enable or disable stencil test based on user setting and whether the current FBO has a stencil buffer.
    void applyStencilTest();

    // Helper for enabling or disabling a capability.
    void enableOrDisable(GCGLenum capability, bool enable);

    // Clamp the width and height to GL_MAX_VIEWPORT_DIMS.
    IntSize clampedCanvasSize();

    virtual GCGLint getMaxDrawBuffers() = 0;
    virtual GCGLint getMaxColorAttachments() = 0;

    void setBackDrawBuffer(GCGLenum);
    void setFramebuffer(const WTF::AbstractLocker&, GCGLenum, WebGLFramebuffer*);

    virtual void restoreCurrentFramebuffer();
    void restoreCurrentTexture2D();

    // Check if EXT_draw_buffers extension is supported and if it satisfies the WebGL requirements.
    bool supportsDrawBuffers();

#if ENABLE(OFFSCREEN_CANVAS)
    OffscreenCanvas* offscreenCanvas();
#endif

    template <typename T> inline std::optional<T> checkedAddAndMultiply(T value, T add, T multiply);
    template <typename T> unsigned getMaxIndex(const RefPtr<JSC::ArrayBuffer> elementArrayBuffer, GCGLintptr uoffset, GCGLsizei n);

    bool validateArrayBufferType(const char* functionName, GCGLenum type, std::optional<JSC::TypedArrayType>);

private:
    void scheduleTaskToDispatchContextLostEvent();
    // Helper for restoration after context lost.
    void maybeRestoreContext();

    void registerWithWebGLStateTracker();
    void checkForContextLossHandling();

    void activityStateDidChange(OptionSet<ActivityState::Flag> oldActivityState, OptionSet<ActivityState::Flag> newActivityState) override;

    WebGLStateTracker::Token m_trackerToken;
    Timer m_checkForContextLossHandlingTimer;
    bool m_isSuspended { false };

#if ENABLE(WEBXR)
    bool m_isXRCompatible { false };
#endif
};

template <typename T>
inline std::optional<T> WebGLRenderingContextBase::checkedAddAndMultiply(T value, T add, T multiply)
{
    Checked<T, RecordOverflow> checkedResult = Checked<T>(value);
    checkedResult += Checked<T>(add);
    checkedResult *= Checked<T>(multiply);
    if (checkedResult.hasOverflowed())
        return std::nullopt;

    return checkedResult.value();
}

template<typename T>
inline unsigned WebGLRenderingContextBase::getMaxIndex(const RefPtr<JSC::ArrayBuffer> elementArrayBuffer, GCGLintptr uoffset, GCGLsizei n)
{
    unsigned maxIndex = 0;
    T restartIndex = 0;

#if ENABLE(WEBGL2)
    // WebGL 2 spec enforces that GL_PRIMITIVE_RESTART_FIXED_INDEX is always enabled, so ignore the restart index.
    if (isWebGL2())
        restartIndex = std::numeric_limits<T>::max();
#endif

    // Make uoffset an element offset.
    uoffset /= sizeof(T);
    const T* p = static_cast<const T*>(elementArrayBuffer->data()) + uoffset;
    while (n-- > 0) {
        if (*p != restartIndex && *p > maxIndex)
            maxIndex = *p;
        ++p;
    }

    return maxIndex;
}

} // namespace WebCore

SPECIALIZE_TYPE_TRAITS_CANVASRENDERINGCONTEXT(WebCore::WebGLRenderingContextBase, isWebGL())

#endif
