// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "modules/webgl/WebGL2RenderingContextBase.h"

#include "bindings/modules/v8/WebGLAny.h"
#include "core/dom/DOMException.h"
#include "core/frame/ImageBitmap.h"
#include "core/html/HTMLCanvasElement.h"
#include "core/html/HTMLImageElement.h"
#include "core/html/HTMLVideoElement.h"
#include "core/html/ImageData.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/gles2_interface.h"
#include "modules/webgl/WebGLActiveInfo.h"
#include "modules/webgl/WebGLBuffer.h"
#include "modules/webgl/WebGLFenceSync.h"
#include "modules/webgl/WebGLFramebuffer.h"
#include "modules/webgl/WebGLProgram.h"
#include "modules/webgl/WebGLQuery.h"
#include "modules/webgl/WebGLRenderbuffer.h"
#include "modules/webgl/WebGLSampler.h"
#include "modules/webgl/WebGLSync.h"
#include "modules/webgl/WebGLTexture.h"
#include "modules/webgl/WebGLTransformFeedback.h"
#include "modules/webgl/WebGLUniformLocation.h"
#include "modules/webgl/WebGLVertexArrayObject.h"
#include "public/platform/WebGraphicsContext3DProvider.h"
#include "wtf/CheckedNumeric.h"
#include "wtf/PtrUtil.h"
#include "wtf/text/WTFString.h"
#include <memory>

using WTF::String;

namespace blink {

namespace {

const GLuint64 kMaxClientWaitTimeout = 0u;

GLsync syncObjectOrZero(const WebGLSync* object) {
  return object ? object->object() : nullptr;
}

// TODO(kainino): Change outByteLength to GLuint and change the associated
// range checking (and all uses) - overflow becomes possible in cases below
bool validateSubSourceAndGetData(DOMArrayBufferView* view,
                                 GLuint subOffset,
                                 GLuint subLength,
                                 void** outBaseAddress,
                                 long long* outByteLength) {
  // This is guaranteed to be non-null by DOM.
  DCHECK(view);

  size_t typeSize = view->typeSize();
  DCHECK_GE(8u, typeSize);
  long long byteLength = 0;
  if (subLength) {
    // type size is at most 8, so no overflow.
    byteLength = subLength * typeSize;
  }
  long long byteOffset = 0;
  if (subOffset) {
    // type size is at most 8, so no overflow.
    byteOffset = subOffset * typeSize;
  }
  CheckedNumeric<long long> total = byteOffset;
  total += byteLength;
  if (!total.IsValid() || total.ValueOrDie() > view->byteLength()) {
    return false;
  }
  if (!byteLength) {
    byteLength = view->byteLength() - byteOffset;
  }
  uint8_t* data = static_cast<uint8_t*>(view->baseAddress());
  data += byteOffset;
  *outBaseAddress = data;
  *outByteLength = byteLength;
  return true;
}

}  // namespace

// These enums are from manual pages for glTexStorage2D/glTexStorage3D.
const GLenum kSupportedInternalFormatsStorage[] = {
    GL_R8,
    GL_R8_SNORM,
    GL_R16F,
    GL_R32F,
    GL_R8UI,
    GL_R8I,
    GL_R16UI,
    GL_R16I,
    GL_R32UI,
    GL_R32I,
    GL_RG8,
    GL_RG8_SNORM,
    GL_RG16F,
    GL_RG32F,
    GL_RG8UI,
    GL_RG8I,
    GL_RG16UI,
    GL_RG16I,
    GL_RG32UI,
    GL_RG32I,
    GL_RGB8,
    GL_SRGB8,
    GL_RGB565,
    GL_RGB8_SNORM,
    GL_R11F_G11F_B10F,
    GL_RGB9_E5,
    GL_RGB16F,
    GL_RGB32F,
    GL_RGB8UI,
    GL_RGB8I,
    GL_RGB16UI,
    GL_RGB16I,
    GL_RGB32UI,
    GL_RGB32I,
    GL_RGBA8,
    GL_SRGB8_ALPHA8,
    GL_RGBA8_SNORM,
    GL_RGB5_A1,
    GL_RGBA4,
    GL_RGB10_A2,
    GL_RGBA16F,
    GL_RGBA32F,
    GL_RGBA8UI,
    GL_RGBA8I,
    GL_RGB10_A2UI,
    GL_RGBA16UI,
    GL_RGBA16I,
    GL_RGBA32UI,
    GL_RGBA32I,
    GL_DEPTH_COMPONENT16,
    GL_DEPTH_COMPONENT24,
    GL_DEPTH_COMPONENT32F,
    GL_DEPTH24_STENCIL8,
    GL_DEPTH32F_STENCIL8,
};

class WebGLGetBufferSubDataAsyncCallback
    : public GarbageCollected<WebGLGetBufferSubDataAsyncCallback> {
 public:
  WebGLGetBufferSubDataAsyncCallback(
      WebGL2RenderingContextBase* context,
      ScriptPromiseResolver* promiseResolver,
      void* shmReadbackResultData,
      GLuint commandsIssuedQueryID,
      DOMArrayBufferView* destinationArrayBufferView,
      void* destinationDataPtr,
      long long destinationByteLength)
      : m_context(context),
        m_promiseResolver(promiseResolver),
        m_shmReadbackResultData(shmReadbackResultData),
        m_commandsIssuedQueryID(commandsIssuedQueryID),
        m_destinationArrayBufferView(destinationArrayBufferView),
        m_destinationDataPtr(destinationDataPtr),
        m_destinationByteLength(destinationByteLength) {
    DCHECK(shmReadbackResultData);
    DCHECK(destinationDataPtr);
  }

  void destroy() {
    DCHECK(m_shmReadbackResultData);
    m_context->contextGL()->FreeSharedMemory(m_shmReadbackResultData);
    m_shmReadbackResultData = nullptr;
    DOMException* exception =
        DOMException::create(InvalidStateError, "Context lost or destroyed");
    m_promiseResolver->reject(exception);
  }

  void resolve() {
    if (!m_context || !m_shmReadbackResultData) {
      DOMException* exception =
          DOMException::create(InvalidStateError, "Context lost or destroyed");
      m_promiseResolver->reject(exception);
      return;
    }
    if (m_destinationArrayBufferView->buffer()->isNeutered()) {
      DOMException* exception = DOMException::create(
          InvalidStateError, "ArrayBufferView became invalid asynchronously");
      m_promiseResolver->reject(exception);
      return;
    }
    memcpy(m_destinationDataPtr, m_shmReadbackResultData,
           m_destinationByteLength);
    // TODO(kainino): What would happen if the DOM was suspended when the
    // promise became resolved? Could another JS task happen between the memcpy
    // and the promise resolution task, which would see the wrong data?
    m_promiseResolver->resolve(m_destinationArrayBufferView);

    m_context->contextGL()->DeleteQueriesEXT(1, &m_commandsIssuedQueryID);
    this->destroy();
    m_context->unregisterGetBufferSubDataAsyncCallback(this);
  }

  DECLARE_TRACE();

 private:
  WeakMember<WebGL2RenderingContextBase> m_context;
  Member<ScriptPromiseResolver> m_promiseResolver;

  // Pointer to shared memory where the gpu readback result is stored.
  void* m_shmReadbackResultData;
  // ID of the GL query used to call this callback.
  GLuint m_commandsIssuedQueryID;

  // ArrayBufferView returned from the promise.
  Member<DOMArrayBufferView> m_destinationArrayBufferView;
  // Pointer into the offset into destinationArrayBufferView.
  void* m_destinationDataPtr;
  // Size in bytes of the copy operation being performed.
  long long m_destinationByteLength;
};

DEFINE_TRACE(WebGLGetBufferSubDataAsyncCallback) {
  visitor->trace(m_context);
  visitor->trace(m_promiseResolver);
  visitor->trace(m_destinationArrayBufferView);
}

WebGL2RenderingContextBase::WebGL2RenderingContextBase(
    HTMLCanvasElement* passedCanvas,
    std::unique_ptr<WebGraphicsContext3DProvider> contextProvider,
    const CanvasContextCreationAttributes& requestedAttributes)
    : WebGLRenderingContextBase(passedCanvas,
                                std::move(contextProvider),
                                requestedAttributes,
                                2),
      m_readFramebufferBinding(this, nullptr),
      m_transformFeedbackBinding(this, nullptr),
      m_boundCopyReadBuffer(this, nullptr),
      m_boundCopyWriteBuffer(this, nullptr),
      m_boundPixelPackBuffer(this, nullptr),
      m_boundPixelUnpackBuffer(this, nullptr),
      m_boundTransformFeedbackBuffer(this, nullptr),
      m_boundUniformBuffer(this, nullptr),
      m_currentBooleanOcclusionQuery(this, nullptr),
      m_currentTransformFeedbackPrimitivesWrittenQuery(this, nullptr),
      m_currentElapsedQuery(this, nullptr) {
  m_supportedInternalFormatsStorage.insert(
      kSupportedInternalFormatsStorage,
      kSupportedInternalFormatsStorage +
          WTF_ARRAY_LENGTH(kSupportedInternalFormatsStorage));
}

WebGL2RenderingContextBase::WebGL2RenderingContextBase(
    OffscreenCanvas* passedOffscreenCanvas,
    std::unique_ptr<WebGraphicsContext3DProvider> contextProvider,
    const CanvasContextCreationAttributes& requestedAttributes)
    : WebGLRenderingContextBase(passedOffscreenCanvas,
                                std::move(contextProvider),
                                requestedAttributes,
                                2),
      m_readFramebufferBinding(this, nullptr),
      m_transformFeedbackBinding(this, nullptr),
      m_boundCopyReadBuffer(this, nullptr),
      m_boundCopyWriteBuffer(this, nullptr),
      m_boundPixelPackBuffer(this, nullptr),
      m_boundPixelUnpackBuffer(this, nullptr),
      m_boundTransformFeedbackBuffer(this, nullptr),
      m_boundUniformBuffer(this, nullptr),
      m_currentBooleanOcclusionQuery(this, nullptr),
      m_currentTransformFeedbackPrimitivesWrittenQuery(this, nullptr),
      m_currentElapsedQuery(this, nullptr) {
  m_supportedInternalFormatsStorage.insert(
      kSupportedInternalFormatsStorage,
      kSupportedInternalFormatsStorage +
          WTF_ARRAY_LENGTH(kSupportedInternalFormatsStorage));
}

WebGL2RenderingContextBase::~WebGL2RenderingContextBase() {
  m_readFramebufferBinding = nullptr;

  m_boundCopyReadBuffer = nullptr;
  m_boundCopyWriteBuffer = nullptr;
  m_boundPixelPackBuffer = nullptr;
  m_boundPixelUnpackBuffer = nullptr;
  m_boundTransformFeedbackBuffer = nullptr;
  m_boundUniformBuffer = nullptr;

  m_currentBooleanOcclusionQuery = nullptr;
  m_currentTransformFeedbackPrimitivesWrittenQuery = nullptr;
  m_currentElapsedQuery = nullptr;
}

void WebGL2RenderingContextBase::destroyContext() {
  for (auto& callback : m_getBufferSubDataAsyncCallbacks) {
    callback->destroy();
  }
  m_getBufferSubDataAsyncCallbacks.clear();

  WebGLRenderingContextBase::destroyContext();
}

void WebGL2RenderingContextBase::initializeNewContext() {
  ASSERT(!isContextLost());
  ASSERT(drawingBuffer());

  m_readFramebufferBinding = nullptr;

  m_boundCopyReadBuffer = nullptr;
  m_boundCopyWriteBuffer = nullptr;
  m_boundPixelPackBuffer = nullptr;
  m_boundPixelUnpackBuffer = nullptr;
  m_boundTransformFeedbackBuffer = nullptr;
  m_boundUniformBuffer = nullptr;

  m_currentBooleanOcclusionQuery = nullptr;
  m_currentTransformFeedbackPrimitivesWrittenQuery = nullptr;
  m_currentElapsedQuery = nullptr;

  GLint numCombinedTextureImageUnits = 0;
  contextGL()->GetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS,
                           &numCombinedTextureImageUnits);
  m_samplerUnits.clear();
  m_samplerUnits.resize(numCombinedTextureImageUnits);

  m_maxTransformFeedbackSeparateAttribs = 0;
  contextGL()->GetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS,
                           &m_maxTransformFeedbackSeparateAttribs);
  m_boundIndexedTransformFeedbackBuffers.clear();
  m_boundIndexedTransformFeedbackBuffers.resize(
      m_maxTransformFeedbackSeparateAttribs);

  GLint maxUniformBufferBindings = 0;
  contextGL()->GetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS,
                           &maxUniformBufferBindings);
  m_boundIndexedUniformBuffers.clear();
  m_boundIndexedUniformBuffers.resize(maxUniformBufferBindings);
  m_maxBoundUniformBufferIndex = 0;

  m_packRowLength = 0;
  m_packSkipPixels = 0;
  m_packSkipRows = 0;
  m_unpackRowLength = 0;
  m_unpackImageHeight = 0;
  m_unpackSkipPixels = 0;
  m_unpackSkipRows = 0;
  m_unpackSkipImages = 0;

  WebGLRenderingContextBase::initializeNewContext();
}

void WebGL2RenderingContextBase::bufferData(GLenum target,
                                            DOMArrayBufferView* srcData,
                                            GLenum usage,
                                            GLuint srcOffset,
                                            GLuint length) {
  if (isContextLost())
    return;
  void* subBaseAddress = nullptr;
  long long subByteLength = 0;
  if (!validateSubSourceAndGetData(srcData, srcOffset, length, &subBaseAddress,
                                   &subByteLength)) {
    synthesizeGLError(GL_INVALID_VALUE, "bufferData",
                      "srcOffset + length too large");
    return;
  }
  bufferDataImpl(target, subByteLength, subBaseAddress, usage);
}

void WebGL2RenderingContextBase::bufferData(GLenum target,
                                            long long size,
                                            GLenum usage) {
  WebGLRenderingContextBase::bufferData(target, size, usage);
}

void WebGL2RenderingContextBase::bufferData(GLenum target,
                                            DOMArrayBuffer* data,
                                            GLenum usage) {
  WebGLRenderingContextBase::bufferData(target, data, usage);
}

void WebGL2RenderingContextBase::bufferData(GLenum target,
                                            DOMArrayBufferView* data,
                                            GLenum usage) {
  WebGLRenderingContextBase::bufferData(target, data, usage);
}

void WebGL2RenderingContextBase::bufferSubData(GLenum target,
                                               GLintptr dstByteOffset,
                                               DOMArrayBufferView* srcData,
                                               GLuint srcOffset,
                                               GLuint length) {
  if (isContextLost())
    return;
  void* subBaseAddress = nullptr;
  long long subByteLength = 0;
  if (!validateSubSourceAndGetData(srcData, srcOffset, length, &subBaseAddress,
                                   &subByteLength)) {
    synthesizeGLError(GL_INVALID_VALUE, "bufferSubData",
                      "srcOffset + length too large");
    return;
  }
  bufferSubDataImpl(target, dstByteOffset, subByteLength, subBaseAddress);
}

void WebGL2RenderingContextBase::bufferSubData(GLenum target,
                                               long long offset,
                                               DOMArrayBuffer* data) {
  WebGLRenderingContextBase::bufferSubData(target, offset, data);
}

void WebGL2RenderingContextBase::bufferSubData(
    GLenum target,
    long long offset,
    const FlexibleArrayBufferView& data) {
  WebGLRenderingContextBase::bufferSubData(target, offset, data);
}

void WebGL2RenderingContextBase::copyBufferSubData(GLenum readTarget,
                                                   GLenum writeTarget,
                                                   long long readOffset,
                                                   long long writeOffset,
                                                   long long size) {
  if (isContextLost())
    return;

  if (!validateValueFitNonNegInt32("copyBufferSubData", "readOffset",
                                   readOffset) ||
      !validateValueFitNonNegInt32("copyBufferSubData", "writeOffset",
                                   writeOffset) ||
      !validateValueFitNonNegInt32("copyBufferSubData", "size", size)) {
    return;
  }

  WebGLBuffer* readBuffer =
      validateBufferDataTarget("copyBufferSubData", readTarget);
  if (!readBuffer)
    return;

  WebGLBuffer* writeBuffer =
      validateBufferDataTarget("copyBufferSubData", writeTarget);
  if (!writeBuffer)
    return;

  if (readOffset + size > readBuffer->getSize() ||
      writeOffset + size > writeBuffer->getSize()) {
    synthesizeGLError(GL_INVALID_VALUE, "copyBufferSubData", "buffer overflow");
    return;
  }

  if ((writeBuffer->getInitialTarget() == GL_ELEMENT_ARRAY_BUFFER &&
       readBuffer->getInitialTarget() != GL_ELEMENT_ARRAY_BUFFER) ||
      (writeBuffer->getInitialTarget() != GL_ELEMENT_ARRAY_BUFFER &&
       readBuffer->getInitialTarget() == GL_ELEMENT_ARRAY_BUFFER)) {
    synthesizeGLError(GL_INVALID_OPERATION, "copyBufferSubData",
                      "Cannot copy into an element buffer destination from a "
                      "non-element buffer source");
    return;
  }

  if (writeBuffer->getInitialTarget() == 0)
    writeBuffer->setInitialTarget(readBuffer->getInitialTarget());

  contextGL()->CopyBufferSubData(
      readTarget, writeTarget, static_cast<GLintptr>(readOffset),
      static_cast<GLintptr>(writeOffset), static_cast<GLsizeiptr>(size));
}

void WebGL2RenderingContextBase::getBufferSubData(GLenum target,
                                                  long long srcByteOffset,
                                                  DOMArrayBufferView* dstData,
                                                  GLuint dstOffset,
                                                  GLuint length) {
  WebGLBuffer* sourceBuffer = nullptr;
  void* destinationDataPtr = nullptr;
  long long destinationByteLength = 0;
  const char* message = validateGetBufferSubData(
      __FUNCTION__, target, srcByteOffset, dstData, dstOffset, length,
      &sourceBuffer, &destinationDataPtr, &destinationByteLength);
  if (message) {
    // If there was a GL error, it was already synthesized in
    // validateGetBufferSubData, so it's not done here.
    return;
  }

  // If the length of the copy is zero, this is a no-op.
  if (!destinationByteLength) {
    return;
  }

  void* mappedData =
      contextGL()->MapBufferRange(target, static_cast<GLintptr>(srcByteOffset),
                                  destinationByteLength, GL_MAP_READ_BIT);

  if (!mappedData)
    return;

  memcpy(destinationDataPtr, mappedData, destinationByteLength);

  contextGL()->UnmapBuffer(target);
}

ScriptPromise WebGL2RenderingContextBase::getBufferSubDataAsync(
    ScriptState* scriptState,
    GLenum target,
    GLintptr srcByteOffset,
    DOMArrayBufferView* dstData,
    GLuint dstOffset,
    GLuint length) {
  ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
  ScriptPromise promise = resolver->promise();

  WebGLBuffer* sourceBuffer = nullptr;
  void* destinationDataPtr = nullptr;
  long long destinationByteLength = 0;
  const char* message = validateGetBufferSubData(
      __FUNCTION__, target, srcByteOffset, dstData, dstOffset, length,
      &sourceBuffer, &destinationDataPtr, &destinationByteLength);
  if (message) {
    // If there was a GL error, it was already synthesized in
    // validateGetBufferSubData, so it's not done here.
    DOMException* exception = DOMException::create(InvalidStateError, message);
    resolver->reject(exception);
    return promise;
  }

  message = validateGetBufferSubDataBounds(
      __FUNCTION__, sourceBuffer, srcByteOffset, destinationByteLength);
  if (message) {
    // If there was a GL error, it was already synthesized in
    // validateGetBufferSubDataBounds, so it's not done here.
    DOMException* exception = DOMException::create(InvalidStateError, message);
    resolver->reject(exception);
    return promise;
  }

  // If the length of the copy is zero, this is a no-op.
  if (!destinationByteLength) {
    resolver->resolve(dstData);
    return promise;
  }

  GLuint queryID;
  contextGL()->GenQueriesEXT(1, &queryID);
  contextGL()->BeginQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM, queryID);
  void* mappedData = contextGL()->GetBufferSubDataAsyncCHROMIUM(
      target, srcByteOffset, destinationByteLength);
  contextGL()->EndQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM);
  if (!mappedData) {
    DOMException* exception =
        DOMException::create(InvalidStateError, "Out of memory");
    resolver->reject(exception);
    return promise;
  }

  auto callbackObject = new WebGLGetBufferSubDataAsyncCallback(
      this, resolver, mappedData, queryID, dstData, destinationDataPtr,
      destinationByteLength);
  registerGetBufferSubDataAsyncCallback(callbackObject);
  auto callback = WTF::bind(&WebGLGetBufferSubDataAsyncCallback::resolve,
                            wrapPersistent(callbackObject));
  drawingBuffer()->contextProvider()->signalQuery(
      queryID, convertToBaseCallback(std::move(callback)));

  return promise;
}

void WebGL2RenderingContextBase::registerGetBufferSubDataAsyncCallback(
    WebGLGetBufferSubDataAsyncCallback* callback) {
  m_getBufferSubDataAsyncCallbacks.add(callback);
}

void WebGL2RenderingContextBase::unregisterGetBufferSubDataAsyncCallback(
    WebGLGetBufferSubDataAsyncCallback* callback) {
  m_getBufferSubDataAsyncCallbacks.remove(callback);
}

void WebGL2RenderingContextBase::blitFramebuffer(GLint srcX0,
                                                 GLint srcY0,
                                                 GLint srcX1,
                                                 GLint srcY1,
                                                 GLint dstX0,
                                                 GLint dstY0,
                                                 GLint dstX1,
                                                 GLint dstY1,
                                                 GLbitfield mask,
                                                 GLenum filter) {
  if (isContextLost())
    return;

  contextGL()->BlitFramebufferCHROMIUM(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
                                       dstX1, dstY1, mask, filter);
}

