/*
 * Copyright (C) 2009 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 COMPUTER, 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 COMPUTER, 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.
 */

#ifndef WebGLRenderingContextBase_h
#define WebGLRenderingContextBase_h

#include "bindings/core/v8/Nullable.h"
#include "bindings/core/v8/ScriptState.h"
#include "bindings/core/v8/ScriptValue.h"
#include "bindings/core/v8/ScriptWrappable.h"
#include "bindings/core/v8/ScriptWrappableVisitor.h"
#include "core/CoreExport.h"
#include "core/dom/DOMTypedArray.h"
#include "core/dom/TypedFlexibleArrayBufferView.h"
#include "core/html/canvas/CanvasContextCreationAttributes.h"
#include "core/html/canvas/CanvasRenderingContext.h"
#include "core/layout/ContentChangeType.h"
#include "modules/webgl/WebGLContextAttributes.h"
#include "modules/webgl/WebGLExtensionName.h"
#include "modules/webgl/WebGLTexture.h"
#include "modules/webgl/WebGLVertexArrayObjectBase.h"
#include "platform/Timer.h"
#include "platform/graphics/ImageBuffer.h"
#include "platform/graphics/gpu/DrawingBuffer.h"
#include "platform/graphics/gpu/Extensions3DUtil.h"
#include "platform/graphics/gpu/WebGLImageConversion.h"
#include "public/platform/Platform.h"
#include "public/platform/WebGraphicsContext3DProvider.h"
#include "third_party/khronos/GLES2/gl2.h"
#include "wtf/CheckedNumeric.h"
#include "wtf/text/WTFString.h"
#include <memory>
#include <set>

namespace blink {
class WebLayer;
}

namespace gpu {
namespace gles2 {
class GLES2Interface;
}
}

namespace blink {

class EXTDisjointTimerQuery;
class EXTDisjointTimerQueryWebGL2;
class ExceptionState;
class HTMLCanvasElementOrOffscreenCanvas;
class HTMLImageElement;
class HTMLVideoElement;
class ImageBitmap;
class ImageBuffer;
class ImageData;
class IntSize;
class OESVertexArrayObject;
class WebGLActiveInfo;
class WebGLBuffer;
class WebGLCompressedTextureASTC;
class WebGLCompressedTextureATC;
class WebGLCompressedTextureETC;
class WebGLCompressedTextureETC1;
class WebGLCompressedTexturePVRTC;
class WebGLCompressedTextureS3TC;
class WebGLCompressedTextureS3TCsRGB;
class WebGLContextGroup;
class WebGLContextObject;
class WebGLDebugShaders;
class WebGLDrawBuffers;
class WebGLExtension;
class WebGLFramebuffer;
class WebGLObject;
class WebGLProgram;
class WebGLRenderbuffer;
class WebGLShader;
class WebGLShaderPrecisionFormat;
class WebGLUniformLocation;
class WebGLVertexArrayObjectBase;

class WebGLRenderingContextErrorMessageCallback;

// This class uses the color mask to prevent drawing to the alpha channel, if
// the DrawingBuffer requires RGB emulation.
class ScopedRGBEmulationColorMask {
  STACK_ALLOCATED();

 public:
  ScopedRGBEmulationColorMask(WebGLRenderingContextBase*,
                              GLboolean* colorMask,
                              DrawingBuffer*);
  ~ScopedRGBEmulationColorMask();

