/*
 * 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 <memory>
#include <set>
#include "bindings/core/v8/Nullable.h"
#include "bindings/core/v8/ScriptValue.h"
#include "core/CoreExport.h"
#include "core/html/canvas/CanvasContextCreationAttributes.h"
#include "core/html/canvas/CanvasRenderingContext.h"
#include "core/layout/ContentChangeType.h"
#include "core/typed_arrays/ArrayBufferViewHelpers.h"
#include "core/typed_arrays/DOMTypedArray.h"
#include "core/typed_arrays/TypedFlexibleArrayBufferView.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/bindings/ScriptState.h"
#include "platform/bindings/ScriptWrappable.h"
#include "platform/bindings/ScriptWrappableVisitor.h"
#include "platform/graphics/gpu/DrawingBuffer.h"
#include "platform/graphics/gpu/Extensions3DUtil.h"
#include "platform/graphics/gpu/WebGLImageConversion.h"
#include "platform/wtf/CheckedNumeric.h"
#include "platform/wtf/text/WTFString.h"
#include "public/platform/Platform.h"
#include "public/platform/WebGraphicsContext3DProvider.h"
#include "third_party/khronos/GLES2/gl2.h"

namespace blink {
class WebLayer;
}

namespace gpu {
namespace gles2 {
class GLES2Interface;
}
}

namespace blink {

class CanvasResourceProvider;
class EXTDisjointTimerQuery;
class EXTDisjointTimerQueryWebGL2;
class ExceptionState;
class HTMLCanvasElementOrOffscreenCanvas;
class HTMLImageElement;
class HTMLVideoElement;
class ImageBitmap;
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* color_mask,
                              DrawingBuffer*);
  ~ScopedRGBEmulationColorMask();

 private:
  Member<WebGLRenderingContextBase> context_;
  GLboolean color_mask_[4];
  const bool requires_emulation_;
};

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

 public:
  ~WebGLRenderingContextBase() override;

  HTMLCanvasElement* canvas() const {
    if (Host()->IsOffscreenCanvas())
      return nullptr;
    return static_cast<HTMLCanvasElement*>(Host());
  }

  virtual String ContextName() const = 0;
  virtual void RegisterContextExtensions() = 0;

  virtual void InitializeNewContext();

  static unsigned GetWebGLVersion(const CanvasRenderingContext*);

  static std::unique_ptr<WebGraphicsContext3DProvider>
  CreateWebGraphicsContext3DProvider(CanvasRenderingContextHost*,
                                     const CanvasContextCreationAttributes&,
                                     unsigned web_gl_version,
                                     bool* using_gpu_compositing);
  static void ForceNextWebGLContextCreationToFail();

  unsigned Version() const { return 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 mode_rgb, GLenum mode_alpha);
  void blendFunc(GLenum sfactor, GLenum dfactor);
  void blendFuncSeparate(GLenum src_rgb,
                         GLenum dst_rgb,
                         GLenum src_alpha,
                         GLenum dst_alpha);

  void bufferData(GLenum target, long long size, GLenum usage);
  void bufferData(GLenum target, DOMArrayBuffer* data, GLenum usage);
  void bufferData(GLenum target,
                  MaybeShared<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,
                            MaybeShared<DOMArrayBufferView> data);
  void compressedTexSubImage2D(GLenum target,
                               GLint level,
                               GLint xoffset,
                               GLint yoffset,
                               GLsizei width,
                               GLsizei height,
                               GLenum format,
                               MaybeShared<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 z_near, GLfloat z_far);
  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 shader_type,
                                                       GLenum precision_type);
  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,
                          MaybeShared<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,
                  MaybeShared<DOMArrayBufferView>);
  void texImage2D(GLenum target,
                  GLint level,
                  GLint internalformat,
                  GLenum format,
                  GLenum type,
                  ImageData*);
  void texImage2D(ExecutionContext*,
                  GLenum target,
                  GLint level,
                  GLint internalformat,
                  GLenum format,
                  GLenum type,
                  HTMLImageElement*,
                  ExceptionState&);
  void texImage2D(ExecutionContext*,
                  GLenum target,
                  GLint level,
                  GLint internalformat,
                  GLenum format,
                  GLenum type,
                  HTMLCanvasElement*,
                  ExceptionState&);
  void texImage2D(ExecutionContext*,
                  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,
                     MaybeShared<DOMArrayBufferView>);
  void texSubImage2D(GLenum target,
                     GLint level,
                     GLint xoffset,
                     GLint yoffset,
                     GLenum format,
                     GLenum type,
                     ImageData*);
  void texSubImage2D(ExecutionContext*,
                     GLenum target,
                     GLint level,
                     GLint xoffset,
                     GLint yoffset,
                     GLenum format,
                     GLenum type,
                     HTMLImageElement*,
                     ExceptionState&);
  void texSubImage2D(ExecutionContext*,
                     GLenum target,
                     GLint level,
                     GLint xoffset,
                     GLint yoffset,
                     GLenum format,
                     GLenum type,
                     HTMLCanvasElement*,
                     ExceptionState&);
  void texSubImage2D(ExecutionContext*,
                     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,
                        MaybeShared<DOMFloat32Array> value);
  void uniformMatrix2fv(const WebGLUniformLocation*,
                        GLboolean transpose,
                        Vector<GLfloat>& value);
  void uniformMatrix3fv(const WebGLUniformLocation*,
                        GLboolean transpose,
                        MaybeShared<DOMFloat32Array> value);
  void uniformMatrix3fv(const WebGLUniformLocation*,
                        GLboolean transpose,
                        Vector<GLfloat>& value);
  void uniformMatrix4fv(const WebGLUniformLocation*,
                        GLboolean transpose,
                        MaybeShared<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, MaybeShared<const DOMFloat32Array> values);
  void vertexAttrib1fv(GLuint index, const Vector<GLfloat>& values);
  void vertexAttrib2f(GLuint index, GLfloat x, GLfloat y);
  void vertexAttrib2fv(GLuint index, MaybeShared<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, MaybeShared<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, MaybeShared<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.
    kManual,

    // Restore when resources are available.
    kWhenAvailable,

    // Restore as soon as possible, but only when
    // the canvas is visible.
    kAuto
  };
  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 = GetDrawingBuffer();
    if (!d)
      return nullptr;
    return d->ContextGL();
  }
  WebGLContextGroup* ContextGroup() const { return context_group_.Get(); }
  Extensions3DUtil* ExtensionsUtil();

  void Reshape(int width, int height) override;

  void MarkLayerComposited() override;

  scoped_refptr<Uint8Array> PaintRenderingResultsToDataArray(
      SourceDrawingBuffer) override;

  unsigned MaxVertexAttribs() const { return max_vertex_attribs_; }

  virtual void Trace(blink::Visitor*);

  virtual void TraceWrappers(const ScriptWrappableVisitor*) const;

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

  // Returns the drawing buffer size after it is, probably, has scaled down
  // to the maximum supported canvas size.
  IntSize DrawingBufferSize() const override;
  DrawingBuffer* GetDrawingBuffer() const;

  class TextureUnitState {
    DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();

   public:
    TraceWrapperMember<WebGLTexture> texture2d_binding_;
    TraceWrapperMember<WebGLTexture> texture_cube_map_binding_;
    TraceWrapperMember<WebGLTexture> texture3d_binding_;
    TraceWrapperMember<WebGLTexture> texture2d_array_binding_;

    void Trace(blink::Visitor*);
    // Wrappers are traced by parent since TextureUnitState is not a heap
    // object.
  };

  scoped_refptr<StaticBitmapImage> GetImage(AccelerationHint) const 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();

  // For use by WebVR, commits the current canvas content similar
  // to the "commit" JS API.
  scoped_refptr<StaticBitmapImage> GetStaticBitmapImage();

 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(CanvasRenderingContextHost*,
                            std::unique_ptr<WebGraphicsContext3DProvider>,
                            bool using_gpu_compositing,
                            const CanvasContextCreationAttributes&,
                            unsigned);
  scoped_refptr<DrawingBuffer> CreateDrawingBuffer(
      std::unique_ptr<WebGraphicsContext3DProvider>,
      bool using_gpu_compositing);
  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 DrawingBufferClientRestorePixelPackParameters() override;
  void DrawingBufferClientRestoreTexture2DBinding() override;
  void DrawingBufferClientRestoreRenderbufferBinding() override;
  void DrawingBufferClientRestoreFramebufferBinding() override;
  void DrawingBufferClientRestorePixelUnpackBufferBinding() override;
  void DrawingBufferClientRestorePixelPackBufferBinding() override;

  virtual void DestroyContext();
  void MarkContextChanged(ContentChangeType);

  void OnErrorMessage(const char*, int32_t id);

  // Query if depth_stencil buffer is supported.
  bool IsDepthStencilSupported() { return is_depth_stencil_supported_; }

  // 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();

  scoped_refptr<Image> DrawImageIntoBuffer(scoped_refptr<Image>,
                                           int width,
                                           int height,
                                           const char* function_name);

  scoped_refptr<Image> VideoFrameToImage(
      HTMLVideoElement*,
      int already_uploaded_id,
      WebMediaPlayer::VideoFrameUploadMetadata* out_metadata);

  // Structure for rendering to a DrawingBuffer, instead of directly
  // to the back-buffer of m_context.
  scoped_refptr<DrawingBuffer> drawing_buffer_;

  TraceWrapperMember<WebGLContextGroup> context_group_;

  bool is_hidden_;
  LostContextMode context_lost_mode_;
  AutoRecoveryMethod auto_recovery_method_;
  // 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> dispatch_context_lost_event_timer_;
  bool restore_allowed_;
  TaskRunnerTimer<WebGLRenderingContextBase> restore_timer_;
  scoped_refptr<WebTaskRunner> task_runner_;

  bool marked_canvas_dirty_;
  bool animation_frame_in_progress_;

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

  Member<WebGLVertexArrayObjectBase> default_vertex_array_object_;
  TraceWrapperMember<WebGLVertexArrayObjectBase> bound_vertex_array_object_;
  void SetBoundVertexArrayObject(WebGLVertexArrayObjectBase*);

  enum VertexAttribValueType {
    kFloat32ArrayType,
    kInt32ArrayType,
    kUint32ArrayType,
  };

  Vector<VertexAttribValueType> vertex_attrib_type_;
  unsigned max_vertex_attribs_;
  void SetVertexAttribType(GLuint index, VertexAttribValueType);

  TraceWrapperMember<WebGLProgram> current_program_;
  TraceWrapperMember<WebGLFramebuffer> framebuffer_binding_;
  TraceWrapperMember<WebGLRenderbuffer> renderbuffer_binding_;

  HeapVector<TextureUnitState> texture_units_;
  unsigned long active_texture_unit_;

  Vector<GLenum> compressed_texture_formats_;

  // Fixed-size cache of reusable resource providers for video texImage2D calls.
  class LRUCanvasResourceProviderCache {
   public:
    LRUCanvasResourceProviderCache(int capacity);
    // The pointer returned is owned by the image buffer map.
    CanvasResourceProvider* GetCanvasResourceProvider(const IntSize&);

   private:
    void BubbleToFront(int idx);
    std::unique_ptr<std::unique_ptr<CanvasResourceProvider>[]>
        resource_providers_;
    int capacity_;
  };
  LRUCanvasResourceProviderCache generated_image_cache_;

  GLint max_texture_size_;
  GLint max_cube_map_texture_size_;
  GLint max3d_texture_size_;
  GLint max_array_texture_layers_;
  GLint max_renderbuffer_size_;
  GLint max_viewport_dims_[2];
  GLint max_texture_level_;
  GLint max_cube_map_texture_level_;
  GLint max3d_texture_level_;

  GLint max_draw_buffers_;
  GLint max_color_attachments_;
  GLenum back_draw_buffer_;
  bool draw_buffers_web_gl_requirements_checked_;
  bool draw_buffers_supported_;

  GLenum read_buffer_of_default_framebuffer_;

  GLint pack_alignment_ = 4;
  GLint unpack_alignment_ = 4;
  bool unpack_flip_y_ = false;
  bool unpack_premultiply_alpha_ = false;
  GLenum unpack_colorspace_conversion_ = GC3D_BROWSER_DEFAULT_WEBGL;
  // The following three unpack params belong to WebGL2 only.
  GLint unpack_skip_pixels_ = 0;
  GLint unpack_skip_rows_ = 0;
  GLint unpack_row_length_ = 0;

  GLfloat clear_color_[4];
  bool scissor_enabled_;
  GLint scissor_box_[4];
  GLfloat clear_depth_;
  GLint clear_stencil_;
  GLboolean color_mask_[4];
  GLboolean depth_mask_;

  bool stencil_enabled_;
  GLuint stencil_mask_, stencil_mask_back_;
  GLint stencil_func_ref_,
      stencil_func_ref_back_;  // Note that these are the user specified values,
                               // not the internal clamped value.
  GLuint stencil_func_mask_, stencil_func_mask_back_;

  bool is_depth_stencil_supported_;

  bool synthesized_errors_to_console_;
  int num_gl_errors_to_console_allowed_;

  unsigned long one_plus_max_non_default_texture_unit_;

  std::unique_ptr<Extensions3DUtil> extensions_util_;

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

  class ExtensionTracker : public GarbageCollected<ExtensionTracker>,
                           public TraceWrapperBase {
   public:
    ExtensionTracker(ExtensionFlags flags, const char* const* prefixes)
        : draft_(flags & kDraftExtension), prefixes_(prefixes) {}

    bool Draft() const { return 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;

    virtual void Trace(blink::Visitor* visitor) {}
    void TraceWrappers(const ScriptWrappableVisitor*) const override {}

   private:
    bool draft_;
    const char* const* prefixes_;
  };

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

    WebGLExtension* GetExtension(WebGLRenderingContextBase* context) override {
      if (!extension_) {
        extension_ = T::Create(context);
        extension_field_ = extension_;
      }

      return 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 (extension_) {
        extension_->Lose(force);
        if (extension_->IsLost())
          extension_ = nullptr;
      }
    }

    WebGLExtension* GetExtensionObjectIfAlreadyEnabled() override {
      return extension_;
    }

    virtual void Trace(blink::Visitor* visitor) {
      visitor->Trace(extension_);
      ExtensionTracker::Trace(visitor);
    }

    virtual void TraceWrappers(const ScriptWrappableVisitor* visitor) const {
      visitor->TraceWrappers(extension_);
      ExtensionTracker::TraceWrappers(visitor);
    }

   private:
    TypedExtensionTracker(Member<T>& extension_field,
                          ExtensionFlags flags,
                          const char* const* prefixes)
        : ExtensionTracker(flags, prefixes),
          extension_field_(extension_field) {}

    GC_PLUGIN_IGNORE("http://crbug.com/519953")
    Member<T>& extension_field_;
    // 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> extension_;
  };

  bool extension_enabled_[kWebGLExtensionNameCount];
  HeapVector<TraceWrapperMember<ExtensionTracker>> extensions_;
  HashSet<String> disabled_extensions_;

  template <typename T>
  void RegisterExtension(Member<T>& extension_ptr,
                         ExtensionFlags flags = kApprovedExtension,
                         const char* const* prefixes = nullptr) {
    extensions_.push_back(
        TypedExtensionTracker<T>::Create(extension_ptr, flags, prefixes));
  }

  bool ExtensionSupportedAndAllowed(const ExtensionTracker*);

  inline bool ExtensionEnabled(WebGLExtensionName name) {
    return extension_enabled_[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* drawing_buffer,
                              WebGLFramebuffer* framebuffer_binding)
        : drawing_buffer_(drawing_buffer),
          read_framebuffer_binding_(framebuffer_binding) {
      // Commit DrawingBuffer if needed (e.g., for multisampling)
      if (!read_framebuffer_binding_ && drawing_buffer_)
        drawing_buffer_->ResolveAndBindForReadAndDraw();
    }

    ~ScopedDrawingBufferBinder() {
      // Restore DrawingBuffer if needed
      if (!read_framebuffer_binding_ && drawing_buffer_)
        drawing_buffer_->RestoreFramebufferBindings();
    }

   private:
    DrawingBuffer* drawing_buffer_;
    Member<WebGLFramebuffer> read_framebuffer_binding_;
  };

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

  bool is_web_gl2_formats_types_added_;
  bool is_web_gl2_tex_image_source_formats_types_added_;
  bool is_web_gl2_internal_formats_copy_tex_image_added_;
  bool is_oes_texture_float_formats_types_added_;
  bool is_oes_texture_half_float_formats_types_added_;
  bool is_web_gl_depth_texture_formats_types_added_;
  bool is_ext_srgb_formats_types_added_;
  bool is_ext_color_buffer_float_formats_added_;

  std::set<GLenum> supported_internal_formats_;
  std::set<GLenum> supported_tex_image_source_internal_formats_;
  std::set<GLenum> supported_internal_formats_copy_tex_image_;
  std::set<GLenum> supported_formats_;
  std::set<GLenum> supported_tex_image_source_formats_;
  std::set<GLenum> supported_types_;
  std::set<GLenum> supported_tex_image_source_types_;

  // 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.
    kSkipped,
    // Clear the backbuffer.
    kJustClear,
    // Combine webgl.clear() API with the backbuffer clear, so webgl.clear()
    // doesn't have to call glClear() again.
    kCombinedClear
  };
  HowToClear ClearIfComposited(GLbitfield clear_mask = 0);

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

  enum TexImageFunctionType {
    kTexImage,
    kTexSubImage,
    kCopyTexImage,
    kCompressedTexImage
  };

  // This must stay in sync with WebMediaPlayer::TexImageFunctionID.
  enum TexImageFunctionID {
    kTexImage2D,
    kTexSubImage2D,
    kTexImage3D,
    kTexSubImage3D
  };

  enum TexImageDimension { kTex2D, kTex3D };
  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 flip_y,
                    bool premultiply_alpha,
                    const IntRect&,
                    GLsizei depth,
                    GLint unpack_image_height);

  template <typename T>
  IntRect GetTextureSourceSize(T* texture_source) {
    return IntRect(0, 0, texture_source->width(), texture_source->height());
  }

  template <typename T>
  bool ValidateTexImageSubRectangle(const char* function_name,
                                    TexImageFunctionID function_id,
                                    T* image,
                                    const IntRect& sub_rect,
                                    GLsizei depth,
                                    GLint unpack_image_height,
                                    bool* selecting_sub_rectangle) {
    DCHECK(function_name);
    DCHECK(selecting_sub_rectangle);
    DCHECK(image);
    int image_width = static_cast<int>(image->width());
    int image_height = static_cast<int>(image->height());
    *selecting_sub_rectangle =
        !(sub_rect.X() == 0 && sub_rect.Y() == 0 &&
          sub_rect.Width() == image_width && sub_rect.Height() == image_height);
    // 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(!*selecting_sub_rectangle || IsWebGL2OrHigher())
        << "subRect = (" << sub_rect.Width() << " x " << sub_rect.Height()
        << ") @ (" << sub_rect.X() << ", " << sub_rect.Y() << "), image = ("
        << image_width << " x " << image_height << ")";

    if (!sub_rect.IsValid() || sub_rect.X() < 0 || sub_rect.Y() < 0 ||
        sub_rect.MaxX() > image_width || sub_rect.MaxY() > image_height ||
        sub_rect.Width() < 0 || sub_rect.Height() < 0) {
      SynthesizeGLError(GL_INVALID_OPERATION, function_name,
                        "source sub-rectangle specified via pixel unpack "
                        "parameters is invalid");
      return false;
    }

    if (function_id == kTexImage3D || function_id == kTexSubImage3D) {
      DCHECK_GE(unpack_image_height, 0);

      if (depth < 1) {
        SynthesizeGLError(GL_INVALID_OPERATION, function_name,
                          "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> max_y_accessed;
      if (unpack_image_height) {
        max_y_accessed = unpack_image_height;
      } else {
        max_y_accessed = sub_rect.Height();
      }
      max_y_accessed *= depth - 1;
      max_y_accessed += sub_rect.Height();
      max_y_accessed += sub_rect.Y();

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

      if (max_y_accessed.ValueOrDie() > image_height) {
        SynthesizeGLError(GL_INVALID_OPERATION, function_name,
                          "Not enough data supplied to upload to a 3D texture "
                          "with depth > 1");
        return false;
      }
    } else {
      DCHECK_EQ(depth, 1);
      DCHECK_EQ(unpack_image_height, 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 xoffset,
                     GLint yoffset,
                     GLint zoffset,
                     CanvasImageSource*,
                     const IntRect& source_sub_rectangle);
  bool CanUseTexImageByGPU(GLenum format, 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 tex_internal_format,
      GLenum color_buffer_format);

  // Helper function to verify limits on the length of uniform and attribute
  // locations.
  virtual unsigned GetMaxWebGLLocationLength() const { return 256; }
  bool ValidateLocationLength(const char* function_name, 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* function_name, 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* function_name, 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* function_name,
                                       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* function_name,
                                         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* function_name,
                                           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* function_name,
                                    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* function_name,
      WebGLFramebuffer*& read_framebuffer_binding);

  // 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 buffer_size);

  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* function_name,
                            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* function_name,
                                   const char* param_name,
                                   long long value);

  enum TexFuncValidationSourceType {
    kSourceArrayBufferView,
    kSourceImageData,
    kSourceHTMLImageElement,
    kSourceHTMLCanvasElement,
    kSourceHTMLVideoElement,
    kSourceImageBitmap,
    kSourceUnpackBuffer,
  };

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

  enum NullDisposition { kNullAllowed, kNullNotAllowed, kNullNotReachable };

  // 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* function_name,
                           TexImageDimension,
                           GLint level,
                           GLsizei width,
                           GLsizei height,
                           GLsizei depth,
                           GLenum format,
                           GLenum type,
                           DOMArrayBufferView* pixels,
                           NullDisposition,
                           GLuint src_offset);

  // 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* function_name, GLenum format);

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

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

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

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

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

  // 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* function_name,
                                         GLenum target,
                                         GLenum attachment);

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

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

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

  // Helper function to validate input parameters for uniform functions.
  bool ValidateUniformParameters(const char* function_name,
                                 const WebGLUniformLocation*,
                                 void*,
                                 GLsizei,
                                 GLsizei mod,
                                 GLuint src_offset,
                                 GLuint src_length);
  bool ValidateUniformMatrixParameters(const char* function_name,
                                       const WebGLUniformLocation*,
                                       GLboolean transpose,
                                       DOMFloat32Array*,
                                       GLsizei mod,
                                       GLuint src_offset,
                                       GLuint src_length);
  bool ValidateUniformMatrixParameters(const char* function_name,
                                       const WebGLUniformLocation*,
                                       GLboolean transpose,
                                       void*,
                                       GLsizei,
                                       GLsizei mod,
                                       GLuint src_offset,
                                       GLuint src_length);

  template <typename WTFTypedArray>
  bool ValidateUniformParameters(
      const char* function_name,
      const WebGLUniformLocation* location,
      const TypedFlexibleArrayBufferView<WTFTypedArray>& v,
      GLsizei required_min_size,
      GLuint src_offset,
      GLuint src_length) {
    if (!v.DataMaybeOnStack()) {
      SynthesizeGLError(GL_INVALID_VALUE, function_name, "no array");
      return false;
    }
    return ValidateUniformMatrixParameters(
        function_name, location, false, v.DataMaybeOnStack(), v.length(),
        required_min_size, src_offset, src_length);
  }

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

  virtual bool ValidateAndUpdateBufferBindTarget(const char* function_name,
                                                 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 SecurityOrigin*,
                                const char* function_name,
                                HTMLImageElement*,
                                ExceptionState&);

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

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

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

  // Helper function to validate drawArrays(Instanced) calls
  bool ValidateDrawArrays(const char* function_name);

  // Helper function to validate drawElements(Instanced) calls
  bool ValidateDrawElements(const char* function_name,
                            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* function_name,
                            WebGLObject*,
                            bool& deleted);

  void DispatchContextLostEvent(TimerBase*);
  // Helper for restoration after context lost.
  void MaybeRestoreContext(TimerBase*);

  enum ConsoleDisplayPreference { kDisplayInConsole, kDontDisplayInConsole };

  // Reports an error to glGetError, sends a message to the JavaScript
  // console.
  void SynthesizeGLError(GLenum,
                         const char* function_name,
                         const char* description,
                         ConsoleDisplayPreference = kDisplayInConsole);
  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* function_name);

  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 active_scoped_rgb_emulation_color_masks_;

  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 src_offset);
  void TexImageHelperImageData(TexImageFunctionID,
                               GLenum,
                               GLint,
                               GLint,
                               GLint,
                               GLenum,
                               GLenum,
                               GLsizei,
                               GLint,
                               GLint,
                               GLint,
                               ImageData*,
                               const IntRect&,
                               GLint);

  void TexImageHelperHTMLImageElement(const SecurityOrigin*,
                                      TexImageFunctionID,
                                      GLenum,
                                      GLint,
                                      GLint,
                                      GLenum,
                                      GLenum,
                                      GLint,
                                      GLint,
                                      GLint,
                                      HTMLImageElement*,
                                      const IntRect&,
                                      GLsizei,
                                      GLint,
                                      ExceptionState&);

  void TexImageHelperHTMLCanvasElement(const SecurityOrigin*,
                                       TexImageFunctionID,
                                       GLenum,
                                       GLint,
                                       GLint,
                                       GLenum,
                                       GLenum,
                                       GLint,
                                       GLint,
                                       GLint,
                                       HTMLCanvasElement*,
                                       const IntRect&,
                                       GLsizei,
                                       GLint,
                                       ExceptionState&);

  void TexImageHelperHTMLVideoElement(const SecurityOrigin*,
                                      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(CanvasRenderingContextHost*,
                            scoped_refptr<WebTaskRunner>,
                            std::unique_ptr<WebGraphicsContext3DProvider>,
                            bool using_gpu_compositing,
                            const CanvasContextCreationAttributes&,
                            unsigned);
  static bool SupportOwnOffscreenSurface(ExecutionContext*);
  static std::unique_ptr<WebGraphicsContext3DProvider>
  CreateContextProviderInternal(CanvasRenderingContextHost*,
                                const CanvasContextCreationAttributes&,
                                unsigned web_gl_version,
                                bool* using_gpu_compositing);
  void TexImageCanvasByGPU(TexImageFunctionID,
                           HTMLCanvasElement*,
                           GLenum,
                           GLuint,
                           GLint,
                           GLint,
                           const IntRect&);
  void TexImageBitmapByGPU(ImageBitmap*,
                           GLenum,
                           GLuint,
                           GLint,
                           GLint,
                           const IntRect&);

  scoped_refptr<StaticBitmapImage> MakeImageSnapshot(SkImageInfo&) const;
  const unsigned version_;

  bool IsPaintable() const final { return GetDrawingBuffer(); }
  bool CopyRenderingResultsFromDrawingBuffer(CanvasResourceProvider*,
                                             SourceDrawingBuffer) const;
  void HoldReferenceToDrawingBuffer(DrawingBuffer*);
};

// TODO(fserb): remove this.
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