bool WebGL2RenderingContextBase::validateTexFuncLayer(const char* functionName,
                                                      GLenum texTarget,
                                                      GLint layer) {
  if (layer < 0) {
    synthesizeGLError(GL_INVALID_VALUE, functionName, "layer out of range");
    return false;
  }
  switch (texTarget) {
    case GL_TEXTURE_3D:
      if (layer > m_max3DTextureSize - 1) {
        synthesizeGLError(GL_INVALID_VALUE, functionName, "layer out of range");
        return false;
      }
      break;
    case GL_TEXTURE_2D_ARRAY:
      if (layer > m_maxArrayTextureLayers - 1) {
        synthesizeGLError(GL_INVALID_VALUE, functionName, "layer out of range");
        return false;
      }
      break;
    default:
      ASSERT_NOT_REACHED();
      return false;
  }
  return true;
}

void WebGL2RenderingContextBase::framebufferTextureLayer(GLenum target,
                                                         GLenum attachment,
                                                         WebGLTexture* texture,
                                                         GLint level,
                                                         GLint layer) {
  if (isContextLost() ||
      !validateFramebufferFuncParameters("framebufferTextureLayer", target,
                                         attachment))
    return;
  if (texture && !texture->validate(contextGroup(), this)) {
    synthesizeGLError(GL_INVALID_VALUE, "framebufferTextureLayer",
                      "no texture or texture not from this context");
    return;
  }
  GLenum textarget = texture ? texture->getTarget() : 0;
  if (texture) {
    if (textarget != GL_TEXTURE_3D && textarget != GL_TEXTURE_2D_ARRAY) {
      synthesizeGLError(GL_INVALID_OPERATION, "framebufferTextureLayer",
                        "invalid texture type");
      return;
    }
    if (!validateTexFuncLayer("framebufferTextureLayer", textarget, layer))
      return;
    if (!validateTexFuncLevel("framebufferTextureLayer", textarget, level))
      return;
  }

  WebGLFramebuffer* framebufferBinding = getFramebufferBinding(target);
  if (!framebufferBinding || !framebufferBinding->object()) {
    synthesizeGLError(GL_INVALID_OPERATION, "framebufferTextureLayer",
                      "no framebuffer bound");
    return;
  }
  framebufferBinding->setAttachmentForBoundFramebuffer(
      target, attachment, textarget, texture, level, layer);
  applyStencilTest();
}

ScriptValue WebGL2RenderingContextBase::getInternalformatParameter(
    ScriptState* scriptState,
    GLenum target,
    GLenum internalformat,
    GLenum pname) {
  if (isContextLost())
    return ScriptValue::createNull(scriptState);

  if (target != GL_RENDERBUFFER) {
    synthesizeGLError(GL_INVALID_ENUM, "getInternalformatParameter",
                      "invalid target");
    return ScriptValue::createNull(scriptState);
  }

  switch (internalformat) {
    // Renderbuffer doesn't support unsized internal formats,
    // though GL_RGB and GL_RGBA are color-renderable.
    case GL_RGB:
    case GL_RGBA:
    // Multisampling is not supported for signed and unsigned integer internal
    // formats.
    case GL_R8UI:
    case GL_R8I:
    case GL_R16UI:
    case GL_R16I:
    case GL_R32UI:
    case GL_R32I:
    case GL_RG8UI:
    case GL_RG8I:
    case GL_RG16UI:
    case GL_RG16I:
    case GL_RG32UI:
    case GL_RG32I:
    case GL_RGBA8UI:
    case GL_RGBA8I:
    case GL_RGB10_A2UI:
    case GL_RGBA16UI:
    case GL_RGBA16I:
    case GL_RGBA32UI:
    case GL_RGBA32I:
      return WebGLAny(scriptState, DOMInt32Array::create(0));
    case GL_R8:
    case GL_RG8:
    case GL_RGB8:
    case GL_RGB565:
    case GL_RGBA8:
    case GL_SRGB8_ALPHA8:
    case GL_RGB5_A1:
    case GL_RGBA4:
    case GL_RGB10_A2:
    case GL_DEPTH_COMPONENT16:
    case GL_DEPTH_COMPONENT24:
    case GL_DEPTH_COMPONENT32F:
    case GL_DEPTH24_STENCIL8:
    case GL_DEPTH32F_STENCIL8:
    case GL_STENCIL_INDEX8:
      break;
    case GL_R16F:
    case GL_RG16F:
    case GL_RGBA16F:
    case GL_R32F:
    case GL_RG32F:
    case GL_RGBA32F:
    case GL_R11F_G11F_B10F:
      if (!extensionEnabled(EXTColorBufferFloatName)) {
        synthesizeGLError(GL_INVALID_ENUM, "getInternalformatParameter",
                          "invalid internalformat when EXT_color_buffer_float "
                          "is not enabled");
        return ScriptValue::createNull(scriptState);
      }
      break;
    default:
      synthesizeGLError(GL_INVALID_ENUM, "getInternalformatParameter",
                        "invalid internalformat");
      return ScriptValue::createNull(scriptState);
  }

  switch (pname) {
    case GL_SAMPLES: {
      std::unique_ptr<GLint[]> values;
      GLint length = -1;
      contextGL()->GetInternalformativ(target, internalformat,
                                       GL_NUM_SAMPLE_COUNTS, 1, &length);
      if (length <= 0)
        return WebGLAny(scriptState, DOMInt32Array::create(0));

      values = wrapArrayUnique(new GLint[length]);
      for (GLint ii = 0; ii < length; ++ii)
        values[ii] = 0;
      contextGL()->GetInternalformativ(target, internalformat, GL_SAMPLES,
                                       length, values.get());
      return WebGLAny(scriptState, DOMInt32Array::create(values.get(), length));
    }
    default:
      synthesizeGLError(GL_INVALID_ENUM, "getInternalformatParameter",
                        "invalid parameter name");
      return ScriptValue::createNull(scriptState);
  }
}

bool WebGL2RenderingContextBase::checkAndTranslateAttachments(
    const char* functionName,
    GLenum target,
    Vector<GLenum>& attachments) {
  if (!validateFramebufferTarget(target)) {
    synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid target");
    return false;
  }

  WebGLFramebuffer* framebufferBinding = getFramebufferBinding(target);
  ASSERT(framebufferBinding || drawingBuffer());
  if (!framebufferBinding) {
    // For the default framebuffer, translate GL_COLOR/GL_DEPTH/GL_STENCIL.
    // The default framebuffer of WebGL is not fb 0, it is an internal fbo.
    for (size_t i = 0; i < attachments.size(); ++i) {
      switch (attachments[i]) {
        case GL_COLOR:
          attachments[i] = GL_COLOR_ATTACHMENT0;
          break;
        case GL_DEPTH:
          attachments[i] = GL_DEPTH_ATTACHMENT;
          break;
        case GL_STENCIL:
          attachments[i] = GL_STENCIL_ATTACHMENT;
          break;
        default:
          synthesizeGLError(GL_INVALID_ENUM, functionName,
                            "invalid attachment");
          return false;
      }
    }
  }
  return true;
}

IntRect WebGL2RenderingContextBase::getTextureSourceSubRectangle(
    GLsizei width,
    GLsizei height) {
  return IntRect(m_unpackSkipPixels, m_unpackSkipRows, width, height);
}

bool WebGL2RenderingContextBase::canUseTexImageByGPU(
    TexImageFunctionID functionID,
    GLint internalformat,
    GLenum type) {
  switch (internalformat) {
    case GL_RGB565:
    case GL_RGBA4:
    case GL_RGB5_A1:
      // FIXME: ES3 limitation that CopyTexImage with sized internalformat,
      // component sizes have to match the source color format.
      return false;
    default:
      break;
  }
  return WebGLRenderingContextBase::canUseTexImageByGPU(functionID,
                                                        internalformat, type);
}

void WebGL2RenderingContextBase::invalidateFramebuffer(
    GLenum target,
    const Vector<GLenum>& attachments) {
  if (isContextLost())
    return;

  Vector<GLenum> translatedAttachments = attachments;
  if (!checkAndTranslateAttachments("invalidateFramebuffer", target,
                                    translatedAttachments))
    return;
  contextGL()->InvalidateFramebuffer(target, translatedAttachments.size(),
                                     translatedAttachments.data());
}

void WebGL2RenderingContextBase::invalidateSubFramebuffer(
    GLenum target,
    const Vector<GLenum>& attachments,
    GLint x,
    GLint y,
    GLsizei width,
    GLsizei height) {
  if (isContextLost())
    return;

  Vector<GLenum> translatedAttachments = attachments;
  if (!checkAndTranslateAttachments("invalidateSubFramebuffer", target,
                                    translatedAttachments))
    return;
  contextGL()->InvalidateSubFramebuffer(target, translatedAttachments.size(),
                                        translatedAttachments.data(), x, y,
                                        width, height);
}

void WebGL2RenderingContextBase::readBuffer(GLenum mode) {
  if (isContextLost())
    return;

  switch (mode) {
    case GL_BACK:
    case GL_NONE:
    case GL_COLOR_ATTACHMENT0:
      break;
    default:
      if (mode > GL_COLOR_ATTACHMENT0 &&
          mode <
              static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + maxColorAttachments()))
        break;
      synthesizeGLError(GL_INVALID_ENUM, "readBuffer", "invalid read buffer");
      return;
  }

  WebGLFramebuffer* readFramebufferBinding =
      getFramebufferBinding(GL_READ_FRAMEBUFFER);
  if (!readFramebufferBinding) {
    ASSERT(drawingBuffer());
    if (mode != GL_BACK && mode != GL_NONE) {
      synthesizeGLError(GL_INVALID_OPERATION, "readBuffer",
                        "invalid read buffer");
      return;
    }
    m_readBufferOfDefaultFramebuffer = mode;
    // translate GL_BACK to GL_COLOR_ATTACHMENT0, because the default
    // framebuffer for WebGL is not fb 0, it is an internal fbo.
    if (mode == GL_BACK)
      mode = GL_COLOR_ATTACHMENT0;
  } else {
    if (mode == GL_BACK) {
      synthesizeGLError(GL_INVALID_OPERATION, "readBuffer",
                        "invalid read buffer");
      return;
    }
    readFramebufferBinding->readBuffer(mode);
  }
  contextGL()->ReadBuffer(mode);
}

void WebGL2RenderingContextBase::pixelStorei(GLenum pname, GLint param) {
  if (isContextLost())
    return;
  if (param < 0) {
    synthesizeGLError(GL_INVALID_VALUE, "pixelStorei", "negative value");
    return;
  }
  switch (pname) {
    case GL_PACK_ROW_LENGTH:
      m_packRowLength = param;
      break;
    case GL_PACK_SKIP_PIXELS:
      m_packSkipPixels = param;
      break;
    case GL_PACK_SKIP_ROWS:
      m_packSkipRows = param;
      break;
    case GL_UNPACK_ROW_LENGTH:
      m_unpackRowLength = param;
      break;
    case GL_UNPACK_IMAGE_HEIGHT:
      m_unpackImageHeight = param;
      break;
    case GL_UNPACK_SKIP_PIXELS:
      m_unpackSkipPixels = param;
      break;
    case GL_UNPACK_SKIP_ROWS:
      m_unpackSkipRows = param;
      break;
    case GL_UNPACK_SKIP_IMAGES:
      m_unpackSkipImages = param;
      break;
    default:
      WebGLRenderingContextBase::pixelStorei(pname, param);
      return;
  }
  contextGL()->PixelStorei(pname, param);
}

void WebGL2RenderingContextBase::readPixels(GLint x,
                                            GLint y,
                                            GLsizei width,
                                            GLsizei height,
                                            GLenum format,
                                            GLenum type,
                                            DOMArrayBufferView* pixels) {
  if (isContextLost())
    return;
  if (m_boundPixelPackBuffer.get()) {
    synthesizeGLError(GL_INVALID_OPERATION, "readPixels",
                      "PIXEL_PACK buffer should not be bound");
    return;
  }

  readPixelsHelper(x, y, width, height, format, type, pixels, 0);
}

void WebGL2RenderingContextBase::readPixels(GLint x,
                                            GLint y,
                                            GLsizei width,
                                            GLsizei height,
                                            GLenum format,
                                            GLenum type,
                                            DOMArrayBufferView* pixels,
                                            GLuint offset) {
  if (isContextLost())
    return;
  if (m_boundPixelPackBuffer.get()) {
    synthesizeGLError(GL_INVALID_OPERATION, "readPixels",
                      "PIXEL_PACK buffer should not be bound");
    return;
  }

  readPixelsHelper(x, y, width, height, format, type, pixels, offset);
}

void WebGL2RenderingContextBase::readPixels(GLint x,
                                            GLint y,
                                            GLsizei width,
                                            GLsizei height,
                                            GLenum format,
                                            GLenum type,
                                            long long offset) {
  if (isContextLost())
    return;

  // Due to WebGL's same-origin restrictions, it is not possible to
  // taint the origin using the WebGL API.
  ASSERT(canvas()->originClean());

  if (!validateValueFitNonNegInt32("readPixels", "offset", offset))
    return;

  WebGLBuffer* buffer = m_boundPixelPackBuffer.get();
  if (!buffer) {
    synthesizeGLError(GL_INVALID_OPERATION, "readPixels",
                      "no PIXEL_PACK buffer bound");
    return;
  }

  const char* reason = "framebuffer incomplete";
  WebGLFramebuffer* framebuffer = getReadFramebufferBinding();
  if (framebuffer &&
      framebuffer->checkDepthStencilStatus(&reason) !=
          GL_FRAMEBUFFER_COMPLETE) {
    synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "readPixels", reason);
    return;
  }

  long long size = buffer->getSize() - offset;
  // If size is negative, or size is not large enough to store pixels, those
  // cases are handled by validateReadPixelsFuncParameters to generate
  // INVALID_OPERATION.
  if (!validateReadPixelsFuncParameters(width, height, format, type, nullptr,
                                        size))
    return;

  clearIfComposited();

  {
    ScopedDrawingBufferBinder binder(drawingBuffer(), framebuffer);
    contextGL()->ReadPixels(x, y, width, height, format, type,
                            reinterpret_cast<void*>(offset));
  }
}

void WebGL2RenderingContextBase::renderbufferStorageHelper(
    GLenum target,
    GLsizei samples,
    GLenum internalformat,
    GLsizei width,
    GLsizei height,
    const char* functionName) {
  if (!samples) {
    contextGL()->RenderbufferStorage(target, internalformat, width, height);
  } else {
    GLint maxNumberOfSamples = 0;
    contextGL()->GetInternalformativ(target, internalformat, GL_SAMPLES, 1,
                                     &maxNumberOfSamples);
    if (samples > maxNumberOfSamples) {
      synthesizeGLError(GL_INVALID_OPERATION, functionName,
                        "samples out of range");
      return;
    }
    contextGL()->RenderbufferStorageMultisampleCHROMIUM(
        target, samples, internalformat, width, height);
  }
}

void WebGL2RenderingContextBase::renderbufferStorageImpl(
    GLenum target,
    GLsizei samples,
    GLenum internalformat,
    GLsizei width,
    GLsizei height,
    const char* functionName) {
  switch (internalformat) {
    case GL_R8UI:
    case GL_R8I:
    case GL_R16UI:
    case GL_R16I:
    case GL_R32UI:
    case GL_R32I:
    case GL_RG8UI:
    case GL_RG8I:
    case GL_RG16UI:
    case GL_RG16I:
    case GL_RG32UI:
    case GL_RG32I:
    case GL_RGBA8UI:
    case GL_RGBA8I:
    case GL_RGB10_A2UI:
    case GL_RGBA16UI:
    case GL_RGBA16I:
    case GL_RGBA32UI:
    case GL_RGBA32I:
      if (samples > 0) {
        synthesizeGLError(GL_INVALID_OPERATION, functionName,
                          "for integer formats, samples > 0");
        return;
      }
    case GL_R8:
    case GL_RG8:
    case GL_RGB8:
    case GL_RGB565:
    case GL_RGBA8:
    case GL_SRGB8_ALPHA8:
    case GL_RGB5_A1:
    case GL_RGBA4:
    case GL_RGB10_A2:
    case GL_DEPTH_COMPONENT16:
    case GL_DEPTH_COMPONENT24:
    case GL_DEPTH_COMPONENT32F:
    case GL_DEPTH24_STENCIL8:
    case GL_DEPTH32F_STENCIL8:
    case GL_STENCIL_INDEX8:
      renderbufferStorageHelper(target, samples, internalformat, width, height,
                                functionName);
      break;
    case GL_DEPTH_STENCIL:
      // To be WebGL 1 backward compatible.
      if (samples > 0) {
        synthesizeGLError(GL_INVALID_ENUM, functionName,
                          "invalid internalformat");
        return;
      }
      renderbufferStorageHelper(target, 0, GL_DEPTH24_STENCIL8, width, height,
                                functionName);
      break;
    case GL_R16F:
    case GL_RG16F:
    case GL_RGBA16F:
    case GL_R32F:
    case GL_RG32F:
    case GL_RGBA32F:
    case GL_R11F_G11F_B10F:
      if (!extensionEnabled(EXTColorBufferFloatName)) {
        synthesizeGLError(GL_INVALID_ENUM, functionName,
                          "EXT_color_buffer_float not enabled");
        return;
      }
      renderbufferStorageHelper(target, samples, internalformat, width, height,
                                functionName);
      break;
    default:
      synthesizeGLError(GL_INVALID_ENUM, functionName,
                        "invalid internalformat");
      return;
  }
  m_renderbufferBinding->setInternalFormat(internalformat);
  m_renderbufferBinding->setSize(width, height);
}

void WebGL2RenderingContextBase::renderbufferStorageMultisample(
    GLenum target,
    GLsizei samples,
    GLenum internalformat,
    GLsizei width,
    GLsizei height) {
  const char* functionName = "renderbufferStorageMultisample";
  if (isContextLost())
    return;
  if (target != GL_RENDERBUFFER) {
    synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid target");
    return;
  }
  if (!m_renderbufferBinding || !m_renderbufferBinding->object()) {
    synthesizeGLError(GL_INVALID_OPERATION, functionName,
                      "no bound renderbuffer");
    return;
  }
  if (!validateSize("renderbufferStorage", width, height))
    return;
  if (samples < 0) {
    synthesizeGLError(GL_INVALID_VALUE, functionName, "samples < 0");
    return;
  }
  renderbufferStorageImpl(target, samples, internalformat, width, height,
                          functionName);
  applyStencilTest();
}

void WebGL2RenderingContextBase::resetUnpackParameters() {
  WebGLRenderingContextBase::resetUnpackParameters();

  if (m_unpackRowLength)
    contextGL()->PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
  if (m_unpackImageHeight)
    contextGL()->PixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
  if (m_unpackSkipPixels)
    contextGL()->PixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
  if (m_unpackSkipRows)
    contextGL()->PixelStorei(GL_UNPACK_SKIP_ROWS, 0);
  if (m_unpackSkipImages)
    contextGL()->PixelStorei(GL_UNPACK_SKIP_IMAGES, 0);
}

void WebGL2RenderingContextBase::restoreUnpackParameters() {
  WebGLRenderingContextBase::restoreUnpackParameters();

  if (m_unpackRowLength)
    contextGL()->PixelStorei(GL_UNPACK_ROW_LENGTH, m_unpackRowLength);
  if (m_unpackImageHeight)
    contextGL()->PixelStorei(GL_UNPACK_IMAGE_HEIGHT, m_unpackImageHeight);
  if (m_unpackSkipPixels)
    contextGL()->PixelStorei(GL_UNPACK_SKIP_PIXELS, m_unpackSkipPixels);
  if (m_unpackSkipRows)
    contextGL()->PixelStorei(GL_UNPACK_SKIP_ROWS, m_unpackSkipRows);
  if (m_unpackSkipImages)
    contextGL()->PixelStorei(GL_UNPACK_SKIP_IMAGES, m_unpackSkipImages);
}

/* Texture objects */
bool WebGL2RenderingContextBase::validateTexStorage(
    const char* functionName,
    GLenum target,
    GLsizei levels,
    GLenum internalformat,
    GLsizei width,
    GLsizei height,
    GLsizei depth,
    TexStorageType functionType) {
  if (functionType == TexStorageType2D) {
    if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP) {
      synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid 2D target");
      return false;
    }
  } else {
    if (target != GL_TEXTURE_3D && target != GL_TEXTURE_2D_ARRAY) {
      synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid 3D target");
      return false;
    }
  }

  if (functionType == TexStorageType3D && target != GL_TEXTURE_2D_ARRAY &&
      m_compressedTextureFormatsETC2EAC.find(internalformat) !=
          m_compressedTextureFormatsETC2EAC.end()) {
    synthesizeGLError(
        GL_INVALID_OPERATION, functionName,
        "target for ETC2/EAC internal formats must be TEXTURE_2D_ARRAY");
    return false;
  }

  if (m_supportedInternalFormatsStorage.find(internalformat) ==
          m_supportedInternalFormatsStorage.end() &&
      (functionType == TexStorageType2D &&
       !m_compressedTextureFormats.contains(internalformat))) {
    synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid internalformat");
    return false;
  }

  if (width <= 0 || height <= 0 || depth <= 0) {
    synthesizeGLError(GL_INVALID_VALUE, functionName, "invalid dimensions");
    return false;
  }

  if (levels <= 0) {
    synthesizeGLError(GL_INVALID_VALUE, functionName, "invalid levels");
    return false;
  }

  if (target == GL_TEXTURE_3D) {
    if (levels > log2(std::max(std::max(width, height), depth)) + 1) {
      synthesizeGLError(GL_INVALID_OPERATION, functionName, "to many levels");
      return false;
    }
  } else {
    if (levels > log2(std::max(width, height)) + 1) {
      synthesizeGLError(GL_INVALID_OPERATION, functionName, "to many levels");
      return false;
    }
  }

  return true;
}