 private:
  Member<WebGLRenderingContextBase> m_context;
  GLboolean m_colorMask[4];
  const bool m_requiresEmulation;
};

class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext,
                                                 public DrawingBuffer::Client {
  WTF_MAKE_NONCOPYABLE(WebGLRenderingContextBase);

 public:
  ~WebGLRenderingContextBase() override;

  virtual String contextName() const = 0;
  virtual void registerContextExtensions() = 0;

  virtual void initializeNewContext();

  static unsigned getWebGLVersion(const CanvasRenderingContext*);

  static std::unique_ptr<WebGraphicsContext3DProvider>
  createWebGraphicsContext3DProvider(HTMLCanvasElement*,
                                     const CanvasContextCreationAttributes&,
                                     unsigned webGLVersion);
  static std::unique_ptr<WebGraphicsContext3DProvider>
  createWebGraphicsContext3DProvider(ScriptState*,
                                     const CanvasContextCreationAttributes&,
                                     unsigned webGLVersion);
  static void forceNextWebGLContextCreationToFail();

  unsigned version() const { return m_version; }

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

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

  void bufferData(GLenum target, long long size, GLenum usage);
  void bufferData(GLenum target, DOMArrayBuffer* data, GLenum usage);
  void bufferData(GLenum target, DOMArrayBufferView* data, GLenum usage);
  void bufferSubData(GLenum target, long long offset, DOMArrayBuffer* data);
  void bufferSubData(GLenum target,
                     long long offset,
                     const FlexibleArrayBufferView& data);

  GLenum checkFramebufferStatus(GLenum target);
  void clear(GLbitfield mask);
  void clearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
  void clearDepth(GLfloat);
  void clearStencil(GLint);
  void colorMask(GLboolean red,
                 GLboolean green,
                 GLboolean blue,
                 GLboolean alpha);
  void compileShader(WebGLShader*);

  void compressedTexImage2D(GLenum target,
                            GLint level,
                            GLenum internalformat,
                            GLsizei width,
                            GLsizei height,
                            GLint border,
                            DOMArrayBufferView* data);
  void compressedTexSubImage2D(GLenum target,
                               GLint level,
                               GLint xoffset,
                               GLint yoffset,
                               GLsizei width,
                               GLsizei height,
                               GLenum format,
                               DOMArrayBufferView* data);

  void copyTexImage2D(GLenum target,
                      GLint level,
                      GLenum internalformat,
                      GLint x,
                      GLint y,
                      GLsizei width,
                      GLsizei height,
                      GLint border);
  void copyTexSubImage2D(GLenum target,
                         GLint level,
                         GLint xoffset,
                         GLint yoffset,
                         GLint x,
                         GLint y,
                         GLsizei width,
                         GLsizei height);

  WebGLBuffer* createBuffer();
  WebGLFramebuffer* createFramebuffer();
  WebGLProgram* createProgram();
  WebGLRenderbuffer* createRenderbuffer();
  WebGLShader* createShader(GLenum type);
  WebGLTexture* createTexture();

  void cullFace(GLenum mode);

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

  void depthFunc(GLenum);
  void depthMask(GLboolean);
  void depthRange(GLfloat zNear, GLfloat zFar);
  void detachShader(WebGLProgram*, WebGLShader*);
  void disable(GLenum cap);
  void disableVertexAttribArray(GLuint index);
  void drawArrays(GLenum mode, GLint first, GLsizei count);
  void drawElements(GLenum mode, GLsizei count, GLenum type, long long offset);

  void drawArraysInstancedANGLE(GLenum mode,
                                GLint first,
                                GLsizei count,
                                GLsizei primcount);
  void drawElementsInstancedANGLE(GLenum mode,
                                  GLsizei count,
                                  GLenum type,
                                  long long offset,
                                  GLsizei primcount);

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

  WebGLActiveInfo* getActiveAttrib(WebGLProgram*, GLuint index);
  WebGLActiveInfo* getActiveUniform(WebGLProgram*, GLuint index);
  bool getAttachedShaders(WebGLProgram*, HeapVector<Member<WebGLShader>>&);
  Nullable<HeapVector<Member<WebGLShader>>> getAttachedShaders(WebGLProgram*);
  GLint getAttribLocation(WebGLProgram*, const String& name);
  ScriptValue getBufferParameter(ScriptState*, GLenum target, GLenum pname);
  void getContextAttributes(Nullable<WebGLContextAttributes>&);
  GLenum getError();
  ScriptValue getExtension(ScriptState*, const String& name);
  virtual ScriptValue getFramebufferAttachmentParameter(ScriptState*,
                                                        GLenum target,
                                                        GLenum attachment,
                                                        GLenum pname);
  virtual ScriptValue getParameter(ScriptState*, GLenum pname);
  ScriptValue getProgramParameter(ScriptState*, WebGLProgram*, GLenum pname);
  String getProgramInfoLog(WebGLProgram*);
  ScriptValue getRenderbufferParameter(ScriptState*,
                                       GLenum target,
                                       GLenum pname);
  ScriptValue getShaderParameter(ScriptState*, WebGLShader*, GLenum pname);
  String getShaderInfoLog(WebGLShader*);
  WebGLShaderPrecisionFormat* getShaderPrecisionFormat(GLenum shaderType,
                                                       GLenum precisionType);
  String getShaderSource(WebGLShader*);
  Nullable<Vector<String>> getSupportedExtensions();
  virtual ScriptValue getTexParameter(ScriptState*,
                                      GLenum target,
                                      GLenum pname);
  ScriptValue getUniform(ScriptState*,
                         WebGLProgram*,
                         const WebGLUniformLocation*);
  WebGLUniformLocation* getUniformLocation(WebGLProgram*, const String&);
  ScriptValue getVertexAttrib(ScriptState*, GLuint index, GLenum pname);
  long long getVertexAttribOffset(GLuint index, GLenum pname);

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

  void lineWidth(GLfloat);
  void linkProgram(WebGLProgram*);
  virtual void pixelStorei(GLenum pname, GLint param);
  void polygonOffset(GLfloat factor, GLfloat units);
  virtual void readPixels(GLint x,
                          GLint y,
                          GLsizei width,
                          GLsizei height,
                          GLenum format,
                          GLenum type,
                          DOMArrayBufferView* pixels);
  void renderbufferStorage(GLenum target,
                           GLenum internalformat,
                           GLsizei width,
                           GLsizei height);
  void sampleCoverage(GLfloat value, GLboolean invert);
  void scissor(GLint x, GLint y, GLsizei width, GLsizei height);
  void shaderSource(WebGLShader*, const String&);
  void stencilFunc(GLenum func, GLint ref, GLuint mask);
  void stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask);
  void stencilMask(GLuint);
  void stencilMaskSeparate(GLenum face, GLuint mask);
  void stencilOp(GLenum fail, GLenum zfail, GLenum zpass);
  void stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass);

  void texImage2D(GLenum target,
                  GLint level,
                  GLint internalformat,
                  GLsizei width,
                  GLsizei height,
                  GLint border,
                  GLenum format,
                  GLenum type,
                  DOMArrayBufferView*);
  void texImage2D(GLenum target,
                  GLint level,
                  GLint internalformat,
                  GLenum format,
                  GLenum type,
                  ImageData*);
  void texImage2D(GLenum target,
                  GLint level,
                  GLint internalformat,
                  GLenum format,
                  GLenum type,
                  HTMLImageElement*,
                  ExceptionState&);
  void texImage2D(GLenum target,
                  GLint level,
                  GLint internalformat,
                  GLenum format,
                  GLenum type,
                  HTMLCanvasElement*,
                  ExceptionState&);
  void texImage2D(GLenum target,
                  GLint level,
                  GLint internalformat,
                  GLenum format,
                  GLenum type,
                  HTMLVideoElement*,
                  ExceptionState&);
  void texImage2D(GLenum target,
                  GLint level,
                  GLint internalformat,
                  GLenum format,
                  GLenum type,
                  ImageBitmap*,
                  ExceptionState&);

  void texParameterf(GLenum target, GLenum pname, GLfloat param);
  void texParameteri(GLenum target, GLenum pname, GLint param);

  void texSubImage2D(GLenum target,
                     GLint level,
                     GLint xoffset,
                     GLint yoffset,
                     GLsizei width,
                     GLsizei height,
                     GLenum format,
                     GLenum type,
                     DOMArrayBufferView*);
  void texSubImage2D(GLenum target,
                     GLint level,
                     GLint xoffset,
                     GLint yoffset,
                     GLenum format,
                     GLenum type,
                     ImageData*);
  void texSubImage2D(GLenum target,
                     GLint level,
                     GLint xoffset,
                     GLint yoffset,
                     GLenum format,
                     GLenum type,
                     HTMLImageElement*,
                     ExceptionState&);
  void texSubImage2D(GLenum target,
                     GLint level,
                     GLint xoffset,
                     GLint yoffset,
                     GLenum format,
                     GLenum type,
                     HTMLCanvasElement*,
                     ExceptionState&);
  void texSubImage2D(GLenum target,
                     GLint level,
                     GLint xoffset,
                     GLint yoffset,
                     GLenum format,
                     GLenum type,
                     HTMLVideoElement*,
                     ExceptionState&);
  void texSubImage2D(GLenum target,
                     GLint level,
                     GLint xoffset,
                     GLint yoffset,
                     GLenum format,
                     GLenum type,
                     ImageBitmap*,
                     ExceptionState&);

  void uniform1f(const WebGLUniformLocation*, GLfloat x);
  void uniform1fv(const WebGLUniformLocation*, const FlexibleFloat32ArrayView&);
  void uniform1fv(const WebGLUniformLocation*, Vector<GLfloat>&);
  void uniform1i(const WebGLUniformLocation*, GLint x);
  void uniform1iv(const WebGLUniformLocation*, const FlexibleInt32ArrayView&);
  void uniform1iv(const WebGLUniformLocation*, Vector<GLint>&);
  void uniform2f(const WebGLUniformLocation*, GLfloat x, GLfloat y);
  void uniform2fv(const WebGLUniformLocation*, const FlexibleFloat32ArrayView&);
  void uniform2fv(const WebGLUniformLocation*, Vector<GLfloat>&);
  void uniform2i(const WebGLUniformLocation*, GLint x, GLint y);
  void uniform2iv(const WebGLUniformLocation*, const FlexibleInt32ArrayView&);
  void uniform2iv(const WebGLUniformLocation*, Vector<GLint>&);
  void uniform3f(const WebGLUniformLocation*, GLfloat x, GLfloat y, GLfloat z);
  void uniform3fv(const WebGLUniformLocation*, const FlexibleFloat32ArrayView&);
  void uniform3fv(const WebGLUniformLocation*, Vector<GLfloat>&);
  void uniform3i(const WebGLUniformLocation*, GLint x, GLint y, GLint z);
  void uniform3iv(const WebGLUniformLocation*, const FlexibleInt32ArrayView&);
  void uniform3iv(const WebGLUniformLocation*, Vector<GLint>&);
  void uniform4f(const WebGLUniformLocation*,
                 GLfloat x,
                 GLfloat y,
                 GLfloat z,
                 GLfloat w);
  void uniform4fv(const WebGLUniformLocation*, const FlexibleFloat32ArrayView&);
  void uniform4fv(const WebGLUniformLocation*, Vector<GLfloat>&);
  void uniform4i(const WebGLUniformLocation*,
                 GLint x,
                 GLint y,
                 GLint z,
                 GLint w);
  void uniform4iv(const WebGLUniformLocation*, const FlexibleInt32ArrayView&);
  void uniform4iv(const WebGLUniformLocation*, Vector<GLint>&);
  void uniformMatrix2fv(const WebGLUniformLocation*,
                        GLboolean transpose,
                        DOMFloat32Array* value);
  void uniformMatrix2fv(const WebGLUniformLocation*,
                        GLboolean transpose,
                        Vector<GLfloat>& value);
  void uniformMatrix3fv(const WebGLUniformLocation*,
                        GLboolean transpose,
                        DOMFloat32Array* value);
  void uniformMatrix3fv(const WebGLUniformLocation*,
                        GLboolean transpose,
                        Vector<GLfloat>& value);
  void uniformMatrix4fv(const WebGLUniformLocation*,
                        GLboolean transpose,
                        DOMFloat32Array* value);
  void uniformMatrix4fv(const WebGLUniformLocation*,
                        GLboolean transpose,
                        Vector<GLfloat>& value);

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

  void vertexAttrib1f(GLuint index, GLfloat x);
  void vertexAttrib1fv(GLuint index, const DOMFloat32Array* values);
  void vertexAttrib1fv(GLuint index, const Vector<GLfloat>& values);
  void vertexAttrib2f(GLuint index, GLfloat x, GLfloat y);
  void vertexAttrib2fv(GLuint index, const DOMFloat32Array* values);
  void vertexAttrib2fv(GLuint index, const Vector<GLfloat>& values);
  void vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z);
  void vertexAttrib3fv(GLuint index, const DOMFloat32Array* values);
  void vertexAttrib3fv(GLuint index, const Vector<GLfloat>& values);
  void vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
  void vertexAttrib4fv(GLuint index, const DOMFloat32Array* values);
  void vertexAttrib4fv(GLuint index, const Vector<GLfloat>& values);
  void vertexAttribPointer(GLuint index,
                           GLint size,
                           GLenum type,
                           GLboolean normalized,
                           GLsizei stride,
                           long long offset);

  void vertexAttribDivisorANGLE(GLuint index, GLuint divisor);

  void viewport(GLint x, GLint y, GLsizei width, GLsizei height);

  // WEBGL_lose_context support
  enum AutoRecoveryMethod {
    // Don't restore automatically.
    Manual,

    // Restore when resources are available.
    WhenAvailable,

    // Restore as soon as possible, but only when
    // the canvas is visible.
    Auto
  };
  void loseContext(LostContextMode) override;
  void forceLostContext(LostContextMode, AutoRecoveryMethod);
  void forceRestoreContext();
  void loseContextImpl(LostContextMode, AutoRecoveryMethod);
  uint32_t numberOfContextLosses() const;

  // Utilities to restore GL state to match the rendering context's
  // saved state. Use these after contextGL()-based state changes that
  // bypass the rendering context.
  void restoreScissorEnabled();
  void restoreScissorBox();
  void restoreClearColor();
  void restoreColorMask();

  gpu::gles2::GLES2Interface* contextGL() const {
    DrawingBuffer* d = drawingBuffer();
    if (!d)
      return nullptr;
    return d->contextGL();
  }
  WebGLContextGroup* contextGroup() const { return m_contextGroup.get(); }
  Extensions3DUtil* extensionsUtil();

  void reshape(int width, int height) override;

  void markLayerComposited() override;
  ImageData* paintRenderingResultsToImageData(SourceDrawingBuffer) override;

  unsigned maxVertexAttribs() const { return m_maxVertexAttribs; }

  DECLARE_VIRTUAL_TRACE();

  DECLARE_VIRTUAL_TRACE_WRAPPERS();

  // Returns approximate gpu memory allocated per pixel.
  int externallyAllocatedBytesPerPixel() override;

  class TextureUnitState {
    DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();

   public:
    TraceWrapperMember<WebGLTexture> m_texture2DBinding;
    TraceWrapperMember<WebGLTexture> m_textureCubeMapBinding;
    TraceWrapperMember<WebGLTexture> m_texture3DBinding;
    TraceWrapperMember<WebGLTexture> m_texture2DArrayBinding;

    DECLARE_TRACE();
    // Wrappers are traced by parent since TextureUnitState is not a heap
    // object.
  };

  PassRefPtr<Image> getImage(AccelerationHint, SnapshotReason) const override;
  ImageData* toImageData(SnapshotReason) override;
  void setFilterQuality(SkFilterQuality) override;
  bool isWebGL2OrHigher() { return version() >= 2; }

  void getHTMLOrOffscreenCanvas(HTMLCanvasElementOrOffscreenCanvas&) const;

  ScriptPromise commit(ScriptState*, ExceptionState&);

  // For use by WebVR which doesn't use the normal compositing path.
  // This clears the backbuffer if preserveDrawingBuffer is false.
  void markCompositedAndClearBackbufferIfNeeded();

 protected:
  friend class EXTDisjointTimerQuery;
  friend class EXTDisjointTimerQueryWebGL2;
  friend class WebGLDrawBuffers;
  friend class WebGLFramebuffer;
  friend class WebGLObject;
  friend class WebGLContextObject;
  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 WebGLRenderingContextErrorMessageCallback;
  friend class WebGLVertexArrayObjectBase;
  friend class ScopedDrawingBufferBinder;
  friend class ScopedTexture2DRestorer;
  friend class ScopedFramebufferRestorer;
  friend class ScopedUnpackParametersResetRestore;

  WebGLRenderingContextBase(HTMLCanvasElement*,
                            std::unique_ptr<WebGraphicsContext3DProvider>,
                            const CanvasContextCreationAttributes&,
                            unsigned);
  WebGLRenderingContextBase(OffscreenCanvas*,
                            std::unique_ptr<WebGraphicsContext3DProvider>,
                            const CanvasContextCreationAttributes&,
                            unsigned);
  PassRefPtr<DrawingBuffer> createDrawingBuffer(
      std::unique_ptr<WebGraphicsContext3DProvider>,
      DrawingBuffer::ChromiumImageUsage);
  void setupFlags();

  // CanvasRenderingContext implementation.
  bool is3d() const override { return true; }
  bool isComposited() const override { return true; }
  bool isAccelerated() const override { return true; }
  void setIsHidden(bool) override;
  bool paintRenderingResultsToCanvas(SourceDrawingBuffer) override;
  WebLayer* platformLayer() const override;
  void stop() override;
  void finalizeFrame() override;

  // DrawingBuffer::Client implementation.
  bool DrawingBufferClientIsBoundForDraw() override;
  void DrawingBufferClientRestoreScissorTest() override;
  void DrawingBufferClientRestoreMaskAndClearValues() override;
  void DrawingBufferClientRestorePixelPackAlignment() override;
  void DrawingBufferClientRestoreTexture2DBinding() override;
  void DrawingBufferClientRestoreRenderbufferBinding() override;
  void DrawingBufferClientRestoreFramebufferBinding() override;
  void DrawingBufferClientRestorePixelUnpackBufferBinding() override;

  virtual void destroyContext();
  void markContextChanged(ContentChangeType);

  void onErrorMessage(const char*, int32_t id);

  void notifyCanvasContextChanged();

  // Query if depth_stencil buffer is supported.
  bool isDepthStencilSupported() { return m_isDepthStencilSupported; }

  // Check if each enabled vertex attribute is bound to a buffer.
  bool validateRenderingState(const char*);

  bool validateWebGLObject(const char*, WebGLObject*);

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

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

  PassRefPtr<Image> drawImageIntoBuffer(PassRefPtr<Image>,
                                        int width,
                                        int height,
                                        const char* functionName);

  PassRefPtr<Image> videoFrameToImage(HTMLVideoElement*);

  // Structure for rendering to a DrawingBuffer, instead of directly
  // to the back-buffer of m_context.
  RefPtr<DrawingBuffer> m_drawingBuffer;
  DrawingBuffer* drawingBuffer() const;

  TraceWrapperMember<WebGLContextGroup> m_contextGroup;

  bool m_isHidden;
  LostContextMode m_contextLostMode;
  AutoRecoveryMethod m_autoRecoveryMethod;
  // Dispatches a context lost event once it is determined that one is needed.
  // This is used for synthetic, WEBGL_lose_context and real context losses. For
  // real ones, it's likely that there's no JavaScript on the stack, but that
  // might be dependent on how exactly the platform discovers that the context
  // was lost. For better portability we always defer the dispatch of the event.
  TaskRunnerTimer<WebGLRenderingContextBase> m_dispatchContextLostEventTimer;
  bool m_restoreAllowed;
  TaskRunnerTimer<WebGLRenderingContextBase> m_restoreTimer;

  bool m_markedCanvasDirty;
  bool m_animationFrameInProgress;

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

  Member<WebGLVertexArrayObjectBase> m_defaultVertexArrayObject;
  TraceWrapperMember<WebGLVertexArrayObjectBase> m_boundVertexArrayObject;
  void setBoundVertexArrayObject(WebGLVertexArrayObjectBase*);

  enum VertexAttribValueType {
    Float32ArrayType,
    Int32ArrayType,
    Uint32ArrayType,
  };

  Vector<VertexAttribValueType> m_vertexAttribType;
  unsigned m_maxVertexAttribs;
  void setVertexAttribType(GLuint index, VertexAttribValueType);

  TraceWrapperMember<WebGLProgram> m_currentProgram;
  TraceWrapperMember<WebGLFramebuffer> m_framebufferBinding;
  TraceWrapperMember<WebGLRenderbuffer> m_renderbufferBinding;

  HeapVector<TextureUnitState> m_textureUnits;
  unsigned long m_activeTextureUnit;

  Vector<GLenum> m_compressedTextureFormats;

  // Fixed-size cache of reusable image buffers for video texImage2D calls.
  class LRUImageBufferCache {
   public:
    LRUImageBufferCache(int capacity);
    // The pointer returned is owned by the image buffer map.
    ImageBuffer* imageBuffer(const IntSize&);

   private:
    void bubbleToFront(int idx);
    std::unique_ptr<std::unique_ptr<ImageBuffer>[]> m_buffers;
    int m_capacity;
  };
  LRUImageBufferCache m_generatedImageCache;

  GLint m_maxTextureSize;
  GLint m_maxCubeMapTextureSize;
  GLint m_max3DTextureSize;
  GLint m_maxArrayTextureLayers;
  GLint m_maxRenderbufferSize;
  GLint m_maxViewportDims[2];
  GLint m_maxTextureLevel;
  GLint m_maxCubeMapTextureLevel;
  GLint m_max3DTextureLevel;

  GLint m_maxDrawBuffers;
  GLint m_maxColorAttachments;
  GLenum m_backDrawBuffer;
  bool m_drawBuffersWebGLRequirementsChecked;
  bool m_drawBuffersSupported;

  GLenum m_readBufferOfDefaultFramebuffer;

  GLint m_packAlignment;
  GLint m_unpackAlignment;
  bool m_unpackFlipY;
  bool m_unpackPremultiplyAlpha;
  GLenum m_unpackColorspaceConversion;

  GLfloat m_clearColor[4];
  bool m_scissorEnabled;
  GLint m_scissorBox[4];
  GLfloat m_clearDepth;
  GLint m_clearStencil;
  GLboolean m_colorMask[4];
  GLboolean m_depthMask;

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

  bool m_isDepthStencilSupported;

  bool m_synthesizedErrorsToConsole;
  int m_numGLErrorsToConsoleAllowed;

  unsigned long m_onePlusMaxNonDefaultTextureUnit;

  std::unique_ptr<Extensions3DUtil> m_extensionsUtil;

  enum ExtensionFlags {
    ApprovedExtension = 0x00,
    // Extension that is behind the draft extensions runtime flag:
    DraftExtension = 0x01,
  };

  class ExtensionTracker : public GarbageCollected<ExtensionTracker>,
                           public TraceWrapperBase {
   public:
    ExtensionTracker(ExtensionFlags flags, const char* const* prefixes)
        : m_draft(flags & DraftExtension), m_prefixes(prefixes) {}

    bool draft() const { return m_draft; }

    const char* const* prefixes() const;
    bool matchesNameWithPrefixes(const String&) const;

    virtual WebGLExtension* getExtension(WebGLRenderingContextBase*) = 0;
    virtual bool supported(WebGLRenderingContextBase*) const = 0;
    virtual const char* extensionName() const = 0;
    virtual void loseExtension(bool) = 0;

    // This is only used for keeping the JS wrappers of extensions alive.
    virtual WebGLExtension* getExtensionObjectIfAlreadyEnabled() = 0;

    DEFINE_INLINE_VIRTUAL_TRACE() {}

   private:
    bool m_draft;
    const char* const* m_prefixes;
  };

  template <typename T>
  class TypedExtensionTracker final : public ExtensionTracker {
   public:
    static TypedExtensionTracker<T>* create(Member<T>& extensionField,
                                            ExtensionFlags flags,
                                            const char* const* prefixes) {
      return new TypedExtensionTracker<T>(extensionField, flags, prefixes);
    }

    WebGLExtension* getExtension(WebGLRenderingContextBase* context) override {
      if (!m_extension) {
        m_extension = T::create(context);
        m_extensionField = m_extension;
      }

      return m_extension;
    }

    bool supported(WebGLRenderingContextBase* context) const override {
      return T::supported(context);
    }

    const char* extensionName() const override { return T::extensionName(); }

    void loseExtension(bool force) override {
      if (m_extension) {
        m_extension->lose(force);
        if (m_extension->isLost())
          m_extension = nullptr;
      }
    }

    WebGLExtension* getExtensionObjectIfAlreadyEnabled() override {
      return m_extension;
    }

    DEFINE_INLINE_VIRTUAL_TRACE() {
      visitor->trace(m_extension);
      ExtensionTracker::trace(visitor);
    }

    DEFINE_INLINE_VIRTUAL_TRACE_WRAPPERS() {
      visitor->traceWrappers(m_extension);
    }

   private:
    TypedExtensionTracker(Member<T>& extensionField,
                          ExtensionFlags flags,
                          const char* const* prefixes)
        : ExtensionTracker(flags, prefixes),
          m_extensionField(extensionField),
          m_extension(this, nullptr) {}

    GC_PLUGIN_IGNORE("http://crbug.com/519953")
    Member<T>& m_extensionField;
    // ExtensionTracker holds it's own reference to the extension to ensure
    // that it is not deleted before this object's destructor is called
    TraceWrapperMember<T> m_extension;
  };

  bool m_extensionEnabled[WebGLExtensionNameCount];
  HeapVector<TraceWrapperMember<ExtensionTracker>> m_extensions;

  template <typename T>
  void registerExtension(Member<T>& extensionPtr,
                         ExtensionFlags flags = ApprovedExtension,
                         const char* const* prefixes = nullptr) {
    m_extensions.push_back(TraceWrapperMember<ExtensionTracker>(
        this, TypedExtensionTracker<T>::create(extensionPtr, flags, prefixes)));
  }

  bool extensionSupportedAndAllowed(const ExtensionTracker*);

  inline bool extensionEnabled(WebGLExtensionName name) {
    return m_extensionEnabled[name];
  }

  // ScopedDrawingBufferBinder is used for
  // ReadPixels/CopyTexImage2D/CopySubImage2D to read from a multisampled
  // DrawingBuffer. In this situation, we need to blit to a single sampled
  // buffer for reading, during which the bindings could be changed and need to
  // be recovered.
  class ScopedDrawingBufferBinder {
    STACK_ALLOCATED();

   public:
    ScopedDrawingBufferBinder(DrawingBuffer* drawingBuffer,
                              WebGLFramebuffer* framebufferBinding)
        : m_drawingBuffer(drawingBuffer),
          m_readFramebufferBinding(framebufferBinding) {
      // Commit DrawingBuffer if needed (e.g., for multisampling)
      if (!m_readFramebufferBinding && m_drawingBuffer)
        m_drawingBuffer->resolveAndBindForReadAndDraw();
    }

    ~ScopedDrawingBufferBinder() {
      // Restore DrawingBuffer if needed
      if (!m_readFramebufferBinding && m_drawingBuffer)
        m_drawingBuffer->restoreFramebufferBindings();
    }

   private:
    DrawingBuffer* m_drawingBuffer;
    Member<WebGLFramebuffer> m_readFramebufferBinding;
  };

  // Errors raised by synthesizeGLError() while the context is lost.
  Vector<GLenum> m_lostContextErrors;
  // Other errors raised by synthesizeGLError().
  Vector<GLenum> m_syntheticErrors;

  bool m_isWebGL2FormatsTypesAdded;
  bool m_isWebGL2TexImageSourceFormatsTypesAdded;
  bool m_isWebGL2InternalFormatsCopyTexImageAdded;
  bool m_isOESTextureFloatFormatsTypesAdded;
  bool m_isOESTextureHalfFloatFormatsTypesAdded;
  bool m_isWebGLDepthTextureFormatsTypesAdded;
  bool m_isEXTsRGBFormatsTypesAdded;

  std::set<GLenum> m_supportedInternalFormats;
  std::set<GLenum> m_supportedTexImageSourceInternalFormats;
  std::set<GLenum> m_supportedInternalFormatsCopyTexImage;
  std::set<GLenum> m_supportedFormats;
  std::set<GLenum> m_supportedTexImageSourceFormats;
  std::set<GLenum> m_supportedTypes;
  std::set<GLenum> m_supportedTexImageSourceTypes;

  // Helpers for getParameter and others
  ScriptValue getBooleanParameter(ScriptState*, GLenum);
  ScriptValue getBooleanArrayParameter(ScriptState*, GLenum);
  ScriptValue getFloatParameter(ScriptState*, GLenum);
  ScriptValue getIntParameter(ScriptState*, GLenum);
  ScriptValue getInt64Parameter(ScriptState*, GLenum);
  ScriptValue getUnsignedIntParameter(ScriptState*, GLenum);
  ScriptValue getWebGLFloatArrayParameter(ScriptState*, GLenum);
  ScriptValue getWebGLIntArrayParameter(ScriptState*, GLenum);

  // 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 |CombinedClear| if that clear is now
  // unnecessary.
  enum HowToClear {
    // Skip clearing the backbuffer.
    Skipped,
    // Clear the backbuffer.
    JustClear,
    // Combine webgl.clear() API with the backbuffer clear, so webgl.clear()
    // doesn't have to call glClear() again.
    CombinedClear
  };
  HowToClear clearIfComposited(GLbitfield clearMask = 0);

  // Convert texture internal format.
  GLenum convertTexInternalFormat(GLenum internalformat, GLenum type);

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

  // This must stay in sync with WebMediaPlayer::TexImageFunctionID.
  enum TexImageFunctionID {
    TexImage2D,
    TexSubImage2D,
    TexImage3D,
    TexSubImage3D
  };

  static SnapshotReason functionIDToSnapshotReason(TexImageFunctionID);

  enum TexImageDimension { Tex2D, Tex3D };
  void texImage2DBase(GLenum target,
                      GLint level,
                      GLint internalformat,
                      GLsizei width,
                      GLsizei height,
                      GLint border,
                      GLenum format,
                      GLenum type,
                      const void* pixels);
  void texImageImpl(TexImageFunctionID,
                    GLenum target,
                    GLint level,
                    GLint internalformat,
                    GLint xoffset,
                    GLint yoffset,
                    GLint zoffset,
                    GLenum format,
                    GLenum type,
                    Image*,
                    WebGLImageConversion::ImageHtmlDomSource,
                    bool flipY,
                    bool premultiplyAlpha,
                    const IntRect&,
                    GLsizei depth,
                    GLint unpackImageHeight);

  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,
                                    GLsizei depth,
                                    GLint unpackImageHeight,
                                    bool* selectingSubRectangle) {
    DCHECK(functionName);
    DCHECK(selectingSubRectangle);
    DCHECK(image);
    int imageWidth = static_cast<int>(image->width());
    int imageHeight = static_cast<int>(image->height());
    *selectingSubRectangle =
        !(subRect.x() == 0 && subRect.y() == 0 &&
          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 or
    // higher, 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.
    DCHECK(!*selectingSubRectangle || isWebGL2OrHigher())
        << "subRect = (" << subRect.width() << " x " << subRect.height()
        << ") @ (" << subRect.x() << ", " << subRect.y() << "), image = ("
        << imageWidth << " x " << imageHeight << ")";

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

    if (functionID == TexImage3D || functionID == TexSubImage3D) {
      DCHECK_GE(unpackImageHeight, 0);

      if (depth < 1) {
        synthesizeGLError(GL_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.
      WTF::CheckedNumeric<GLint> maxYAccessed;
      if (unpackImageHeight) {
        maxYAccessed = unpackImageHeight;
      } else {
        maxYAccessed = subRect.height();
      }
      maxYAccessed *= depth - 1;
      maxYAccessed += subRect.height();
      maxYAccessed += subRect.y();

      if (!maxYAccessed.IsValid()) {
        synthesizeGLError(GL_INVALID_OPERATION, functionName,
                          "Out-of-range parameters passed for 3D texture "
                          "upload");
        return false;
      }

      if (maxYAccessed.ValueOrDie() > imageHeight) {
        synthesizeGLError(GL_INVALID_OPERATION, functionName,
                          "Not enough data supplied to upload to a 3D texture "
                          "with depth > 1");
        return false;
      }
    } else {
      DCHECK_EQ(depth, 1);
      DCHECK_EQ(unpackImageHeight, 0);
    }
    return true;
  }

  // Copy from the source directly to the texture via the gpu, without a
  // read-back to system memory.  Source could be canvas or imageBitmap.
  void texImageByGPU(TexImageFunctionID,
                     WebGLTexture*,
                     GLenum target,
                     GLint level,
                     GLint internalformat,
                     GLenum type,
                     GLint xoffset,
                     GLint yoffset,
                     GLint zoffset,
                     CanvasImageSource*,
                     const IntRect& sourceSubRectangle);
  virtual bool canUseTexImageByGPU(TexImageFunctionID,
                                   GLint internalformat,
                                   GLenum type);

  virtual WebGLImageConversion::PixelStoreParams getPackPixelStoreParams();
  virtual WebGLImageConversion::PixelStoreParams getUnpackPixelStoreParams(
      TexImageDimension);

  // 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(GLenum texInternalFormat,
                                                      GLenum colorBufferFormat);

  // Helper function to verify limits on the length of uniform and attribute
  // locations.
  virtual unsigned getMaxWebGLLocationLength() const { return 256; }
  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, GLint x, GLint y, GLint 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 if all characters in the shader source belong to
  // the ASCII subset as defined in GLSL ES 1.0 spec section 3.1 Character Set
  // for WebGL 1.0 and in GLSL ES 3.00 spec section 3.1 Character Set for WebGL
  // 2.0.
  bool validateShaderSource(const String&);

  // Helper function to check texture binding 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.
  WebGLTexture* validateTextureBinding(const char* functionName, GLenum target);

  // Wrapper function for validateTexture2D(3D)Binding, used in texImageHelper
  // functions.
  virtual WebGLTexture* validateTexImageBinding(const char*,
                                                TexImageFunctionID,
                                                GLenum);

  // 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.
  WebGLTexture* validateTexture2DBinding(const char* functionName,
                                         GLenum target);

  void addExtensionSupportedFormatsTypes();

  // 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,
                                           GLenum internalformat,
                                           GLenum format,
                                           GLenum type);

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

  // Helper function to check readbuffer validity for copyTex{Sub}Image.
  // If yes, obtains the bound read framebuffer, returns true.
  // If not, generates a GL error, returns false.
  bool validateReadBufferAndGetInfo(const char* functionName,
                                    WebGLFramebuffer*& readFramebufferBinding);

  // Helper function to check format/type and ArrayBuffer view type for
  // readPixels.
  // Generates INVALID_ENUM and returns false if parameters are invalid.
  // Generates INVALID_OPERATION if ArrayBuffer view type is incompatible with
  // type.
  virtual bool validateReadPixelsFormatAndType(GLenum format,
                                               GLenum type,
                                               DOMArrayBufferView*);

  // Helper function to check parameters of readPixels. Returns true if all
  // parameters are valid. Otherwise, generates appropriate error and returns
  // false.
  bool validateReadPixelsFuncParameters(GLsizei width,
                                        GLsizei height,
                                        GLenum format,
                                        GLenum type,
                                        DOMArrayBufferView*,
                                        long long bufferSize);

  virtual GLint getMaxTextureLevelForTarget(GLenum target);

  // 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,
                            GLenum target,
                            GLint level);

  // Helper function to check if a 64-bit value is non-negative and can fit into
  // a 32-bit integer.  Generates GL error and returns false if not.
  bool validateValueFitNonNegInt32(const char* functionName,
                                   const char* paramName,
                                   long long value);

  enum TexFuncValidationSourceType {
    SourceArrayBufferView,
    SourceImageData,
    SourceHTMLImageElement,
    SourceHTMLCanvasElement,
    SourceHTMLVideoElement,
    SourceImageBitmap,
    SourceUnpackBuffer,
  };

  // 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,
                       GLenum target,
                       GLint level,
                       GLenum internalformat,
                       GLsizei width,
                       GLsizei height,
                       GLsizei depth,
                       GLint border,
                       GLenum format,
                       GLenum type,
                       GLint xoffset,
                       GLint yoffset,
                       GLint zoffset);

  // Helper function to check input width and height for functions {copy,
  // compressed}Tex{Sub}Image.  Generates GL error and returns false if width or
  // height is invalid.
  bool validateTexFuncDimensions(const char* functionName,
                                 TexImageFunctionType,
                                 GLenum target,
                                 GLint level,
                                 GLsizei width,
                                 GLsizei height,
                                 GLsizei depth);

  // 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,
                                 GLenum target,
                                 GLint level,
                                 GLenum internalformat,
                                 GLsizei width,
                                 GLsizei height,
                                 GLsizei depth,
                                 GLint border,
                                 GLenum format,
                                 GLenum type);

  enum NullDisposition { NullAllowed, NullNotAllowed, NullNotReachable };

  // 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,
                           GLint level,
                           GLsizei width,
                           GLsizei height,
                           GLsizei depth,
                           GLenum format,
                           GLenum type,
                           DOMArrayBufferView* pixels,
                           NullDisposition,
                           GLuint 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 validateSettableTexFormat(const char* functionName, GLenum format);

  // Helper function to validate format for CopyTexImage.
  bool validateCopyTexFormat(const char* functionName, GLenum format);

  // Helper function for validating compressed texture formats.
  bool validateCompressedTexFormat(const char* functionName, GLenum format);

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

  // Helper function to validate stencil or depth func.
  bool validateStencilOrDepthFunc(const char* functionName, GLenum);

  // Helper function for texParameterf and texParameteri.
  void texParameter(GLenum target,
                    GLenum pname,
                    GLfloat paramf,
                    GLint parami,
                    bool isFloat);

  // Helper function to print GL errors to console.
  void printGLErrorToConsole(const String&);

  // Helper function to print warnings to console. Currently
  // used only to warn about use of obsolete functions.
  void printWarningToConsole(const String&);

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

  // Get the framebuffer bound to given target
  virtual WebGLFramebuffer* getFramebufferBinding(GLenum 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,
                                         GLenum target,
                                         GLenum attachment);

  // Helper function to validate blend equation mode.
  bool validateBlendEquation(const char* functionName, GLenum);

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

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

  // Helper function to validate input parameters for uniform functions.
  bool validateUniformParameters(const char* functionName,
                                 const WebGLUniformLocation*,
                                 void*,
                                 GLsizei,
                                 GLsizei mod,
                                 GLuint srcOffset,
                                 GLuint srcLength);
  bool validateUniformMatrixParameters(const char* functionName,
                                       const WebGLUniformLocation*,
                                       GLboolean transpose,
                                       DOMFloat32Array*,
                                       GLsizei mod,
                                       GLuint srcOffset,
                                       GLuint srcLength);
  bool validateUniformMatrixParameters(const char* functionName,
                                       const WebGLUniformLocation*,
                                       GLboolean transpose,
                                       void*,
                                       GLsizei,
                                       GLsizei mod,
                                       GLuint srcOffset,
                                       GLuint srcLength);

  template <typename WTFTypedArray>
  bool validateUniformParameters(
      const char* functionName,
      const WebGLUniformLocation* location,
      const TypedFlexibleArrayBufferView<WTFTypedArray>& v,
      GLsizei requiredMinSize,
      GLuint srcOffset,
      GLuint srcLength) {
    if (!v.dataMaybeOnStack()) {
      synthesizeGLError(GL_INVALID_VALUE, functionName, "no array");
      return false;
    }
    return validateUniformMatrixParameters(
        functionName, location, false, v.dataMaybeOnStack(), v.length(),
        requiredMinSize, srcOffset, srcLength);
  }

  // Helper function to validate the target for bufferData and
  // getBufferParameter.
  virtual bool validateBufferTarget(const char* functionName, GLenum 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,
                                                GLenum target);
  // Helper function to validate the usage for bufferData.
  virtual bool validateBufferDataUsage(const char* functionName, GLenum usage);

  virtual bool validateAndUpdateBufferBindTarget(const char* functionName,
                                                 GLenum target,
                                                 WebGLBuffer*);

  virtual void removeBoundBuffer(WebGLBuffer*);

  // Helper function for tex{Sub}Image2D to make sure image is ready and
  // wouldn't taint Origin.
  bool validateHTMLImageElement(const char* functionName,
                                HTMLImageElement*,
                                ExceptionState&);

  // Helper function for tex{Sub}Image2D to make sure canvas is ready and
  // wouldn't taint Origin.
  bool validateHTMLCanvasElement(const char* functionName,
                                 HTMLCanvasElement*,
                                 ExceptionState&);

  // Helper function for tex{Sub}Image2D to make sure video is ready wouldn't
  // taint Origin.
  bool validateHTMLVideoElement(const char* functionName,
                                HTMLVideoElement*,
                                ExceptionState&);

  // Helper function for tex{Sub}Image2D to make sure imagebitmap is ready and
  // wouldn't taint Origin.
  bool validateImageBitmap(const char* functionName,
                           ImageBitmap*,
                           ExceptionState&);

  // Helper function to validate drawArrays(Instanced) calls
  bool validateDrawArrays(const char* functionName);

  // Helper function to validate drawElements(Instanced) calls
  bool validateDrawElements(const char* functionName,
                            GLenum type,
                            long long offset);

  // Helper functions to bufferData() and bufferSubData().
  void bufferDataImpl(GLenum target,
                      long long size,
                      const void* data,
                      GLenum usage);
  void bufferSubDataImpl(GLenum target,
                         long long offset,
                         GLsizeiptr,
                         const void* data);

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

  // Helper function for bind* (bindBuffer, bindTexture, etc) and useProgram.
  // If the object has already been deleted, set deleted to true upon return.
  // Return false if caller should return without further processing.
  bool checkObjectToBeBound(const char* functionName,
                            WebGLObject*,
                            bool& deleted);

  void dispatchContextLostEvent(TimerBase*);
  // Helper for restoration after context lost.
  void maybeRestoreContext(TimerBase*);

  enum ConsoleDisplayPreference { DisplayInConsole, DontDisplayInConsole };

  // Reports an error to glGetError, sends a message to the JavaScript
  // console.
  void synthesizeGLError(GLenum,
                         const char* functionName,
                         const char* description,
                         ConsoleDisplayPreference = DisplayInConsole);
  void emitGLWarning(const char* function, const char* reason);

  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(GLenum capability, bool enable);

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

  // First time called, if EXT_draw_buffers is supported, query the value;
  // otherwise return 0.  Later, return the cached value.
  GLint maxDrawBuffers();
  GLint maxColorAttachments();

  void setBackDrawBuffer(GLenum);
  void setFramebuffer(GLenum, WebGLFramebuffer*);

  virtual void restoreCurrentFramebuffer();
  void restoreCurrentTexture2D();

  void findNewMaxNonDefaultTextureUnit();

  virtual void renderbufferStorageImpl(GLenum target,
                                       GLsizei samples,
                                       GLenum internalformat,
                                       GLsizei width,
                                       GLsizei height,
                                       const char* functionName);

  friend class WebGLStateRestorer;
  friend class WebGLRenderingContextEvictionManager;

  static void activateContext(WebGLRenderingContextBase*);
  static void deactivateContext(WebGLRenderingContextBase*);
  static void addToEvictedList(WebGLRenderingContextBase*);
  static void removeFromEvictedList(WebGLRenderingContextBase*);
  static void restoreEvictedContext(WebGLRenderingContextBase*);
  static void forciblyLoseOldestContext(const String& reason);
  // Return the least recently used context's position in the active context
  // vector.  If the vector is empty, return the maximum allowed active context
  // number.
  static WebGLRenderingContextBase* oldestContext();
  static WebGLRenderingContextBase* oldestEvictedContext();

  friend class ScopedRGBEmulationColorMask;
  unsigned m_activeScopedRGBEmulationColorMasks;

  ImageBitmap* transferToImageBitmapBase(ScriptState*);

  // Helper functions for tex(Sub)Image2D && texSubImage3D
  void texImageHelperDOMArrayBufferView(TexImageFunctionID,
                                        GLenum,
                                        GLint,
                                        GLint,
                                        GLsizei,
                                        GLsizei,
                                        GLsizei,
                                        GLint,
                                        GLenum,
                                        GLenum,
                                        GLint,
                                        GLint,
                                        GLint,
                                        DOMArrayBufferView*,
                                        NullDisposition,
                                        GLuint srcOffset);
  void texImageHelperImageData(TexImageFunctionID,
                               GLenum,
                               GLint,
                               GLint,
                               GLint,
                               GLenum,
                               GLenum,
                               GLsizei,
                               GLint,
                               GLint,
                               GLint,
                               ImageData*,
                               const IntRect&,
                               GLint);
  void texImageHelperHTMLImageElement(TexImageFunctionID,
                                      GLenum,
                                      GLint,
                                      GLint,
                                      GLenum,
                                      GLenum,
                                      GLint,
                                      GLint,
                                      GLint,
                                      HTMLImageElement*,
                                      const IntRect&,
                                      GLsizei,
                                      GLint,
                                      ExceptionState&);
  void texImageHelperHTMLCanvasElement(TexImageFunctionID,
                                       GLenum,
                                       GLint,
                                       GLint,
                                       GLenum,
                                       GLenum,
                                       GLint,
                                       GLint,
                                       GLint,
                                       HTMLCanvasElement*,
                                       const IntRect&,
                                       GLsizei,
                                       GLint,
                                       ExceptionState&);
  void texImageHelperHTMLVideoElement(TexImageFunctionID,
                                      GLenum,
                                      GLint,
                                      GLint,
                                      GLenum,
                                      GLenum,
                                      GLint,
                                      GLint,
                                      GLint,
                                      HTMLVideoElement*,
                                      const IntRect&,
                                      GLsizei,
                                      GLint,
                                      ExceptionState&);
  void texImageHelperImageBitmap(TexImageFunctionID,
                                 GLenum,
                                 GLint,
                                 GLint,
                                 GLenum,
                                 GLenum,
                                 GLint,
                                 GLint,
                                 GLint,
                                 ImageBitmap*,
                                 const IntRect&,
                                 GLsizei,
                                 GLint,
                                 ExceptionState&);
  static const char* getTexImageFunctionName(TexImageFunctionID);
  IntRect sentinelEmptyRect();
  IntRect safeGetImageSize(Image*);
  IntRect getImageDataSize(ImageData*);

  // Helper implementing readPixels for WebGL 1.0 and 2.0.
  void readPixelsHelper(GLint x,
                        GLint y,
                        GLsizei width,
                        GLsizei height,
                        GLenum format,
                        GLenum type,
                        DOMArrayBufferView* pixels,
                        GLuint offset);

 private:
  WebGLRenderingContextBase(HTMLCanvasElement*,
                            OffscreenCanvas*,
                            RefPtr<WebTaskRunner>,
                            std::unique_ptr<WebGraphicsContext3DProvider>,
                            const CanvasContextCreationAttributes&,
                            unsigned);
  static bool supportOwnOffscreenSurface(ExecutionContext*);
  static std::unique_ptr<WebGraphicsContext3DProvider>
  createContextProviderInternal(HTMLCanvasElement*,
                                ScriptState*,
                                const CanvasContextCreationAttributes&,
                                unsigned);
  void texImageCanvasByGPU(TexImageFunctionID,
                           HTMLCanvasElement*,
                           GLuint,
                           GLenum,
                           GLenum,
                           GLint,
                           GLint,
                           GLint,
                           const IntRect& sourceSubRectangle);
  void texImageBitmapByGPU(ImageBitmap*, GLuint, GLenum, GLenum, GLint, bool);

  sk_sp<SkImage> makeImageSnapshot(SkImageInfo&);
  const unsigned m_version;

  bool isPaintable() const final { return drawingBuffer(); }
};

DEFINE_TYPE_CASTS(WebGLRenderingContextBase,
                  CanvasRenderingContext,
                  context,
                  context->is3d(),
                  context.is3d());

}  // namespace blink

WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(
    blink::WebGLRenderingContextBase::TextureUnitState);

#endif  // WebGLRenderingContextBase_h