void WebGL2RenderingContextBase::texImage2D(GLenum target,
                                            GLint level,
                                            GLint internalformat,
                                            GLsizei width,
                                            GLsizei height,
                                            GLint border,
                                            GLenum format,
                                            GLenum type,
                                            GLintptr offset) {
  if (isContextLost())
    return;
  if (!validateTexture2DBinding("texImage2D", target))
    return;
  if (!m_boundPixelUnpackBuffer) {
    synthesizeGLError(GL_INVALID_OPERATION, "texImage2D",
                      "no bound PIXEL_UNPACK_BUFFER");
    return;
  }
  if (!validateTexFunc("texImage2D", TexImage, SourceUnpackBuffer, target,
                       level, internalformat, width, height, 1, border, format,
                       type, 0, 0, 0))
    return;
  if (!validateValueFitNonNegInt32("texImage2D", "offset", offset))
    return;

  contextGL()->TexImage2D(
      target, level, convertTexInternalFormat(internalformat, type), width,
      height, border, format, type, reinterpret_cast<const void*>(offset));
}

void WebGL2RenderingContextBase::texSubImage2D(GLenum target,
                                               GLint level,
                                               GLint xoffset,
                                               GLint yoffset,
                                               GLsizei width,
                                               GLsizei height,
                                               GLenum format,
                                               GLenum type,
                                               GLintptr offset) {
  if (isContextLost())
    return;
  if (!validateTexture2DBinding("texSubImage2D", target))
    return;
  if (!m_boundPixelUnpackBuffer) {
    synthesizeGLError(GL_INVALID_OPERATION, "texSubImage2D",
                      "no bound PIXEL_UNPACK_BUFFER");
    return;
  }
  if (!validateTexFunc("texSubImage2D", TexSubImage, SourceUnpackBuffer, target,
                       level, 0, width, height, 1, 0, format, type, xoffset,
                       yoffset, 0))
    return;
  if (!validateValueFitNonNegInt32("texSubImage2D", "offset", offset))
    return;

  contextGL()->TexSubImage2D(target, level, xoffset, yoffset, width, height,
                             format, type,
                             reinterpret_cast<const void*>(offset));
}

void WebGL2RenderingContextBase::texImage2D(GLenum target,
                                            GLint level,
                                            GLint internalformat,
                                            GLsizei width,
                                            GLsizei height,
                                            GLint border,
                                            GLenum format,
                                            GLenum type,
                                            DOMArrayBufferView* data) {
  WebGLRenderingContextBase::texImage2D(target, level, internalformat, width,
                                        height, border, format, type, data);
}

void WebGL2RenderingContextBase::texImage2D(GLenum target,
                                            GLint level,
                                            GLint internalformat,
                                            GLsizei width,
                                            GLsizei height,
                                            GLint border,
                                            GLenum format,
                                            GLenum type,
                                            DOMArrayBufferView* data,
                                            GLuint srcOffset) {
  texImageHelperDOMArrayBufferView(TexImage2D, target, level, internalformat,
                                   width, height, 1, border, format, type, 0, 0,
                                   0, data, NullNotReachable, srcOffset);
}

void WebGL2RenderingContextBase::texImage2D(GLenum target,
                                            GLint level,
                                            GLint internalformat,
                                            GLsizei width,
                                            GLsizei height,
                                            GLint border,
                                            GLenum format,
                                            GLenum type,
                                            ImageData* pixels) {
  DCHECK(pixels);
  texImageHelperImageData(TexImage2D, target, level, internalformat, 0, format,
                          type, 1, 0, 0, 0, pixels,
                          getTextureSourceSubRectangle(width, height), 0);
}

void WebGL2RenderingContextBase::texImage2D(GLenum target,
                                            GLint level,
                                            GLint internalformat,
                                            GLsizei width,
                                            GLsizei height,
                                            GLint border,
                                            GLenum format,
                                            GLenum type,
                                            HTMLImageElement* image,
                                            ExceptionState& exceptionState) {
  texImageHelperHTMLImageElement(TexImage2D, target, level, internalformat,
                                 format, type, 0, 0, 0, image,
                                 getTextureSourceSubRectangle(width, height), 1,
                                 m_unpackImageHeight, exceptionState);
}

void WebGL2RenderingContextBase::texImage2D(GLenum target,
                                            GLint level,
                                            GLint internalformat,
                                            GLsizei width,
                                            GLsizei height,
                                            GLint border,
                                            GLenum format,
                                            GLenum type,
                                            HTMLCanvasElement* canvas,
                                            ExceptionState& exceptionState) {
  texImageHelperHTMLCanvasElement(
      TexImage2D, target, level, internalformat, format, type, 0, 0, 0, canvas,
      getTextureSourceSubRectangle(width, height), 1, 0, exceptionState);
}

void WebGL2RenderingContextBase::texImage2D(GLenum target,
                                            GLint level,
                                            GLint internalformat,
                                            GLsizei width,
                                            GLsizei height,
                                            GLint border,
                                            GLenum format,
                                            GLenum type,
                                            HTMLVideoElement* video,
                                            ExceptionState& exceptionState) {
  texImageHelperHTMLVideoElement(
      TexImage2D, target, level, internalformat, format, type, 0, 0, 0, video,
      getTextureSourceSubRectangle(width, height), 1, 0, exceptionState);
}

void WebGL2RenderingContextBase::texImage2D(GLenum target,
                                            GLint level,
                                            GLint internalformat,
                                            GLsizei width,
                                            GLsizei height,
                                            GLint border,
                                            GLenum format,
                                            GLenum type,
                                            ImageBitmap* bitmap,
                                            ExceptionState& exceptionState) {
  DCHECK(bitmap);
  texImageHelperImageBitmap(
      TexImage2D, target, level, internalformat, format, type, 0, 0, 0, bitmap,
      getTextureSourceSubRectangle(width, height), 1, 0, exceptionState);
}

void WebGL2RenderingContextBase::texImage2D(GLenum target,
                                            GLint level,
                                            GLint internalformat,
                                            GLenum format,
                                            GLenum type,
                                            ImageData* imageData) {
  WebGLRenderingContextBase::texImage2D(target, level, internalformat, format,
                                        type, imageData);
}

void WebGL2RenderingContextBase::texImage2D(GLenum target,
                                            GLint level,
                                            GLint internalformat,
                                            GLenum format,
                                            GLenum type,
                                            HTMLImageElement* image,
                                            ExceptionState& exceptionState) {
  WebGLRenderingContextBase::texImage2D(target, level, internalformat, format,
                                        type, image, exceptionState);
}

void WebGL2RenderingContextBase::texImage2D(GLenum target,
                                            GLint level,
                                            GLint internalformat,
                                            GLenum format,
                                            GLenum type,
                                            HTMLCanvasElement* canvas,
                                            ExceptionState& exceptionState) {
  WebGLRenderingContextBase::texImage2D(target, level, internalformat, format,
                                        type, canvas, exceptionState);
}

void WebGL2RenderingContextBase::texImage2D(GLenum target,
                                            GLint level,
                                            GLint internalformat,
                                            GLenum format,
                                            GLenum type,
                                            HTMLVideoElement* video,
                                            ExceptionState& exceptionState) {
  WebGLRenderingContextBase::texImage2D(target, level, internalformat, format,
                                        type, video, exceptionState);
}

void WebGL2RenderingContextBase::texImage2D(GLenum target,
                                            GLint level,
                                            GLint internalformat,
                                            GLenum format,
                                            GLenum type,
                                            ImageBitmap* imageBitMap,
                                            ExceptionState& exceptionState) {
  WebGLRenderingContextBase::texImage2D(target, level, internalformat, format,
                                        type, imageBitMap, exceptionState);
}

void WebGL2RenderingContextBase::texSubImage2D(GLenum target,
                                               GLint level,
                                               GLint xoffset,
                                               GLint yoffset,
                                               GLsizei width,
                                               GLsizei height,
                                               GLenum format,
                                               GLenum type,
                                               DOMArrayBufferView* pixels) {
  WebGLRenderingContextBase::texSubImage2D(target, level, xoffset, yoffset,
                                           width, height, format, type, pixels);
}

void WebGL2RenderingContextBase::texSubImage2D(GLenum target,
                                               GLint level,
                                               GLint xoffset,
                                               GLint yoffset,
                                               GLsizei width,
                                               GLsizei height,
                                               GLenum format,
                                               GLenum type,
                                               DOMArrayBufferView* pixels,
                                               GLuint srcOffset) {
  texImageHelperDOMArrayBufferView(TexSubImage2D, target, level, 0, width,
                                   height, 1, 0, format, type, xoffset, yoffset,
                                   0, pixels, NullNotReachable, srcOffset);
}

void WebGL2RenderingContextBase::texSubImage2D(GLenum target,
                                               GLint level,
                                               GLint xoffset,
                                               GLint yoffset,
                                               GLsizei width,
                                               GLsizei height,
                                               GLenum format,
                                               GLenum type,
                                               ImageData* pixels) {
  DCHECK(pixels);
  texImageHelperImageData(TexSubImage2D, target, level, 0, 0, format, type, 1,
                          xoffset, yoffset, 0, pixels,
                          getTextureSourceSubRectangle(width, height), 0);
}

void WebGL2RenderingContextBase::texSubImage2D(GLenum target,
                                               GLint level,
                                               GLint xoffset,
                                               GLint yoffset,
                                               GLsizei width,
                                               GLsizei height,
                                               GLenum format,
                                               GLenum type,
                                               HTMLImageElement* image,
                                               ExceptionState& exceptionState) {
  texImageHelperHTMLImageElement(
      TexSubImage2D, target, level, 0, format, type, xoffset, yoffset, 0, image,
      getTextureSourceSubRectangle(width, height), 1, 0, exceptionState);
}

void WebGL2RenderingContextBase::texSubImage2D(GLenum target,
                                               GLint level,
                                               GLint xoffset,
                                               GLint yoffset,
                                               GLsizei width,
                                               GLsizei height,
                                               GLenum format,
                                               GLenum type,
                                               HTMLCanvasElement* canvas,
                                               ExceptionState& exceptionState) {
  texImageHelperHTMLCanvasElement(TexSubImage2D, target, level, 0, format, type,
                                  xoffset, yoffset, 0, canvas,
                                  getTextureSourceSubRectangle(width, height),
                                  1, 0, exceptionState);
}

void WebGL2RenderingContextBase::texSubImage2D(GLenum target,
                                               GLint level,
                                               GLint xoffset,
                                               GLint yoffset,
                                               GLsizei width,
                                               GLsizei height,
                                               GLenum format,
                                               GLenum type,
                                               HTMLVideoElement* video,
                                               ExceptionState& exceptionState) {
  texImageHelperHTMLVideoElement(
      TexSubImage2D, target, level, 0, format, type, xoffset, yoffset, 0, video,
      getTextureSourceSubRectangle(width, height), 1, 0, exceptionState);
}

void WebGL2RenderingContextBase::texSubImage2D(GLenum target,
                                               GLint level,
                                               GLint xoffset,
                                               GLint yoffset,
                                               GLsizei width,
                                               GLsizei height,
                                               GLenum format,
                                               GLenum type,
                                               ImageBitmap* bitmap,
                                               ExceptionState& exceptionState) {
  DCHECK(bitmap);
  texImageHelperImageBitmap(TexSubImage2D, target, level, 0, format, type,
                            xoffset, yoffset, 0, bitmap,
                            getTextureSourceSubRectangle(width, height), 1, 0,
                            exceptionState);
}

void WebGL2RenderingContextBase::texSubImage2D(GLenum target,
                                               GLint level,
                                               GLint xoffset,
                                               GLint yoffset,
                                               GLenum format,
                                               GLenum type,
                                               ImageData* pixels) {
  WebGLRenderingContextBase::texSubImage2D(target, level, xoffset, yoffset,
                                           format, type, pixels);
}

void WebGL2RenderingContextBase::texSubImage2D(GLenum target,
                                               GLint level,
                                               GLint xoffset,
                                               GLint yoffset,
                                               GLenum format,
                                               GLenum type,
                                               HTMLImageElement* image,
                                               ExceptionState& exceptionState) {
  WebGLRenderingContextBase::texSubImage2D(target, level, xoffset, yoffset,
                                           format, type, image, exceptionState);
}

void WebGL2RenderingContextBase::texSubImage2D(GLenum target,
                                               GLint level,
                                               GLint xoffset,
                                               GLint yoffset,
                                               GLenum format,
                                               GLenum type,
                                               HTMLCanvasElement* canvas,
                                               ExceptionState& exceptionState) {
  WebGLRenderingContextBase::texSubImage2D(
      target, level, xoffset, yoffset, format, type, canvas, exceptionState);
}

void WebGL2RenderingContextBase::texSubImage2D(GLenum target,
                                               GLint level,
                                               GLint xoffset,
                                               GLint yoffset,
                                               GLenum format,
                                               GLenum type,
                                               HTMLVideoElement* video,
                                               ExceptionState& exceptionState) {
  WebGLRenderingContextBase::texSubImage2D(target, level, xoffset, yoffset,
                                           format, type, video, exceptionState);
}

void WebGL2RenderingContextBase::texSubImage2D(GLenum target,
                                               GLint level,
                                               GLint xoffset,
                                               GLint yoffset,
                                               GLenum format,
                                               GLenum type,
                                               ImageBitmap* bitmap,
                                               ExceptionState& exceptionState) {
  WebGLRenderingContextBase::texSubImage2D(
      target, level, xoffset, yoffset, format, type, bitmap, exceptionState);
}

void WebGL2RenderingContextBase::texStorage2D(GLenum target,
                                              GLsizei levels,
                                              GLenum internalformat,
                                              GLsizei width,
                                              GLsizei height) {
  if (isContextLost() ||
      !validateTexStorage("texStorage2D", target, levels, internalformat, width,
                          height, 1, TexStorageType2D))
    return;

  contextGL()->TexStorage2DEXT(target, levels, internalformat, width, height);
}

void WebGL2RenderingContextBase::texStorage3D(GLenum target,
                                              GLsizei levels,
                                              GLenum internalformat,
                                              GLsizei width,
                                              GLsizei height,
                                              GLsizei depth) {
  if (isContextLost() ||
      !validateTexStorage("texStorage3D", target, levels, internalformat, width,
                          height, depth, TexStorageType3D))
    return;

  contextGL()->TexStorage3D(target, levels, internalformat, width, height,
                            depth);
}

void WebGL2RenderingContextBase::texImage3D(GLenum target,
                                            GLint level,
                                            GLint internalformat,
                                            GLsizei width,
                                            GLsizei height,
                                            GLsizei depth,
                                            GLint border,
                                            GLenum format,
                                            GLenum type,
                                            DOMArrayBufferView* pixels) {
  texImageHelperDOMArrayBufferView(TexImage3D, target, level, internalformat,
                                   width, height, depth, border, format, type,
                                   0, 0, 0, pixels, NullAllowed, 0);
}

void WebGL2RenderingContextBase::texImage3D(GLenum target,
                                            GLint level,
                                            GLint internalformat,
                                            GLsizei width,
                                            GLsizei height,
                                            GLsizei depth,
                                            GLint border,
                                            GLenum format,
                                            GLenum type,
                                            DOMArrayBufferView* pixels,
                                            GLuint srcOffset) {
  texImageHelperDOMArrayBufferView(
      TexImage3D, target, level, internalformat, width, height, depth, border,
      format, type, 0, 0, 0, pixels, NullNotReachable, srcOffset);
}

void WebGL2RenderingContextBase::texImage3D(GLenum target,
                                            GLint level,
                                            GLint internalformat,
                                            GLsizei width,
                                            GLsizei height,
                                            GLsizei depth,
                                            GLint border,
                                            GLenum format,
                                            GLenum type,
                                            GLintptr offset) {
  if (isContextLost())
    return;
  if (!validateTexture3DBinding("texImage3D", target))
    return;
  if (!m_boundPixelUnpackBuffer) {
    synthesizeGLError(GL_INVALID_OPERATION, "texImage3D",
                      "no bound PIXEL_UNPACK_BUFFER");
    return;
  }
  if (!validateTexFunc("texImage3D", TexImage, SourceUnpackBuffer, target,
                       level, internalformat, width, height, depth, border,
                       format, type, 0, 0, 0))
    return;
  if (!validateValueFitNonNegInt32("texImage3D", "offset", offset))
    return;

  contextGL()->TexImage3D(target, level,
                          convertTexInternalFormat(internalformat, type), width,
                          height, depth, border, format, type,
                          reinterpret_cast<const void*>(offset));
}

void WebGL2RenderingContextBase::texImage3D(GLenum target,
                                            GLint level,
                                            GLint internalformat,
                                            GLsizei width,
                                            GLsizei height,
                                            GLsizei depth,
                                            GLint border,
                                            GLenum format,
                                            GLenum type,
                                            ImageData* pixels) {
  DCHECK(pixels);
  IntRect sourceImageRect;
  sourceImageRect.setLocation(IntPoint(m_unpackSkipPixels, m_unpackSkipRows));
  sourceImageRect.setSize(IntSize(width, height));
  texImageHelperImageData(TexImage3D, target, level, internalformat, 0, format,
                          type, depth, 0, 0, 0, pixels, sourceImageRect,
                          m_unpackImageHeight);
}

void WebGL2RenderingContextBase::texImage3D(GLenum target,
                                            GLint level,
                                            GLint internalformat,
                                            GLsizei width,
                                            GLsizei height,
                                            GLsizei depth,
                                            GLint border,
                                            GLenum format,
                                            GLenum type,
                                            HTMLImageElement* image,
                                            ExceptionState& exceptionState) {
  texImageHelperHTMLImageElement(TexImage3D, target, level, internalformat,
                                 format, type, 0, 0, 0, image,
                                 getTextureSourceSubRectangle(width, height),
                                 depth, m_unpackImageHeight, exceptionState);
}

void WebGL2RenderingContextBase::texImage3D(GLenum target,
                                            GLint level,
                                            GLint internalformat,
                                            GLsizei width,
                                            GLsizei height,
                                            GLsizei depth,
                                            GLint border,
                                            GLenum format,
                                            GLenum type,
                                            HTMLCanvasElement* canvas,
                                            ExceptionState& exceptionState) {
  texImageHelperHTMLCanvasElement(TexImage3D, target, level, internalformat,
                                  format, type, 0, 0, 0, canvas,
                                  getTextureSourceSubRectangle(width, height),
                                  depth, m_unpackImageHeight, exceptionState);
}

void WebGL2RenderingContextBase::texImage3D(GLenum target,
                                            GLint level,
                                            GLint internalformat,
                                            GLsizei width,
                                            GLsizei height,
                                            GLsizei depth,
                                            GLint border,
                                            GLenum format,
                                            GLenum type,
                                            HTMLVideoElement* video,
                                            ExceptionState& exceptionState) {
  texImageHelperHTMLVideoElement(TexImage3D, target, level, internalformat,
                                 format, type, 0, 0, 0, video,
                                 getTextureSourceSubRectangle(width, height),
                                 depth, m_unpackImageHeight, exceptionState);
}

void WebGL2RenderingContextBase::texImage3D(GLenum target,
                                            GLint level,
                                            GLint internalformat,
                                            GLsizei width,
                                            GLsizei height,
                                            GLsizei depth,
                                            GLint border,
                                            GLenum format,
                                            GLenum type,
                                            ImageBitmap* bitmap,
                                            ExceptionState& exceptionState) {
  texImageHelperImageBitmap(TexImage3D, target, level, internalformat, format,
                            type, 0, 0, 0, bitmap,
                            getTextureSourceSubRectangle(width, height), depth,
                            m_unpackImageHeight, exceptionState);
}

void WebGL2RenderingContextBase::texSubImage3D(GLenum target,
                                               GLint level,
                                               GLint xoffset,
                                               GLint yoffset,
                                               GLint zoffset,
                                               GLsizei width,
                                               GLsizei height,
                                               GLsizei depth,
                                               GLenum format,
                                               GLenum type,
                                               DOMArrayBufferView* pixels,
                                               GLuint srcOffset) {
  texImageHelperDOMArrayBufferView(
      TexSubImage3D, target, level, 0, width, height, depth, 0, format, type,
      xoffset, yoffset, zoffset, pixels, NullNotReachable, srcOffset);
}

void WebGL2RenderingContextBase::texSubImage3D(GLenum target,
                                               GLint level,
                                               GLint xoffset,
                                               GLint yoffset,
                                               GLint zoffset,
                                               GLsizei width,
                                               GLsizei height,
                                               GLsizei depth,
                                               GLenum format,
                                               GLenum type,
                                               GLintptr offset) {
  if (isContextLost())
    return;
  if (!validateTexture3DBinding("texSubImage3D", target))
    return;
  if (!m_boundPixelUnpackBuffer) {
    synthesizeGLError(GL_INVALID_OPERATION, "texSubImage3D",
                      "no bound PIXEL_UNPACK_BUFFER");
    return;
  }
  if (!validateTexFunc("texSubImage3D", TexSubImage, SourceUnpackBuffer, target,
                       level, 0, width, height, depth, 0, format, type, xoffset,
                       yoffset, zoffset))
    return;
  if (!validateValueFitNonNegInt32("texSubImage3D", "offset", offset))
    return;

  contextGL()->TexSubImage3D(target, level, xoffset, yoffset, zoffset, width,
                             height, depth, format, type,
                             reinterpret_cast<const void*>(offset));
}

void WebGL2RenderingContextBase::texSubImage3D(GLenum target,
                                               GLint level,
                                               GLint xoffset,
                                               GLint yoffset,
                                               GLint zoffset,
                                               GLsizei width,
                                               GLsizei height,
                                               GLsizei depth,
                                               GLenum format,
                                               GLenum type,
                                               ImageData* pixels) {
  DCHECK(pixels);
  texImageHelperImageData(TexSubImage3D, target, level, 0, 0, format, type,
                          depth, xoffset, yoffset, zoffset, pixels,
                          getTextureSourceSubRectangle(width, height),
                          m_unpackImageHeight);
}

void WebGL2RenderingContextBase::texSubImage3D(GLenum target,
                                               GLint level,
                                               GLint xoffset,
                                               GLint yoffset,
                                               GLint zoffset,
                                               GLsizei width,
                                               GLsizei height,
                                               GLsizei depth,
                                               GLenum format,
                                               GLenum type,
                                               HTMLImageElement* image,
                                               ExceptionState& exceptionState) {
  texImageHelperHTMLImageElement(TexSubImage3D, target, level, 0, format, type,
                                 xoffset, yoffset, zoffset, image,
                                 getTextureSourceSubRectangle(width, height),
                                 depth, m_unpackImageHeight, exceptionState);
}

void WebGL2RenderingContextBase::texSubImage3D(GLenum target,
                                               GLint level,
                                               GLint xoffset,
                                               GLint yoffset,
                                               GLint zoffset,
                                               GLsizei width,
                                               GLsizei height,
                                               GLsizei depth,
                                               GLenum format,
                                               GLenum type,
                                               HTMLCanvasElement* canvas,
                                               ExceptionState& exceptionState) {
  texImageHelperHTMLCanvasElement(TexSubImage3D, target, level, 0, format, type,
                                  xoffset, yoffset, zoffset, canvas,
                                  getTextureSourceSubRectangle(width, height),
                                  depth, m_unpackImageHeight, exceptionState);
}

void WebGL2RenderingContextBase::texSubImage3D(GLenum target,
                                               GLint level,
                                               GLint xoffset,
                                               GLint yoffset,
                                               GLint zoffset,
                                               GLsizei width,
                                               GLsizei height,
                                               GLsizei depth,
                                               GLenum format,
                                               GLenum type,
                                               HTMLVideoElement* video,
                                               ExceptionState& exceptionState) {
  texImageHelperHTMLVideoElement(TexSubImage3D, target, level, 0, format, type,
                                 xoffset, yoffset, zoffset, video,
                                 getTextureSourceSubRectangle(width, height),
                                 depth, m_unpackImageHeight, exceptionState);
}

void WebGL2RenderingContextBase::texSubImage3D(GLenum target,
                                               GLint level,
                                               GLint xoffset,
                                               GLint yoffset,
                                               GLint zoffset,
                                               GLsizei width,
                                               GLsizei height,
                                               GLsizei depth,
                                               GLenum format,
                                               GLenum type,
                                               ImageBitmap* bitmap,
                                               ExceptionState& exceptionState) {
  texImageHelperImageBitmap(TexSubImage3D, target, level, 0, format, type,
                            xoffset, yoffset, zoffset, bitmap,
                            getTextureSourceSubRectangle(width, height), depth,
                            m_unpackImageHeight, exceptionState);
}

void WebGL2RenderingContextBase::copyTexSubImage3D(GLenum target,
                                                   GLint level,
                                                   GLint xoffset,
                                                   GLint yoffset,
                                                   GLint zoffset,
                                                   GLint x,
                                                   GLint y,
                                                   GLsizei width,
                                                   GLsizei height) {
  if (isContextLost())
    return;
  if (!validateTexture3DBinding("copyTexSubImage3D", target))
    return;
  WebGLFramebuffer* readFramebufferBinding = nullptr;
  if (!validateReadBufferAndGetInfo("copyTexSubImage3D",
                                    readFramebufferBinding))
    return;
  clearIfComposited();
  ScopedDrawingBufferBinder binder(drawingBuffer(), readFramebufferBinding);
  contextGL()->CopyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y,
                                 width, height);
}

void WebGL2RenderingContextBase::compressedTexImage2D(
    GLenum target,
    GLint level,
    GLenum internalformat,
    GLsizei width,
    GLsizei height,
    GLint border,
    DOMArrayBufferView* data) {
  WebGLRenderingContextBase::compressedTexImage2D(target, level, internalformat,
                                                  width, height, border, data);
}

void WebGL2RenderingContextBase::compressedTexImage2D(
    GLenum target,
    GLint level,
    GLenum internalformat,
    GLsizei width,
    GLsizei height,
    GLint border,
    DOMArrayBufferView* data,
    GLuint srcOffset,
    GLuint srcLengthOverride) {
  if (isContextLost())
    return;
  if (!validateTexture2DBinding("compressedTexImage2D", target))
    return;
  if (!validateCompressedTexFormat("compressedTexImage2D", internalformat))
    return;
  if (srcOffset > data->byteLength()) {
    synthesizeGLError(GL_INVALID_VALUE, "compressedTexImage2D",
                      "srcOffset is out of range");
    return;
  }
  if (srcLengthOverride == 0) {
    srcLengthOverride = data->byteLength() - srcOffset;
  } else if (srcLengthOverride > data->byteLength() - srcOffset) {
    synthesizeGLError(GL_INVALID_VALUE, "compressedTexImage2D",
                      "srcLengthOverride is out of range");
    return;
  }
  contextGL()->CompressedTexImage2D(
      target, level, internalformat, width, height, border, srcLengthOverride,
      static_cast<uint8_t*>(data->baseAddress()) + srcOffset);
}

void WebGL2RenderingContextBase::compressedTexSubImage2D(
    GLenum target,
    GLint level,
    GLint xoffset,
    GLint yoffset,
    GLsizei width,
    GLsizei height,
    GLenum format,
    DOMArrayBufferView* data) {
  WebGLRenderingContextBase::compressedTexSubImage2D(
      target, level, xoffset, yoffset, width, height, format, data);
}

void WebGL2RenderingContextBase::compressedTexSubImage2D(
    GLenum target,
    GLint level,
    GLint xoffset,
    GLint yoffset,
    GLsizei width,
    GLsizei height,
    GLenum format,
    DOMArrayBufferView* data,
    GLuint srcOffset,
    GLuint srcLengthOverride) {
  if (isContextLost())
    return;
  if (!validateTexture2DBinding("compressedTexSubImage2D", target))
    return;
  if (!validateCompressedTexFormat("compressedTexSubImage2D", format))
    return;
  if (srcOffset > data->byteLength()) {
    synthesizeGLError(GL_INVALID_VALUE, "compressedTexSubImage2D",
                      "srcOffset is out of range");
    return;
  }
  if (srcLengthOverride == 0) {
    srcLengthOverride = data->byteLength() - srcOffset;
  } else if (srcLengthOverride > data->byteLength() - srcOffset) {
    synthesizeGLError(GL_INVALID_VALUE, "compressedTexImage2D",
                      "srcLengthOverride is out of range");
    return;
  }
  contextGL()->CompressedTexSubImage2D(
      target, level, xoffset, yoffset, width, height, format, srcLengthOverride,
      static_cast<uint8_t*>(data->baseAddress()) + srcOffset);
}

void WebGL2RenderingContextBase::compressedTexImage3D(
    GLenum target,
    GLint level,
    GLenum internalformat,
    GLsizei width,
    GLsizei height,
    GLsizei depth,
    GLint border,
    DOMArrayBufferView* data,
    GLuint srcOffset,
    GLuint srcLengthOverride) {
  if (isContextLost())
    return;
  if (!validateTexture3DBinding("compressedTexImage3D", target))
    return;
  if (!validateCompressedTexFormat("compressedTexImage3D", internalformat))
    return;
  if (srcOffset > data->byteLength()) {
    synthesizeGLError(GL_INVALID_VALUE, "compressedTexImage3D",
                      "srcOffset is out of range");
    return;
  }
  if (srcLengthOverride == 0) {
    srcLengthOverride = data->byteLength() - srcOffset;
  } else if (srcLengthOverride > data->byteLength() - srcOffset) {
    synthesizeGLError(GL_INVALID_VALUE, "compressedTexImage3D",
                      "srcLengthOverride is out of range");
    return;
  }
  contextGL()->CompressedTexImage3D(
      target, level, internalformat, width, height, depth, border,
      srcLengthOverride,
      static_cast<uint8_t*>(data->baseAddress()) + srcOffset);
}

void WebGL2RenderingContextBase::compressedTexSubImage3D(
    GLenum target,
    GLint level,
    GLint xoffset,
    GLint yoffset,
    GLint zoffset,
    GLsizei width,
    GLsizei height,
    GLsizei depth,
    GLenum format,
    DOMArrayBufferView* data,
    GLuint srcOffset,
    GLuint srcLengthOverride) {
  if (isContextLost())
    return;
  if (!validateTexture3DBinding("compressedTexSubImage3D", target))
    return;
  if (!validateCompressedTexFormat("compressedTexSubImage3D", format))
    return;
  if (srcOffset > data->byteLength()) {
    synthesizeGLError(GL_INVALID_VALUE, "compressedTexSubImage3D",
                      "srcOffset is out of range");
    return;
  }
  if (srcLengthOverride == 0) {
    srcLengthOverride = data->byteLength() - srcOffset;
  } else if (srcLengthOverride > data->byteLength() - srcOffset) {
    synthesizeGLError(GL_INVALID_VALUE, "compressedTexSubImage3D",
                      "srcLengthOverride is out of range");
    return;
  }
  contextGL()->CompressedTexSubImage3D(
      target, level, xoffset, yoffset, zoffset, width, height, depth, format,
      srcLengthOverride,
      static_cast<uint8_t*>(data->baseAddress()) + srcOffset);
}

GLint WebGL2RenderingContextBase::getFragDataLocation(WebGLProgram* program,
                                                      const String& name) {
  if (isContextLost() || !validateWebGLObject("getFragDataLocation", program))
    return -1;

  return contextGL()->GetFragDataLocation(objectOrZero(program),
                                          name.utf8().data());
}

void WebGL2RenderingContextBase::uniform1ui(
    const WebGLUniformLocation* location,
    GLuint v0) {
  if (isContextLost() || !location)
    return;

  if (location->program() != m_currentProgram) {
    synthesizeGLError(GL_INVALID_OPERATION, "uniform1ui",
                      "location not for current program");
    return;
  }

  contextGL()->Uniform1ui(location->location(), v0);
}

void WebGL2RenderingContextBase::uniform2ui(
    const WebGLUniformLocation* location,
    GLuint v0,
    GLuint v1) {
  if (isContextLost() || !location)
    return;

  if (location->program() != m_currentProgram) {
    synthesizeGLError(GL_INVALID_OPERATION, "uniform2ui",
                      "location not for current program");
    return;
  }

  contextGL()->Uniform2ui(location->location(), v0, v1);
}

void WebGL2RenderingContextBase::uniform3ui(
    const WebGLUniformLocation* location,
    GLuint v0,
    GLuint v1,
    GLuint v2) {
  if (isContextLost() || !location)
    return;

  if (location->program() != m_currentProgram) {
    synthesizeGLError(GL_INVALID_OPERATION, "uniform3ui",
                      "location not for current program");
    return;
  }

  contextGL()->Uniform3ui(location->location(), v0, v1, v2);
}

void WebGL2RenderingContextBase::uniform4ui(
    const WebGLUniformLocation* location,
    GLuint v0,
    GLuint v1,
    GLuint v2,
    GLuint v3) {
  if (isContextLost() || !location)
    return;

  if (location->program() != m_currentProgram) {
    synthesizeGLError(GL_INVALID_OPERATION, "uniform4ui",
                      "location not for current program");
    return;
  }

  contextGL()->Uniform4ui(location->location(), v0, v1, v2, v3);
}

void WebGL2RenderingContextBase::uniform1uiv(
    const WebGLUniformLocation* location,
    const FlexibleUint32ArrayView& v) {
  if (isContextLost() ||
      !validateUniformParameters<WTF::Uint32Array>("uniform1uiv", location, v,
                                                   1))
    return;

  contextGL()->Uniform1uiv(location->location(), v.length(),
                           v.dataMaybeOnStack());
}

void WebGL2RenderingContextBase::uniform1uiv(
    const WebGLUniformLocation* location,
    Vector<GLuint>& value) {
  if (isContextLost() ||
      !validateUniformParameters("uniform1uiv", location, value.data(),
                                 value.size(), 1))
    return;

  contextGL()->Uniform1uiv(location->location(), value.size(), value.data());
}

void WebGL2RenderingContextBase::uniform2uiv(
    const WebGLUniformLocation* location,
    const FlexibleUint32ArrayView& v) {
  if (isContextLost() ||
      !validateUniformParameters<WTF::Uint32Array>("uniform2uiv", location, v,
                                                   2))
    return;

  contextGL()->Uniform2uiv(location->location(), v.length() >> 1,
                           v.dataMaybeOnStack());
}

void WebGL2RenderingContextBase::uniform2uiv(
    const WebGLUniformLocation* location,
    Vector<GLuint>& value) {
  if (isContextLost() ||
      !validateUniformParameters("uniform2uiv", location, value.data(),
                                 value.size(), 2))
    return;

  contextGL()->Uniform2uiv(location->location(), value.size() / 2,
                           value.data());
}

void WebGL2RenderingContextBase::uniform3uiv(
    const WebGLUniformLocation* location,
    const FlexibleUint32ArrayView& v) {
  if (isContextLost() ||
      !validateUniformParameters<WTF::Uint32Array>("uniform3uiv", location, v,
                                                   3))
    return;

  contextGL()->Uniform3uiv(location->location(), v.length() / 3,
                           v.dataMaybeOnStack());
}

void WebGL2RenderingContextBase::uniform3uiv(
    const WebGLUniformLocation* location,
    Vector<GLuint>& value) {
  if (isContextLost() ||
      !validateUniformParameters("uniform3uiv", location, value.data(),
                                 value.size(), 3))
    return;

  contextGL()->Uniform3uiv(location->location(), value.size() / 3,
                           value.data());
}

void WebGL2RenderingContextBase::uniform4uiv(
    const WebGLUniformLocation* location,
    const FlexibleUint32ArrayView& v) {
  if (isContextLost() ||
      !validateUniformParameters<WTF::Uint32Array>("uniform4uiv", location, v,
                                                   4))
    return;

  contextGL()->Uniform4uiv(location->location(), v.length() >> 2,
                           v.dataMaybeOnStack());
}

void WebGL2RenderingContextBase::uniform4uiv(
    const WebGLUniformLocation* location,
    Vector<GLuint>& value) {
  if (isContextLost() ||
      !validateUniformParameters("uniform4uiv", location, value.data(),
                                 value.size(), 4))
    return;

  contextGL()->Uniform4uiv(location->location(), value.size() / 4,
                           value.data());
}

void WebGL2RenderingContextBase::uniformMatrix2x3fv(
    const WebGLUniformLocation* location,
    GLboolean transpose,
    DOMFloat32Array* value) {
  if (isContextLost() ||
      !validateUniformMatrixParameters("uniformMatrix2x3fv", location,
                                       transpose, value, 6))
    return;
  contextGL()->UniformMatrix2x3fv(location->location(), value->length() / 6,
                                  transpose, value->data());
}

void WebGL2RenderingContextBase::uniformMatrix2x3fv(
    const WebGLUniformLocation* location,
    GLboolean transpose,
    Vector<GLfloat>& value) {
  if (isContextLost() ||
      !validateUniformMatrixParameters("uniformMatrix2x3fv", location,
                                       transpose, value.data(), value.size(),
                                       6))
    return;
  contextGL()->UniformMatrix2x3fv(location->location(), value.size() / 6,
                                  transpose, value.data());
}

void WebGL2RenderingContextBase::uniformMatrix3x2fv(
    const WebGLUniformLocation* location,
    GLboolean transpose,
    DOMFloat32Array* value) {
  if (isContextLost() ||
      !validateUniformMatrixParameters("uniformMatrix3x2fv", location,
                                       transpose, value, 6))
    return;
  contextGL()->UniformMatrix3x2fv(location->location(), value->length() / 6,
                                  transpose, value->data());
}

void WebGL2RenderingContextBase::uniformMatrix3x2fv(
    const WebGLUniformLocation* location,
    GLboolean transpose,
    Vector<GLfloat>& value) {
  if (isContextLost() ||
      !validateUniformMatrixParameters("uniformMatrix3x2fv", location,
                                       transpose, value.data(), value.size(),
                                       6))
    return;
  contextGL()->UniformMatrix3x2fv(location->location(), value.size() / 6,
                                  transpose, value.data());
}

void WebGL2RenderingContextBase::uniformMatrix2x4fv(
    const WebGLUniformLocation* location,
    GLboolean transpose,
    DOMFloat32Array* value) {
  if (isContextLost() ||
      !validateUniformMatrixParameters("uniformMatrix2x4fv", location,
                                       transpose, value, 8))
    return;
  contextGL()->UniformMatrix2x4fv(location->location(), value->length() / 8,
                                  transpose, value->data());
}

void WebGL2RenderingContextBase::uniformMatrix2x4fv(
    const WebGLUniformLocation* location,
    GLboolean transpose,
    Vector<GLfloat>& value) {
  if (isContextLost() ||
      !validateUniformMatrixParameters("uniformMatrix2x4fv", location,
                                       transpose, value.data(), value.size(),
                                       8))
    return;
  contextGL()->UniformMatrix2x4fv(location->location(), value.size() / 8,
                                  transpose, value.data());
}

void WebGL2RenderingContextBase::uniformMatrix4x2fv(
    const WebGLUniformLocation* location,
    GLboolean transpose,
    DOMFloat32Array* value) {
  if (isContextLost() ||
      !validateUniformMatrixParameters("uniformMatrix4x2fv", location,
                                       transpose, value, 8))
    return;
  contextGL()->UniformMatrix4x2fv(location->location(), value->length() / 8,
                                  transpose, value->data());
}

void WebGL2RenderingContextBase::uniformMatrix4x2fv(
    const WebGLUniformLocation* location,
    GLboolean transpose,
    Vector<GLfloat>& value) {
  if (isContextLost() ||
      !validateUniformMatrixParameters("uniformMatrix4x2fv", location,
                                       transpose, value.data(), value.size(),
                                       8))
    return;
  contextGL()->UniformMatrix4x2fv(location->location(), value.size() / 8,
                                  transpose, value.data());
}

void WebGL2RenderingContextBase::uniformMatrix3x4fv(
    const WebGLUniformLocation* location,
    GLboolean transpose,
    DOMFloat32Array* value) {
  if (isContextLost() ||
      !validateUniformMatrixParameters("uniformMatrix3x4fv", location,
                                       transpose, value, 12))
    return;
  contextGL()->UniformMatrix3x4fv(location->location(), value->length() / 12,
                                  transpose, value->data());
}

void WebGL2RenderingContextBase::uniformMatrix3x4fv(
    const WebGLUniformLocation* location,
    GLboolean transpose,
    Vector<GLfloat>& value) {
  if (isContextLost() ||
      !validateUniformMatrixParameters("uniformMatrix3x4fv", location,
                                       transpose, value.data(), value.size(),
                                       12))
    return;
  contextGL()->UniformMatrix3x4fv(location->location(), value.size() / 12,
                                  transpose, value.data());
}

void WebGL2RenderingContextBase::uniformMatrix4x3fv(
    const WebGLUniformLocation* location,
    GLboolean transpose,
    DOMFloat32Array* value) {
  if (isContextLost() ||
      !validateUniformMatrixParameters("uniformMatrix4x3fv", location,
                                       transpose, value, 12))
    return;
  contextGL()->UniformMatrix4x3fv(location->location(), value->length() / 12,
                                  transpose, value->data());
}

void WebGL2RenderingContextBase::uniformMatrix4x3fv(
    const WebGLUniformLocation* location,
    GLboolean transpose,
    Vector<GLfloat>& value) {
  if (isContextLost() ||
      !validateUniformMatrixParameters("uniformMatrix4x3fv", location,
                                       transpose, value.data(), value.size(),
                                       12))
    return;
  contextGL()->UniformMatrix4x3fv(location->location(), value.size() / 12,
                                  transpose, value.data());
}

void WebGL2RenderingContextBase::vertexAttribI4i(GLuint index,
                                                 GLint x,
                                                 GLint y,
                                                 GLint z,
                                                 GLint w) {
  if (isContextLost())
    return;
  contextGL()->VertexAttribI4i(index, x, y, z, w);
  setVertexAttribType(index, Int32ArrayType);
}

void WebGL2RenderingContextBase::vertexAttribI4iv(GLuint index,
                                                  const DOMInt32Array* v) {
  if (isContextLost())
    return;
  if (!v || v->length() < 4) {
    synthesizeGLError(GL_INVALID_VALUE, "vertexAttribI4iv", "invalid array");
    return;
  }
  contextGL()->VertexAttribI4iv(index, v->data());
  setVertexAttribType(index, Int32ArrayType);
}

void WebGL2RenderingContextBase::vertexAttribI4iv(GLuint index,
                                                  const Vector<GLint>& v) {
  if (isContextLost())
    return;
  if (v.size() < 4) {
    synthesizeGLError(GL_INVALID_VALUE, "vertexAttribI4iv", "invalid array");
    return;
  }
  contextGL()->VertexAttribI4iv(index, v.data());
  setVertexAttribType(index, Int32ArrayType);
}

void WebGL2RenderingContextBase::vertexAttribI4ui(GLuint index,
                                                  GLuint x,
                                                  GLuint y,
                                                  GLuint z,
                                                  GLuint w) {
  if (isContextLost())
    return;
  contextGL()->VertexAttribI4ui(index, x, y, z, w);
  setVertexAttribType(index, Uint32ArrayType);
}

void WebGL2RenderingContextBase::vertexAttribI4uiv(GLuint index,
                                                   const DOMUint32Array* v) {
  if (isContextLost())
    return;
  if (!v || v->length() < 4) {
    synthesizeGLError(GL_INVALID_VALUE, "vertexAttribI4uiv", "invalid array");
    return;
  }
  contextGL()->VertexAttribI4uiv(index, v->data());
  setVertexAttribType(index, Uint32ArrayType);
}

void WebGL2RenderingContextBase::vertexAttribI4uiv(GLuint index,
                                                   const Vector<GLuint>& v) {
  if (isContextLost())
    return;
  if (v.size() < 4) {
    synthesizeGLError(GL_INVALID_VALUE, "vertexAttribI4uiv", "invalid array");
    return;
  }
  contextGL()->VertexAttribI4uiv(index, v.data());
  setVertexAttribType(index, Uint32ArrayType);
}

void WebGL2RenderingContextBase::vertexAttribIPointer(GLuint index,
                                                      GLint size,
                                                      GLenum type,
                                                      GLsizei stride,
                                                      long long offset) {
  if (isContextLost())
    return;
  if (index >= m_maxVertexAttribs) {
    synthesizeGLError(GL_INVALID_VALUE, "vertexAttribIPointer",
                      "index out of range");
    return;
  }
  if (!validateValueFitNonNegInt32("vertexAttribIPointer", "offset", offset))
    return;
  if (!m_boundArrayBuffer) {
    synthesizeGLError(GL_INVALID_OPERATION, "vertexAttribIPointer",
                      "no bound ARRAY_BUFFER");
    return;
  }

  m_boundVertexArrayObject->setArrayBufferForAttrib(index, m_boundArrayBuffer);
  contextGL()->VertexAttribIPointer(
      index, size, type, stride,
      reinterpret_cast<void*>(static_cast<intptr_t>(offset)));
}

/* Writing to the drawing buffer */
void WebGL2RenderingContextBase::vertexAttribDivisor(GLuint index,
                                                     GLuint divisor) {
  if (isContextLost())
    return;

  if (index >= m_maxVertexAttribs) {
    synthesizeGLError(GL_INVALID_VALUE, "vertexAttribDivisor",
                      "index out of range");
    return;
  }

  contextGL()->VertexAttribDivisorANGLE(index, divisor);
}

void WebGL2RenderingContextBase::drawArraysInstanced(GLenum mode,
                                                     GLint first,
                                                     GLsizei count,
                                                     GLsizei instanceCount) {
  if (!validateDrawArrays("drawArraysInstanced"))
    return;

  if (!m_boundVertexArrayObject->isAllEnabledAttribBufferBound()) {
    synthesizeGLError(GL_INVALID_OPERATION, "drawArraysInstanced",
                      "no buffer is bound to enabled attribute");
    return;
  }

  ScopedRGBEmulationColorMask emulationColorMask(contextGL(), m_colorMask,
                                                 m_drawingBuffer.get());
  clearIfComposited();
  contextGL()->DrawArraysInstancedANGLE(mode, first, count, instanceCount);
  markContextChanged(CanvasChanged);
}

void WebGL2RenderingContextBase::drawElementsInstanced(GLenum mode,
                                                       GLsizei count,
                                                       GLenum type,
                                                       long long offset,
                                                       GLsizei instanceCount) {
  if (!validateDrawElements("drawElementsInstanced", type, offset))
    return;

  if (!m_boundVertexArrayObject->isAllEnabledAttribBufferBound()) {
    synthesizeGLError(GL_INVALID_OPERATION, "drawElementsInstanced",
                      "no buffer is bound to enabled attribute");
    return;
  }

  ScopedRGBEmulationColorMask emulationColorMask(contextGL(), m_colorMask,
                                                 m_drawingBuffer.get());
  clearIfComposited();
  contextGL()->DrawElementsInstancedANGLE(
      mode, count, type, reinterpret_cast<void*>(static_cast<intptr_t>(offset)),
      instanceCount);
  markContextChanged(CanvasChanged);
}

void WebGL2RenderingContextBase::drawRangeElements(GLenum mode,
                                                   GLuint start,
                                                   GLuint end,
                                                   GLsizei count,
                                                   GLenum type,
                                                   long long offset) {
  if (!validateDrawElements("drawRangeElements", type, offset))
    return;

  if (!m_boundVertexArrayObject->isAllEnabledAttribBufferBound()) {
    synthesizeGLError(GL_INVALID_OPERATION, "drawRangeElements",
                      "no buffer is bound to enabled attribute");
    return;
  }

  ScopedRGBEmulationColorMask emulationColorMask(contextGL(), m_colorMask,
                                                 m_drawingBuffer.get());
  clearIfComposited();
  contextGL()->DrawRangeElements(
      mode, start, end, count, type,
      reinterpret_cast<void*>(static_cast<intptr_t>(offset)));
  markContextChanged(CanvasChanged);
}

void WebGL2RenderingContextBase::drawBuffers(const Vector<GLenum>& buffers) {
  if (isContextLost())
    return;

  ScopedRGBEmulationColorMask emulationColorMask(contextGL(), m_colorMask,
                                                 m_drawingBuffer.get());
  GLsizei n = buffers.size();
  const GLenum* bufs = buffers.data();
  for (GLsizei i = 0; i < n; ++i) {
    switch (bufs[i]) {
      case GL_NONE:
      case GL_BACK:
      case GL_COLOR_ATTACHMENT0:
        break;
      default:
        if (bufs[i] > GL_COLOR_ATTACHMENT0 &&
            bufs[i] < static_cast<GLenum>(GL_COLOR_ATTACHMENT0 +
                                          maxColorAttachments()))
          break;
        synthesizeGLError(GL_INVALID_ENUM, "drawBuffers", "invalid buffer");
        return;
    }
  }
  if (!m_framebufferBinding) {
    if (n != 1) {
      synthesizeGLError(GL_INVALID_OPERATION, "drawBuffers",
                        "the number of buffers is not 1");
      return;
    }
    if (bufs[0] != GL_BACK && bufs[0] != GL_NONE) {
      synthesizeGLError(GL_INVALID_OPERATION, "drawBuffers", "BACK or NONE");
      return;
    }
    // Because the backbuffer is simulated on all current WebKit ports, we need
    // to change BACK to COLOR_ATTACHMENT0.
    GLenum value = (bufs[0] == GL_BACK) ? GL_COLOR_ATTACHMENT0 : GL_NONE;
    contextGL()->DrawBuffersEXT(1, &value);
    setBackDrawBuffer(bufs[0]);
  } else {
    if (n > maxDrawBuffers()) {
      synthesizeGLError(GL_INVALID_VALUE, "drawBuffers",
                        "more than max draw buffers");
      return;
    }
    for (GLsizei i = 0; i < n; ++i) {
      if (bufs[i] != GL_NONE &&
          bufs[i] != static_cast<GLenum>(GL_COLOR_ATTACHMENT0_EXT + i)) {
        synthesizeGLError(GL_INVALID_OPERATION, "drawBuffers",
                          "COLOR_ATTACHMENTi_EXT or NONE");
        return;
      }
    }
    m_framebufferBinding->drawBuffers(buffers);
  }
}

bool WebGL2RenderingContextBase::validateClearBuffer(const char* functionName,
                                                     GLenum buffer,
                                                     GLsizei size) {
  switch (buffer) {
    case GL_COLOR:
      if (size < 4) {
        synthesizeGLError(GL_INVALID_VALUE, functionName, "invalid array size");
        return false;
      }
      break;
    case GL_DEPTH:
    case GL_STENCIL:
      if (size < 1) {
        synthesizeGLError(GL_INVALID_VALUE, functionName, "invalid array size");
        return false;
      }
      break;
    default:
      synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid buffer");
      return false;
  }
  return true;
}

WebGLTexture* WebGL2RenderingContextBase::validateTexImageBinding(
    const char* funcName,
    TexImageFunctionID functionID,
    GLenum target) {
  if (functionID == TexImage3D || functionID == TexSubImage3D)
    return validateTexture3DBinding(funcName, target);
  return validateTexture2DBinding(funcName, target);
}

void WebGL2RenderingContextBase::clearBufferiv(GLenum buffer,
                                               GLint drawbuffer,
                                               DOMInt32Array* value) {
  if (isContextLost() ||
      !validateClearBuffer("clearBufferiv", buffer, value->length()))
    return;

  contextGL()->ClearBufferiv(buffer, drawbuffer, value->data());
}

void WebGL2RenderingContextBase::clearBufferiv(GLenum buffer,
                                               GLint drawbuffer,
                                               const Vector<GLint>& value) {
  if (isContextLost() ||
      !validateClearBuffer("clearBufferiv", buffer, value.size()))
    return;

  contextGL()->ClearBufferiv(buffer, drawbuffer, value.data());
}

void WebGL2RenderingContextBase::clearBufferuiv(GLenum buffer,
                                                GLint drawbuffer,
                                                DOMUint32Array* value) {
  if (isContextLost() ||
      !validateClearBuffer("clearBufferuiv", buffer, value->length()))
    return;

  contextGL()->ClearBufferuiv(buffer, drawbuffer, value->data());
}

void WebGL2RenderingContextBase::clearBufferuiv(GLenum buffer,
                                                GLint drawbuffer,
                                                const Vector<GLuint>& value) {
  if (isContextLost() ||
      !validateClearBuffer("clearBufferuiv", buffer, value.size()))
    return;

  contextGL()->ClearBufferuiv(buffer, drawbuffer, value.data());
}

void WebGL2RenderingContextBase::clearBufferfv(GLenum buffer,
                                               GLint drawbuffer,
                                               DOMFloat32Array* value) {
  if (isContextLost() ||
      !validateClearBuffer("clearBufferfv", buffer, value->length()))
    return;

  contextGL()->ClearBufferfv(buffer, drawbuffer, value->data());
}

void WebGL2RenderingContextBase::clearBufferfv(GLenum buffer,
                                               GLint drawbuffer,
                                               const Vector<GLfloat>& value) {
  if (isContextLost() ||
      !validateClearBuffer("clearBufferfv", buffer, value.size()))
    return;

  contextGL()->ClearBufferfv(buffer, drawbuffer, value.data());
}

void WebGL2RenderingContextBase::clearBufferfi(GLenum buffer,
                                               GLint drawbuffer,
                                               GLfloat depth,
                                               GLint stencil) {
  if (isContextLost())
    return;

  contextGL()->ClearBufferfi(buffer, drawbuffer, depth, stencil);
}

WebGLQuery* WebGL2RenderingContextBase::createQuery() {
  if (isContextLost())
    return nullptr;
  WebGLQuery* o = WebGLQuery::create(this);
  addSharedObject(o);
  return o;
}

void WebGL2RenderingContextBase::deleteQuery(WebGLQuery* query) {
  if (isContextLost() || !query)
    return;

  if (m_currentBooleanOcclusionQuery == query) {
    contextGL()->EndQueryEXT(m_currentBooleanOcclusionQuery->getTarget());
    m_currentBooleanOcclusionQuery = nullptr;
  }

  if (m_currentTransformFeedbackPrimitivesWrittenQuery == query) {
    contextGL()->EndQueryEXT(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
    m_currentTransformFeedbackPrimitivesWrittenQuery = nullptr;
  }

  if (m_currentElapsedQuery == query) {
    contextGL()->EndQueryEXT(m_currentElapsedQuery->getTarget());
    m_currentElapsedQuery = nullptr;
  }

  deleteObject(query);
}

GLboolean WebGL2RenderingContextBase::isQuery(WebGLQuery* query) {
  if (isContextLost() || !query)
    return 0;

  return contextGL()->IsQueryEXT(query->object());
}

void WebGL2RenderingContextBase::beginQuery(GLenum target, WebGLQuery* query) {
  bool deleted;
  DCHECK(query);
  if (!checkObjectToBeBound("beginQuery", query, deleted))
    return;
  if (deleted) {
    synthesizeGLError(GL_INVALID_OPERATION, "beginQuery",
                      "attempted to begin a deleted query object");
    return;
  }

  if (query->getTarget() && query->getTarget() != target) {
    synthesizeGLError(GL_INVALID_OPERATION, "beginQuery",
                      "query type does not match target");
    return;
  }

  switch (target) {
    case GL_ANY_SAMPLES_PASSED:
    case GL_ANY_SAMPLES_PASSED_CONSERVATIVE: {
      if (m_currentBooleanOcclusionQuery) {
        synthesizeGLError(GL_INVALID_OPERATION, "beginQuery",
                          "a query is already active for target");
        return;
      }
      m_currentBooleanOcclusionQuery = query;
    } break;
    case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: {
      if (m_currentTransformFeedbackPrimitivesWrittenQuery) {
        synthesizeGLError(GL_INVALID_OPERATION, "beginQuery",
                          "a query is already active for target");
        return;
      }
      m_currentTransformFeedbackPrimitivesWrittenQuery = query;
    } break;
    case GL_TIME_ELAPSED_EXT: {
      if (!extensionEnabled(EXTDisjointTimerQueryWebGL2Name)) {
        synthesizeGLError(GL_INVALID_ENUM, "beginQuery", "invalid target");
        return;
      }
      if (m_currentElapsedQuery) {
        synthesizeGLError(GL_INVALID_OPERATION, "beginQuery",
                          "a query is already active for target");
        return;
      }
      m_currentElapsedQuery = query;
    } break;
    default:
      synthesizeGLError(GL_INVALID_ENUM, "beginQuery", "invalid target");
      return;
  }

  if (!query->getTarget())
    query->setTarget(target);

  contextGL()->BeginQueryEXT(target, query->object());
}

void WebGL2RenderingContextBase::endQuery(GLenum target) {
  if (isContextLost())
    return;

  switch (target) {
    case GL_ANY_SAMPLES_PASSED:
    case GL_ANY_SAMPLES_PASSED_CONSERVATIVE: {
      if (m_currentBooleanOcclusionQuery &&
          m_currentBooleanOcclusionQuery->getTarget() == target) {
        m_currentBooleanOcclusionQuery->resetCachedResult();
        m_currentBooleanOcclusionQuery = nullptr;
      } else {
        synthesizeGLError(GL_INVALID_OPERATION, "endQuery",
                          "target query is not active");
        return;
      }
    } break;
    case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: {
      if (m_currentTransformFeedbackPrimitivesWrittenQuery) {
        m_currentTransformFeedbackPrimitivesWrittenQuery->resetCachedResult();
        m_currentTransformFeedbackPrimitivesWrittenQuery = nullptr;
      } else {
        synthesizeGLError(GL_INVALID_OPERATION, "endQuery",
                          "target query is not active");
        return;
      }
    } break;
    case GL_TIME_ELAPSED_EXT: {
      if (!extensionEnabled(EXTDisjointTimerQueryWebGL2Name)) {
        synthesizeGLError(GL_INVALID_ENUM, "endQuery", "invalid target");
        return;
      }
      if (m_currentElapsedQuery) {
        m_currentElapsedQuery->resetCachedResult();
        m_currentElapsedQuery = nullptr;
      } else {
        synthesizeGLError(GL_INVALID_OPERATION, "endQuery",
                          "target query is not active");
        return;
      }
    } break;
    default:
      synthesizeGLError(GL_INVALID_ENUM, "endQuery", "invalid target");
      return;
  }

  contextGL()->EndQueryEXT(target);
}

ScriptValue WebGL2RenderingContextBase::getQuery(ScriptState* scriptState,
                                                 GLenum target,
                                                 GLenum pname) {
  if (isContextLost())
    return ScriptValue::createNull(scriptState);

  if (extensionEnabled(EXTDisjointTimerQueryWebGL2Name)) {
    if (pname == GL_QUERY_COUNTER_BITS_EXT) {
      if (target == GL_TIMESTAMP_EXT || target == GL_TIME_ELAPSED_EXT) {
        GLint value = 0;
        contextGL()->GetQueryivEXT(target, pname, &value);
        return WebGLAny(scriptState, value);
      }
      synthesizeGLError(GL_INVALID_ENUM, "getQuery",
                        "invalid target/pname combination");
      return ScriptValue::createNull(scriptState);
    }

    if (target == GL_TIME_ELAPSED_EXT && pname == GL_CURRENT_QUERY) {
      return m_currentElapsedQuery
                 ? WebGLAny(scriptState, m_currentElapsedQuery)
                 : ScriptValue::createNull(scriptState);
    }

    if (target == GL_TIMESTAMP_EXT && pname == GL_CURRENT_QUERY) {
      return ScriptValue::createNull(scriptState);
    }
  }

  if (pname != GL_CURRENT_QUERY) {
    synthesizeGLError(GL_INVALID_ENUM, "getQuery", "invalid parameter name");
    return ScriptValue::createNull(scriptState);
  }

  switch (target) {
    case GL_ANY_SAMPLES_PASSED:
    case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
      if (m_currentBooleanOcclusionQuery &&
          m_currentBooleanOcclusionQuery->getTarget() == target)
        return WebGLAny(scriptState, m_currentBooleanOcclusionQuery);
      break;
    case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
      return WebGLAny(scriptState,
                      m_currentTransformFeedbackPrimitivesWrittenQuery);
    default:
      synthesizeGLError(GL_INVALID_ENUM, "getQuery", "invalid target");
      return ScriptValue::createNull(scriptState);
  }
  return ScriptValue::createNull(scriptState);
}

ScriptValue WebGL2RenderingContextBase::getQueryParameter(
    ScriptState* scriptState,
    WebGLQuery* query,
    GLenum pname) {
  DCHECK(query);
  bool deleted;
  if (!checkObjectToBeBound("getQueryParameter", query, deleted))
    return ScriptValue::createNull(scriptState);
  if (deleted) {
    synthesizeGLError(GL_INVALID_OPERATION, "getQueryParameter",
                      "attempted to access to a deleted query object");
    return ScriptValue::createNull(scriptState);
  }

  // Query is non-null at this point.
  if (!query->getTarget()) {
    synthesizeGLError(GL_INVALID_OPERATION, "getQueryParameter",
                      "'query' is not a query object yet, since it has't been "
                      "used by beginQuery");
    return ScriptValue::createNull(scriptState);
  }
  if (query == m_currentBooleanOcclusionQuery ||
      query == m_currentTransformFeedbackPrimitivesWrittenQuery ||
      query == m_currentElapsedQuery) {
    synthesizeGLError(GL_INVALID_OPERATION, "getQueryParameter",
                      "query is currently active");
    return ScriptValue::createNull(scriptState);
  }

  switch (pname) {
    case GL_QUERY_RESULT: {
      query->updateCachedResult(contextGL());
      return WebGLAny(scriptState, query->getQueryResult());
    }
    case GL_QUERY_RESULT_AVAILABLE: {
      query->updateCachedResult(contextGL());
      return WebGLAny(scriptState, query->isQueryResultAvailable());
    }
    default:
      synthesizeGLError(GL_INVALID_ENUM, "getQueryParameter",
                        "invalid parameter name");
      return ScriptValue::createNull(scriptState);
  }
}

WebGLSampler* WebGL2RenderingContextBase::createSampler() {
  if (isContextLost())
    return nullptr;
  WebGLSampler* o = WebGLSampler::create(this);
  addSharedObject(o);
  return o;
}

void WebGL2RenderingContextBase::deleteSampler(WebGLSampler* sampler) {
  if (isContextLost())
    return;

  for (size_t i = 0; i < m_samplerUnits.size(); ++i) {
    if (sampler == m_samplerUnits[i]) {
      m_samplerUnits[i] = nullptr;
      contextGL()->BindSampler(i, 0);
    }
  }

  deleteObject(sampler);
}

GLboolean WebGL2RenderingContextBase::isSampler(WebGLSampler* sampler) {
  if (isContextLost() || !sampler)
    return 0;

  return contextGL()->IsSampler(sampler->object());
}

void WebGL2RenderingContextBase::bindSampler(GLuint unit,
                                             WebGLSampler* sampler) {
  if (isContextLost())
    return;

  bool deleted;
  if (!checkObjectToBeBound("bindSampler", sampler, deleted))
    return;
  if (deleted) {
    synthesizeGLError(GL_INVALID_OPERATION, "bindSampler",
                      "attempted to bind a deleted sampler");
    return;
  }

  if (unit >= m_samplerUnits.size()) {
    synthesizeGLError(GL_INVALID_VALUE, "bindSampler",
                      "texture unit out of range");
    return;
  }

  m_samplerUnits[unit] = TraceWrapperMember<WebGLSampler>(this, sampler);

  contextGL()->BindSampler(unit, objectOrZero(sampler));
}

void WebGL2RenderingContextBase::samplerParameter(WebGLSampler* sampler,
                                                  GLenum pname,
                                                  GLfloat paramf,
                                                  GLint parami,
                                                  bool isFloat) {
  if (isContextLost() || !validateWebGLObject("samplerParameter", sampler))
    return;

  GLint param = isFloat ? static_cast<GLint>(paramf) : parami;
  switch (pname) {
    case GL_TEXTURE_MAX_LOD:
    case GL_TEXTURE_MIN_LOD:
      break;
    case GL_TEXTURE_COMPARE_FUNC:
      switch (param) {
        case GL_LEQUAL:
        case GL_GEQUAL:
        case GL_LESS:
        case GL_GREATER:
        case GL_EQUAL:
        case GL_NOTEQUAL:
        case GL_ALWAYS:
        case GL_NEVER:
          break;
        default:
          synthesizeGLError(GL_INVALID_ENUM, "samplerParameter",
                            "invalid parameter");
          return;
      }
      break;
    case GL_TEXTURE_COMPARE_MODE:
      switch (param) {
        case GL_COMPARE_REF_TO_TEXTURE:
        case GL_NONE:
          break;
        default:
          synthesizeGLError(GL_INVALID_ENUM, "samplerParameter",
                            "invalid parameter");
          return;
      }
      break;
    case GL_TEXTURE_MAG_FILTER:
      switch (param) {
        case GL_NEAREST:
        case GL_LINEAR:
          break;
        default:
          synthesizeGLError(GL_INVALID_ENUM, "samplerParameter",
                            "invalid parameter");
          return;
      }
      break;
    case GL_TEXTURE_MIN_FILTER:
      switch (param) {
        case GL_NEAREST:
        case GL_LINEAR:
        case GL_NEAREST_MIPMAP_NEAREST:
        case GL_LINEAR_MIPMAP_NEAREST:
        case GL_NEAREST_MIPMAP_LINEAR:
        case GL_LINEAR_MIPMAP_LINEAR:
          break;
        default:
          synthesizeGLError(GL_INVALID_ENUM, "samplerParameter",
                            "invalid parameter");
          return;
      }
      break;
    case GL_TEXTURE_WRAP_R:
    case GL_TEXTURE_WRAP_S:
    case GL_TEXTURE_WRAP_T:
      switch (param) {
        case GL_CLAMP_TO_EDGE:
        case GL_MIRRORED_REPEAT:
        case GL_REPEAT:
          break;
        default:
          synthesizeGLError(GL_INVALID_ENUM, "samplerParameter",
                            "invalid parameter");
          return;
      }
      break;
    default:
      synthesizeGLError(GL_INVALID_ENUM, "samplerParameter",
                        "invalid parameter name");
      return;
  }

  if (isFloat) {
    contextGL()->SamplerParameterf(objectOrZero(sampler), pname, paramf);
  } else {
    contextGL()->SamplerParameteri(objectOrZero(sampler), pname, parami);
  }
}

void WebGL2RenderingContextBase::samplerParameteri(WebGLSampler* sampler,
                                                   GLenum pname,
                                                   GLint param) {
  samplerParameter(sampler, pname, 0, param, false);
}

void WebGL2RenderingContextBase::samplerParameterf(WebGLSampler* sampler,
                                                   GLenum pname,
                                                   GLfloat param) {
  samplerParameter(sampler, pname, param, 0, true);
}

ScriptValue WebGL2RenderingContextBase::getSamplerParameter(
    ScriptState* scriptState,
    WebGLSampler* sampler,
    GLenum pname) {
  if (isContextLost() || !validateWebGLObject("getSamplerParameter", sampler))
    return ScriptValue::createNull(scriptState);

  switch (pname) {
    case GL_TEXTURE_COMPARE_FUNC:
    case GL_TEXTURE_COMPARE_MODE:
    case GL_TEXTURE_MAG_FILTER:
    case GL_TEXTURE_MIN_FILTER:
    case GL_TEXTURE_WRAP_R:
    case GL_TEXTURE_WRAP_S:
    case GL_TEXTURE_WRAP_T: {
      GLint value = 0;
      contextGL()->GetSamplerParameteriv(objectOrZero(sampler), pname, &value);
      return WebGLAny(scriptState, static_cast<unsigned>(value));
    }
    case GL_TEXTURE_MAX_LOD:
    case GL_TEXTURE_MIN_LOD: {
      GLfloat value = 0.f;
      contextGL()->GetSamplerParameterfv(objectOrZero(sampler), pname, &value);
      return WebGLAny(scriptState, value);
    }
    default:
      synthesizeGLError(GL_INVALID_ENUM, "getSamplerParameter",
                        "invalid parameter name");
      return ScriptValue::createNull(scriptState);
  }
}

WebGLSync* WebGL2RenderingContextBase::fenceSync(GLenum condition,
                                                 GLbitfield flags) {
  if (isContextLost())
    return nullptr;

  WebGLSync* o = WebGLFenceSync::create(this, condition, flags);
  addSharedObject(o);
  return o;
}

GLboolean WebGL2RenderingContextBase::isSync(WebGLSync* sync) {
  if (isContextLost() || !sync)
    return 0;

  return contextGL()->IsSync(sync->object());
}

void WebGL2RenderingContextBase::deleteSync(WebGLSync* sync) {
  deleteObject(sync);
}

GLenum WebGL2RenderingContextBase::clientWaitSync(WebGLSync* sync,
                                                  GLbitfield flags,
                                                  GLuint64 timeout) {
  if (isContextLost() || !validateWebGLObject("clientWaitSync", sync))
    return GL_WAIT_FAILED;

  if (timeout > kMaxClientWaitTimeout) {
    synthesizeGLError(GL_INVALID_OPERATION, "clientWaitSync",
                      "timeout > MAX_CLIENT_WAIT_TIMEOUT_WEBGL");
    return GL_WAIT_FAILED;
  }

  return contextGL()->ClientWaitSync(syncObjectOrZero(sync), flags, timeout);
}

void WebGL2RenderingContextBase::waitSync(WebGLSync* sync,
                                          GLbitfield flags,
                                          GLint64 timeout) {
  if (isContextLost() || !validateWebGLObject("waitSync", sync))
    return;

  if (flags) {
    synthesizeGLError(GL_INVALID_VALUE, "waitSync", "invalid flags");
    return;
  }

  if (timeout != -1) {
    synthesizeGLError(GL_INVALID_VALUE, "waitSync", "invalid timeout");
    return;
  }

  // This is intentionally changed to an no-op in WebGL2.
}

ScriptValue WebGL2RenderingContextBase::getSyncParameter(
    ScriptState* scriptState,
    WebGLSync* sync,
    GLenum pname) {
  if (isContextLost() || !validateWebGLObject("getSyncParameter", sync))
    return ScriptValue::createNull(scriptState);

  switch (pname) {
    case GL_OBJECT_TYPE:
    case GL_SYNC_STATUS:
    case GL_SYNC_CONDITION:
    case GL_SYNC_FLAGS: {
      GLint value = 0;
      GLsizei length = -1;
      contextGL()->GetSynciv(syncObjectOrZero(sync), pname, 1, &length, &value);
      return WebGLAny(scriptState, static_cast<unsigned>(value));
    }
    default:
      synthesizeGLError(GL_INVALID_ENUM, "getSyncParameter",
                        "invalid parameter name");
      return ScriptValue::createNull(scriptState);
  }
}

WebGLTransformFeedback* WebGL2RenderingContextBase::createTransformFeedback() {
  if (isContextLost())
    return nullptr;
  WebGLTransformFeedback* o = WebGLTransformFeedback::create(this);
  addSharedObject(o);
  return o;
}

void WebGL2RenderingContextBase::deleteTransformFeedback(
    WebGLTransformFeedback* feedback) {
  if (feedback == m_transformFeedbackBinding)
    m_transformFeedbackBinding = nullptr;

  deleteObject(feedback);
}

GLboolean WebGL2RenderingContextBase::isTransformFeedback(
    WebGLTransformFeedback* feedback) {
  if (isContextLost() || !feedback)
    return 0;

  if (!feedback->hasEverBeenBound())
    return 0;

  return contextGL()->IsTransformFeedback(feedback->object());
}

void WebGL2RenderingContextBase::bindTransformFeedback(
    GLenum target,
    WebGLTransformFeedback* feedback) {
  bool deleted;
  if (!checkObjectToBeBound("bindTransformFeedback", feedback, deleted))
    return;
  if (deleted) {
    synthesizeGLError(GL_INVALID_OPERATION, "bindTransformFeedback",
                      "attempted to bind a deleted transform feedback object");
    return;
  }

  if (target != GL_TRANSFORM_FEEDBACK) {
    synthesizeGLError(GL_INVALID_ENUM, "bindTransformFeedback",
                      "target must be TRANSFORM_FEEDBACK");
    return;
  }

  m_transformFeedbackBinding = feedback;

  contextGL()->BindTransformFeedback(target, objectOrZero(feedback));
  if (feedback) {
    feedback->setTarget(target);
  }
}

void WebGL2RenderingContextBase::beginTransformFeedback(GLenum primitiveMode) {
  if (isContextLost())
    return;
  if (!validateTransformFeedbackPrimitiveMode("beginTransformFeedback",
                                              primitiveMode))
    return;

  contextGL()->BeginTransformFeedback(primitiveMode);

  if (m_currentProgram)
    m_currentProgram->increaseActiveTransformFeedbackCount();

  if (m_transformFeedbackBinding)
    m_transformFeedbackBinding->setProgram(m_currentProgram);
}

void WebGL2RenderingContextBase::endTransformFeedback() {
  if (isContextLost())
    return;

  contextGL()->EndTransformFeedback();

  if (m_currentProgram)
    m_currentProgram->decreaseActiveTransformFeedbackCount();
}

void WebGL2RenderingContextBase::transformFeedbackVaryings(
    WebGLProgram* program,
    const Vector<String>& varyings,
    GLenum bufferMode) {
  if (isContextLost() ||
      !validateWebGLObject("transformFeedbackVaryings", program))
    return;

  switch (bufferMode) {
    case GL_SEPARATE_ATTRIBS:
      if (varyings.size() >
          static_cast<size_t>(m_maxTransformFeedbackSeparateAttribs)) {
        synthesizeGLError(GL_INVALID_VALUE, "transformFeedbackVaryings",
                          "too many varyings");
        return;
      }
      break;
    case GL_INTERLEAVED_ATTRIBS:
      break;
    default:
      synthesizeGLError(GL_INVALID_ENUM, "transformFeedbackVaryings",
                        "invalid buffer mode");
      return;
  }

  Vector<CString>
      keepAlive;  // Must keep these instances alive while looking at their data
  Vector<const char*> varyingStrings;
  for (size_t i = 0; i < varyings.size(); ++i) {
    keepAlive.append(varyings[i].ascii());
    varyingStrings.append(keepAlive.back().data());
  }

  contextGL()->TransformFeedbackVaryings(objectOrZero(program), varyings.size(),
                                         varyingStrings.data(), bufferMode);
}

WebGLActiveInfo* WebGL2RenderingContextBase::getTransformFeedbackVarying(
    WebGLProgram* program,
    GLuint index) {
  if (isContextLost() ||
      !validateWebGLObject("getTransformFeedbackVarying", program))
    return nullptr;

  if (!program->linkStatus(this)) {
    synthesizeGLError(GL_INVALID_OPERATION, "getTransformFeedbackVarying",
                      "program not linked");
    return nullptr;
  }
  GLint maxIndex = 0;
  contextGL()->GetProgramiv(objectOrZero(program),
                            GL_TRANSFORM_FEEDBACK_VARYINGS, &maxIndex);
  if (index >= static_cast<GLuint>(maxIndex)) {
    synthesizeGLError(GL_INVALID_VALUE, "getTransformFeedbackVarying",
                      "invalid index");
    return nullptr;
  }

  GLint maxNameLength = -1;
  contextGL()->GetProgramiv(objectOrZero(program),
                            GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH,
                            &maxNameLength);
  if (maxNameLength <= 0) {
    return nullptr;
  }
  std::unique_ptr<GLchar[]> name = wrapArrayUnique(new GLchar[maxNameLength]);
  GLsizei length = 0;
  GLsizei size = 0;
  GLenum type = 0;
  contextGL()->GetTransformFeedbackVarying(objectOrZero(program), index,
                                           maxNameLength, &length, &size, &type,
                                           name.get());

  if (length == 0 || size == 0 || type == 0) {
    return nullptr;
  }

  return WebGLActiveInfo::create(String(name.get(), length), type, size);
}

void WebGL2RenderingContextBase::pauseTransformFeedback() {
  if (isContextLost())
    return;

  contextGL()->PauseTransformFeedback();
}

void WebGL2RenderingContextBase::resumeTransformFeedback() {
  if (isContextLost())
    return;

  if (m_transformFeedbackBinding &&
      m_transformFeedbackBinding->getProgram() != m_currentProgram) {
    synthesizeGLError(GL_INVALID_OPERATION, "resumeTransformFeedback",
                      "the program object is not active");
    return;
  }

  contextGL()->ResumeTransformFeedback();
}

bool WebGL2RenderingContextBase::validateTransformFeedbackPrimitiveMode(
    const char* functionName,
    GLenum primitiveMode) {
  switch (primitiveMode) {
    case GL_POINTS:
    case GL_LINES:
    case GL_TRIANGLES:
      return true;
    default:
      synthesizeGLError(GL_INVALID_ENUM, functionName,
                        "invalid transform feedback primitive mode");
      return false;
  }
}

void WebGL2RenderingContextBase::bindBufferBase(GLenum target,
                                                GLuint index,
                                                WebGLBuffer* buffer) {
  if (isContextLost())
    return;
  bool deleted;
  if (!checkObjectToBeBound("bindBufferBase", buffer, deleted))
    return;
  if (deleted) {
    synthesizeGLError(GL_INVALID_OPERATION, "bindBufferBase",
                      "attempt to bind a deleted buffer");
    return;
  }
  if (!validateAndUpdateBufferBindBaseTarget("bindBufferBase", target, index,
                                             buffer))
    return;

  contextGL()->BindBufferBase(target, index, objectOrZero(buffer));
}

void WebGL2RenderingContextBase::bindBufferRange(GLenum target,
                                                 GLuint index,
                                                 WebGLBuffer* buffer,
                                                 long long offset,
                                                 long long size) {
  if (isContextLost())
    return;
  bool deleted;
  if (!checkObjectToBeBound("bindBufferRange", buffer, deleted))
    return;
  if (deleted) {
    synthesizeGLError(GL_INVALID_OPERATION, "bindBufferRange",
                      "attempt to bind a deleted buffer");
    return;
  }
  if (!validateValueFitNonNegInt32("bindBufferRange", "offset", offset) ||
      !validateValueFitNonNegInt32("bindBufferRange", "size", size)) {
    return;
  }

  if (!validateAndUpdateBufferBindBaseTarget("bindBufferRange", target, index,
                                             buffer))
    return;

  contextGL()->BindBufferRange(target, index, objectOrZero(buffer),
                               static_cast<GLintptr>(offset),
                               static_cast<GLsizeiptr>(size));
}

ScriptValue WebGL2RenderingContextBase::getIndexedParameter(
    ScriptState* scriptState,
    GLenum target,
    GLuint index) {
  if (isContextLost())
    return ScriptValue::createNull(scriptState);

  switch (target) {
    case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
      if (index >= m_boundIndexedTransformFeedbackBuffers.size()) {
        synthesizeGLError(GL_INVALID_VALUE, "getIndexedParameter",
                          "index out of range");
        return ScriptValue::createNull(scriptState);
      }
      return WebGLAny(scriptState,
                      m_boundIndexedTransformFeedbackBuffers[index].get());
    case GL_UNIFORM_BUFFER_BINDING:
      if (index >= m_boundIndexedUniformBuffers.size()) {
        synthesizeGLError(GL_INVALID_VALUE, "getIndexedParameter",
                          "index out of range");
        return ScriptValue::createNull(scriptState);
      }
      return WebGLAny(scriptState, m_boundIndexedUniformBuffers[index].get());
    case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
    case GL_TRANSFORM_FEEDBACK_BUFFER_START:
    case GL_UNIFORM_BUFFER_SIZE:
    case GL_UNIFORM_BUFFER_START: {
      GLint64 value = -1;
      contextGL()->GetInteger64i_v(target, index, &value);
      return WebGLAny(scriptState, value);
    }
    default:
      synthesizeGLError(GL_INVALID_ENUM, "getIndexedParameter",
                        "invalid parameter name");
      return ScriptValue::createNull(scriptState);
  }
}

Vector<GLuint> WebGL2RenderingContextBase::getUniformIndices(
    WebGLProgram* program,
    const Vector<String>& uniformNames) {
  Vector<GLuint> result;
  if (isContextLost() || !validateWebGLObject("getUniformIndices", program))
    return result;

  Vector<CString>
      keepAlive;  // Must keep these instances alive while looking at their data
  Vector<const char*> uniformStrings;
  for (size_t i = 0; i < uniformNames.size(); ++i) {
    keepAlive.append(uniformNames[i].ascii());
    uniformStrings.append(keepAlive.back().data());
  }

  result.resize(uniformNames.size());
  contextGL()->GetUniformIndices(objectOrZero(program), uniformStrings.size(),
                                 uniformStrings.data(), result.data());
  return result;
}

ScriptValue WebGL2RenderingContextBase::getActiveUniforms(
    ScriptState* scriptState,
    WebGLProgram* program,
    const Vector<GLuint>& uniformIndices,
    GLenum pname) {
  if (isContextLost() || !validateWebGLObject("getActiveUniforms", program))
    return ScriptValue::createNull(scriptState);

  enum ReturnType { EnumType, UnsignedIntType, IntType, BoolType };

  int returnType;
  switch (pname) {
    case GL_UNIFORM_TYPE:
      returnType = EnumType;
      break;
    case GL_UNIFORM_SIZE:
      returnType = UnsignedIntType;
      break;
    case GL_UNIFORM_BLOCK_INDEX:
    case GL_UNIFORM_OFFSET:
    case GL_UNIFORM_ARRAY_STRIDE:
    case GL_UNIFORM_MATRIX_STRIDE:
      returnType = IntType;
      break;
    case GL_UNIFORM_IS_ROW_MAJOR:
      returnType = BoolType;
      break;
    default:
      synthesizeGLError(GL_INVALID_ENUM, "getActiveUniforms",
                        "invalid parameter name");
      return ScriptValue::createNull(scriptState);
  }

  GLint activeUniforms = -1;
  contextGL()->GetProgramiv(objectOrZero(program), GL_ACTIVE_UNIFORMS,
                            &activeUniforms);

  GLuint activeUniformsUnsigned = activeUniforms;
  size_t size = uniformIndices.size();
  for (size_t i = 0; i < size; ++i) {
    if (uniformIndices[i] >= activeUniformsUnsigned) {
      synthesizeGLError(GL_INVALID_VALUE, "getActiveUniforms",
                        "uniform index greater than ACTIVE_UNIFORMS");
      return ScriptValue::createNull(scriptState);
    }
  }

  Vector<GLint> result(size);
  contextGL()->GetActiveUniformsiv(objectOrZero(program), uniformIndices.size(),
                                   uniformIndices.data(), pname, result.data());
  switch (returnType) {
    case EnumType: {
      Vector<GLenum> enumResult(size);
      for (size_t i = 0; i < size; ++i)
        enumResult[i] = static_cast<GLenum>(result[i]);
      return WebGLAny(scriptState, enumResult);
    }
    case UnsignedIntType: {
      Vector<GLuint> uintResult(size);
      for (size_t i = 0; i < size; ++i)
        uintResult[i] = static_cast<GLuint>(result[i]);
      return WebGLAny(scriptState, uintResult);
    }
    case IntType: {
      return WebGLAny(scriptState, result);
    }
    case BoolType: {
      Vector<bool> boolResult(size);
      for (size_t i = 0; i < size; ++i)
        boolResult[i] = static_cast<bool>(result[i]);
      return WebGLAny(scriptState, boolResult);
    }
    default:
      ASSERT_NOT_REACHED();
      return ScriptValue::createNull(scriptState);
  }
}

GLuint WebGL2RenderingContextBase::getUniformBlockIndex(
    WebGLProgram* program,
    const String& uniformBlockName) {
  if (isContextLost() || !validateWebGLObject("getUniformBlockIndex", program))
    return 0;
  if (!validateString("getUniformBlockIndex", uniformBlockName))
    return 0;

  return contextGL()->GetUniformBlockIndex(objectOrZero(program),
                                           uniformBlockName.utf8().data());
}

bool WebGL2RenderingContextBase::validateUniformBlockIndex(
    const char* functionName,
    WebGLProgram* program,
    GLuint blockIndex) {
  ASSERT(program);
  if (!program->linkStatus(this)) {
    synthesizeGLError(GL_INVALID_OPERATION, functionName, "program not linked");
    return false;
  }
  GLint activeUniformBlocks = 0;
  contextGL()->GetProgramiv(objectOrZero(program), GL_ACTIVE_UNIFORM_BLOCKS,
                            &activeUniformBlocks);
  if (blockIndex >= static_cast<GLuint>(activeUniformBlocks)) {
    synthesizeGLError(GL_INVALID_VALUE, functionName,
                      "invalid uniform block index");
    return false;
  }
  return true;
}

ScriptValue WebGL2RenderingContextBase::getActiveUniformBlockParameter(
    ScriptState* scriptState,
    WebGLProgram* program,
    GLuint uniformBlockIndex,
    GLenum pname) {
  if (isContextLost() ||
      !validateWebGLObject("getActiveUniformBlockParameter", program))
    return ScriptValue::createNull(scriptState);

  if (!validateUniformBlockIndex("getActiveUniformBlockParameter", program,
                                 uniformBlockIndex))
    return ScriptValue::createNull(scriptState);

  switch (pname) {
    case GL_UNIFORM_BLOCK_BINDING:
    case GL_UNIFORM_BLOCK_DATA_SIZE:
    case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS: {
      GLint intValue = 0;
      contextGL()->GetActiveUniformBlockiv(objectOrZero(program),
                                           uniformBlockIndex, pname, &intValue);
      return WebGLAny(scriptState, static_cast<unsigned>(intValue));
    }
    case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES: {
      GLint uniformCount = 0;
      contextGL()->GetActiveUniformBlockiv(
          objectOrZero(program), uniformBlockIndex,
          GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &uniformCount);

      Vector<GLint> indices(uniformCount);
      contextGL()->GetActiveUniformBlockiv(
          objectOrZero(program), uniformBlockIndex, pname, indices.data());
      return WebGLAny(
          scriptState,
          DOMUint32Array::create(reinterpret_cast<GLuint*>(indices.data()),
                                 indices.size()));
    }
    case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
    case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER: {
      GLint boolValue = 0;
      contextGL()->GetActiveUniformBlockiv(
          objectOrZero(program), uniformBlockIndex, pname, &boolValue);
      return WebGLAny(scriptState, static_cast<bool>(boolValue));
    }
    default:
      synthesizeGLError(GL_INVALID_ENUM, "getActiveUniformBlockParameter",
                        "invalid parameter name");
      return ScriptValue::createNull(scriptState);
  }
}

String WebGL2RenderingContextBase::getActiveUniformBlockName(
    WebGLProgram* program,
    GLuint uniformBlockIndex) {
  if (isContextLost() ||
      !validateWebGLObject("getActiveUniformBlockName", program))
    return String();

  if (!validateUniformBlockIndex("getActiveUniformBlockName", program,
                                 uniformBlockIndex))
    return String();

  GLint maxNameLength = -1;
  contextGL()->GetProgramiv(objectOrZero(program),
                            GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH,
                            &maxNameLength);
  if (maxNameLength <= 0) {
    // This state indicates that there are no active uniform blocks
    synthesizeGLError(GL_INVALID_VALUE, "getActiveUniformBlockName",
                      "invalid uniform block index");
    return String();
  }
  std::unique_ptr<GLchar[]> name = wrapArrayUnique(new GLchar[maxNameLength]);

  GLsizei length = 0;
  contextGL()->GetActiveUniformBlockName(objectOrZero(program),
                                         uniformBlockIndex, maxNameLength,
                                         &length, name.get());

  return String(name.get(), length);
}

void WebGL2RenderingContextBase::uniformBlockBinding(
    WebGLProgram* program,
    GLuint uniformBlockIndex,
    GLuint uniformBlockBinding) {
  if (isContextLost() || !validateWebGLObject("uniformBlockBinding", program))
    return;

  if (!validateUniformBlockIndex("uniformBlockBinding", program,
                                 uniformBlockIndex))
    return;

  contextGL()->UniformBlockBinding(objectOrZero(program), uniformBlockIndex,
                                   uniformBlockBinding);
}

WebGLVertexArrayObject* WebGL2RenderingContextBase::createVertexArray() {
  if (isContextLost())
    return nullptr;

  WebGLVertexArrayObject* o = WebGLVertexArrayObject::create(
      this, WebGLVertexArrayObjectBase::VaoTypeUser);
  addContextObject(o);
  return o;
}

void WebGL2RenderingContextBase::deleteVertexArray(
    WebGLVertexArrayObject* vertexArray) {
  if (isContextLost() || !vertexArray)
    return;

  if (!vertexArray->isDefaultObject() &&
      vertexArray == m_boundVertexArrayObject)
    setBoundVertexArrayObject(nullptr);

  vertexArray->deleteObject(contextGL());
}

GLboolean WebGL2RenderingContextBase::isVertexArray(
    WebGLVertexArrayObject* vertexArray) {
  if (isContextLost() || !vertexArray)
    return 0;

  if (!vertexArray->hasEverBeenBound())
    return 0;

  return contextGL()->IsVertexArrayOES(vertexArray->object());
}

void WebGL2RenderingContextBase::bindVertexArray(
    WebGLVertexArrayObject* vertexArray) {
  if (isContextLost())
    return;

  if (vertexArray &&
      (vertexArray->isDeleted() || !vertexArray->validate(0, this))) {
    synthesizeGLError(GL_INVALID_OPERATION, "bindVertexArray",
                      "invalid vertexArray");
    return;
  }

  if (vertexArray && !vertexArray->isDefaultObject() && vertexArray->object()) {
    contextGL()->BindVertexArrayOES(objectOrZero(vertexArray));

    vertexArray->setHasEverBeenBound();
    setBoundVertexArrayObject(vertexArray);
  } else {
    contextGL()->BindVertexArrayOES(0);
    setBoundVertexArrayObject(nullptr);
  }
}

void WebGL2RenderingContextBase::bindFramebuffer(GLenum target,
                                                 WebGLFramebuffer* buffer) {
  bool deleted;
  if (!checkObjectToBeBound("bindFramebuffer", buffer, deleted))
    return;

  if (deleted) {
    synthesizeGLError(GL_INVALID_OPERATION, "bindFramebuffer",
                      "attempt to bind a deleted framebuffer");
    return;
  }

  switch (target) {
    case GL_DRAW_FRAMEBUFFER:
      break;
    case GL_FRAMEBUFFER:
    case GL_READ_FRAMEBUFFER:
      m_readFramebufferBinding = buffer;
      break;
    default:
      synthesizeGLError(GL_INVALID_ENUM, "bindFramebuffer", "invalid target");
      return;
  }

  setFramebuffer(target, buffer);
}

void WebGL2RenderingContextBase::deleteFramebuffer(
    WebGLFramebuffer* framebuffer) {
  if (!deleteObject(framebuffer))
    return;
  GLenum target = 0;
  if (framebuffer == m_framebufferBinding) {
    if (framebuffer == m_readFramebufferBinding) {
      target = GL_FRAMEBUFFER;
      m_framebufferBinding = nullptr;
      m_readFramebufferBinding = nullptr;
    } else {
      target = GL_DRAW_FRAMEBUFFER;
      m_framebufferBinding = nullptr;
    }
  } else if (framebuffer == m_readFramebufferBinding) {
    target = GL_READ_FRAMEBUFFER;
    m_readFramebufferBinding = nullptr;
  }
  if (target) {
    // Have to call drawingBuffer()->bind() here to bind back to internal fbo.
    drawingBuffer()->bind(target);
  }
}

ScriptValue WebGL2RenderingContextBase::getParameter(ScriptState* scriptState,
                                                     GLenum pname) {
  if (isContextLost())
    return ScriptValue::createNull(scriptState);
  switch (pname) {
    case GL_SHADING_LANGUAGE_VERSION: {
      return WebGLAny(
          scriptState,
          "WebGL GLSL ES 3.00 (" +
              String(contextGL()->GetString(GL_SHADING_LANGUAGE_VERSION)) +
              ")");
    }
    case GL_VERSION:
      return WebGLAny(
          scriptState,
          "WebGL 2.0 (" + String(contextGL()->GetString(GL_VERSION)) + ")");

    case GL_COPY_READ_BUFFER_BINDING:
      return WebGLAny(scriptState, m_boundCopyReadBuffer.get());
    case GL_COPY_WRITE_BUFFER_BINDING:
      return WebGLAny(scriptState, m_boundCopyWriteBuffer.get());
    case GL_DRAW_FRAMEBUFFER_BINDING:
      return WebGLAny(scriptState, m_framebufferBinding.get());
    case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
      return getUnsignedIntParameter(scriptState, pname);
    case GL_MAX_3D_TEXTURE_SIZE:
      return getIntParameter(scriptState, pname);
    case GL_MAX_ARRAY_TEXTURE_LAYERS:
      return getIntParameter(scriptState, pname);
    case GC3D_MAX_CLIENT_WAIT_TIMEOUT_WEBGL:
      return WebGLAny(scriptState, kMaxClientWaitTimeout);
    case GL_MAX_COLOR_ATTACHMENTS:
      return getIntParameter(scriptState, pname);
    case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
      return getInt64Parameter(scriptState, pname);
    case GL_MAX_COMBINED_UNIFORM_BLOCKS:
      return getIntParameter(scriptState, pname);
    case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
      return getInt64Parameter(scriptState, pname);
    case GL_MAX_DRAW_BUFFERS:
      return getIntParameter(scriptState, pname);
    case GL_MAX_ELEMENT_INDEX:
      return getInt64Parameter(scriptState, pname);
    case GL_MAX_ELEMENTS_INDICES:
      return getIntParameter(scriptState, pname);
    case GL_MAX_ELEMENTS_VERTICES:
      return getIntParameter(scriptState, pname);
    case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
      return getIntParameter(scriptState, pname);
    case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
      return getIntParameter(scriptState, pname);
    case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
      return getIntParameter(scriptState, pname);
    case GL_MAX_PROGRAM_TEXEL_OFFSET:
      return getIntParameter(scriptState, pname);
    case GL_MAX_SAMPLES:
      return getIntParameter(scriptState, pname);
    case GL_MAX_SERVER_WAIT_TIMEOUT:
      return getInt64Parameter(scriptState, pname);
    case GL_MAX_TEXTURE_LOD_BIAS:
      return getFloatParameter(scriptState, pname);
    case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
      return getIntParameter(scriptState, pname);
    case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
      return getIntParameter(scriptState, pname);
    case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
      return getIntParameter(scriptState, pname);
    case GL_MAX_UNIFORM_BLOCK_SIZE:
      return getInt64Parameter(scriptState, pname);
    case GL_MAX_UNIFORM_BUFFER_BINDINGS:
      return getIntParameter(scriptState, pname);
    case GL_MAX_VARYING_COMPONENTS:
      return getIntParameter(scriptState, pname);
    case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
      return getIntParameter(scriptState, pname);
    case GL_MAX_VERTEX_UNIFORM_BLOCKS:
      return getIntParameter(scriptState, pname);
    case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
      return getIntParameter(scriptState, pname);
    case GL_MIN_PROGRAM_TEXEL_OFFSET:
      return getIntParameter(scriptState, pname);
    case GL_PACK_ROW_LENGTH:
      return getIntParameter(scriptState, pname);
    case GL_PACK_SKIP_PIXELS:
      return getIntParameter(scriptState, pname);
    case GL_PACK_SKIP_ROWS:
      return getIntParameter(scriptState, pname);
    case GL_PIXEL_PACK_BUFFER_BINDING:
      return WebGLAny(scriptState, m_boundPixelPackBuffer.get());
    case GL_PIXEL_UNPACK_BUFFER_BINDING:
      return WebGLAny(scriptState, m_boundPixelUnpackBuffer.get());
    case GL_RASTERIZER_DISCARD:
      return getBooleanParameter(scriptState, pname);
    case GL_READ_BUFFER: {
      GLenum value = 0;
      if (!isContextLost()) {
        WebGLFramebuffer* readFramebufferBinding =
            getFramebufferBinding(GL_READ_FRAMEBUFFER);
        if (!readFramebufferBinding)
          value = m_readBufferOfDefaultFramebuffer;
        else
          value = readFramebufferBinding->getReadBuffer();
      }
      return WebGLAny(scriptState, value);
    }
    case GL_READ_FRAMEBUFFER_BINDING:
      return WebGLAny(scriptState, m_readFramebufferBinding.get());
    case GL_SAMPLE_ALPHA_TO_COVERAGE:
      return getBooleanParameter(scriptState, pname);
    case GL_SAMPLE_COVERAGE:
      return getBooleanParameter(scriptState, pname);
    case GL_SAMPLER_BINDING:
      return WebGLAny(scriptState, m_samplerUnits[m_activeTextureUnit].get());
    case GL_TEXTURE_BINDING_2D_ARRAY:
      return WebGLAny(
          scriptState,
          m_textureUnits[m_activeTextureUnit].m_texture2DArrayBinding.get());
    case GL_TEXTURE_BINDING_3D:
      return WebGLAny(
          scriptState,
          m_textureUnits[m_activeTextureUnit].m_texture3DBinding.get());
    case GL_TRANSFORM_FEEDBACK_ACTIVE:
      return getBooleanParameter(scriptState, pname);
    case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
      return WebGLAny(scriptState, m_boundTransformFeedbackBuffer.get());
    case GL_TRANSFORM_FEEDBACK_BINDING:
      return WebGLAny(scriptState, m_transformFeedbackBinding.get());
    case GL_TRANSFORM_FEEDBACK_PAUSED:
      return getBooleanParameter(scriptState, pname);
    case GL_UNIFORM_BUFFER_BINDING:
      return WebGLAny(scriptState, m_boundUniformBuffer.get());
    case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
      return getIntParameter(scriptState, pname);
    case GL_UNPACK_IMAGE_HEIGHT:
      return getIntParameter(scriptState, pname);
    case GL_UNPACK_ROW_LENGTH:
      return getIntParameter(scriptState, pname);
    case GL_UNPACK_SKIP_IMAGES:
      return getIntParameter(scriptState, pname);
    case GL_UNPACK_SKIP_PIXELS:
      return getIntParameter(scriptState, pname);
    case GL_UNPACK_SKIP_ROWS:
      return getIntParameter(scriptState, pname);
    case GL_TIMESTAMP_EXT:
      if (extensionEnabled(EXTDisjointTimerQueryWebGL2Name)) {
        return WebGLAny(scriptState, 0);
      }
      synthesizeGLError(GL_INVALID_ENUM, "getParameter",
                        "invalid parameter name, "
                        "EXT_disjoint_timer_query_webgl2 not enabled");
      return ScriptValue::createNull(scriptState);
    case GL_GPU_DISJOINT_EXT:
      if (extensionEnabled(EXTDisjointTimerQueryWebGL2Name)) {
        return getBooleanParameter(scriptState, GL_GPU_DISJOINT_EXT);
      }
      synthesizeGLError(GL_INVALID_ENUM, "getParameter",
                        "invalid parameter name, "
                        "EXT_disjoint_timer_query_webgl2 not enabled");
      return ScriptValue::createNull(scriptState);

    default:
      return WebGLRenderingContextBase::getParameter(scriptState, pname);
  }
}

ScriptValue WebGL2RenderingContextBase::getInt64Parameter(
    ScriptState* scriptState,
    GLenum pname) {
  GLint64 value = 0;
  if (!isContextLost())
    contextGL()->GetInteger64v(pname, &value);
  return WebGLAny(scriptState, value);
}

bool WebGL2RenderingContextBase::validateCapability(const char* functionName,
                                                    GLenum cap) {
  switch (cap) {
    case GL_RASTERIZER_DISCARD:
      return true;
    default:
      return WebGLRenderingContextBase::validateCapability(functionName, cap);
  }
}

bool WebGL2RenderingContextBase::isBufferBoundToTransformFeedback(
    WebGLBuffer* buffer) {
  ASSERT(buffer);

  if (m_boundTransformFeedbackBuffer == buffer)
    return true;

  for (size_t i = 0; i < m_boundIndexedTransformFeedbackBuffers.size(); ++i) {
    if (m_boundIndexedTransformFeedbackBuffers[i] == buffer)
      return true;
  }

  return false;
}

bool WebGL2RenderingContextBase::isBufferBoundToNonTransformFeedback(
    WebGLBuffer* buffer) {
  ASSERT(buffer);

  if (m_boundArrayBuffer == buffer ||
      m_boundVertexArrayObject->boundElementArrayBuffer() == buffer ||
      m_boundCopyReadBuffer == buffer || m_boundCopyWriteBuffer == buffer ||
      m_boundPixelPackBuffer == buffer || m_boundPixelUnpackBuffer == buffer ||
      m_boundUniformBuffer == buffer) {
    return true;
  }

  for (size_t i = 0; i <= m_maxBoundUniformBufferIndex; ++i) {
    if (m_boundIndexedUniformBuffers[i] == buffer)
      return true;
  }

  return false;
}

bool WebGL2RenderingContextBase::validateBufferTargetCompatibility(
    const char* functionName,
    GLenum target,
    WebGLBuffer* buffer) {
  ASSERT(buffer);

  switch (buffer->getInitialTarget()) {
    case GL_ELEMENT_ARRAY_BUFFER:
      switch (target) {
        case GL_ARRAY_BUFFER:
        case GL_PIXEL_PACK_BUFFER:
        case GL_PIXEL_UNPACK_BUFFER:
        case GL_TRANSFORM_FEEDBACK_BUFFER:
        case GL_UNIFORM_BUFFER:
          synthesizeGLError(
              GL_INVALID_OPERATION, functionName,
              "element array buffers can not be bound to a different target");

          return false;
        default:
          break;
      }
      break;
    case GL_ARRAY_BUFFER:
    case GL_COPY_READ_BUFFER:
    case GL_COPY_WRITE_BUFFER:
    case GL_PIXEL_PACK_BUFFER:
    case GL_PIXEL_UNPACK_BUFFER:
    case GL_UNIFORM_BUFFER:
    case GL_TRANSFORM_FEEDBACK_BUFFER:
      if (target == GL_ELEMENT_ARRAY_BUFFER) {
        synthesizeGLError(GL_INVALID_OPERATION, functionName,
                          "buffers bound to non ELEMENT_ARRAY_BUFFER targets "
                          "can not be bound to ELEMENT_ARRAY_BUFFER target");
        return false;
      }
      break;
    default:
      break;
  }

  if (target == GL_TRANSFORM_FEEDBACK_BUFFER) {
    if (isBufferBoundToNonTransformFeedback(buffer)) {
      synthesizeGLError(GL_INVALID_OPERATION, functionName,
                        "a buffer bound to TRANSFORM_FEEDBACK_BUFFER can not "
                        "be bound to any other targets");
      return false;
    }
  } else if (isBufferBoundToTransformFeedback(buffer)) {
    synthesizeGLError(GL_INVALID_OPERATION, functionName,
                      "a buffer bound to TRANSFORM_FEEDBACK_BUFFER can not be "
                      "bound to any other targets");
    return false;
  }

  return true;
}

bool WebGL2RenderingContextBase::validateBufferTarget(const char* functionName,
                                                      GLenum target) {
  switch (target) {
    case GL_ARRAY_BUFFER:
    case GL_COPY_READ_BUFFER:
    case GL_COPY_WRITE_BUFFER:
    case GL_ELEMENT_ARRAY_BUFFER:
    case GL_PIXEL_PACK_BUFFER:
    case GL_PIXEL_UNPACK_BUFFER:
    case GL_TRANSFORM_FEEDBACK_BUFFER:
    case GL_UNIFORM_BUFFER:
      return true;
    default:
      synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid target");
      return false;
  }
}

bool WebGL2RenderingContextBase::validateAndUpdateBufferBindTarget(
    const char* functionName,
    GLenum target,
    WebGLBuffer* buffer) {
  if (!validateBufferTarget(functionName, target))
    return false;

  if (buffer &&
      !validateBufferTargetCompatibility(functionName, target, buffer))
    return false;

  switch (target) {
    case GL_ARRAY_BUFFER:
      m_boundArrayBuffer = buffer;
      break;
    case GL_COPY_READ_BUFFER:
      m_boundCopyReadBuffer = buffer;
      break;
    case GL_COPY_WRITE_BUFFER:
      m_boundCopyWriteBuffer = buffer;
      break;
    case GL_ELEMENT_ARRAY_BUFFER:
      m_boundVertexArrayObject->setElementArrayBuffer(buffer);
      break;
    case GL_PIXEL_PACK_BUFFER:
      m_boundPixelPackBuffer = buffer;
      break;
    case GL_PIXEL_UNPACK_BUFFER:
      m_boundPixelUnpackBuffer = buffer;
      break;
    case GL_TRANSFORM_FEEDBACK_BUFFER:
      m_boundTransformFeedbackBuffer = buffer;
      break;
    case GL_UNIFORM_BUFFER:
      m_boundUniformBuffer = buffer;
      break;
    default:
      ASSERT_NOT_REACHED();
      break;
  }

  if (buffer && !buffer->getInitialTarget())
    buffer->setInitialTarget(target);
  return true;
}

bool WebGL2RenderingContextBase::validateBufferBaseTarget(
    const char* functionName,
    GLenum target) {
  switch (target) {
    case GL_TRANSFORM_FEEDBACK_BUFFER:
    case GL_UNIFORM_BUFFER:
      return true;
    default:
      synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid target");
      return false;
  }
}

bool WebGL2RenderingContextBase::validateAndUpdateBufferBindBaseTarget(
    const char* functionName,
    GLenum target,
    GLuint index,
    WebGLBuffer* buffer) {
  if (!validateBufferBaseTarget(functionName, target))
    return false;

  if (buffer &&
      !validateBufferTargetCompatibility(functionName, target, buffer))
    return false;

  switch (target) {
    case GL_TRANSFORM_FEEDBACK_BUFFER:
      if (index >= m_boundIndexedTransformFeedbackBuffers.size()) {
        synthesizeGLError(GL_INVALID_VALUE, functionName, "index out of range");
        return false;
      }
      m_boundIndexedTransformFeedbackBuffers[index] =
          TraceWrapperMember<WebGLBuffer>(this, buffer);
      m_boundTransformFeedbackBuffer = buffer;
      break;
    case GL_UNIFORM_BUFFER:
      if (index >= m_boundIndexedUniformBuffers.size()) {
        synthesizeGLError(GL_INVALID_VALUE, functionName, "index out of range");
        return false;
      }
      m_boundIndexedUniformBuffers[index] =
          TraceWrapperMember<WebGLBuffer>(this, buffer);
      m_boundUniformBuffer = buffer;

      // Keep track of what the maximum bound uniform buffer index is
      if (buffer) {
        if (index > m_maxBoundUniformBufferIndex)
          m_maxBoundUniformBufferIndex = index;
      } else if (m_maxBoundUniformBufferIndex > 0 &&
                 index == m_maxBoundUniformBufferIndex) {
        size_t i = m_maxBoundUniformBufferIndex - 1;
        for (; i > 0; --i) {
          if (m_boundIndexedUniformBuffers[i].get())
            break;
        }
        m_maxBoundUniformBufferIndex = i;
      }
      break;
    default:
      ASSERT_NOT_REACHED();
      break;
  }

  if (buffer && !buffer->getInitialTarget())
    buffer->setInitialTarget(target);
  return true;
}

bool WebGL2RenderingContextBase::validateFramebufferTarget(GLenum target) {
  switch (target) {
    case GL_FRAMEBUFFER:
    case GL_READ_FRAMEBUFFER:
    case GL_DRAW_FRAMEBUFFER:
      return true;
    default:
      return false;
  }
}

bool WebGL2RenderingContextBase::validateReadPixelsFormatAndType(
    GLenum format,
    GLenum type,
    DOMArrayBufferView* buffer) {
  switch (format) {
    case GL_RED:
    case GL_RED_INTEGER:
    case GL_RG:
    case GL_RG_INTEGER:
    case GL_RGB:
    case GL_RGB_INTEGER:
    case GL_RGBA:
    case GL_RGBA_INTEGER:
    case GL_LUMINANCE_ALPHA:
    case GL_LUMINANCE:
    case GL_ALPHA:
      break;
    default:
      synthesizeGLError(GL_INVALID_ENUM, "readPixels", "invalid format");
      return false;
  }

  switch (type) {
    case GL_UNSIGNED_BYTE:
      if (buffer && buffer->type() != DOMArrayBufferView::TypeUint8) {
        synthesizeGLError(
            GL_INVALID_OPERATION, "readPixels",
            "type UNSIGNED_BYTE but ArrayBufferView not Uint8Array");
        return false;
      }
      return true;
    case GL_BYTE:
      if (buffer && buffer->type() != DOMArrayBufferView::TypeInt8) {
        synthesizeGLError(GL_INVALID_OPERATION, "readPixels",
                          "type BYTE but ArrayBufferView not Int8Array");
        return false;
      }
      return true;
    case GL_HALF_FLOAT:
      if (buffer && buffer->type() != DOMArrayBufferView::TypeUint16) {
        synthesizeGLError(
            GL_INVALID_OPERATION, "readPixels",
            "type HALF_FLOAT but ArrayBufferView not Uint16Array");
        return false;
      }
      return true;
    case GL_FLOAT:
      if (buffer && buffer->type() != DOMArrayBufferView::TypeFloat32) {
        synthesizeGLError(GL_INVALID_OPERATION, "readPixels",
                          "type FLOAT but ArrayBufferView not Float32Array");
        return false;
      }
      return true;
    case GL_UNSIGNED_SHORT:
    case GL_UNSIGNED_SHORT_5_6_5:
    case GL_UNSIGNED_SHORT_4_4_4_4:
    case GL_UNSIGNED_SHORT_5_5_5_1:
      if (buffer && buffer->type() != DOMArrayBufferView::TypeUint16) {
        synthesizeGLError(
            GL_INVALID_OPERATION, "readPixels",
            "type UNSIGNED_SHORT but ArrayBufferView not Uint16Array");
        return false;
      }
      return true;
    case GL_SHORT:
      if (buffer && buffer->type() != DOMArrayBufferView::TypeInt16) {
        synthesizeGLError(GL_INVALID_OPERATION, "readPixels",
                          "type SHORT but ArrayBufferView not Int16Array");
        return false;
      }
      return true;
    case GL_UNSIGNED_INT:
    case GL_UNSIGNED_INT_2_10_10_10_REV:
    case GL_UNSIGNED_INT_10F_11F_11F_REV:
    case GL_UNSIGNED_INT_5_9_9_9_REV:
      if (buffer && buffer->type() != DOMArrayBufferView::TypeUint32) {
        synthesizeGLError(
            GL_INVALID_OPERATION, "readPixels",
            "type UNSIGNED_INT but ArrayBufferView not Uint32Array");
        return false;
      }
      return true;
    case GL_INT:
      if (buffer && buffer->type() != DOMArrayBufferView::TypeInt32) {
        synthesizeGLError(GL_INVALID_OPERATION, "readPixels",
                          "type INT but ArrayBufferView not Int32Array");
        return false;
      }
      return true;
    default:
      synthesizeGLError(GL_INVALID_ENUM, "readPixels", "invalid type");
      return false;
  }
}

WebGLFramebuffer* WebGL2RenderingContextBase::getFramebufferBinding(
    GLenum target) {
  switch (target) {
    case GL_READ_FRAMEBUFFER:
      return m_readFramebufferBinding.get();
    case GL_DRAW_FRAMEBUFFER:
      return m_framebufferBinding.get();
    default:
      return WebGLRenderingContextBase::getFramebufferBinding(target);
  }
}

WebGLFramebuffer* WebGL2RenderingContextBase::getReadFramebufferBinding() {
  return m_readFramebufferBinding.get();
}

bool WebGL2RenderingContextBase::validateGetFramebufferAttachmentParameterFunc(
    const char* functionName,
    GLenum target,
    GLenum attachment) {
  if (!validateFramebufferTarget(target)) {
    synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid target");
    return false;
  }

  WebGLFramebuffer* framebufferBinding = getFramebufferBinding(target);
  ASSERT(framebufferBinding || drawingBuffer());
  if (!framebufferBinding) {
    // for the default framebuffer
    switch (attachment) {
      case GL_BACK:
      case GL_DEPTH:
      case GL_STENCIL:
        break;
      default:
        synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid attachment");
        return false;
    }
  } else {
    // for the FBO
    switch (attachment) {
      case GL_COLOR_ATTACHMENT0:
      case GL_DEPTH_ATTACHMENT:
      case GL_STENCIL_ATTACHMENT:
        break;
      case GL_DEPTH_STENCIL_ATTACHMENT:
        if (framebufferBinding->getAttachmentObject(GL_DEPTH_ATTACHMENT) !=
            framebufferBinding->getAttachmentObject(GL_STENCIL_ATTACHMENT)) {
          synthesizeGLError(GL_INVALID_OPERATION, functionName,
                            "different objects are bound to the depth and "
                            "stencil attachment points");
          return false;
        }
        break;
      default:
        if (attachment > GL_COLOR_ATTACHMENT0 &&
            attachment < static_cast<GLenum>(GL_COLOR_ATTACHMENT0 +
                                             maxColorAttachments()))
          break;
        synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid attachment");
        return false;
    }
  }
  return true;
}

ScriptValue WebGL2RenderingContextBase::getFramebufferAttachmentParameter(
    ScriptState* scriptState,
    GLenum target,
    GLenum attachment,
    GLenum pname) {
  const char kFunctionName[] = "getFramebufferAttachmentParameter";
  if (isContextLost() ||
      !validateGetFramebufferAttachmentParameterFunc(kFunctionName, target,
                                                     attachment))
    return ScriptValue::createNull(scriptState);

  WebGLFramebuffer* framebufferBinding = getFramebufferBinding(target);
  ASSERT(!framebufferBinding || framebufferBinding->object());

  // Default framebuffer (an internal fbo)
  if (!framebufferBinding) {
    // We can use creationAttributes() because in WebGL 2, they are required to
    // be honored.
    bool hasDepth = creationAttributes().depth();
    bool hasStencil = creationAttributes().stencil();
    bool hasAlpha = creationAttributes().alpha();
    bool missingImage = (attachment == GL_DEPTH && !hasDepth) ||
                        (attachment == GL_STENCIL && !hasStencil);
    if (missingImage) {
      switch (pname) {
        case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
          return WebGLAny(scriptState, GL_NONE);
        default:
          synthesizeGLError(GL_INVALID_OPERATION, kFunctionName,
                            "invalid parameter name");
          return ScriptValue::createNull(scriptState);
      }
    }
    switch (pname) {
      case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
        return WebGLAny(scriptState, GL_FRAMEBUFFER_DEFAULT);
      case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
      case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
      case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE: {
        GLint value = attachment == GL_BACK ? 8 : 0;
        return WebGLAny(scriptState, value);
      }
      case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE: {
        GLint value = (attachment == GL_BACK && hasAlpha) ? 8 : 0;
        return WebGLAny(scriptState, value);
      }
      case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE: {
        // For ES3 capable backend, DEPTH24_STENCIL8 has to be supported.
        GLint value = attachment == GL_DEPTH ? 24 : 0;
        return WebGLAny(scriptState, value);
      }
      case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE: {
        GLint value = attachment == GL_STENCIL ? 8 : 0;
        return WebGLAny(scriptState, value);
      }
      case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
        return WebGLAny(scriptState, GL_UNSIGNED_NORMALIZED);
      case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
        return WebGLAny(scriptState, GL_LINEAR);
      default:
        synthesizeGLError(GL_INVALID_ENUM, kFunctionName,
                          "invalid parameter name");
        return ScriptValue::createNull(scriptState);
    }
  }

  WebGLSharedObject* attachmentObject = nullptr;
  if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) {
    WebGLSharedObject* depthAttachment =
        framebufferBinding->getAttachmentObject(GL_DEPTH_ATTACHMENT);
    WebGLSharedObject* stencilAttachment =
        framebufferBinding->getAttachmentObject(GL_STENCIL_ATTACHMENT);
    if (depthAttachment != stencilAttachment) {
      synthesizeGLError(
          GL_INVALID_OPERATION, kFunctionName,
          "different objects bound to DEPTH_ATTACHMENT and STENCIL_ATTACHMENT");
      return ScriptValue::createNull(scriptState);
    }
    attachmentObject = depthAttachment;
  } else {
    attachmentObject = framebufferBinding->getAttachmentObject(attachment);
  }

  if (!attachmentObject) {
    switch (pname) {
      case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
        return WebGLAny(scriptState, GL_NONE);
      case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
        return ScriptValue::createNull(scriptState);
      default:
        synthesizeGLError(GL_INVALID_OPERATION, kFunctionName,
                          "invalid parameter name");
        return ScriptValue::createNull(scriptState);
    }
  }
  ASSERT(attachmentObject->isTexture() || attachmentObject->isRenderbuffer());

  switch (pname) {
    case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
      if (attachmentObject->isTexture())
        return WebGLAny(scriptState, GL_TEXTURE);
      return WebGLAny(scriptState, GL_RENDERBUFFER);
    case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
      return WebGLAny(scriptState, attachmentObject);
    case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
    case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
    case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
      if (!attachmentObject->isTexture())
        break;
    case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
    case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
    case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
    case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
    case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
    case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE: {
      GLint value = 0;
      contextGL()->GetFramebufferAttachmentParameteriv(target, attachment,
                                                       pname, &value);
      return WebGLAny(scriptState, value);
    }
    case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
      if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) {
        synthesizeGLError(
            GL_INVALID_OPERATION, kFunctionName,
            "COMPONENT_TYPE can't be queried for DEPTH_STENCIL_ATTACHMENT");
        return ScriptValue::createNull(scriptState);
      }
    case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING: {
      GLint value = 0;
      contextGL()->GetFramebufferAttachmentParameteriv(target, attachment,
                                                       pname, &value);
      return WebGLAny(scriptState, static_cast<unsigned>(value));
    }
    default:
      break;
  }
  synthesizeGLError(GL_INVALID_ENUM, kFunctionName, "invalid parameter name");
  return ScriptValue::createNull(scriptState);
}

DEFINE_TRACE(WebGL2RenderingContextBase) {
  visitor->trace(m_readFramebufferBinding);
  visitor->trace(m_transformFeedbackBinding);
  visitor->trace(m_boundCopyReadBuffer);
  visitor->trace(m_boundCopyWriteBuffer);
  visitor->trace(m_boundPixelPackBuffer);
  visitor->trace(m_boundPixelUnpackBuffer);
  visitor->trace(m_boundTransformFeedbackBuffer);
  visitor->trace(m_boundUniformBuffer);
  visitor->trace(m_boundIndexedTransformFeedbackBuffers);
  visitor->trace(m_boundIndexedUniformBuffers);
  visitor->trace(m_currentBooleanOcclusionQuery);
  visitor->trace(m_currentTransformFeedbackPrimitivesWrittenQuery);
  visitor->trace(m_currentElapsedQuery);
  visitor->trace(m_samplerUnits);
  visitor->trace(m_getBufferSubDataAsyncCallbacks);
  WebGLRenderingContextBase::trace(visitor);
}

DEFINE_TRACE_WRAPPERS(WebGL2RenderingContextBase) {
  if (isContextLost()) {
    return;
  }

  visitor->traceWrappers(m_transformFeedbackBinding);
  visitor->traceWrappers(m_readFramebufferBinding);
  visitor->traceWrappers(m_boundCopyReadBuffer);
  visitor->traceWrappers(m_boundCopyWriteBuffer);
  visitor->traceWrappers(m_boundPixelPackBuffer);
  visitor->traceWrappers(m_boundPixelUnpackBuffer);
  visitor->traceWrappers(m_boundTransformFeedbackBuffer);
  visitor->traceWrappers(m_boundUniformBuffer);
  for (auto& buf : m_boundIndexedTransformFeedbackBuffers) {
    visitor->traceWrappers(buf);
  }
  for (auto& buf : m_boundIndexedUniformBuffers) {
    visitor->traceWrappers(buf);
  }
  visitor->traceWrappers(m_currentBooleanOcclusionQuery);
  visitor->traceWrappers(m_currentTransformFeedbackPrimitivesWrittenQuery);
  visitor->traceWrappers(m_currentElapsedQuery);
  for (auto& unit : m_samplerUnits) {
    visitor->traceWrappers(unit);
  }
  WebGLRenderingContextBase::traceWrappers(visitor);
}

WebGLTexture* WebGL2RenderingContextBase::validateTexture3DBinding(
    const char* functionName,
    GLenum target) {
  WebGLTexture* tex = nullptr;
  switch (target) {
    case GL_TEXTURE_2D_ARRAY:
      tex = m_textureUnits[m_activeTextureUnit].m_texture2DArrayBinding.get();
      break;
    case GL_TEXTURE_3D:
      tex = m_textureUnits[m_activeTextureUnit].m_texture3DBinding.get();
      break;
    default:
      synthesizeGLError(GL_INVALID_ENUM, functionName,
                        "invalid texture target");
      return nullptr;
  }
  if (!tex)
    synthesizeGLError(GL_INVALID_OPERATION, functionName,
                      "no texture bound to target");
  return tex;
}

GLint WebGL2RenderingContextBase::getMaxTextureLevelForTarget(GLenum target) {
  switch (target) {
    case GL_TEXTURE_3D:
      return m_max3DTextureLevel;
    case GL_TEXTURE_2D_ARRAY:
      return m_maxTextureLevel;
  }
  return WebGLRenderingContextBase::getMaxTextureLevelForTarget(target);
}

ScriptValue WebGL2RenderingContextBase::getTexParameter(
    ScriptState* scriptState,
    GLenum target,
    GLenum pname) {
  if (isContextLost() || !validateTextureBinding("getTexParameter", target))
    return ScriptValue::createNull(scriptState);

  switch (pname) {
    case GL_TEXTURE_WRAP_R:
    case GL_TEXTURE_COMPARE_FUNC:
    case GL_TEXTURE_COMPARE_MODE:
    case GL_TEXTURE_IMMUTABLE_LEVELS: {
      GLint value = 0;
      contextGL()->GetTexParameteriv(target, pname, &value);
      return WebGLAny(scriptState, static_cast<unsigned>(value));
    }
    case GL_TEXTURE_IMMUTABLE_FORMAT: {
      GLint value = 0;
      contextGL()->GetTexParameteriv(target, pname, &value);
      return WebGLAny(scriptState, static_cast<bool>(value));
    }
    case GL_TEXTURE_BASE_LEVEL:
    case GL_TEXTURE_MAX_LEVEL: {
      GLint value = 0;
      contextGL()->GetTexParameteriv(target, pname, &value);
      return WebGLAny(scriptState, value);
    }
    case GL_TEXTURE_MAX_LOD:
    case GL_TEXTURE_MIN_LOD: {
      GLfloat value = 0.f;
      contextGL()->GetTexParameterfv(target, pname, &value);
      return WebGLAny(scriptState, value);
    }
    default:
      return WebGLRenderingContextBase::getTexParameter(scriptState, target,
                                                        pname);
  }
}

WebGLBuffer* WebGL2RenderingContextBase::validateBufferDataTarget(
    const char* functionName,
    GLenum target) {
  WebGLBuffer* buffer = nullptr;
  switch (target) {
    case GL_ELEMENT_ARRAY_BUFFER:
      buffer = m_boundVertexArrayObject->boundElementArrayBuffer();
      break;
    case GL_ARRAY_BUFFER:
      buffer = m_boundArrayBuffer.get();
      break;
    case GL_COPY_READ_BUFFER:
      buffer = m_boundCopyReadBuffer.get();
      break;
    case GL_COPY_WRITE_BUFFER:
      buffer = m_boundCopyWriteBuffer.get();
      break;
    case GL_PIXEL_PACK_BUFFER:
      buffer = m_boundPixelPackBuffer.get();
      break;
    case GL_PIXEL_UNPACK_BUFFER:
      buffer = m_boundPixelUnpackBuffer.get();
      break;
    case GL_TRANSFORM_FEEDBACK_BUFFER:
      buffer = m_boundTransformFeedbackBuffer.get();
      break;
    case GL_UNIFORM_BUFFER:
      buffer = m_boundUniformBuffer.get();
      break;
    default:
      synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid target");
      return nullptr;
  }
  if (!buffer) {
    synthesizeGLError(GL_INVALID_OPERATION, functionName, "no buffer");
    return nullptr;
  }
  return buffer;
}

bool WebGL2RenderingContextBase::validateBufferDataUsage(
    const char* functionName,
    GLenum usage) {
  switch (usage) {
    case GL_STREAM_READ:
    case GL_STREAM_COPY:
    case GL_STATIC_READ:
    case GL_STATIC_COPY:
    case GL_DYNAMIC_READ:
    case GL_DYNAMIC_COPY:
      return true;
    default:
      return WebGLRenderingContextBase::validateBufferDataUsage(functionName,
                                                                usage);
  }
}

const char* WebGL2RenderingContextBase::validateGetBufferSubData(
    const char* functionName,
    GLenum target,
    GLintptr sourceByteOffset,
    DOMArrayBufferView* destinationArrayBufferView,
    GLuint destinationOffset,
    GLuint length,
    WebGLBuffer** outSourceBuffer,
    void** outDestinationDataPtr,
    long long* outDestinationByteLength) {
  if (isContextLost()) {
    return "Context lost";
  }

  if (!validateValueFitNonNegInt32(functionName, "srcByteOffset",
                                   sourceByteOffset)) {
    return "Invalid value: srcByteOffset";
  }
  if (target == GL_TRANSFORM_FEEDBACK_BUFFER && m_currentProgram &&
      m_currentProgram->activeTransformFeedbackCount()) {
    synthesizeGLError(GL_INVALID_OPERATION, functionName,
                      "targeted transform feedback buffer is active");
    return "Invalid operation: targeted transform feedback buffer is active";
  }

  WebGLBuffer* sourceBuffer = validateBufferDataTarget(functionName, target);
  if (!sourceBuffer) {
    return "Invalid operation: no buffer bound to target";
  }
  *outSourceBuffer = sourceBuffer;

  if (!validateSubSourceAndGetData(
          destinationArrayBufferView, destinationOffset, length,
          outDestinationDataPtr, outDestinationByteLength)) {
    synthesizeGLError(GL_INVALID_VALUE, functionName, "overflow of dstData");
    return "Invalid value: overflow of dstData";
  }

  return nullptr;
}

const char* WebGL2RenderingContextBase::validateGetBufferSubDataBounds(
    const char* functionName,
    WebGLBuffer* sourceBuffer,
    GLintptr sourceByteOffset,
    long long destinationByteLength) {
  CheckedNumeric<long long> srcEnd = sourceByteOffset;
  srcEnd += destinationByteLength;
  if (!srcEnd.IsValid() || srcEnd.ValueOrDie() > sourceBuffer->getSize()) {
    synthesizeGLError(GL_INVALID_VALUE, functionName,
                      "overflow of bound buffer");
    return "Invalid value: overflow of bound buffer";
  }

  return nullptr;
}

void WebGL2RenderingContextBase::removeBoundBuffer(WebGLBuffer* buffer) {
  if (m_boundCopyReadBuffer == buffer)
    m_boundCopyReadBuffer = nullptr;
  if (m_boundCopyWriteBuffer == buffer)
    m_boundCopyWriteBuffer = nullptr;
  if (m_boundPixelPackBuffer == buffer)
    m_boundPixelPackBuffer = nullptr;
  if (m_boundPixelUnpackBuffer == buffer)
    m_boundPixelUnpackBuffer = nullptr;
  if (m_boundTransformFeedbackBuffer == buffer)
    m_boundTransformFeedbackBuffer = nullptr;
  if (m_boundUniformBuffer == buffer)
    m_boundUniformBuffer = nullptr;

  WebGLRenderingContextBase::removeBoundBuffer(buffer);
}

void WebGL2RenderingContextBase::restoreCurrentFramebuffer() {
  bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_framebufferBinding.get());
  bindFramebuffer(GL_READ_FRAMEBUFFER, m_readFramebufferBinding.get());
}

void WebGL2RenderingContextBase::visitChildDOMWrappers(
    v8::Isolate* isolate,
    const v8::Persistent<v8::Object>& wrapper) {
  if (isContextLost()) {
    return;
  }

  WebGLRenderingContextBase::visitChildDOMWrappers(isolate, wrapper);

  DOMWrapperWorld::setWrapperReferencesInAllWorlds(
      wrapper, m_transformFeedbackBinding, isolate);
  DOMWrapperWorld::setWrapperReferencesInAllWorlds(
      wrapper, m_readFramebufferBinding, isolate);

  DOMWrapperWorld::setWrapperReferencesInAllWorlds(
      wrapper, m_boundCopyReadBuffer, isolate);
  DOMWrapperWorld::setWrapperReferencesInAllWorlds(
      wrapper, m_boundCopyWriteBuffer, isolate);
  DOMWrapperWorld::setWrapperReferencesInAllWorlds(
      wrapper, m_boundPixelPackBuffer, isolate);
  DOMWrapperWorld::setWrapperReferencesInAllWorlds(
      wrapper, m_boundPixelUnpackBuffer, isolate);
  DOMWrapperWorld::setWrapperReferencesInAllWorlds(
      wrapper, m_boundTransformFeedbackBuffer, isolate);
  DOMWrapperWorld::setWrapperReferencesInAllWorlds(
      wrapper, m_boundUniformBuffer, isolate);

  for (auto& buf : m_boundIndexedTransformFeedbackBuffers) {
    DOMWrapperWorld::setWrapperReferencesInAllWorlds(wrapper, buf, isolate);
  }

  for (auto& buf : m_boundIndexedUniformBuffers) {
    DOMWrapperWorld::setWrapperReferencesInAllWorlds(wrapper, buf, isolate);
  }

  DOMWrapperWorld::setWrapperReferencesInAllWorlds(
      wrapper, m_currentBooleanOcclusionQuery, isolate);
  DOMWrapperWorld::setWrapperReferencesInAllWorlds(
      wrapper, m_currentTransformFeedbackPrimitivesWrittenQuery, isolate);
  DOMWrapperWorld::setWrapperReferencesInAllWorlds(
      wrapper, m_currentElapsedQuery, isolate);

  for (auto& unit : m_samplerUnits) {
    DOMWrapperWorld::setWrapperReferencesInAllWorlds(wrapper, unit, isolate);
  }
}

WebGLImageConversion::PixelStoreParams
WebGL2RenderingContextBase::getPackPixelStoreParams() {
  WebGLImageConversion::PixelStoreParams params;
  params.alignment = m_packAlignment;
  params.rowLength = m_packRowLength;
  params.skipPixels = m_packSkipPixels;
  params.skipRows = m_packSkipRows;
  return params;
}

WebGLImageConversion::PixelStoreParams
WebGL2RenderingContextBase::getUnpackPixelStoreParams(
    TexImageDimension dimension) {
  WebGLImageConversion::PixelStoreParams params;
  params.alignment = m_unpackAlignment;
  params.rowLength = m_unpackRowLength;
  params.skipPixels = m_unpackSkipPixels;
  params.skipRows = m_unpackSkipRows;
  if (dimension == Tex3D) {
    params.imageHeight = m_unpackImageHeight;
    params.skipImages = m_unpackSkipImages;
  }
  return params;
}

void WebGL2RenderingContextBase::
    DrawingBufferClientRestorePixelUnpackBufferBinding() {
  if (!contextGL())
    return;
  contextGL()->BindBuffer(GL_PIXEL_UNPACK_BUFFER,
                          objectOrZero(m_boundPixelUnpackBuffer.get()));
}

}  // namespace blink
