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

// A class to emulate GLES2 over command buffers.

#include "gpu/command_buffer/client/gles2_implementation.h"

#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <GLES2/gl2extchromium.h>
#include <GLES3/gl3.h>
#include <GLES3/gl31.h>
#include <stddef.h>
#include <stdint.h>

#include <algorithm>
#include <array>
#include <map>
#include <memory>
#include <set>
#include <sstream>
#include <string>

#include "base/atomic_sequence_num.h"
#include "base/atomicops.h"
#include "base/bits.h"
#include "base/compiler_specific.h"
#include "base/containers/heap_array.h"
#include "base/containers/span.h"
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/memory/raw_ptr.h"
#include "base/numerics/ostream_operators.h"
#include "base/numerics/safe_math.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/system/sys_info.h"
#include "base/time/time.h"
#include "base/trace_event/memory_allocator_dump.h"
#include "base/trace_event/memory_dump_manager.h"
#include "base/trace_event/process_memory_dump.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "gpu/command_buffer/client/buffer_tracker.h"
#include "gpu/command_buffer/client/client_shared_image.h"
#include "gpu/command_buffer/client/gles2_cmd_helper.h"
#include "gpu/command_buffer/client/gpu_control.h"
#include "gpu/command_buffer/client/program_info_manager.h"
#include "gpu/command_buffer/client/query_tracker.h"
#include "gpu/command_buffer/client/readback_buffer_shadow_tracker.h"
#include "gpu/command_buffer/client/shared_memory_limits.h"
#include "gpu/command_buffer/client/transfer_buffer.h"
#include "gpu/command_buffer/client/transfer_buffer_cmd_copy_helpers.h"
#include "gpu/command_buffer/client/vertex_array_object_manager.h"
#include "gpu/command_buffer/common/context_creation_attribs.h"
#include "gpu/command_buffer/common/gles2_cmd_utils.h"
#include "gpu/command_buffer/common/id_allocator.h"
#include "gpu/command_buffer/common/swap_buffers_complete_params.h"
#include "gpu/command_buffer/common/sync_token.h"
#include "third_party/skia/include/core/SkAlphaType.h"
#include "third_party/skia/include/gpu/ganesh/GrTypes.h"
#include "ui/gfx/color_space.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/rect_f.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gl/gpu_preference.h"

#if defined(GPU_CLIENT_DEBUG)
#define GPU_CLIENT_SINGLE_THREAD_CHECK() \
  DeferErrorCallbacks deferrer(this);    \
  SingleThreadChecker checker(this);
#else  // !defined(GPU_CLIENT_DEBUG)
#define GPU_CLIENT_SINGLE_THREAD_CHECK() DeferErrorCallbacks deferrer(this);
#endif  // defined(GPU_CLIENT_DEBUG)

// Check that destination pointers point to initialized memory.
// When the context is lost, calling GL function has no effect so if destination
// pointers point to initialized memory it can often lead to crash bugs. eg.
//
// GLsizei len;
// glGetShaderSource(shader, max_size, &len, buffer);
// std::string src(buffer, buffer + len);  // len can be uninitialized here!!!
//
// Because this check is not official GL this check happens only on Chrome code,
// not Pepper.
//
// If it was up to us we'd just always write to the destination but the OpenGL
// spec defines the behavior of OpenGL functions, not us. :-(
#if defined(GPU_DCHECK)
#define GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION_ASSERT(v) GPU_DCHECK(v)
#define GPU_CLIENT_DCHECK(v) GPU_DCHECK(v)
#elif defined(DCHECK)
#define GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION_ASSERT(v) DCHECK(v)
#define GPU_CLIENT_DCHECK(v) DCHECK(v)
#else
#define GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION_ASSERT(v) ASSERT(v)
#define GPU_CLIENT_DCHECK(v) ASSERT(v)
#endif

#define GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION(type, ptr) \
  GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION_ASSERT(          \
      ptr &&                                                     \
      (ptr[0] == static_cast<type>(0) || ptr[0] == static_cast<type>(-1)));

#define GPU_CLIENT_VALIDATE_DESTINATION_OPTIONAL_INITALIZATION(type, ptr) \
  GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION_ASSERT(                   \
      !ptr ||                                                             \
      (ptr[0] == static_cast<type>(0) || ptr[0] == static_cast<type>(-1)));

namespace gpu {
namespace gles2 {


namespace {

#if !BUILDFLAG(IS_ANDROID)
// Valid gl texture internal format that can try to use direct uploading path.
bool ValidFormatForDirectUploading(GLenum format, uint32_t type) {
  switch (format) {
    case GL_RGBA:
      return type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_SHORT_4_4_4_4;
    case GL_RGB:
      return type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_SHORT_5_6_5;
    // WebGL2 supported sized formats
    case GL_RGBA8:
    case GL_RGB565:
    case GL_RGBA16F:
    case GL_RGB8:
    case GL_RGB10_A2:
    case GL_RGBA4:
      // TODO(crbug.com/356649879): RasterContextProvider never has ES3 context.
      // Use the correct WebGL major version here.
      return false;
    default:
      return false;
  }
}
#endif


void CopyRectToBuffer(base::span<const uint8_t> pixels,
                      uint32_t height,
                      uint32_t unpadded_row_size,
                      uint32_t pixels_padded_row_size,
                      base::span<uint8_t> buffer,
                      uint32_t buffer_padded_row_size) {
  if (height == 0)
    return;
  if (pixels_padded_row_size != buffer_padded_row_size) {
    uint32_t buffer_offset = 0;
    uint32_t pixels_offset = 0;
    for (uint32_t ii = 0; ii < height; ++ii) {
      buffer.subspan(buffer_offset, unpadded_row_size)
          .copy_from(pixels.subspan(pixels_offset, unpadded_row_size));
      buffer_offset += buffer_padded_row_size;
      pixels_offset += pixels_padded_row_size;
    }
  } else {
    uint32_t size = (height - 1) * pixels_padded_row_size + unpadded_row_size;
    buffer.copy_prefix_from(pixels.first(size));
  }
}

static base::AtomicSequenceNumber g_flush_id;

uint32_t GenerateNextFlushId() {
  return static_cast<uint32_t>(g_flush_id.GetNext());
}

bool IsReadbackUsage(GLenum usage) {
  return usage == GL_STREAM_READ || usage == GL_DYNAMIC_READ ||
         usage == GL_STATIC_READ;
}

void UpdateProgramInfo(base::span<const uint8_t>& data,
                       ProgramInfoManager* manager,
                       ProgramInfoManager::ProgramInfoType type) {
  CHECK(data.size() >= sizeof(cmds::GLES2ReturnProgramInfo));
  const cmds::GLES2ReturnProgramInfo* return_program_info =
      reinterpret_cast<const cmds::GLES2ReturnProgramInfo*>(data.data());
  uint32_t program = return_program_info->program_client_id;
  base::span<const int8_t> UNSAFE_TODO(info(
      reinterpret_cast<const int8_t*>(return_program_info->deserialized_buffer),
      data.size() - sizeof(cmds::GLES2ReturnProgramInfo)));
  manager->UpdateProgramInfo(program, info, type);
}

bool CanCopySharedImageToGLTextureViaTextureCopy(
    ClientSharedImage* shared_image) {
  const bool si_format_has_single_texture =
      shared_image->format().is_single_plane() ||
      shared_image->format().PrefersExternalSampler();
  const bool si_usable_by_gles2_interface =
      shared_image->GetTextureTarget() != 0;

  // Copying the shared image to the destination texture via a direct
  // texture-to-texture copy requires being able to obtain a client-side GL
  // texture for the shared image, which in turn requires that the shared image
  // be either single-plane or use external sampler and that it be usable by GL.
  return si_format_has_single_texture && si_usable_by_gles2_interface;
}

bool CanCopySharedImageToGLTextureViaSkia(bool is_opaque,
                                          uint32_t shared_image_target,
                                          uint32_t dst_target,
                                          uint32_t dst_internal_format,
                                          uint32_t dst_type,
                                          int32_t dst_level,
                                          SkAlphaType dst_alpha_type) {
  // NOTE: CopySharedImageToGLTextureINTERNAL() is implemented only in the
  // passthrough command decoder, which is not yet fully rolled out on Android.
  // Hence, disable this codepath on Android.
  // TODO(crbug.com/40075313): Enable on Android once the passthrough command
  // decoder is used universally there.
#if BUILDFLAG(IS_ANDROID)
  return false;
#else
  bool si_usable_by_gles2_interface = shared_image_target != 0;
  // Since skia always produces premultiply alpha outputs, trying direct
  // uploading path when the source is opaque or premultiply alpha been
  // requested.
  // TODO(crbug.com/40159723): Figure out whether premultiply options here are
  // accurate.
  // TODO(crbug.com/492116792): Remove the `is_opaque` param by querying the
  // SharedImage's format directly after verifying that this doesn't change
  // behavior for any existing callers.
  bool is_premul = is_opaque || dst_alpha_type == kPremul_SkAlphaType;
  bool supports_one_copy_format = ValidFormatForDirectUploading(
      static_cast<GLenum>(dst_internal_format), dst_type);
  // dst texture mipLevel must be 0.
  // TODO(crbug.com/40141173): Support more texture target, e.g.
  // 2d array, 3d etc.
  return si_usable_by_gles2_interface && dst_level == 0 && is_premul &&
         dst_target == GL_TEXTURE_2D && supports_one_copy_format;
#endif  // BUILDFLAG(IS_ANDROID)
}

}  // anonymous namespace

GLES2Implementation::GLStaticState::GLStaticState() = default;

GLES2Implementation::GLStaticState::~GLStaticState() = default;

GLES2Implementation::DeferErrorCallbacks::DeferErrorCallbacks(
    GLES2Implementation* gles2_implementation)
    : gles2_implementation_(*gles2_implementation) {
  DCHECK_EQ(false, gles2_implementation_.deferring_error_callbacks_);
  gles2_implementation_.deferring_error_callbacks_ = true;
}

GLES2Implementation::DeferErrorCallbacks::~DeferErrorCallbacks() {
  DCHECK_EQ(true, gles2_implementation_.deferring_error_callbacks_);
  gles2_implementation_.deferring_error_callbacks_ = false;
  gles2_implementation_.CallDeferredErrorCallbacks();
}

GLES2Implementation::DeferredErrorCallback::DeferredErrorCallback(
    std::string message,
    int32_t id)
    : message(std::move(message)), id(id) {}

GLES2Implementation::SingleThreadChecker::SingleThreadChecker(
    GLES2Implementation* gles2_implementation)
    : gles2_implementation_(gles2_implementation) {
  CHECK_EQ(0, gles2_implementation_->use_count_);
  ++gles2_implementation_->use_count_;
}

GLES2Implementation::SingleThreadChecker::~SingleThreadChecker() {
  --gles2_implementation_->use_count_;
  CHECK_EQ(0, gles2_implementation_->use_count_);
}

GLES2Implementation::GLES2Implementation(
    GLES2CmdHelper* helper,
    scoped_refptr<ShareGroup> share_group,
    TransferBufferInterface* transfer_buffer,
    bool lose_context_when_out_of_memory,
    GpuControl* gpu_control)
    : ImplementationBase(helper, transfer_buffer, gpu_control),
      helper_(helper),
      chromium_framebuffer_multisample_(kUnknownExtensionStatus),
      gl_capabilities_(gpu_control->GetGLCapabilities()),
      pack_alignment_(4),
      pack_row_length_(0),
      pack_skip_pixels_(0),
      pack_skip_rows_(0),
      unpack_alignment_(4),
      unpack_row_length_(0),
      unpack_image_height_(0),
      unpack_skip_rows_(0),
      unpack_skip_pixels_(0),
      unpack_skip_images_(0),
      active_texture_unit_(0),
      bound_framebuffer_(0),
      bound_read_framebuffer_(0),
      bound_renderbuffer_(0),
      current_program_(0),
      bound_array_buffer_(0),
      bound_copy_read_buffer_(0),
      bound_copy_write_buffer_(0),
      bound_pixel_pack_buffer_(0),
      bound_pixel_unpack_buffer_(0),
      bound_transform_feedback_buffer_(0),
      bound_uniform_buffer_(0),
      bound_pixel_pack_transfer_buffer_id_(0),
      bound_pixel_unpack_transfer_buffer_id_(0),
      error_bits_(0),
      lose_context_when_out_of_memory_(lose_context_when_out_of_memory),
      use_count_(0),
      flush_id_(0),
      max_extra_transfer_buffer_size_(0),
      current_trace_stack_(0),
      aggressively_free_resources_(false),
      cached_extension_string_(nullptr) {
  DCHECK(helper);

  std::stringstream ss;
  ss << std::hex << this;
  this_in_hex_ = ss.str();

  share_group_ =
      (share_group ? std::move(share_group)
                   : base::MakeRefCounted<ShareGroup>(
                         gpu_control_->GetCommandBufferID().GetUnsafeValue()));
}

gpu::ContextResult GLES2Implementation::Initialize(
    const SharedMemoryLimits& limits) {
  TRACE_EVENT0("gpu", "GLES2Implementation::Initialize");
  auto result = ImplementationBase::Initialize(limits);
  if (result != gpu::ContextResult::kSuccess) {
    return result;
  }

  max_extra_transfer_buffer_size_ = limits.max_mapped_memory_for_texture_upload;

  GLStaticState::ShaderPrecisionMap* shader_precisions =
      &static_state_.shader_precisions;
  gl_capabilities_.VisitPrecisions(
      [shader_precisions](GLenum shader, GLenum type,
                          GLCapabilities::ShaderPrecision* result) {
        const GLStaticState::ShaderPrecisionKey key(shader, type);
        cmds::GetShaderPrecisionFormat::Result cached_result = {
            true, result->min_range, result->max_range, result->precision};
        shader_precisions->insert(std::make_pair(key, cached_result));
      });

  util_.set_num_compressed_texture_formats(
      gl_capabilities_.num_compressed_texture_formats);
  util_.set_num_shader_binary_formats(
      gl_capabilities_.num_shader_binary_formats);

  texture_units_ = base::HeapArray<internal::TextureUnit>::WithSize(
      gl_capabilities_.max_combined_texture_image_units);

  buffer_tracker_ = std::make_unique<BufferTracker>(mapped_memory_.get());
  readback_buffer_shadow_tracker_ =
      std::make_unique<ReadbackBufferShadowTracker>(mapped_memory_.get(),
                                                    helper_);

  for (int i = 0; i < static_cast<int>(IdNamespaces::kNumIdNamespaces); ++i) {
    id_allocators_[i] = std::make_unique<IdAllocator>();
  }

  vertex_array_object_manager_ = std::make_unique<VertexArrayObjectManager>(
      gl_capabilities_.max_vertex_attribs);

  return gpu::ContextResult::kSuccess;
}

GLES2Implementation::~GLES2Implementation() {
  // Assure no DeferErrorCallbacks instances are loose in the wild.
  CHECK(!deferring_error_callbacks_);

  // Make sure the queries are finished otherwise we'll delete the
  // shared memory (mapped_memory_) which will free the memory used
  // by the queries. The GPU process when validating that memory is still
  // shared will fail and abort (ie, it will stop running).
  WaitForCmd();

  query_tracker_.reset();

  // Release remaining BufferMap mem; This is when a MapBufferSubData() is
  // called but not the UnmapBufferSubData() pair.
  ClearMappedBufferMap();

  // Release remaining TextureMap mem; This is when a MapTexSubImage2D() is
  // called but not the UnmapTexSubImage2D() pair.
  ClearMappedTextureMap();

  // Release any per-context data in share group.
  share_group_->FreeContext(this);

  buffer_tracker_.reset();
  readback_buffer_shadow_tracker_.reset();

  // Make sure the commands make it the service.
  WaitForCmd();
}

GLES2CmdHelper* GLES2Implementation::helper() const {
  return helper_;
}

IdHandlerInterface* GLES2Implementation::GetIdHandler(
    SharedIdNamespaces namespace_id) const {
  return share_group_->GetIdHandler(namespace_id);
}

RangeIdHandlerInterface* GLES2Implementation::GetRangeIdHandler(
    int namespace_id) const {
  return share_group_->GetRangeIdHandler(namespace_id);
}

IdAllocator* GLES2Implementation::GetIdAllocator(
    IdNamespaces namespace_id) const {
  return id_allocators_[static_cast<int>(namespace_id)].get();
}

void GLES2Implementation::OnGpuControlLostContext() {
  // This should never occur more than once.
  DCHECK(!lost_context_callback_run_);
  lost_context_callback_run_ = true;
  share_group_->Lose();
  if (!lost_context_callback_.is_null()) {
    std::move(lost_context_callback_).Run();
  }
}

void GLES2Implementation::OnGpuControlLostContextMaybeReentrant() {
  // Queries for lost context state should immediately reflect reality,
  // but don't call out to clients yet to avoid them re-entering this
  // class.
  share_group_->Lose();
}

void GLES2Implementation::OnGpuControlErrorMessage(const char* message,
                                                   int32_t id) {
  SendErrorMessage(message, id);
}

void GLES2Implementation::OnGpuSwitched() {
  gpu_switched_ = true;
}

GLboolean GLES2Implementation::DidGpuSwitch(gl::GpuPreference* active_gpu) {
  if (gpu_switched_) {
    *active_gpu = gl::GpuPreference::kDefault;
  }
  GLboolean result = gpu_switched_ ? GL_TRUE : GL_FALSE;
  gpu_switched_ = false;
  return result;
}

bool GLES2Implementation::CanCopySharedImageDirectlyToGLTexture(
    bool is_opaque,
    ClientSharedImage* shared_image,
    uint32_t dst_target,
    uint32_t dst_internal_format,
    uint32_t dst_type,
    int32_t dst_level,
    SkAlphaType dst_alpha_type) {
  return CanCopySharedImageToGLTextureViaTextureCopy(shared_image) ||
         CanCopySharedImageToGLTextureViaSkia(
             is_opaque, shared_image->GetTextureTarget(), dst_target,
             dst_internal_format, dst_type, dst_level, dst_alpha_type);
}

CopySharedImageSyncCallback
GLES2Implementation::CopySharedImageToGLTextureViaTextureCopy(
    const gfx::Rect& src_rect,
    ClientSharedImage* source_shared_image,
    const gpu::SyncToken& source_sync_token,
    uint32_t dst_target,
    uint32_t dst_texture,
    uint32_t dst_internal_format,
    uint32_t dst_format,
    uint32_t dst_type,
    int32_t dst_level,
    SkAlphaType dst_alpha_type,
    GrSurfaceOrigin dst_origin) {
  auto si_texture = source_shared_image->CreateGLTexture(this);
  auto scoped_si_access =
      si_texture->BeginAccess(source_sync_token, /*readonly=*/true);

  const bool do_premultiply_alpha =
      dst_alpha_type == kPremul_SkAlphaType &&
      source_shared_image->alpha_type() == kUnpremul_SkAlphaType;
  const bool do_unpremultiply_alpha =
      dst_alpha_type == kUnpremul_SkAlphaType &&
      source_shared_image->alpha_type() == kPremul_SkAlphaType;

  const bool do_flip_y = source_shared_image->surface_origin() != dst_origin;
  // There should always be enough data in the source texture to
  // cover this copy.
  GPU_CLIENT_DCHECK(src_rect.width() <= source_shared_image->size().width());
  GPU_CLIENT_DCHECK(src_rect.height() <= source_shared_image->size().height());
  // TODO(crbug.com/378688985): `src_rect` is always in top-left
  // coordinate space, but CopySubTextureCHROMIUM requires it to be in texture
  // space, so this is incorrect if `source_shared_image` origin is bottom
  // left.
  CopySubTextureCHROMIUM(
      scoped_si_access->texture_id(), 0, dst_target, dst_texture, dst_level, 0,
      0, src_rect.x(), src_rect.y(), src_rect.width(), src_rect.height(),
      do_flip_y, do_premultiply_alpha, do_unpremultiply_alpha);
  return base::BindOnce(
      [](std::unique_ptr<SharedImageTexture::ScopedAccess> si_access,
         std::unique_ptr<SharedImageTexture> si_texture) {
        return gpu::SharedImageTexture::ScopedAccess::EndAccess(
            std::move(si_access));
      },
      std::move(scoped_si_access), std::move(si_texture));
}

CopySharedImageSyncCallback
GLES2Implementation::CopySharedImageDirectlyToGLTexture(
    const gfx::Rect& src_rect,
    ClientSharedImage* source_shared_image,
    const gpu::SyncToken& source_sync_token,
    bool is_opaque,
    uint32_t dst_target,
    uint32_t dst_texture,
    uint32_t dst_internal_format,
    uint32_t dst_format,
    uint32_t dst_type,
    int32_t dst_level,
    SkAlphaType dst_alpha_type,
    GrSurfaceOrigin dst_origin) {
  CopySharedImageSyncCallback sync_callback;
  if (CanCopySharedImageToGLTextureViaTextureCopy(source_shared_image)) {
    sync_callback = CopySharedImageToGLTextureViaTextureCopy(
        src_rect, source_shared_image, source_sync_token, dst_target,
        dst_texture, dst_internal_format, dst_format, dst_type, dst_level,
        dst_alpha_type, dst_origin);
    ShallowFlushCHROMIUM();
  } else {
    CHECK(CanCopySharedImageToGLTextureViaSkia(
        is_opaque, source_shared_image->GetTextureTarget(), dst_target,
        dst_internal_format, dst_type, dst_level, dst_alpha_type));
    // Do a service-side copy from the SharedImage to the destination texture
    // via Skia wrapping the destination texture in an SkSurface. Note that
    // this relies on the service-side GL implementation using a Ganesh/GL
    // context. Currently this assumption is satisfied as the passthrough
    // decoder always uses a Ganesh/GL context.
    // TODO(crbug.com/40064510): Eliminate this reliance to enable one-copy
    // upload to work for Graphite *without* depending on being able to create a
    // Ganesh/GL context.

    std::unique_ptr<gpu::RasterScopedAccess> destination_access =
        source_shared_image->BeginGLAccessForCopySharedImage(
            this, source_sync_token, /*readonly=*/true);

    const bool is_dst_origin_top_left = dst_origin == kTopLeft_GrSurfaceOrigin;
    CopySharedImageToTextureINTERNAL(
        dst_texture, dst_target, dst_internal_format, dst_type, src_rect.x(),
        src_rect.y(), src_rect.width(), src_rect.height(),
        is_dst_origin_top_left, source_shared_image->mailbox().name);
    sync_callback = base::BindOnce(
        [](std::unique_ptr<gpu::RasterScopedAccess> ri_access) {
          return gpu::RasterScopedAccess::EndAccess(std::move(ri_access));
        },
        std::move(destination_access));
  }
  return sync_callback;
}

void GLES2Implementation::SendErrorMessage(std::string message, int32_t id) {
  if (error_message_callback_.is_null())
    return;

  if (deferring_error_callbacks_) {
    deferred_error_callbacks_.emplace_back(std::move(message), id);
    return;
  }

  error_message_callback_.Run(message.c_str(), id);
}

void GLES2Implementation::CallDeferredErrorCallbacks() {
  if (deferred_error_callbacks_.empty())
    return;

  if (error_message_callback_.is_null()) {
    // User probably cleared this out.
    deferred_error_callbacks_.clear();
    return;
  }

  std::deque<DeferredErrorCallback> local_callbacks;
  std::swap(deferred_error_callbacks_, local_callbacks);
  for (const auto& c : local_callbacks) {
    error_message_callback_.Run(c.message.c_str(), c.id);
  }
}

void GLES2Implementation::OnGpuControlReturnData(
    base::span<const uint8_t> data) {
  CHECK(data.size() >= sizeof(cmds::GLES2ReturnDataHeader));
  const cmds::GLES2ReturnDataHeader& gles2ReturnDataHeader =
      *reinterpret_cast<const cmds::GLES2ReturnDataHeader*>(data.data());

  switch (gles2ReturnDataHeader.return_data_type) {
    case GLES2ReturnDataType::kES2ProgramInfo: {
      UpdateProgramInfo(data, share_group_->program_info_manager(),
                        ProgramInfoManager::kES2);
    } break;
    case GLES2ReturnDataType::kES3UniformBlocks: {
      UpdateProgramInfo(data, share_group_->program_info_manager(),
                        ProgramInfoManager::kES3UniformBlocks);
    } break;
    case GLES2ReturnDataType::kES3TransformFeedbackVaryings: {
      UpdateProgramInfo(data, share_group_->program_info_manager(),
                        ProgramInfoManager::kES3TransformFeedbackVaryings);
    } break;
    case GLES2ReturnDataType::kES3Uniforms: {
      UpdateProgramInfo(data, share_group_->program_info_manager(),
                        ProgramInfoManager::kES3Uniformsiv);
    } break;

    default:
      NOTREACHED();
  }
}

void GLES2Implementation::FreeSharedMemory(void* mem) {
  mapped_memory_->FreePendingToken(mem, helper_->InsertToken());
}

GLuint GLES2Implementation::CreateGpuFenceCHROMIUM() {
  GLuint client_id = GetIdAllocator(IdNamespaces::kGpuFences)
                         ->AllocateIDAtOrAbove(last_gpu_fence_id_ + 1);
  // Out of paranoia, don't allow IDs to wrap around to avoid potential
  // collisions on reuse. The space of 2^32 IDs is enough for over a year of
  // allocating two per frame at 60fps. TODO(crbug.com/40552536): Revisit if
  // this is an issue, for example by deferring ID release if they would be
  // reissued too soon.
  CHECK(client_id > last_gpu_fence_id_) << "ID wrap prevented";
  last_gpu_fence_id_ = client_id;
  helper_->CreateGpuFenceINTERNAL(client_id);
  GPU_CLIENT_LOG("returned " << client_id);
  CheckGLError();
  return client_id;
}

GLuint GLES2Implementation::CreateClientGpuFenceCHROMIUM(
    ClientGpuFence source) {
  GLuint client_id = GetIdAllocator(IdNamespaces::kGpuFences)
                         ->AllocateIDAtOrAbove(last_gpu_fence_id_ + 1);
  // See CreateGpuFenceCHROMIUM comment re wraparound.
  CHECK(client_id > last_gpu_fence_id_) << "ID wrap prevented";
  last_gpu_fence_id_ = client_id;

  // Create the service-side GpuFenceEntry via gpu_control. This is guaranteed
  // to arrive before any future GL helper_ commands on this stream, so it's
  // safe to use the client_id generated here in following commands such as
  // WaitGpuFenceCHROMIUM without explicit flushing.
  gpu_control_->CreateGpuFence(client_id, source);

  GPU_CLIENT_LOG("returned " << client_id);
  CheckGLError();
  return client_id;
}

void GLES2Implementation::DestroyGpuFenceCHROMIUMHelper(GLuint client_id) {
  if (GetIdAllocator(IdNamespaces::kGpuFences)->InUse(client_id)) {
    GetIdAllocator(IdNamespaces::kGpuFences)->FreeID(client_id);
    helper_->DestroyGpuFenceCHROMIUM(client_id);
  } else {
    SetGLError(GL_INVALID_VALUE, "glDestroyGpuFenceCHROMIUM",
               "id not created by this context.");
  }
}

void GLES2Implementation::SetAggressivelyFreeResources(
    bool aggressively_free_resources) {
  TRACE_EVENT1("gpu", "GLES2Implementation::SetAggressivelyFreeResources",
               "aggressively_free_resources", aggressively_free_resources);
  aggressively_free_resources_ = aggressively_free_resources;

  if (aggressively_free_resources_ && helper_->HaveRingBuffer()) {
    // Ensure that we clean up as much cache memory as possible and fully flush.
    FlushDriverCachesCHROMIUM();

    // Flush will delete transfer buffer resources if
    // |aggressively_free_resources_| is true.
    Flush();
  } else {
    ShallowFlushCHROMIUM();
  }
}

bool GLES2Implementation::IsExtensionAvailable(const char* ext) {
  const char* extensions =
      reinterpret_cast<const char*>(GetStringHelper(GL_EXTENSIONS));
  if (!extensions)
    return false;

  int length = strlen(ext);
  while (true) {
    int n = UNSAFE_TODO(strcspn(extensions, " "));
    if (n == length && 0 == UNSAFE_TODO(strncmp(ext, extensions, length))) {
      return true;
    }
    if ('\0' == UNSAFE_TODO(extensions[n])) {
      return false;
    }
    UNSAFE_TODO(extensions += n + 1);
  }
}

bool GLES2Implementation::IsExtensionAvailableHelper(const char* extension,
                                                     ExtensionStatus* status) {
  switch (*status) {
    case kAvailableExtensionStatus:
      return true;
    case kUnavailableExtensionStatus:
      return false;
    default: {
      bool available = IsExtensionAvailable(extension);
      *status =
          available ? kAvailableExtensionStatus : kUnavailableExtensionStatus;
      return available;
    }
  }
}

bool GLES2Implementation::IsChromiumFramebufferMultisampleAvailable() {
  return IsExtensionAvailableHelper("GL_CHROMIUM_framebuffer_multisample",
                                    &chromium_framebuffer_multisample_);
}

const std::string& GLES2Implementation::GetLogPrefix() const {
  const std::string& prefix(debug_marker_manager_.GetMarker());
  return prefix.empty() ? this_in_hex_ : prefix;
}

GLenum GLES2Implementation::GetError() {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetError()");
  GLenum err = GetGLError();
  GPU_CLIENT_LOG("returned " << GLES2Util::GetStringError(err));
  return err;
}

GLenum GLES2Implementation::GetGLError() {
  TRACE_EVENT0("gpu", "GLES2::GetGLError");
  // Check the GL error first, then our wrapped error.
  typedef cmds::GetError::Result Result;
  auto result = GetResultAs<Result>();
  // If we couldn't allocate a result the context is lost.
  if (!result) {
    return GL_NO_ERROR;
  }
  *result = GL_NO_ERROR;
  helper_->GetError(GetResultShmId(), result.offset());
  if (!WaitForCmd()) {
    return GL_NO_ERROR;
  }
  GLenum error = *result;
  if (error == GL_NO_ERROR) {
    error = GetClientSideGLError();
  } else {
    // There was an error, clear the corresponding wrapped error.
    error_bits_ &= ~GLES2Util::GLErrorToErrorBit(error);
  }
  return error;
}

#if defined(GL_CLIENT_FAIL_GL_ERRORS)
void GLES2Implementation::FailGLError(GLenum error) {
  if (error != GL_NO_ERROR) {
    NOTREACHED() << "Error";
  }
}
// NOTE: Calling GetGLError overwrites data in the result buffer.
void GLES2Implementation::CheckGLError() {
  FailGLError(GetGLError());
}
#endif  // defined(GPU_CLIENT_FAIL_GL_ERRORS)

void GLES2Implementation::SetGLError(GLenum error,
                                     const char* function_name,
                                     const char* msg) {
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] Client Synthesized Error: "
                     << GLES2Util::GetStringError(error) << ": "
                     << function_name << ": " << msg);
  FailGLError(error);
  if (msg) {
    last_error_ = msg;
  }
  if (!error_message_callback_.is_null()) {
    std::string temp(GLES2Util::GetStringError(error) + " : " + function_name +
                     ": " + (msg ? msg : ""));
    SendErrorMessage(temp.c_str(), 0);
  }
  error_bits_ |= GLES2Util::GLErrorToErrorBit(error);

  if (error == GL_OUT_OF_MEMORY && lose_context_when_out_of_memory_) {
    helper_->LoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB,
                                 GL_UNKNOWN_CONTEXT_RESET_ARB);
  }
}

void GLES2Implementation::SetGLErrorInvalidEnum(const char* function_name,
                                                GLenum value,
                                                const char* label) {
  SetGLError(
      GL_INVALID_ENUM, function_name,
      (std::string(label) + " was " + GLES2Util::GetStringEnum(value)).c_str());
}

void GLES2Implementation::Disable(GLenum cap) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDisable("
                     << GLES2Util::GetStringCapability(cap) << ")");
  bool changed = false;
  if (!state_.SetCapabilityState(cap, false, &changed) || changed) {
    helper_->Disable(cap);
  }
  CheckGLError();
}

void GLES2Implementation::DisableiOES(GLenum target, GLuint index) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDisableiOES("
                     << GLES2Util::GetStringEnum(target) << ", " << index
                     << ")");
  if (index == 0u && target == GL_BLEND) {
    bool changed = false;
    DCHECK(target == GL_BLEND);
    if (!state_.SetCapabilityState(target, false, &changed) || changed) {
      helper_->DisableiOES(target, index);
    }
  } else {
    helper_->DisableiOES(target, index);
  }

  CheckGLError();
}

void GLES2Implementation::Enable(GLenum cap) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glEnable("
                     << GLES2Util::GetStringCapability(cap) << ")");
  bool changed = false;
  if (!state_.SetCapabilityState(cap, true, &changed) || changed) {
    helper_->Enable(cap);
  }
  CheckGLError();
}

void GLES2Implementation::EnableiOES(GLenum target, GLuint index) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glEnableiOES("
                     << GLES2Util::GetStringEnum(target) << ", " << index
                     << ")");
  if (index == 0u && target == GL_BLEND) {
    bool changed = false;
    DCHECK(target == GL_BLEND);
    if (!state_.SetCapabilityState(target, true, &changed) || changed) {
      helper_->EnableiOES(target, index);
    }
  } else {
    helper_->EnableiOES(target, index);
  }

  CheckGLError();
}

GLboolean GLES2Implementation::IsEnabled(GLenum cap) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glIsEnabled("
                     << GLES2Util::GetStringCapability(cap) << ")");
  bool state = false;
  if (!state_.GetEnabled(cap, &state)) {
    typedef cmds::IsEnabled::Result Result;
    auto result = GetResultAs<Result>();
    if (!result) {
      return GL_FALSE;
    }
    *result = 0;
    helper_->IsEnabled(cap, GetResultShmId(), result.offset());
    if (!WaitForCmd()) {
      return GL_FALSE;
    }
    state = (*result) != 0;
  }

  GPU_CLIENT_LOG("returned " << state);
  CheckGLError();
  return state;
}

GLboolean GLES2Implementation::IsEnablediOES(GLenum target, GLuint index) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glIsEnablediOES("
                     << GLES2Util::GetStringCapability(target) << ", " << index
                     << ")");
  bool state = false;
  typedef cmds::IsEnabled::Result Result;
  // Limit scope of result to avoid overlap with CheckGLError()
  {
    auto result = GetResultAs<Result>();
    *result = 0;
    helper_->IsEnablediOES(target, index, GetResultShmId(), result.offset());
    if (!WaitForCmd()) {
      return GL_FALSE;
    }
    state = (*result) != 0;
  }

  GPU_CLIENT_LOG("returned " << state);
  CheckGLError();
  return state;
}

bool GLES2Implementation::GetHelper(GLenum pname, GLint* params) {
  // TODO(zmo): For all the BINDING points, there is a possibility where
  // resources are shared among multiple contexts, that the cached points
  // are invalid. It is not a problem for now, but once we allow resource
  // sharing in WebGL, we need to implement a mechanism to allow correct
  // client side binding points tracking.  crbug.com/465562.

  // ES2 parameters.
  switch (pname) {
    case GL_ACTIVE_TEXTURE:
      *params = active_texture_unit_ + GL_TEXTURE0;
      return true;
    case GL_ARRAY_BUFFER_BINDING:
      *params = bound_array_buffer_;
      return true;
    case GL_ELEMENT_ARRAY_BUFFER_BINDING:
      *params = vertex_array_object_manager_->bound_element_array_buffer();
      return true;
    case GL_FRAMEBUFFER_BINDING:
      *params = bound_framebuffer_;
      return true;
    case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
      *params = gl_capabilities_.max_combined_texture_image_units;
      return true;
    case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
      *params = gl_capabilities_.max_cube_map_texture_size;
      return true;
    case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
      *params = gl_capabilities_.max_fragment_uniform_vectors;
      return true;
    case GL_MAX_RENDERBUFFER_SIZE:
      *params = gl_capabilities_.max_renderbuffer_size;
      return true;
    case GL_MAX_TEXTURE_IMAGE_UNITS:
      *params = gl_capabilities_.max_texture_image_units;
      return true;
    case GL_MAX_TEXTURE_SIZE:
      *params = gl_capabilities_.max_texture_size;
      return true;
    case GL_MAX_VARYING_VECTORS:
      *params = gl_capabilities_.max_varying_vectors;
      return true;
    case GL_MAX_VERTEX_ATTRIBS:
      *params = gl_capabilities_.max_vertex_attribs;
      return true;
    case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
      *params = gl_capabilities_.max_vertex_texture_image_units;
      return true;
    case GL_MAX_VERTEX_UNIFORM_VECTORS:
      *params = gl_capabilities_.max_vertex_uniform_vectors;
      return true;
    case GL_MAX_VIEWPORT_DIMS:
      if (gl_capabilities_.max_viewport_width > 0 &&
          gl_capabilities_.max_viewport_height > 0) {
        params[0] = gl_capabilities_.max_viewport_width;
        UNSAFE_TODO(params[1]) = gl_capabilities_.max_viewport_height;
        return true;
      }
      // If they are not cached on the client side yet, query the service side.
      return false;
    case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
      *params = gl_capabilities_.num_compressed_texture_formats;
      return true;
    case GL_NUM_SHADER_BINARY_FORMATS:
      *params = gl_capabilities_.num_shader_binary_formats;
      return true;
    case GL_RENDERBUFFER_BINDING:
      *params = bound_renderbuffer_;
      return true;
    case GL_TEXTURE_BINDING_2D:
      *params = texture_units_[active_texture_unit_].bound_texture_2d;
      return true;
    case GL_TEXTURE_BINDING_CUBE_MAP:
      *params = texture_units_[active_texture_unit_].bound_texture_cube_map;
      return true;

    // Non-standard parameters.
    case GL_TEXTURE_BINDING_EXTERNAL_OES:
      *params = texture_units_[active_texture_unit_].bound_texture_external_oes;
      return true;
    case GL_TEXTURE_BINDING_RECTANGLE_ARB:
      *params =
          texture_units_[active_texture_unit_].bound_texture_rectangle_arb;
      return true;
    case GL_PIXEL_PACK_TRANSFER_BUFFER_BINDING_CHROMIUM:
      *params = bound_pixel_pack_transfer_buffer_id_;
      return true;
    case GL_PIXEL_UNPACK_TRANSFER_BUFFER_BINDING_CHROMIUM:
      *params = bound_pixel_unpack_transfer_buffer_id_;
      return true;
    case GL_READ_FRAMEBUFFER_BINDING:
      if (gl_capabilities_.major_version >= 3 ||
          IsChromiumFramebufferMultisampleAvailable()) {
        *params = bound_read_framebuffer_;
        return true;
      }
      break;
    case GL_TIMESTAMP_EXT:
      // We convert all GPU timestamps to CPU time.
      *params = base::saturated_cast<GLint>(
          (base::TimeTicks::Now() - base::TimeTicks()).InMicroseconds() *
          base::Time::kNanosecondsPerMicrosecond);
      return true;
    case GL_GPU_DISJOINT_EXT:
      *params = static_cast<GLint>(query_tracker_->CheckAndResetDisjoint());
      return true;
    case GL_UNPACK_ALIGNMENT:
      *params = unpack_alignment_;
      return true;
    case GL_VIEWPORT:
      if (state_.viewport_width > 0 && state_.viewport_height > 0 &&
          gl_capabilities_.max_viewport_width > 0 &&
          gl_capabilities_.max_viewport_height > 0) {
        params[0] = state_.viewport_x;
        UNSAFE_TODO(params[1]) = state_.viewport_y;
        UNSAFE_TODO(params[2]) = std::min(state_.viewport_width,
                                          gl_capabilities_.max_viewport_width);
        UNSAFE_TODO(params[3]) = std::min(state_.viewport_height,
                                          gl_capabilities_.max_viewport_height);
        return true;
      }
      // If they haven't been cached on the client side, go to service side
      // to query the underlying driver.
      return false;

    // Non-cached parameters.
    case GL_ALIASED_LINE_WIDTH_RANGE:
    case GL_ALIASED_POINT_SIZE_RANGE:
    case GL_ALPHA_BITS:
    case GL_BLEND:
    case GL_BLEND_COLOR:
    case GL_BLEND_DST_ALPHA:
    case GL_BLEND_DST_RGB:
    case GL_BLEND_EQUATION_ALPHA:
    case GL_BLEND_EQUATION_RGB:
    case GL_BLEND_SRC_ALPHA:
    case GL_BLEND_SRC_RGB:
    case GL_BLUE_BITS:
    case GL_COLOR_CLEAR_VALUE:
    case GL_COLOR_WRITEMASK:
    case GL_COMPRESSED_TEXTURE_FORMATS:
    case GL_CULL_FACE:
    case GL_CULL_FACE_MODE:
    case GL_CURRENT_PROGRAM:
    case GL_DEPTH_BITS:
    case GL_DEPTH_CLEAR_VALUE:
    case GL_DEPTH_FUNC:
    case GL_DEPTH_RANGE:
    case GL_DEPTH_TEST:
    case GL_DEPTH_WRITEMASK:
    case GL_DITHER:
    case GL_FRONT_FACE:
    case GL_GENERATE_MIPMAP_HINT:
    case GL_GREEN_BITS:
    case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
    case GL_IMPLEMENTATION_COLOR_READ_TYPE:
    case GL_LINE_WIDTH:
    case GL_PACK_ALIGNMENT:
    case GL_POLYGON_OFFSET_FACTOR:
    case GL_POLYGON_OFFSET_FILL:
    case GL_POLYGON_OFFSET_UNITS:
    case GL_RED_BITS:
    case GL_SAMPLE_ALPHA_TO_COVERAGE:
    case GL_SAMPLE_BUFFERS:
    case GL_SAMPLE_COVERAGE:
    case GL_SAMPLE_COVERAGE_INVERT:
    case GL_SAMPLE_COVERAGE_VALUE:
    case GL_SAMPLES:
    case GL_SCISSOR_BOX:
    case GL_SCISSOR_TEST:
    case GL_SHADER_BINARY_FORMATS:
    case GL_SHADER_COMPILER:
    case GL_STENCIL_BACK_FAIL:
    case GL_STENCIL_BACK_FUNC:
    case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
    case GL_STENCIL_BACK_PASS_DEPTH_PASS:
    case GL_STENCIL_BACK_REF:
    case GL_STENCIL_BACK_VALUE_MASK:
    case GL_STENCIL_BACK_WRITEMASK:
    case GL_STENCIL_BITS:
    case GL_STENCIL_CLEAR_VALUE:
    case GL_STENCIL_FAIL:
    case GL_STENCIL_FUNC:
    case GL_STENCIL_PASS_DEPTH_FAIL:
    case GL_STENCIL_PASS_DEPTH_PASS:
    case GL_STENCIL_REF:
    case GL_STENCIL_TEST:
    case GL_STENCIL_VALUE_MASK:
    case GL_STENCIL_WRITEMASK:
    case GL_SUBPIXEL_BITS:
      return false;
    default:
      break;
  }

  if (gl_capabilities_.major_version < 3) {
    return false;
  }

  // ES3 parameters.
  switch (pname) {
    case GL_COPY_READ_BUFFER_BINDING:
      *params = bound_copy_read_buffer_;
      return true;
    case GL_COPY_WRITE_BUFFER_BINDING:
      *params = bound_copy_write_buffer_;
      return true;
    case GL_MAJOR_VERSION:
      *params = gl_capabilities_.major_version;
      return true;
    case GL_MAX_3D_TEXTURE_SIZE:
      *params = gl_capabilities_.max_3d_texture_size;
      return true;
    case GL_MAX_ARRAY_TEXTURE_LAYERS:
      *params = gl_capabilities_.max_array_texture_layers;
      return true;
    case GL_MAX_COLOR_ATTACHMENTS:
      *params = gl_capabilities_.max_color_attachments;
      return true;
    case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
      *params = static_cast<GLint>(
          gl_capabilities_.max_combined_fragment_uniform_components);
      return true;
    case GL_MAX_COMBINED_UNIFORM_BLOCKS:
      *params = gl_capabilities_.max_combined_uniform_blocks;
      return true;
    case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
      *params = static_cast<GLint>(
          gl_capabilities_.max_combined_vertex_uniform_components);
      return true;
    case GL_MAX_DRAW_BUFFERS:
      *params = gl_capabilities_.max_draw_buffers;
      return true;
    case GL_MAX_ELEMENT_INDEX:
      *params = static_cast<GLint>(gl_capabilities_.max_element_index);
      return true;
    case GL_MAX_ELEMENTS_INDICES:
      *params = gl_capabilities_.max_elements_indices;
      return true;
    case GL_MAX_ELEMENTS_VERTICES:
      *params = gl_capabilities_.max_elements_vertices;
      return true;
    case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
      *params = gl_capabilities_.max_fragment_input_components;
      return true;
    case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
      *params = gl_capabilities_.max_fragment_uniform_blocks;
      return true;
    case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
      *params = gl_capabilities_.max_fragment_uniform_components;
      return true;
    case GL_MAX_PROGRAM_TEXEL_OFFSET:
      *params = gl_capabilities_.max_program_texel_offset;
      return true;
    case GL_MAX_SAMPLES:
      *params = gl_capabilities_.max_samples;
      return true;
    case GL_MAX_SERVER_WAIT_TIMEOUT:
      *params = static_cast<GLint>(gl_capabilities_.max_server_wait_timeout);
      return true;
    case GL_MAX_TEXTURE_LOD_BIAS:
      *params = static_cast<GLint>(gl_capabilities_.max_texture_lod_bias);
      return true;
    case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
      *params = gl_capabilities_.max_transform_feedback_interleaved_components;
      return true;
    case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
      *params = gl_capabilities_.max_transform_feedback_separate_attribs;
      return true;
    case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
      *params = gl_capabilities_.max_transform_feedback_separate_components;
      return true;
    case GL_MAX_UNIFORM_BLOCK_SIZE:
      *params = static_cast<GLint>(gl_capabilities_.max_uniform_block_size);
      return true;
    case GL_MAX_UNIFORM_BUFFER_BINDINGS:
      *params = gl_capabilities_.max_uniform_buffer_bindings;
      return true;
    case GL_MAX_VARYING_COMPONENTS:
      *params = gl_capabilities_.max_varying_components;
      return true;
    case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
      *params = gl_capabilities_.max_vertex_output_components;
      return true;
    case GL_MAX_VERTEX_UNIFORM_BLOCKS:
      *params = gl_capabilities_.max_vertex_uniform_blocks;
      return true;
    case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
      *params = gl_capabilities_.max_vertex_uniform_components;
      return true;
    case GL_MIN_PROGRAM_TEXEL_OFFSET:
      *params = gl_capabilities_.min_program_texel_offset;
      return true;
    case GL_MINOR_VERSION:
      *params = gl_capabilities_.minor_version;
      return true;
    case GL_NUM_EXTENSIONS:
      UpdateCachedExtensionsIfNeeded();
      *params = cached_extensions_.size();
      return true;
    case GL_NUM_PROGRAM_BINARY_FORMATS:
      *params = gl_capabilities_.num_program_binary_formats;
      return true;
    case GL_PACK_SKIP_PIXELS:
      *params = pack_skip_pixels_;
      return true;
    case GL_PACK_SKIP_ROWS:
      *params = pack_skip_rows_;
      return true;
    case GL_PIXEL_PACK_BUFFER_BINDING:
      *params = bound_pixel_pack_buffer_;
      return true;
    case GL_PIXEL_UNPACK_BUFFER_BINDING:
      *params = bound_pixel_unpack_buffer_;
      return true;
    case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
      *params = bound_transform_feedback_buffer_;
      return true;
    case GL_UNIFORM_BUFFER_BINDING:
      *params = bound_uniform_buffer_;
      return true;
    case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
      *params = gl_capabilities_.uniform_buffer_offset_alignment;
      return true;
    case GL_UNPACK_SKIP_IMAGES:
      *params = unpack_skip_images_;
      return true;
    case GL_UNPACK_SKIP_PIXELS:
      *params = unpack_skip_pixels_;
      return true;
    case GL_UNPACK_SKIP_ROWS:
      *params = unpack_skip_rows_;
      return true;

    // Non-cached ES3 parameters.
    case GL_DRAW_BUFFER0:
    case GL_DRAW_BUFFER1:
    case GL_DRAW_BUFFER2:
    case GL_DRAW_BUFFER3:
    case GL_DRAW_BUFFER4:
    case GL_DRAW_BUFFER5:
    case GL_DRAW_BUFFER6:
    case GL_DRAW_BUFFER7:
    case GL_DRAW_BUFFER8:
    case GL_DRAW_BUFFER9:
    case GL_DRAW_BUFFER10:
    case GL_DRAW_BUFFER11:
    case GL_DRAW_BUFFER12:
    case GL_DRAW_BUFFER13:
    case GL_DRAW_BUFFER14:
    case GL_DRAW_BUFFER15:
    case GL_DRAW_FRAMEBUFFER_BINDING:
    case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
    case GL_PACK_ROW_LENGTH:
    case GL_PRIMITIVE_RESTART_FIXED_INDEX:
    case GL_PROGRAM_BINARY_FORMATS:
    case GL_RASTERIZER_DISCARD:
    case GL_READ_BUFFER:
    case GL_READ_FRAMEBUFFER_BINDING:
    case GL_SAMPLER_BINDING:
    case GL_TEXTURE_BINDING_2D_ARRAY:
    case GL_TEXTURE_BINDING_3D:
    case GL_TRANSFORM_FEEDBACK_BINDING:
    case GL_TRANSFORM_FEEDBACK_ACTIVE:
    case GL_TRANSFORM_FEEDBACK_PAUSED:
    case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
    case GL_TRANSFORM_FEEDBACK_BUFFER_START:
    case GL_UNIFORM_BUFFER_SIZE:
    case GL_UNIFORM_BUFFER_START:
    case GL_UNPACK_IMAGE_HEIGHT:
    case GL_UNPACK_ROW_LENGTH:
    case GL_VERTEX_ARRAY_BINDING:
      return false;
    default:
      return false;
  }
}

bool GLES2Implementation::GetBooleanvHelper(GLenum pname, GLboolean* params) {
  // TODO(gman): Make this handle pnames that return more than 1 value.
  GLint value;
  if (!GetHelper(pname, &value)) {
    return false;
  }
  *params = static_cast<GLboolean>(value);
  return true;
}

bool GLES2Implementation::GetBooleani_vHelper(GLenum pname,
                                              GLuint index,
                                              GLboolean* data) {
  // TODO(zmo): Implement client side caching.
  return false;
}

bool GLES2Implementation::GetFloatvHelper(GLenum pname, GLfloat* params) {
  // TODO(gman): Make this handle pnames that return more than 1 value.
  switch (pname) {
    case GL_MAX_TEXTURE_LOD_BIAS:
      *params = gl_capabilities_.max_texture_lod_bias;
      return true;
    default:
      break;
  }
  GLint value;
  if (!GetHelper(pname, &value)) {
    return false;
  }
  *params = static_cast<GLfloat>(value);
  return true;
}

bool GLES2Implementation::GetInteger64vHelper(GLenum pname, GLint64* params) {
  switch (pname) {
    case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
      *params = gl_capabilities_.max_combined_fragment_uniform_components;
      return true;
    case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
      *params = gl_capabilities_.max_combined_vertex_uniform_components;
      return true;
    case GL_MAX_ELEMENT_INDEX:
      *params = gl_capabilities_.max_element_index;
      return true;
    case GL_MAX_SERVER_WAIT_TIMEOUT:
      *params = gl_capabilities_.max_server_wait_timeout;
      return true;
    case GL_MAX_UNIFORM_BLOCK_SIZE:
      *params = gl_capabilities_.max_uniform_block_size;
      return true;
    case GL_TIMESTAMP_EXT:
      // We convert all GPU timestamps to CPU time.
      *params = (base::TimeTicks::Now() - base::TimeTicks()).InMicroseconds() *
                base::Time::kNanosecondsPerMicrosecond;
      return true;
    default:
      break;
  }
  GLint value;
  if (!GetHelper(pname, &value)) {
    return false;
  }
  *params = static_cast<GLint64>(value);
  return true;
}

bool GLES2Implementation::GetIntegervHelper(GLenum pname, GLint* params) {
  return GetHelper(pname, params);
}

bool GLES2Implementation::GetIntegeri_vHelper(GLenum pname,
                                              GLuint index,
                                              GLint* data) {
  // TODO(zmo): Implement client side caching.
  return false;
}

bool GLES2Implementation::GetInteger64i_vHelper(GLenum pname,
                                                GLuint index,
                                                GLint64* data) {
  // TODO(zmo): Implement client side caching.
  return false;
}

bool GLES2Implementation::GetInternalformativHelper(GLenum target,
                                                    GLenum format,
                                                    GLenum pname,
                                                    GLsizei bufSize,
                                                    GLint* params) {
  // TODO(zmo): Implement the client side caching.
  return false;
}

bool GLES2Implementation::GetSyncivHelper(GLsync sync,
                                          GLenum pname,
                                          GLsizei bufsize,
                                          GLsizei* length,
                                          GLint* values) {
  GLint value = 0;
  switch (pname) {
    case GL_OBJECT_TYPE:
      value = GL_SYNC_FENCE;
      break;
    case GL_SYNC_CONDITION:
      value = GL_SYNC_GPU_COMMANDS_COMPLETE;
      break;
    case GL_SYNC_FLAGS:
      value = 0;
      break;
    default:
      return false;
  }
  if (bufsize > 0) {
    DCHECK(values);
    *values = value;
  }
  if (length) {
    *length = 1;
  }
  return true;
}

bool GLES2Implementation::GetQueryObjectValueHelper(const char* function_name,
                                                    GLuint id,
                                                    GLenum pname,
                                                    GLuint64* params) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] GetQueryObjectValueHelper(" << id
                     << ", " << GLES2Util::GetStringQueryObjectParameter(pname)
                     << ", " << static_cast<const void*>(params) << ")");

  QueryTracker::Query* query = query_tracker_->GetQuery(id);
  if (!query) {
    SetGLError(GL_INVALID_OPERATION, function_name, "unknown query id");
    return false;
  }

  if (query->Active()) {
    SetGLError(GL_INVALID_OPERATION, function_name,
               "query active. Did you call glEndQueryEXT?");
    return false;
  }

  if (query->NeverUsed()) {
    SetGLError(GL_INVALID_OPERATION, function_name,
               "Never used. Did you call glBeginQueryEXT?");
    return false;
  }

  bool valid_value = false;
  const bool flush_if_pending =
      pname != GL_QUERY_RESULT_AVAILABLE_NO_FLUSH_CHROMIUM_EXT;
  switch (pname) {
    case GL_QUERY_RESULT_EXT:
      if (!query->CheckResultsAvailable(helper_, flush_if_pending)) {
        helper_->WaitForToken(query->token());
        if (!query->CheckResultsAvailable(helper_, flush_if_pending)) {
          FinishHelper();
          CHECK(query->CheckResultsAvailable(helper_, flush_if_pending));
        }
      }
      *params = query->GetResult();
      valid_value = true;
      break;
    case GL_QUERY_RESULT_AVAILABLE_EXT:
      *params = query->CheckResultsAvailable(helper_, flush_if_pending);
      valid_value = true;
      break;
    case GL_QUERY_RESULT_AVAILABLE_NO_FLUSH_CHROMIUM_EXT:
      *params = query->CheckResultsAvailable(helper_, flush_if_pending);
      valid_value = true;
      break;
    default:
      SetGLErrorInvalidEnum(function_name, pname, "pname");
      break;
  }
  GPU_CLIENT_LOG("  " << *params);
  CheckGLError();
  return valid_value;
}

GLuint GLES2Implementation::GetMaxValueInBufferCHROMIUMHelper(GLuint buffer_id,
                                                              GLsizei count,
                                                              GLenum type,
                                                              GLuint offset) {
  typedef cmds::GetMaxValueInBufferCHROMIUM::Result Result;
  auto result = GetResultAs<Result>();
  if (!result) {
    return 0;
  }
  *result = 0;
  helper_->GetMaxValueInBufferCHROMIUM(buffer_id, count, type, offset,
                                       GetResultShmId(), result.offset());
  if (!WaitForCmd()) {
    return 0;
  }
  return *result;
}

GLuint GLES2Implementation::GetMaxValueInBufferCHROMIUM(GLuint buffer_id,
                                                        GLsizei count,
                                                        GLenum type,
                                                        GLuint offset) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetMaxValueInBufferCHROMIUM("
                     << buffer_id << ", " << count << ", "
                     << GLES2Util::GetStringGetMaxIndexType(type) << ", "
                     << offset << ")");
  GLuint result =
      GetMaxValueInBufferCHROMIUMHelper(buffer_id, count, type, offset);
  GPU_CLIENT_LOG("returned " << result);
  CheckGLError();
  return result;
}

void GLES2Implementation::DrawElements(GLenum mode,
                                       GLsizei count,
                                       GLenum type,
                                       const void* indices) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDrawElements("
                     << GLES2Util::GetStringDrawMode(mode) << ", " << count
                     << ", " << GLES2Util::GetStringIndexType(type) << ", "
                     << static_cast<const void*>(indices) << ")");
  DrawElementsImpl(mode, count, type, indices, "glDrawElements");
}

void GLES2Implementation::DrawRangeElements(GLenum mode,
                                            GLuint start,
                                            GLuint end,
                                            GLsizei count,
                                            GLenum type,
                                            const void* indices) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDrawRangeElements("
                     << GLES2Util::GetStringDrawMode(mode) << ", " << start
                     << ", " << end << ", " << count << ", "
                     << GLES2Util::GetStringIndexType(type) << ", "
                     << static_cast<const void*>(indices) << ")");
  if (end < start) {
    SetGLError(GL_INVALID_VALUE, "glDrawRangeElements", "end < start");
    return;
  }
  DrawElementsImpl(mode, count, type, indices, "glDrawRangeElements");
}

void GLES2Implementation::DrawElementsImpl(GLenum mode,
                                           GLsizei count,
                                           GLenum type,
                                           const void* indices,
                                           const char* func_name) {
  if (count < 0) {
    SetGLError(GL_INVALID_VALUE, func_name, "count < 0");
    return;
  }
  GLuint offset = ToGLuint(indices);
  if (count > 0) {
    if (vertex_array_object_manager_->bound_element_array_buffer() != 0 &&
        !ValidateOffset(func_name, reinterpret_cast<GLintptr>(indices))) {
      return;
    }
    offset = ToGLuint(indices);
  }
  helper_->DrawElements(mode, count, type, offset);
  CheckGLError();
}

void GLES2Implementation::Flush() {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glFlush()");
  flush_id_ = GenerateNextFlushId();
  // Insert the cmd to call glFlush
  helper_->Flush();
  FlushHelper();
}

// InterfaceBase implementation.
void GLES2Implementation::GenSyncTokenCHROMIUM(GLbyte* sync_token) {
  ImplementationBase::GenSyncToken(sync_token);
}
void GLES2Implementation::GenUnverifiedSyncTokenCHROMIUM(GLbyte* sync_token) {
  ImplementationBase::GenUnverifiedSyncToken(sync_token);
}
void GLES2Implementation::VerifySyncTokensCHROMIUM(GLbyte** sync_tokens,
                                                   GLsizei count) {
  ImplementationBase::VerifySyncTokens(sync_tokens, count);
}
void GLES2Implementation::WaitSyncTokenCHROMIUM(const GLbyte* sync_token) {
  ImplementationBase::WaitSyncToken(sync_token);
}
void GLES2Implementation::ShallowFlushCHROMIUM() {
  IssueShallowFlush();
}

// ImplementationBase implementation.
void GLES2Implementation::IssueShallowFlush() {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glShallowFlushCHROMIUM()");
  flush_id_ = GenerateNextFlushId();
  FlushHelper();
}

void GLES2Implementation::FlushHelper() {
  // Flush our command buffer
  // (tell the service to execute up to the flush cmd.)
  helper_->CommandBufferHelper::Flush();

  if (aggressively_free_resources_)
    FreeEverything();
}

void GLES2Implementation::OrderingBarrierCHROMIUM() {
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glOrderingBarrierCHROMIUM");
  // Flush command buffer at the GPU channel level.  May be implemented as
  // Flush().
  helper_->CommandBufferHelper::OrderingBarrier();
}

void GLES2Implementation::Finish() {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  flush_id_ = GenerateNextFlushId();
  FinishHelper();
}

void GLES2Implementation::ShallowFinishCHROMIUM() {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  TRACE_EVENT0("gpu", "GLES2::ShallowFinishCHROMIUM");
  flush_id_ = GenerateNextFlushId();
  // Flush our command buffer (tell the service to execute up to the flush cmd
  // and don't return until it completes).
  helper_->CommandBufferHelper::Finish();

  if (aggressively_free_resources_)
    FreeEverything();
}

void GLES2Implementation::FinishHelper() {
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glFinish()");
  TRACE_EVENT0("gpu", "GLES2::Finish");
  // Insert the cmd to call glFinish
  helper_->Finish();
  // Finish our command buffer
  // (tell the service to execute up to the Finish cmd and wait for it to
  // execute.)
  helper_->CommandBufferHelper::Finish();

  if (aggressively_free_resources_)
    FreeEverything();
}

GLuint GLES2Implementation::GetLastFlushIdCHROMIUM() {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetLastFlushIdCHROMIUM()");
  return flush_id_;
}

void GLES2Implementation::BindAttribLocation(GLuint program,
                                             GLuint index,
                                             const char* name) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBindAttribLocation(" << program
                     << ", " << index << ", " << name << ")");
  SetBucketAsString(kResultBucketId, name);
  helper_->BindAttribLocationBucket(program, index, kResultBucketId);
  helper_->SetBucketSize(kResultBucketId, 0);
  CheckGLError();
}

void GLES2Implementation::BindFragDataLocationEXT(GLuint program,
                                                  GLuint colorName,
                                                  const char* name) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBindFragDataLocationEXT("
                     << program << ", " << colorName << ", " << name << ")");
  SetBucketAsString(kResultBucketId, name);
  helper_->BindFragDataLocationEXTBucket(program, colorName, kResultBucketId);
  helper_->SetBucketSize(kResultBucketId, 0);
  CheckGLError();
}

void GLES2Implementation::BindFragDataLocationIndexedEXT(GLuint program,
                                                         GLuint colorName,
                                                         GLuint index,
                                                         const char* name) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBindFragDataLocationEXT("
                     << program << ", " << colorName << ", " << index << ", "
                     << name << ")");
  SetBucketAsString(kResultBucketId, name);
  helper_->BindFragDataLocationIndexedEXTBucket(program, colorName, index,
                                                kResultBucketId);
  helper_->SetBucketSize(kResultBucketId, 0);
  CheckGLError();
}

void GLES2Implementation::BindUniformLocationCHROMIUM(GLuint program,
                                                      GLint location,
                                                      const char* name) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBindUniformLocationCHROMIUM("
                     << program << ", " << location << ", " << name << ")");
  SetBucketAsString(kResultBucketId, name);
  helper_->BindUniformLocationCHROMIUMBucket(program, location,
                                             kResultBucketId);
  helper_->SetBucketSize(kResultBucketId, 0);
  CheckGLError();
}

void GLES2Implementation::GetVertexAttribPointerv(GLuint index,
                                                  GLenum pname,
                                                  void** ptr) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetVertexAttribPointer(" << index
                     << ", " << GLES2Util::GetStringVertexPointer(pname) << ", "
                     << static_cast<void*>(ptr) << ")");
  GPU_CLIENT_LOG_CODE_BLOCK(int32_t num_results = 1);
  if (!vertex_array_object_manager_->GetAttribPointer(index, pname, ptr)) {
    TRACE_EVENT0("gpu", "GLES2::GetVertexAttribPointerv");
    typedef cmds::GetVertexAttribPointerv::Result Result;
    auto result = GetResultAs<Result>();
    if (!result) {
      return;
    }
    result->SetNumResults(0);
    helper_->GetVertexAttribPointerv(index, pname, GetResultShmId(),
                                     result.offset());
    if (!WaitForCmd()) {
      return;
    }
    result->CopyResult(ptr);
    GPU_CLIENT_LOG_CODE_BLOCK(num_results = result->GetNumResults());
  }
  UNSAFE_TODO(GPU_CLIENT_LOG_CODE_BLOCK({
    for (int32_t i = 0; i < num_results; ++i) {
      GPU_CLIENT_LOG("  " << i << ": " << ptr[i]);
    }
  }));
  CheckGLError();
}

bool GLES2Implementation::DeleteProgramHelper(GLuint program) {
  if (!GetIdHandler(SharedIdNamespaces::kProgramsAndShaders)
           ->FreeIds(this, 1, &program,
                     &GLES2Implementation::DeleteProgramStub)) {
    SetGLError(GL_INVALID_VALUE, "glDeleteProgram",
               "id not created by this context.");
    return false;
  }
  if (program == current_program_) {
    current_program_ = 0;
  }
  return true;
}

void GLES2Implementation::DeleteProgramStub(GLsizei n, const GLuint* programs) {
  DCHECK_EQ(1, n);
  share_group_->program_info_manager()->DeleteInfo(programs[0]);
  helper_->DeleteProgram(programs[0]);
}

bool GLES2Implementation::DeleteShaderHelper(GLuint shader) {
  if (!GetIdHandler(SharedIdNamespaces::kProgramsAndShaders)
           ->FreeIds(this, 1, &shader,
                     &GLES2Implementation::DeleteShaderStub)) {
    SetGLError(GL_INVALID_VALUE, "glDeleteShader",
               "id not created by this context.");
    return false;
  }
  return true;
}

void GLES2Implementation::DeleteShaderStub(GLsizei n, const GLuint* shaders) {
  DCHECK_EQ(1, n);
  share_group_->program_info_manager()->DeleteInfo(shaders[0]);
  helper_->DeleteShader(shaders[0]);
}

void GLES2Implementation::DeleteSyncHelper(GLsync sync) {
  GLuint sync_uint = ToGLuint(sync);
  if (!GetIdHandler(SharedIdNamespaces::kSyncs)
           ->FreeIds(this, 1, &sync_uint,
                     &GLES2Implementation::DeleteSyncStub)) {
    SetGLError(GL_INVALID_VALUE, "glDeleteSync",
               "id not created by this context.");
  }
}

void GLES2Implementation::DeleteSyncStub(GLsizei n, const GLuint* syncs) {
  DCHECK_EQ(1, n);
  helper_->DeleteSync(syncs[0]);
}

GLint GLES2Implementation::GetAttribLocationHelper(GLuint program,
                                                   const char* name) {
  typedef cmds::GetAttribLocation::Result Result;
  SetBucketAsCString(kResultBucketId, name);
  auto result = GetResultAs<Result>();
  if (!result) {
    return -1;
  }
  *result = -1;
  helper_->GetAttribLocation(program, kResultBucketId, GetResultShmId(),
                             result.offset());
  if (!WaitForCmd()) {
    return -1;
  }
  helper_->SetBucketSize(kResultBucketId, 0);
  return *result;
}

GLint GLES2Implementation::GetAttribLocation(GLuint program, const char* name) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetAttribLocation(" << program
                     << ", " << name << ")");
  TRACE_EVENT0("gpu", "GLES2::GetAttribLocation");
  GLint loc = share_group_->program_info_manager()->GetAttribLocation(
      this, program, name);
  GPU_CLIENT_LOG("returned " << loc);
  CheckGLError();
  return loc;
}

GLint GLES2Implementation::GetUniformLocationHelper(GLuint program,
                                                    const char* name) {
  typedef cmds::GetUniformLocation::Result Result;
  SetBucketAsCString(kResultBucketId, name);
  auto result = GetResultAs<Result>();
  if (!result) {
    return -1;
  }
  *result = -1;
  helper_->GetUniformLocation(program, kResultBucketId, GetResultShmId(),
                              result.offset());
  if (!WaitForCmd()) {
    return -1;
  }
  helper_->SetBucketSize(kResultBucketId, 0);
  return *result;
}

GLint GLES2Implementation::GetUniformLocation(GLuint program,
                                              const char* name) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetUniformLocation(" << program
                     << ", " << name << ")");
  TRACE_EVENT0("gpu", "GLES2::GetUniformLocation");
  GLint loc = share_group_->program_info_manager()->GetUniformLocation(
      this, program, name);
  GPU_CLIENT_LOG("returned " << loc);
  CheckGLError();
  return loc;
}

bool GLES2Implementation::GetUniformIndicesHelper(GLuint program,
                                                  GLsizei count,
                                                  const char* const* names,
                                                  GLuint* indices) {
  if (!PackStringsToBucket(count, names, nullptr, "glGetUniformIndices")) {
    return false;
  }
  typedef cmds::GetUniformIndices::Result Result;
  auto result = GetResultAs<Result>();
  if (!result) {
    return false;
  }
  result->SetNumResults(0);
  helper_->GetUniformIndices(program, kResultBucketId, GetResultShmId(),
                             result.offset());
  if (!WaitForCmd()) {
    return false;
  }
  if (result->GetNumResults() != count) {
    return false;
  }
  result->CopyResult(indices);
  return true;
}

void GLES2Implementation::GetUniformIndices(GLuint program,
                                            GLsizei count,
                                            const char* const* names,
                                            GLuint* indices) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetUniformIndices(" << program
                     << ", " << count << ", " << names << ", " << indices
                     << ")");
  TRACE_EVENT0("gpu", "GLES2::GetUniformIndices");
  if (count < 0) {
    SetGLError(GL_INVALID_VALUE, "glGetUniformIndices", "count < 0");
    return;
  }
  if (count == 0) {
    return;
  }
  bool success = share_group_->program_info_manager()->GetUniformIndices(
      this, program, count, names, indices);
  if (success) {
    UNSAFE_TODO(GPU_CLIENT_LOG_CODE_BLOCK({
      for (GLsizei ii = 0; ii < count; ++ii) {
        GPU_CLIENT_LOG("  " << ii << ": " << indices[ii]);
      }
    }));
  }
  CheckGLError();
}

bool GLES2Implementation::GetProgramivHelper(GLuint program,
                                             GLenum pname,
                                             GLint* params) {
  bool got_value = share_group_->program_info_manager()->GetProgramiv(
      this, program, pname, params);
  GPU_CLIENT_LOG_CODE_BLOCK({
    if (got_value) {
      GPU_CLIENT_LOG("  0: " << *params);
    }
  });
  return got_value;
}

GLint GLES2Implementation::GetFragDataIndexEXTHelper(GLuint program,
                                                     const char* name) {
  typedef cmds::GetFragDataIndexEXT::Result Result;
  SetBucketAsCString(kResultBucketId, name);
  auto result = GetResultAs<Result>();
  if (!result) {
    return -1;
  }
  *result = -1;
  helper_->GetFragDataIndexEXT(program, kResultBucketId, GetResultShmId(),
                               result.offset());
  if (!WaitForCmd()) {
    return -1;
  }
  helper_->SetBucketSize(kResultBucketId, 0);
  return *result;
}

GLint GLES2Implementation::GetFragDataIndexEXT(GLuint program,
                                               const char* name) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetFragDataIndexEXT(" << program
                     << ", " << name << ")");
  TRACE_EVENT0("gpu", "GLES2::GetFragDataIndexEXT");
  GLint loc = share_group_->program_info_manager()->GetFragDataIndex(
      this, program, name);
  GPU_CLIENT_LOG("returned " << loc);
  CheckGLError();
  return loc;
}

GLint GLES2Implementation::GetFragDataLocationHelper(GLuint program,
                                                     const char* name) {
  typedef cmds::GetFragDataLocation::Result Result;
  SetBucketAsCString(kResultBucketId, name);
  auto result = GetResultAs<Result>();
  if (!result) {
    return -1;
  }
  *result = -1;
  helper_->GetFragDataLocation(program, kResultBucketId, GetResultShmId(),
                               result.offset());
  if (!WaitForCmd()) {
    return -1;
  }
  helper_->SetBucketSize(kResultBucketId, 0);
  return *result;
}

GLint GLES2Implementation::GetFragDataLocation(GLuint program,
                                               const char* name) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetFragDataLocation(" << program
                     << ", " << name << ")");
  TRACE_EVENT0("gpu", "GLES2::GetFragDataLocation");
  GLint loc = share_group_->program_info_manager()->GetFragDataLocation(
      this, program, name);
  GPU_CLIENT_LOG("returned " << loc);
  CheckGLError();
  return loc;
}

GLuint GLES2Implementation::GetUniformBlockIndexHelper(GLuint program,
                                                       const char* name) {
  typedef cmds::GetUniformBlockIndex::Result Result;
  SetBucketAsCString(kResultBucketId, name);
  auto result = GetResultAs<Result>();
  if (!result) {
    return GL_INVALID_INDEX;
  }
  *result = GL_INVALID_INDEX;
  helper_->GetUniformBlockIndex(program, kResultBucketId, GetResultShmId(),
                                result.offset());
  if (!WaitForCmd()) {
    return GL_INVALID_INDEX;
  }
  helper_->SetBucketSize(kResultBucketId, 0);
  return *result;
}

GLuint GLES2Implementation::GetUniformBlockIndex(GLuint program,
                                                 const char* name) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetUniformBlockIndex(" << program
                     << ", " << name << ")");
  TRACE_EVENT0("gpu", "GLES2::GetUniformBlockIndex");
  GLuint index = share_group_->program_info_manager()->GetUniformBlockIndex(
      this, program, name);
  GPU_CLIENT_LOG("returned " << index);
  CheckGLError();
  return index;
}

void GLES2Implementation::LinkProgram(GLuint program) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glLinkProgram(" << program << ")");
  helper_->LinkProgram(program);
  share_group_->program_info_manager()->CreateInfo(program);
  CheckGLError();
}

void GLES2Implementation::ShaderBinary(GLsizei n,
                                       const GLuint* shaders,
                                       GLenum binaryformat,
                                       const void* binary,
                                       GLsizei length) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glShaderBinary(" << n << ", "
                     << static_cast<const void*>(shaders) << ", "
                     << GLES2Util::GetStringEnum(binaryformat) << ", "
                     << static_cast<const void*>(binary) << ", " << length
                     << ")");
  if (n < 0) {
    SetGLError(GL_INVALID_VALUE, "glShaderBinary", "n < 0.");
    return;
  }
  if (length < 0) {
    SetGLError(GL_INVALID_VALUE, "glShaderBinary", "length < 0.");
    return;
  }
  // TODO(gman): ShaderBinary should use buckets.
  unsigned int shader_id_size = n * sizeof(*shaders);
  ScopedTransferBufferArray<GLint> buffer(shader_id_size + length, helper_,
                                          transfer_buffer_);
  if (!buffer.valid() || buffer.num_elements() != shader_id_size + length) {
    SetGLError(GL_OUT_OF_MEMORY, "glShaderBinary", "out of memory.");
    return;
  }
  void* shader_ids = buffer.elements();
  void* shader_data = UNSAFE_TODO(buffer.elements() + shader_id_size);
  UNSAFE_TODO(memcpy(shader_ids, shaders, shader_id_size));
  UNSAFE_TODO(memcpy(shader_data, binary, length));
  helper_->ShaderBinary(n, buffer.shm_id(), buffer.offset(), binaryformat,
                        buffer.shm_id(), buffer.offset() + shader_id_size,
                        length);
  CheckGLError();
}

void GLES2Implementation::PixelStorei(GLenum pname, GLint param) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glPixelStorei("
                     << GLES2Util::GetStringPixelStore(pname) << ", " << param
                     << ")");
  // We have to validate before caching these parameters because we use them
  // to compute image sizes on the client side.
  switch (pname) {
    case GL_PACK_ALIGNMENT:
    case GL_UNPACK_ALIGNMENT:
      if (param != 1 && param != 2 && param != 4 && param != 8) {
        SetGLError(GL_INVALID_VALUE, "glPixelStorei", "invalid param");
        return;
      }
      break;
    case GL_PACK_ROW_LENGTH:
    case GL_PACK_SKIP_PIXELS:
    case GL_PACK_SKIP_ROWS:
    case GL_UNPACK_IMAGE_HEIGHT:
    case GL_UNPACK_SKIP_IMAGES:
      if (gl_capabilities_.major_version < 3) {
        SetGLError(GL_INVALID_ENUM, "glPixelStorei", "invalid pname");
        return;
      }
      if (param < 0) {
        SetGLError(GL_INVALID_VALUE, "glPixelStorei", "invalid param");
        return;
      }
      break;
    case GL_UNPACK_ROW_LENGTH:
    case GL_UNPACK_SKIP_ROWS:
    case GL_UNPACK_SKIP_PIXELS:
      // These parameters are always enabled in ES2 by EXT_unpack_subimage.
      if (param < 0) {
        SetGLError(GL_INVALID_VALUE, "glPixelStorei", "invalid param");
        return;
      }
      break;
    default:
      SetGLError(GL_INVALID_ENUM, "glPixelStorei", "invalid pname");
      return;
  }
  // Do not send SKIP parameters to the service side.
  // Handle them on the client side.
  switch (pname) {
    case GL_PACK_ALIGNMENT:
      pack_alignment_ = param;
      break;
    case GL_PACK_ROW_LENGTH:
      pack_row_length_ = param;
      break;
    case GL_PACK_SKIP_PIXELS:
      pack_skip_pixels_ = param;
      return;
    case GL_PACK_SKIP_ROWS:
      pack_skip_rows_ = param;
      return;
    case GL_UNPACK_ALIGNMENT:
      unpack_alignment_ = param;
      break;
    case GL_UNPACK_ROW_LENGTH:
      unpack_row_length_ = param;
      if (gl_capabilities_.major_version < 3) {
        // In ES2 with EXT_unpack_subimage, it's handled on the client side
        // and there is no need to send it to the service side.
        return;
      }
      break;
    case GL_UNPACK_IMAGE_HEIGHT:
      unpack_image_height_ = param;
      break;
    case GL_UNPACK_SKIP_ROWS:
      unpack_skip_rows_ = param;
      return;
    case GL_UNPACK_SKIP_PIXELS:
      unpack_skip_pixels_ = param;
      return;
    case GL_UNPACK_SKIP_IMAGES:
      unpack_skip_images_ = param;
      return;
    default:
      NOTREACHED();
  }
  helper_->PixelStorei(pname, param);
  CheckGLError();
}

void GLES2Implementation::VertexAttribIPointer(GLuint index,
                                               GLint size,
                                               GLenum type,
                                               GLsizei stride,
                                               const void* ptr) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttribIPointer(" << index
                     << ", " << size << ", "
                     << GLES2Util::GetStringVertexAttribIType(type) << ", "
                     << stride << ", " << ptr << ")");
  // Record the info on the client side.
  if (!vertex_array_object_manager_->SetAttribPointer(
          bound_array_buffer_, index, size, type, GL_FALSE, stride, ptr,
          GL_TRUE)) {
    SetGLError(GL_INVALID_OPERATION, "glVertexAttribIPointer",
               "client side arrays are not allowed in vertex array objects.");
    return;
  }
  if (bound_array_buffer_ != 0) {
    // Only report NON client side buffers to the service.
    if (!ValidateOffset("glVertexAttribIPointer",
                        reinterpret_cast<GLintptr>(ptr))) {
      return;
    }
    helper_->VertexAttribIPointer(index, size, type, stride, ToGLuint(ptr));
  }
  CheckGLError();
}

void GLES2Implementation::VertexAttribPointer(GLuint index,
                                              GLint size,
                                              GLenum type,
                                              GLboolean normalized,
                                              GLsizei stride,
                                              const void* ptr) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttribPointer(" << index
                     << ", " << size << ", "
                     << GLES2Util::GetStringVertexAttribType(type) << ", "
                     << GLES2Util::GetStringBool(normalized) << ", " << stride
                     << ", " << ptr << ")");
  // Record the info on the client side.
  if (!vertex_array_object_manager_->SetAttribPointer(
          bound_array_buffer_, index, size, type, normalized, stride, ptr,
          GL_FALSE)) {
    SetGLError(GL_INVALID_OPERATION, "glVertexAttribPointer",
               "client side arrays are not allowed in vertex array objects.");
    return;
  }
  if (bound_array_buffer_ != 0) {
    // Only report NON client side buffers to the service.
    if (!ValidateOffset("glVertexAttribPointer",
                        reinterpret_cast<GLintptr>(ptr))) {
      return;
    }
    helper_->VertexAttribPointer(index, size, type, normalized, stride,
                                 ToGLuint(ptr));
  }
  CheckGLError();
}

void GLES2Implementation::VertexAttribDivisorANGLE(GLuint index,
                                                   GLuint divisor) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttribDivisorANGLE("
                     << index << ", " << divisor << ") ");
  // Record the info on the client side.
  vertex_array_object_manager_->SetAttribDivisor(index, divisor);
  helper_->VertexAttribDivisorANGLE(index, divisor);
  CheckGLError();
}

void GLES2Implementation::BufferDataHelper(GLenum target,
                                           GLsizeiptr size,
                                           const void* data,
                                           GLenum usage) {
  if (!ValidateSize("glBufferData", size))
    return;

#if defined(MEMORY_SANITIZER)
  // Do not upload uninitialized data. Even if it's not a bug, it can cause a
  // bogus MSan report during a readback later. This is because MSan doesn't
  // understand shared memory and would assume we were reading back the same
  // unintialized data.
  if (data)
    __msan_check_mem_is_initialized(data, size);
#endif

  GLuint buffer_id;
  if (GetBoundPixelTransferBuffer(target, "glBufferData", &buffer_id)) {
    if (!buffer_id) {
      return;
    }

    BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffer_id);
    if (buffer)
      RemoveTransferBuffer(buffer);

    // Create new buffer.
    buffer = buffer_tracker_->CreateBuffer(buffer_id, size);
    DCHECK(buffer);
    if (buffer->address() && data)
      UNSAFE_TODO(memcpy(buffer->address(), data, size));
    return;
  }

  if (IsReadbackUsage(usage)) {
    GLuint id = GetBoundBufferHelper(target);
    readback_buffer_shadow_tracker_->GetOrCreateBuffer(id, size);
  }

  // If there is no data just send BufferData
  if (size == 0 || !data) {
    helper_->BufferData(target, size, 0, 0, usage);
    return;
  }

  // See if we can send all at once.
  ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_);
  if (!buffer.valid()) {
    return;
  }

  if (buffer.size() >= static_cast<unsigned int>(size)) {
    UNSAFE_TODO(memcpy(buffer.address(), data, size));
    helper_->BufferData(target, size, buffer.shm_id(), buffer.offset(), usage);
    return;
  }

  // Make the buffer with BufferData then send via BufferSubData
  helper_->BufferData(target, size, 0, 0, usage);
  BufferSubDataHelperImpl(target, 0, size, data, &buffer);
  CheckGLError();
}

void GLES2Implementation::BufferData(GLenum target,
                                     GLsizeiptr size,
                                     const void* data,
                                     GLenum usage) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBufferData("
                     << GLES2Util::GetStringBufferTarget(target) << ", " << size
                     << ", " << static_cast<const void*>(data) << ", "
                     << GLES2Util::GetStringBufferUsage(usage) << ")");
  BufferDataHelper(target, size, data, usage);
  CheckGLError();
}

void GLES2Implementation::BufferSubDataHelper(GLenum target,
                                              GLintptr offset,
                                              GLsizeiptr size,
                                              const void* data) {
  if (size == 0) {
    return;
  }

  if (!ValidateSize("glBufferSubData", size) ||
      !ValidateOffset("glBufferSubData", offset)) {
    return;
  }

  GLuint buffer_id;
  if (GetBoundPixelTransferBuffer(target, "glBufferSubData", &buffer_id)) {
    if (!buffer_id) {
      return;
    }
    BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffer_id);
    if (!buffer) {
      SetGLError(GL_INVALID_VALUE, "glBufferSubData", "unknown buffer");
      return;
    }

    int32_t end = 0;
    int32_t buffer_size = buffer->size();
    if (!base::CheckAdd(offset, size).AssignIfValid(&end) ||
        end > buffer_size) {
      SetGLError(GL_INVALID_VALUE, "glBufferSubData", "out of range");
      return;
    }

    if (buffer->address() && data)
      UNSAFE_TODO(memcpy(static_cast<uint8_t*>(buffer->address()) + offset,
                         data, size));
    return;
  }

  ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_);
  BufferSubDataHelperImpl(target, offset, size, data, &buffer);
}

void GLES2Implementation::BufferSubDataHelperImpl(
    GLenum target,
    GLintptr offset,
    GLsizeiptr size,
    const void* data,
    ScopedTransferBufferPtr* buffer) {
  DCHECK(buffer);
  DCHECK_GT(size, 0);

  auto DoBufferSubData = [&](const std::array<uint32_t, 1>&,
                             uint32_t copy_offset, uint32_t) {
    helper_->BufferSubData(target, offset + copy_offset, buffer->size(),
                           buffer->shm_id(), buffer->offset());
    InvalidateReadbackBufferShadowDataCHROMIUM(GetBoundBufferHelper(target));
  };

  if (!TransferArraysAndExecute(size, buffer, DoBufferSubData,
                                static_cast<const int8_t*>(data))) {
    SetGLError(GL_OUT_OF_MEMORY, "glBufferSubData", "out of memory");
  }
}

void GLES2Implementation::BufferSubData(GLenum target,
                                        GLintptr offset,
                                        GLsizeiptr size,
                                        const void* data) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBufferSubData("
                     << GLES2Util::GetStringBufferTarget(target) << ", "
                     << offset << ", " << size << ", "
                     << static_cast<const void*>(data) << ")");
  BufferSubDataHelper(target, offset, size, data);
  CheckGLError();
}

void GLES2Implementation::MultiDrawArraysWEBGLHelper(GLenum mode,
                                                     const GLint* firsts,
                                                     const GLsizei* counts,
                                                     GLsizei drawcount) {
  DCHECK_GT(drawcount, 0);

  uint32_t buffer_size = ComputeCombinedCopySize(drawcount, firsts, counts);
  ScopedTransferBufferPtr buffer(buffer_size, helper_, transfer_buffer_);

  helper_->MultiDrawBeginCHROMIUM(drawcount);
  auto DoMultiDraw = [&](const std::array<uint32_t, 2>& offsets, uint32_t,
                         uint32_t copy_count) {
    helper_->MultiDrawArraysCHROMIUM(
        mode, buffer.shm_id(), buffer.offset() + offsets[0], buffer.shm_id(),
        buffer.offset() + offsets[1], copy_count);
  };
  if (!TransferArraysAndExecute(drawcount, &buffer, DoMultiDraw, firsts,
                                counts)) {
    SetGLError(GL_OUT_OF_MEMORY, "glMultiDrawArraysWEBGL", "out of memory");
  }
  helper_->MultiDrawEndCHROMIUM();
}

void GLES2Implementation::MultiDrawArraysInstancedWEBGLHelper(
    GLenum mode,
    const GLint* firsts,
    const GLsizei* counts,
    const GLsizei* instance_counts,
    GLsizei drawcount) {
  DCHECK_GT(drawcount, 0);

  uint32_t buffer_size =
      ComputeCombinedCopySize(drawcount, firsts, counts, instance_counts);
  ScopedTransferBufferPtr buffer(buffer_size, helper_, transfer_buffer_);

  helper_->MultiDrawBeginCHROMIUM(drawcount);
  auto DoMultiDraw = [&](const std::array<uint32_t, 3>& offsets, uint32_t,
                         uint32_t copy_count) {
    helper_->MultiDrawArraysInstancedCHROMIUM(
        mode, buffer.shm_id(), buffer.offset() + offsets[0], buffer.shm_id(),
        buffer.offset() + offsets[1], buffer.shm_id(),
        buffer.offset() + offsets[2], copy_count);
  };
  if (!TransferArraysAndExecute(drawcount, &buffer, DoMultiDraw, firsts, counts,
                                instance_counts)) {
    SetGLError(GL_OUT_OF_MEMORY, "glMultiDrawArraysInstancedWEBGL",
               "out of memory");
  }
  helper_->MultiDrawEndCHROMIUM();
}

void GLES2Implementation::MultiDrawArraysInstancedBaseInstanceWEBGLHelper(
    GLenum mode,
    const GLint* firsts,
    const GLsizei* counts,
    const GLsizei* instance_counts,
    const GLuint* baseinstances,
    GLsizei drawcount) {
  DCHECK_GT(drawcount, 0);

  uint32_t buffer_size = ComputeCombinedCopySize(
      drawcount, firsts, counts, instance_counts, baseinstances);
  ScopedTransferBufferPtr buffer(buffer_size, helper_, transfer_buffer_);

  helper_->MultiDrawBeginCHROMIUM(drawcount);
  auto DoMultiDraw = [&](const std::array<uint32_t, 4>& offsets, uint32_t,
                         uint32_t copy_count) {
    helper_->MultiDrawArraysInstancedBaseInstanceCHROMIUM(
        mode, buffer.shm_id(), buffer.offset() + offsets[0], buffer.shm_id(),
        buffer.offset() + offsets[1], buffer.shm_id(),
        buffer.offset() + offsets[2], buffer.shm_id(),
        buffer.offset() + offsets[3], copy_count);
  };
  if (!TransferArraysAndExecute(drawcount, &buffer, DoMultiDraw, firsts, counts,
                                instance_counts, baseinstances)) {
    SetGLError(GL_OUT_OF_MEMORY, "glMultiDrawArraysInstancedBaseInstanceWEBGL",
               "out of memory");
  }
  helper_->MultiDrawEndCHROMIUM();
}

void GLES2Implementation::MultiDrawElementsWEBGLHelper(GLenum mode,
                                                       const GLsizei* counts,
                                                       GLenum type,
                                                       const GLsizei* offsets,
                                                       GLsizei drawcount) {
  DCHECK_GT(drawcount, 0);

  uint32_t buffer_size = ComputeCombinedCopySize(drawcount, counts, offsets);
  ScopedTransferBufferPtr buffer(buffer_size, helper_, transfer_buffer_);

  helper_->MultiDrawBeginCHROMIUM(drawcount);
  auto DoMultiDraw = [&](const std::array<uint32_t, 2>& offsets, uint32_t,
                         uint32_t copy_count) {
    helper_->MultiDrawElementsCHROMIUM(
        mode, buffer.shm_id(), buffer.offset() + offsets[0], type,
        buffer.shm_id(), buffer.offset() + offsets[1], copy_count);
  };
  if (!TransferArraysAndExecute(drawcount, &buffer, DoMultiDraw, counts,
                                offsets)) {
    SetGLError(GL_OUT_OF_MEMORY, "glMultiDrawElementsWEBGL", "out of memory");
  }
  helper_->MultiDrawEndCHROMIUM();
}

void GLES2Implementation::MultiDrawElementsInstancedWEBGLHelper(
    GLenum mode,
    const GLsizei* counts,
    GLenum type,
    const GLsizei* offsets,
    const GLsizei* instance_counts,
    GLsizei drawcount) {
  DCHECK_GT(drawcount, 0);

  uint32_t buffer_size =
      ComputeCombinedCopySize(drawcount, counts, offsets, instance_counts);
  ScopedTransferBufferPtr buffer(buffer_size, helper_, transfer_buffer_);

  helper_->MultiDrawBeginCHROMIUM(drawcount);
  auto DoMultiDraw = [&](const std::array<uint32_t, 3>& offsets, uint32_t,
                         uint32_t copy_count) {
    helper_->MultiDrawElementsInstancedCHROMIUM(
        mode, buffer.shm_id(), buffer.offset() + offsets[0], type,
        buffer.shm_id(), buffer.offset() + offsets[1], buffer.shm_id(),
        buffer.offset() + offsets[2], copy_count);
  };
  if (!TransferArraysAndExecute(drawcount, &buffer, DoMultiDraw, counts,
                                offsets, instance_counts)) {
    SetGLError(GL_OUT_OF_MEMORY, "glMultiDrawElementsInstancedWEBGL",
               "out of memory");
  }
  helper_->MultiDrawEndCHROMIUM();
}

void GLES2Implementation::
    MultiDrawElementsInstancedBaseVertexBaseInstanceWEBGLHelper(
        GLenum mode,
        const GLsizei* counts,
        GLenum type,
        const GLsizei* offsets,
        const GLsizei* instance_counts,
        const GLint* basevertices,
        const GLuint* baseinstances,
        GLsizei drawcount) {
  DCHECK_GT(drawcount, 0);

  uint32_t buffer_size = ComputeCombinedCopySize(
      drawcount, counts, offsets, instance_counts, basevertices, baseinstances);
  ScopedTransferBufferPtr buffer(buffer_size, helper_, transfer_buffer_);

  helper_->MultiDrawBeginCHROMIUM(drawcount);
  auto DoMultiDraw = [&](const std::array<uint32_t, 5>& offsets, uint32_t,
                         uint32_t copy_count) {
    helper_->MultiDrawElementsInstancedBaseVertexBaseInstanceCHROMIUM(
        mode, buffer.shm_id(), buffer.offset() + offsets[0], type,
        buffer.shm_id(), buffer.offset() + offsets[1], buffer.shm_id(),
        buffer.offset() + offsets[2], buffer.shm_id(),
        buffer.offset() + offsets[3], buffer.shm_id(),
        buffer.offset() + offsets[4], copy_count);
  };
  if (!TransferArraysAndExecute(drawcount, &buffer, DoMultiDraw, counts,
                                offsets, instance_counts, basevertices,
                                baseinstances)) {
    SetGLError(GL_OUT_OF_MEMORY,
               "glMultiDrawElementsInstancedBaseVertexBaseInstanceWEBGL",
               "out of memory");
  }
  helper_->MultiDrawEndCHROMIUM();
}

void GLES2Implementation::MultiDrawArraysWEBGL(GLenum mode,
                                               const GLint* firsts,
                                               const GLsizei* counts,
                                               GLsizei drawcount) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glMultiDrawArraysWEBGL("
                     << GLES2Util::GetStringDrawMode(mode) << ", " << firsts
                     << ", " << counts << ", " << drawcount << ")");
  if (drawcount < 0) {
    SetGLError(GL_INVALID_VALUE, "glMultiDrawArraysWEBGL", "drawcount < 0");
    return;
  }
  if (drawcount == 0) {
    return;
  }
  MultiDrawArraysWEBGLHelper(mode, firsts, counts, drawcount);
  CheckGLError();
}

void GLES2Implementation::MultiDrawArraysInstancedWEBGL(
    GLenum mode,
    const GLint* firsts,
    const GLsizei* counts,
    const GLsizei* instance_counts,
    GLsizei drawcount) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glMultiDrawArraysInstancedWEBGL("
                     << GLES2Util::GetStringDrawMode(mode) << ", " << firsts
                     << ", " << counts << ", " << instance_counts << ", "
                     << drawcount << ")");
  if (drawcount < 0) {
    SetGLError(GL_INVALID_VALUE, "glMultiDrawArraysWEBGLInstanced",
               "drawcount < 0");
    return;
  }
  if (drawcount == 0) {
    return;
  }
  MultiDrawArraysInstancedWEBGLHelper(mode, firsts, counts, instance_counts,
                                      drawcount);
  CheckGLError();
}

void GLES2Implementation::MultiDrawArraysInstancedBaseInstanceWEBGL(
    GLenum mode,
    const GLint* firsts,
    const GLsizei* counts,
    const GLsizei* instance_counts,
    const GLuint* baseinstances,
    GLsizei drawcount) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix()
                     << "] glMultiDrawArraysInstancedBaseInstanceWEBGL("
                     << GLES2Util::GetStringDrawMode(mode) << ", " << firsts
                     << ", " << counts << ", " << instance_counts << ", "
                     << baseinstances << ", " << drawcount << ")");
  if (drawcount < 0) {
    SetGLError(GL_INVALID_VALUE, "glMultiDrawArraysInstancedBaseInstanceWEBGL",
               "drawcount < 0");
    return;
  }
  if (drawcount == 0) {
    return;
  }
  MultiDrawArraysInstancedBaseInstanceWEBGLHelper(
      mode, firsts, counts, instance_counts, baseinstances, drawcount);
  CheckGLError();
}

void GLES2Implementation::MultiDrawElementsWEBGL(GLenum mode,
                                                 const GLsizei* counts,
                                                 GLenum type,
                                                 const GLsizei* offsets,
                                                 GLsizei drawcount) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glMultiDrawElementsWEBGL("
                     << GLES2Util::GetStringDrawMode(mode) << ", " << counts
                     << ", " << GLES2Util::GetStringIndexType(type) << ", "
                     << offsets << ", " << drawcount << ")");
  if (drawcount < 0) {
    SetGLError(GL_INVALID_VALUE, "glMultiDrawElementsWEBGL", "drawcount < 0");
    return;
  }
  if (drawcount == 0) {
    return;
  }
  // This is for an extension for WebGL which doesn't support client side arrays
  if (vertex_array_object_manager_->bound_element_array_buffer() == 0) {
    SetGLError(GL_INVALID_OPERATION, "glMultiDrawElementsWEBGL",
               "No element array buffer");
    return;
  }
  MultiDrawElementsWEBGLHelper(mode, counts, type, offsets, drawcount);
  CheckGLError();
}

void GLES2Implementation::MultiDrawElementsInstancedWEBGL(
    GLenum mode,
    const GLsizei* counts,
    GLenum type,
    const GLsizei* offsets,
    const GLsizei* instance_counts,
    GLsizei drawcount) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glMultiDrawElementsInstancedWEBGL("
                     << GLES2Util::GetStringDrawMode(mode) << ", " << counts
                     << ", " << GLES2Util::GetStringIndexType(type) << ", "
                     << offsets << ", " << instance_counts << ", " << drawcount
                     << ")");
  if (drawcount < 0) {
    SetGLError(GL_INVALID_VALUE, "glMultiDrawElementsInstancedWEBGL",
               "drawcount < 0");
    return;
  }
  if (drawcount == 0) {
    return;
  }
  // This is for an extension for WebGL which doesn't support client side arrays
  if (vertex_array_object_manager_->bound_element_array_buffer() == 0) {
    SetGLError(GL_INVALID_OPERATION, "glMultiDrawElementsInstancedWEBGL",
               "No element array buffer");
    return;
  }
  MultiDrawElementsInstancedWEBGLHelper(mode, counts, type, offsets,
                                        instance_counts, drawcount);
  CheckGLError();
}

void GLES2Implementation::MultiDrawElementsInstancedBaseVertexBaseInstanceWEBGL(
    GLenum mode,
    const GLsizei* counts,
    GLenum type,
    const GLsizei* offsets,
    const GLsizei* instance_counts,
    const GLint* basevertices,
    const GLuint* baseinstances,
    GLsizei drawcount) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG(
      "[" << GetLogPrefix()
          << "] glMultiDrawElementsInstancedBaseVertexBaseInstanceWEBGL("
          << GLES2Util::GetStringDrawMode(mode) << ", " << counts << ", "
          << GLES2Util::GetStringIndexType(type) << ", " << offsets << ", "
          << instance_counts << ", " << basevertices << ", " << baseinstances
          << drawcount << ")");
  if (drawcount < 0) {
    SetGLError(GL_INVALID_VALUE, "glMultiDrawElementsInstancedWEBGL",
               "drawcount < 0");
    return;
  }
  if (drawcount == 0) {
    return;
  }
  // This is for an extension for WebGL which doesn't support client side arrays
  if (vertex_array_object_manager_->bound_element_array_buffer() == 0) {
    SetGLError(GL_INVALID_OPERATION,
               "glMultiDrawElementsInstancedBaseVertexBaseInstanceWEBGL",
               "No element array buffer");
    return;
  }
  MultiDrawElementsInstancedBaseVertexBaseInstanceWEBGLHelper(
      mode, counts, type, offsets, instance_counts, basevertices, baseinstances,
      drawcount);
  CheckGLError();
}

void GLES2Implementation::RemoveTransferBuffer(BufferTracker::Buffer* buffer) {
  int32_t token = buffer->last_usage_token();

  if (token) {
    if (helper_->HasTokenPassed(token))
      buffer_tracker_->Free(buffer);
    else
      buffer_tracker_->FreePendingToken(buffer, token);
  } else {
    buffer_tracker_->Free(buffer);
  }

  buffer_tracker_->RemoveBuffer(buffer->id());
}

bool GLES2Implementation::GetBoundPixelTransferBuffer(GLenum target,
                                                      const char* function_name,
                                                      GLuint* buffer_id) {
  *buffer_id = 0;

  switch (target) {
    case GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM:
      *buffer_id = bound_pixel_pack_transfer_buffer_id_;
      break;
    case GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM:
      *buffer_id = bound_pixel_unpack_transfer_buffer_id_;
      break;
    default:
      // Unknown target
      return false;
  }
  if (!*buffer_id) {
    SetGLError(GL_INVALID_OPERATION, function_name, "no buffer bound");
  }
  return true;
}

BufferTracker::Buffer* GLES2Implementation::GetBoundPixelTransferBufferIfValid(
    GLuint buffer_id,
    const char* function_name,
    GLuint offset,
    GLsizei size) {
  DCHECK(buffer_id);
  BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffer_id);
  if (!buffer) {
    SetGLError(GL_INVALID_OPERATION, function_name, "invalid buffer");
    return nullptr;
  }
  if (buffer->mapped()) {
    SetGLError(GL_INVALID_OPERATION, function_name, "buffer mapped");
    return nullptr;
  }
  base::CheckedNumeric<uint32_t> buffer_offset = buffer->shm_offset();
  buffer_offset += offset;
  if (!buffer_offset.IsValid()) {
    SetGLError(GL_INVALID_VALUE, function_name, "offset to large");
    return nullptr;
  }
  base::CheckedNumeric<uint32_t> required_size = offset;
  required_size += size;
  if (!required_size.IsValid() ||
      buffer->size() < required_size.ValueOrDefault(0)) {
    SetGLError(GL_INVALID_VALUE, function_name, "unpack size to large");
    return nullptr;
  }
  return buffer;
}

void GLES2Implementation::InvalidateReadbackBufferShadowDataCHROMIUM(
    GLuint buffer_id) {
  readback_buffer_shadow_tracker_->OnBufferWrite(buffer_id);
}

void GLES2Implementation::CompressedTexImage2D(GLenum target,
                                               GLint level,
                                               GLenum internalformat,
                                               GLsizei width,
                                               GLsizei height,
                                               GLint border,
                                               GLsizei image_size,
                                               const void* data) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG(
      "[" << GetLogPrefix() << "] glCompressedTexImage2D("
          << GLES2Util::GetStringTextureTarget(target) << ", " << level << ", "
          << GLES2Util::GetStringCompressedTextureFormat(internalformat) << ", "
          << width << ", " << height << ", " << border << ", " << image_size
          << ", " << static_cast<const void*>(data) << ")");
  if (width < 0 || height < 0 || level < 0) {
    SetGLError(GL_INVALID_VALUE, "glCompressedTexImage2D", "dimension < 0");
    return;
  }
  if (border != 0) {
    SetGLError(GL_INVALID_VALUE, "glCompressedTexImage2D", "border != 0");
    return;
  }
  // If there's a pixel unpack buffer bound use it when issuing
  // CompressedTexImage2D.
  if (bound_pixel_unpack_transfer_buffer_id_) {
    GLuint offset = ToGLuint(data);
    BufferTracker::Buffer* buffer = GetBoundPixelTransferBufferIfValid(
        bound_pixel_unpack_transfer_buffer_id_, "glCompressedTexImage2D",
        offset, image_size);
    if (buffer && buffer->shm_id() != -1) {
      helper_->CompressedTexImage2D(target, level, internalformat, width,
                                    height, image_size, buffer->shm_id(),
                                    buffer->shm_offset() + offset);
      buffer->set_last_usage_token(helper_->InsertToken());
    }
    return;
  }
  if (bound_pixel_unpack_buffer_) {
    helper_->CompressedTexImage2D(target, level, internalformat, width, height,
                                  image_size, 0, ToGLuint(data));
  } else if (data) {
    SetBucketContents(kResultBucketId, data, image_size);
    helper_->CompressedTexImage2DBucket(target, level, internalformat, width,
                                        height, kResultBucketId);
    // Free the bucket. This is not required but it does free up the memory.
    // and we don't have to wait for the result so from the client's perspective
    // it's cheap.
    helper_->SetBucketSize(kResultBucketId, 0);
  } else {
    helper_->CompressedTexImage2D(target, level, internalformat, width, height,
                                  image_size, 0, 0);
  }
  CheckGLError();
}

void GLES2Implementation::CompressedTexSubImage2D(GLenum target,
                                                  GLint level,
                                                  GLint xoffset,
                                                  GLint yoffset,
                                                  GLsizei width,
                                                  GLsizei height,
                                                  GLenum format,
                                                  GLsizei image_size,
                                                  const void* data) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG(
      "[" << GetLogPrefix() << "] glCompressedTexSubImage2D("
          << GLES2Util::GetStringTextureTarget(target) << ", " << level << ", "
          << xoffset << ", " << yoffset << ", " << width << ", " << height
          << ", " << GLES2Util::GetStringCompressedTextureFormat(format) << ", "
          << image_size << ", " << static_cast<const void*>(data) << ")");
  if (width < 0 || height < 0 || level < 0) {
    SetGLError(GL_INVALID_VALUE, "glCompressedTexSubImage2D", "dimension < 0");
    return;
  }
  // If there's a pixel unpack buffer bound use it when issuing
  // CompressedTexSubImage2D.
  if (bound_pixel_unpack_transfer_buffer_id_) {
    GLuint offset = ToGLuint(data);
    BufferTracker::Buffer* buffer = GetBoundPixelTransferBufferIfValid(
        bound_pixel_unpack_transfer_buffer_id_, "glCompressedTexSubImage2D",
        offset, image_size);
    if (buffer && buffer->shm_id() != -1) {
      helper_->CompressedTexSubImage2D(
          target, level, xoffset, yoffset, width, height, format, image_size,
          buffer->shm_id(), buffer->shm_offset() + offset);
      buffer->set_last_usage_token(helper_->InsertToken());
      CheckGLError();
    }
    return;
  }
  if (bound_pixel_unpack_buffer_) {
    helper_->CompressedTexSubImage2D(target, level, xoffset, yoffset, width,
                                     height, format, image_size, 0,
                                     ToGLuint(data));
  } else if (data) {
    SetBucketContents(kResultBucketId, data, image_size);
    helper_->CompressedTexSubImage2DBucket(target, level, xoffset, yoffset,
                                           width, height, format,
                                           kResultBucketId);
    // Free the bucket. This is not required but it does free up the memory.
    // and we don't have to wait for the result so from the client's perspective
    // it's cheap.
    helper_->SetBucketSize(kResultBucketId, 0);
  } else {
    helper_->CompressedTexSubImage2D(target, level, xoffset, yoffset, width,
                                     height, format, image_size, 0, 0);
  }
  CheckGLError();
}

void GLES2Implementation::CompressedTexImage3D(GLenum target,
                                               GLint level,
                                               GLenum internalformat,
                                               GLsizei width,
                                               GLsizei height,
                                               GLsizei depth,
                                               GLint border,
                                               GLsizei image_size,
                                               const void* data) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG(
      "[" << GetLogPrefix() << "] glCompressedTexImage3D("
          << GLES2Util::GetStringTexture3DTarget(target) << ", " << level
          << ", " << GLES2Util::GetStringCompressedTextureFormat(internalformat)
          << ", " << width << ", " << height << ", " << depth << ", " << border
          << ", " << image_size << ", " << static_cast<const void*>(data)
          << ")");
  if (width < 0 || height < 0 || depth < 0 || level < 0) {
    SetGLError(GL_INVALID_VALUE, "glCompressedTexImage3D", "dimension < 0");
    return;
  }
  if (border != 0) {
    SetGLError(GL_INVALID_VALUE, "glCompressedTexImage3D", "border != 0");
    return;
  }
  // If there's a pixel unpack buffer bound use it when issuing
  // CompressedTexImage3D.
  if (bound_pixel_unpack_transfer_buffer_id_) {
    GLuint offset = ToGLuint(data);
    BufferTracker::Buffer* buffer = GetBoundPixelTransferBufferIfValid(
        bound_pixel_unpack_transfer_buffer_id_, "glCompressedTexImage3D",
        offset, image_size);
    if (buffer && buffer->shm_id() != -1) {
      helper_->CompressedTexImage3D(target, level, internalformat, width,
                                    height, depth, image_size, buffer->shm_id(),
                                    buffer->shm_offset() + offset);
      buffer->set_last_usage_token(helper_->InsertToken());
    }
    return;
  }
  if (bound_pixel_unpack_buffer_) {
    helper_->CompressedTexImage3D(target, level, internalformat, width, height,
                                  depth, image_size, 0, ToGLuint(data));
  } else if (data) {
    SetBucketContents(kResultBucketId, data, image_size);
    helper_->CompressedTexImage3DBucket(target, level, internalformat, width,
                                        height, depth, kResultBucketId);
    // Free the bucket. This is not required but it does free up the memory.
    // and we don't have to wait for the result so from the client's perspective
    // it's cheap.
    helper_->SetBucketSize(kResultBucketId, 0);
  } else {
    helper_->CompressedTexImage3D(target, level, internalformat, width, height,
                                  depth, image_size, 0, 0);
  }
  CheckGLError();
}

void GLES2Implementation::CompressedTexSubImage3D(GLenum target,
                                                  GLint level,
                                                  GLint xoffset,
                                                  GLint yoffset,
                                                  GLint zoffset,
                                                  GLsizei width,
                                                  GLsizei height,
                                                  GLsizei depth,
                                                  GLenum format,
                                                  GLsizei image_size,
                                                  const void* data) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG(
      "[" << GetLogPrefix() << "] glCompressedTexSubImage3D("
          << GLES2Util::GetStringTextureTarget(target) << ", " << level << ", "
          << xoffset << ", " << yoffset << ", " << zoffset << ", " << width
          << ", " << height << ", " << depth << ", "
          << GLES2Util::GetStringCompressedTextureFormat(format) << ", "
          << image_size << ", " << static_cast<const void*>(data) << ")");
  if (width < 0 || height < 0 || depth < 0 || level < 0) {
    SetGLError(GL_INVALID_VALUE, "glCompressedTexSubImage3D", "dimension < 0");
    return;
  }
  // If there's a pixel unpack buffer bound use it when issuing
  // CompressedTexSubImage3D.
  if (bound_pixel_unpack_transfer_buffer_id_) {
    GLuint offset = ToGLuint(data);
    BufferTracker::Buffer* buffer = GetBoundPixelTransferBufferIfValid(
        bound_pixel_unpack_transfer_buffer_id_, "glCompressedTexSubImage3D",
        offset, image_size);
    if (buffer && buffer->shm_id() != -1) {
      helper_->CompressedTexSubImage3D(
          target, level, xoffset, yoffset, zoffset, width, height, depth,
          format, image_size, buffer->shm_id(), buffer->shm_offset() + offset);
      buffer->set_last_usage_token(helper_->InsertToken());
      CheckGLError();
    }
    return;
  }
  if (bound_pixel_unpack_buffer_) {
    helper_->CompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset,
                                     width, height, depth, format, image_size,
                                     0, ToGLuint(data));
  } else if (data) {
    SetBucketContents(kResultBucketId, data, image_size);
    helper_->CompressedTexSubImage3DBucket(target, level, xoffset, yoffset,
                                           zoffset, width, height, depth,
                                           format, kResultBucketId);
    // Free the bucket. This is not required but it does free up the memory.
    // and we don't have to wait for the result so from the client's perspective
    // it's cheap.
    helper_->SetBucketSize(kResultBucketId, 0);
  } else {
    helper_->CompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset,
                                     width, height, depth, format, image_size,
                                     0, 0);
  }
  CheckGLError();
}

PixelStoreParams GLES2Implementation::GetUnpackParameters(Dimension dimension) {
  PixelStoreParams params;
  params.alignment = unpack_alignment_;
  params.row_length = unpack_row_length_;
  params.skip_pixels = unpack_skip_pixels_;
  params.skip_rows = unpack_skip_rows_;
  if (dimension == k3D) {
    params.image_height = unpack_image_height_;
    params.skip_images = unpack_skip_images_;
  }
  return params;
}

void GLES2Implementation::TexImage2D(GLenum target,
                                     GLint level,
                                     GLint internalformat,
                                     GLsizei width,
                                     GLsizei height,
                                     GLint border,
                                     GLenum format,
                                     GLenum type,
                                     const void* pixels) {
  const char* func_name = "glTexImage2D";
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG(
      "[" << GetLogPrefix() << "] glTexImage2D("
          << GLES2Util::GetStringTextureTarget(target) << ", " << level << ", "
          << GLES2Util::GetStringTextureInternalFormat(internalformat) << ", "
          << width << ", " << height << ", " << border << ", "
          << GLES2Util::GetStringTextureFormat(format) << ", "
          << GLES2Util::GetStringPixelType(type) << ", "
          << static_cast<const void*>(pixels) << ")");
  if (level < 0 || height < 0 || width < 0) {
    SetGLError(GL_INVALID_VALUE, func_name, "dimension < 0");
    return;
  }
  if (border != 0) {
    SetGLError(GL_INVALID_VALUE, func_name, "border != 0");
    return;
  }
  if ((bound_pixel_unpack_buffer_ || pixels) &&
      (unpack_skip_pixels_ + width >
       (unpack_row_length_ ? unpack_row_length_ : width))) {
    // This is WebGL 2 specific constraints, but we do it for all ES3 contexts.
    SetGLError(GL_INVALID_OPERATION, func_name,
               "invalid unpack params combination");
    return;
  }

  uint32_t size;
  uint32_t unpadded_row_size;
  uint32_t padded_row_size;
  uint32_t skip_size;
  PixelStoreParams params = GetUnpackParameters(k2D);

  if (!GLES2Util::ComputeImageDataSizesES3(
          width, height, 1, format, type, params, &size, &unpadded_row_size,
          &padded_row_size, &skip_size, nullptr)) {
    SetGLError(GL_INVALID_VALUE, func_name, "image size too large");
    return;
  }
  const uint32_t client_pixels_size = size;

  if (bound_pixel_unpack_buffer_) {
    base::CheckedNumeric<uint32_t> offset = ToGLuint(pixels);
    offset += skip_size;
    if (!offset.IsValid()) {
      SetGLError(GL_INVALID_VALUE, func_name, "skip size too large");
      return;
    }
    helper_->TexImage2D(target, level, internalformat, width, height, format,
                        type, 0, offset.ValueOrDefault(0));
    CheckGLError();
    return;
  }

  // If there's a pixel unpack buffer bound use it when issuing TexImage2D.
  if (bound_pixel_unpack_transfer_buffer_id_) {
    if (unpack_row_length_ > 0 || unpack_image_height_ > 0 ||
        unpack_skip_pixels_ > 0 || unpack_skip_rows_ > 0 ||
        unpack_skip_images_ > 0) {
      SetGLError(GL_INVALID_OPERATION, func_name,
                 "No ES3 pack parameters with pixel unpack transfer buffer.");
      return;
    }
    DCHECK_EQ(0u, skip_size);
    GLuint offset = ToGLuint(pixels);
    BufferTracker::Buffer* buffer = GetBoundPixelTransferBufferIfValid(
        bound_pixel_unpack_transfer_buffer_id_, func_name, offset, size);
    if (buffer && buffer->shm_id() != -1) {
      helper_->TexImage2D(target, level, internalformat, width, height, format,
                          type, buffer->shm_id(),
                          buffer->shm_offset() + offset);
      buffer->set_last_usage_token(helper_->InsertToken());
      CheckGLError();
    }
    return;
  }

  // If there's no data just issue TexImage2D
  if (!pixels || width == 0 || height == 0) {
    helper_->TexImage2D(target, level, internalformat, width, height, format,
                        type, 0, 0);
    CheckGLError();
    return;
  }

  // Compute the advance bytes per row on the service side.
  // Note |size| is recomputed here if needed.
  uint32_t service_padded_row_size;
  if (unpack_row_length_ > 0 && unpack_row_length_ != width) {
    // All parameters have been applied to the data that are sent to the
    // service side except UNPACK_ALIGNMENT.
    PixelStoreParams service_params;
    service_params.alignment = unpack_alignment_;
    if (!GLES2Util::ComputeImageDataSizesES3(
            width, height, 1, format, type, service_params, &size, nullptr,
            &service_padded_row_size, nullptr, nullptr)) {
      SetGLError(GL_INVALID_VALUE, func_name, "image size too large");
      return;
    }
  } else {
    service_padded_row_size = padded_row_size;
  }

  // advance pixels pointer past the skip rows and skip pixels
  auto pixels_span = UNSAFE_TODO(base::span<const uint8_t>(
      static_cast<const uint8_t*>(pixels) + skip_size, client_pixels_size));

  // Check if we can send it all at once.
  int32_t shm_id = 0;
  uint32_t shm_offset = 0;
  base::span<uint8_t> buffer_span;

  ScopedTransferBufferPtr transfer_alloc(size, helper_, transfer_buffer_);
  ScopedMappedMemoryPtr mapped_alloc(0, helper_, mapped_memory_.get());

  if (transfer_alloc.valid() && transfer_alloc.size() >= size) {
    shm_id = transfer_alloc.shm_id();
    shm_offset = transfer_alloc.offset();
    buffer_span = transfer_alloc.as_byte_span();
  } else if (size < max_extra_transfer_buffer_size_) {
    mapped_alloc.Reset(size);
    if (mapped_alloc.valid()) {
      transfer_alloc.Discard();

      mapped_alloc.SetFlushAfterRelease(true);
      shm_id = mapped_alloc.shm_id();
      shm_offset = mapped_alloc.offset();
      buffer_span = mapped_alloc.as_byte_span();
    }
  }

  if (!buffer_span.empty()) {
    CopyRectToBuffer(pixels_span, height, unpadded_row_size, padded_row_size,
                     buffer_span, service_padded_row_size);
    helper_->TexImage2D(target, level, internalformat, width, height, format,
                        type, shm_id, shm_offset);
    CheckGLError();
    return;
  }

  // No, so send it using TexSubImage2D.
  helper_->TexImage2D(target, level, internalformat, width, height, format,
                      type, 0, 0);
  TexSubImage2DImpl(target, level, 0, 0, width, height, format, type,
                    unpadded_row_size, pixels_span, padded_row_size, GL_TRUE,
                    &transfer_alloc, service_padded_row_size);
  CheckGLError();
}

void GLES2Implementation::TexImage3D(GLenum target,
                                     GLint level,
                                     GLint internalformat,
                                     GLsizei width,
                                     GLsizei height,
                                     GLsizei depth,
                                     GLint border,
                                     GLenum format,
                                     GLenum type,
                                     const void* pixels) {
  const char* func_name = "glTexImage3D";
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG(
      "[" << GetLogPrefix() << "] glTexImage3D("
          << GLES2Util::GetStringTextureTarget(target) << ", " << level << ", "
          << GLES2Util::GetStringTextureInternalFormat(internalformat) << ", "
          << width << ", " << height << ", " << depth << ", " << border << ", "
          << GLES2Util::GetStringTextureFormat(format) << ", "
          << GLES2Util::GetStringPixelType(type) << ", "
          << static_cast<const void*>(pixels) << ")");
  if (level < 0 || height < 0 || width < 0 || depth < 0) {
    SetGLError(GL_INVALID_VALUE, func_name, "dimension < 0");
    return;
  }
  if (border != 0) {
    SetGLError(GL_INVALID_VALUE, func_name, "border != 0");
    return;
  }
  if ((bound_pixel_unpack_buffer_ || pixels) &&
      ((unpack_skip_pixels_ + width >
        (unpack_row_length_ ? unpack_row_length_ : width)) ||
       (unpack_skip_rows_ + height >
        (unpack_image_height_ ? unpack_image_height_ : height)))) {
    // This is WebGL 2 specific constraints, but we do it for all ES3 contexts.
    SetGLError(GL_INVALID_OPERATION, func_name,
               "invalid unpack params combination");
    return;
  }

  uint32_t size;
  uint32_t unpadded_row_size;
  uint32_t padded_row_size;
  uint32_t skip_size;
  PixelStoreParams params = GetUnpackParameters(k3D);
  if (!GLES2Util::ComputeImageDataSizesES3(
          width, height, depth, format, type, params, &size, &unpadded_row_size,
          &padded_row_size, &skip_size, nullptr)) {
    SetGLError(GL_INVALID_VALUE, func_name, "image size too large");
    return;
  }
  const uint32_t client_pixels_size = size;

  if (bound_pixel_unpack_buffer_) {
    base::CheckedNumeric<uint32_t> offset = ToGLuint(pixels);
    offset += skip_size;
    if (!offset.IsValid()) {
      SetGLError(GL_INVALID_VALUE, func_name, "skip size too large");
      return;
    }
    helper_->TexImage3D(target, level, internalformat, width, height, depth,
                        format, type, 0, offset.ValueOrDefault(0));
    CheckGLError();
    return;
  }

  // If there's a pixel unpack buffer bound use it when issuing TexImage3D.
  if (bound_pixel_unpack_transfer_buffer_id_) {
    if (unpack_row_length_ > 0 || unpack_image_height_ > 0 ||
        unpack_skip_pixels_ > 0 || unpack_skip_rows_ > 0 ||
        unpack_skip_images_ > 0) {
      SetGLError(GL_INVALID_OPERATION, func_name,
                 "No ES3 pack parameters with pixel unpack transfer buffer.");
      return;
    }
    DCHECK_EQ(0u, skip_size);
    GLuint offset = ToGLuint(pixels);
    BufferTracker::Buffer* buffer = GetBoundPixelTransferBufferIfValid(
        bound_pixel_unpack_transfer_buffer_id_, func_name, offset, size);
    if (buffer && buffer->shm_id() != -1) {
      helper_->TexImage3D(target, level, internalformat, width, height, depth,
                          format, type, buffer->shm_id(),
                          buffer->shm_offset() + offset);
      buffer->set_last_usage_token(helper_->InsertToken());
      CheckGLError();
    }
    return;
  }

  // If there's no data just issue TexImage3D
  if (!pixels || width == 0 || height == 0 || depth == 0) {
    helper_->TexImage3D(target, level, internalformat, width, height, depth,
                        format, type, 0, 0);
    CheckGLError();
    return;
  }

  // Compute the advance bytes per row on the service side.
  // Note |size| is recomputed here if needed.
  uint32_t service_padded_row_size;
  if ((unpack_row_length_ > 0 && unpack_row_length_ != width) ||
      (unpack_image_height_ > 0 && unpack_image_height_ != height)) {
    // All parameters have been applied to the data that are sent to the
    // service side except UNPACK_ALIGNMENT.
    PixelStoreParams service_params;
    service_params.alignment = unpack_alignment_;
    if (!GLES2Util::ComputeImageDataSizesES3(
            width, height, depth, format, type, service_params, &size, nullptr,
            &service_padded_row_size, nullptr, nullptr)) {
      SetGLError(GL_INVALID_VALUE, func_name, "image size too large");
      return;
    }
  } else {
    service_padded_row_size = padded_row_size;
  }
  uint32_t src_height =
      unpack_image_height_ > 0 ? unpack_image_height_ : height;

  // advance pixels pointer past the skip images/rows/pixels
  auto pixels_span = UNSAFE_TODO(base::span<const uint8_t>(
      static_cast<const uint8_t*>(pixels) + skip_size, client_pixels_size));

  // Check if we can send it all at once.
  int32_t shm_id = 0;
  uint32_t shm_offset = 0;
  base::span<uint8_t> buffer_span;

  ScopedTransferBufferPtr transfer_alloc(size, helper_, transfer_buffer_);
  ScopedMappedMemoryPtr mapped_alloc(0, helper_, mapped_memory_.get());

  if (transfer_alloc.valid() && transfer_alloc.size() >= size) {
    shm_id = transfer_alloc.shm_id();
    shm_offset = transfer_alloc.offset();
    buffer_span = transfer_alloc.as_byte_span();
  } else if (size < max_extra_transfer_buffer_size_) {
    mapped_alloc.Reset(size);
    if (mapped_alloc.valid()) {
      transfer_alloc.Discard();

      mapped_alloc.SetFlushAfterRelease(true);
      shm_id = mapped_alloc.shm_id();
      shm_offset = mapped_alloc.offset();
      buffer_span = mapped_alloc.as_byte_span();
    }
  }

  if (!buffer_span.empty()) {
    uint32_t image_size_src = padded_row_size * src_height;
    uint32_t image_size_dst = service_padded_row_size * height;
    uint32_t pixels_offset = 0;
    uint32_t buffer_offset = 0;
    for (GLsizei z = 0; z < depth; ++z) {
      CopyRectToBuffer(pixels_span.subspan(pixels_offset), height,
                       unpadded_row_size, padded_row_size,
                       buffer_span.subspan(buffer_offset),
                       service_padded_row_size);
      pixels_offset += image_size_src;
      buffer_offset += image_size_dst;
    }
    helper_->TexImage3D(target, level, internalformat, width, height, depth,
                        format, type, shm_id, shm_offset);
    CheckGLError();
    return;
  }

  // No, so send it using TexSubImage3D.
  helper_->TexImage3D(target, level, internalformat, width, height, depth,
                      format, type, 0, 0);
  TexSubImage3DImpl(target, level, 0, 0, 0, width, height, depth, format, type,
                    unpadded_row_size, pixels_span, padded_row_size, GL_TRUE,
                    &transfer_alloc, service_padded_row_size);
  CheckGLError();
}

void GLES2Implementation::TexSubImage2D(GLenum target,
                                        GLint level,
                                        GLint xoffset,
                                        GLint yoffset,
                                        GLsizei width,
                                        GLsizei height,
                                        GLenum format,
                                        GLenum type,
                                        const void* pixels) {
  const char* func_name = "glTexSubImage2D";
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTexSubImage2D("
                     << GLES2Util::GetStringTextureTarget(target) << ", "
                     << level << ", " << xoffset << ", " << yoffset << ", "
                     << width << ", " << height << ", "
                     << GLES2Util::GetStringTextureFormat(format) << ", "
                     << GLES2Util::GetStringPixelType(type) << ", "
                     << static_cast<const void*>(pixels) << ")");

  if (level < 0 || height < 0 || width < 0 || xoffset < 0 || yoffset < 0) {
    SetGLError(GL_INVALID_VALUE, func_name, "dimension < 0");
    return;
  }
  if (unpack_skip_pixels_ + width >
      (unpack_row_length_ ? unpack_row_length_ : width)) {
    // This is WebGL 2 specific constraints, but we do it for all ES3 contexts.
    SetGLError(GL_INVALID_OPERATION, func_name,
               "invalid unpack params combination");
    return;
  }

  uint32_t size;
  uint32_t unpadded_row_size;
  uint32_t padded_row_size;
  uint32_t skip_size;
  PixelStoreParams params = GetUnpackParameters(k2D);
  if (!GLES2Util::ComputeImageDataSizesES3(
          width, height, 1, format, type, params, &size, &unpadded_row_size,
          &padded_row_size, &skip_size, nullptr)) {
    SetGLError(GL_INVALID_VALUE, func_name, "image size to large");
    return;
  }
  const uint32_t client_pixels_size = size;

  if (bound_pixel_unpack_buffer_) {
    base::CheckedNumeric<uint32_t> offset = ToGLuint(pixels);
    offset += skip_size;
    if (!offset.IsValid()) {
      SetGLError(GL_INVALID_VALUE, func_name, "skip size too large");
      return;
    }
    helper_->TexSubImage2D(target, level, xoffset, yoffset, width, height,
                           format, type, 0, offset.ValueOrDefault(0), false);
    CheckGLError();
    return;
  }

  // If there's a pixel unpack buffer bound use it when issuing TexSubImage2D.
  if (bound_pixel_unpack_transfer_buffer_id_) {
    if (unpack_row_length_ > 0 || unpack_image_height_ > 0 ||
        unpack_skip_pixels_ > 0 || unpack_skip_rows_ > 0 ||
        unpack_skip_images_ > 0) {
      SetGLError(GL_INVALID_OPERATION, func_name,
                 "No ES3 pack parameters with pixel unpack transfer buffer.");
      return;
    }
    DCHECK_EQ(0u, skip_size);
    GLuint offset = ToGLuint(pixels);
    BufferTracker::Buffer* buffer = GetBoundPixelTransferBufferIfValid(
        bound_pixel_unpack_transfer_buffer_id_, func_name, offset, size);
    if (buffer && buffer->shm_id() != -1) {
      helper_->TexSubImage2D(target, level, xoffset, yoffset, width, height,
                             format, type, buffer->shm_id(),
                             buffer->shm_offset() + offset, false);
      buffer->set_last_usage_token(helper_->InsertToken());
      CheckGLError();
    }
    return;
  }

  if (width == 0 || height == 0) {
    // No need to worry about pixel data.
    helper_->TexSubImage2D(target, level, xoffset, yoffset, width, height,
                           format, type, 0, 0, false);
    CheckGLError();
    return;
  }

  // Compute the advance bytes per row on the service side.
  // Note |size| is recomputed here if needed.
  uint32_t service_padded_row_size;
  if (unpack_row_length_ > 0 && unpack_row_length_ != width) {
    // All parameters have been applied to the data that are sent to the
    // service side except UNPACK_ALIGNMENT.
    PixelStoreParams service_params;
    service_params.alignment = unpack_alignment_;
    if (!GLES2Util::ComputeImageDataSizesES3(
            width, height, 1, format, type, service_params, &size, nullptr,
            &service_padded_row_size, nullptr, nullptr)) {
      SetGLError(GL_INVALID_VALUE, func_name, "image size too large");
      return;
    }
  } else {
    service_padded_row_size = padded_row_size;
  }

  // advance pixels pointer past the skip rows and skip pixels
  auto pixels_span = UNSAFE_TODO(base::span<const uint8_t>(
      static_cast<const uint8_t*>(pixels) + skip_size, client_pixels_size));

  ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_);
  base::CheckedNumeric<GLint> checked_xoffset = xoffset;
  checked_xoffset += width;
  if (!checked_xoffset.IsValid()) {
    SetGLError(GL_INVALID_VALUE, "TexSubImage2D", "xoffset + width overflows");
    return;
  }
  base::CheckedNumeric<GLint> checked_yoffset = yoffset;
  checked_yoffset += height;
  if (!checked_yoffset.IsValid()) {
    SetGLError(GL_INVALID_VALUE, "TexSubImage2D", "yoffset + height overflows");
    return;
  }
  TexSubImage2DImpl(target, level, xoffset, yoffset, width, height, format,
                    type, unpadded_row_size, pixels_span, padded_row_size,
                    GL_FALSE, &buffer, service_padded_row_size);
  CheckGLError();
}

void GLES2Implementation::TexSubImage3D(GLenum target,
                                        GLint level,
                                        GLint xoffset,
                                        GLint yoffset,
                                        GLint zoffset,
                                        GLsizei width,
                                        GLsizei height,
                                        GLsizei depth,
                                        GLenum format,
                                        GLenum type,
                                        const void* pixels) {
  const char* func_name = "glTexSubImage3D";
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTexSubImage3D("
                     << GLES2Util::GetStringTextureTarget(target) << ", "
                     << level << ", " << xoffset << ", " << yoffset << ", "
                     << zoffset << ", " << width << ", " << height << ", "
                     << depth << ", "
                     << GLES2Util::GetStringTextureFormat(format) << ", "
                     << GLES2Util::GetStringPixelType(type) << ", "
                     << static_cast<const void*>(pixels) << ")");

  if (level < 0 || height < 0 || width < 0 || depth < 0 || xoffset < 0 ||
      yoffset < 0 || zoffset < 0) {
    SetGLError(GL_INVALID_VALUE, func_name, "dimension < 0");
    return;
  }
  if ((unpack_skip_pixels_ + width >
       (unpack_row_length_ ? unpack_row_length_ : width)) ||
      (unpack_skip_rows_ + height >
       (unpack_image_height_ ? unpack_image_height_ : height))) {
    // This is WebGL 2 specific constraints, but we do it for all ES3 contexts.
    SetGLError(GL_INVALID_OPERATION, func_name,
               "invalid unpack params combination");
    return;
  }

  uint32_t size;
  uint32_t unpadded_row_size;
  uint32_t padded_row_size;
  uint32_t skip_size;
  PixelStoreParams params = GetUnpackParameters(k3D);
  if (!GLES2Util::ComputeImageDataSizesES3(
          width, height, depth, format, type, params, &size, &unpadded_row_size,
          &padded_row_size, &skip_size, nullptr)) {
    SetGLError(GL_INVALID_VALUE, func_name, "image size to large");
    return;
  }
  const uint32_t client_pixels_size = size;

  if (bound_pixel_unpack_buffer_) {
    base::CheckedNumeric<uint32_t> offset = ToGLuint(pixels);
    offset += skip_size;
    if (!offset.IsValid()) {
      SetGLError(GL_INVALID_VALUE, func_name, "skip size too large");
      return;
    }
    helper_->TexSubImage3D(target, level, xoffset, yoffset, zoffset, width,
                           height, depth, format, type, 0,
                           offset.ValueOrDefault(0), false);
    CheckGLError();
    return;
  }

  // If there's a pixel unpack buffer bound use it when issuing TexSubImage2D.
  if (bound_pixel_unpack_transfer_buffer_id_) {
    if (unpack_row_length_ > 0 || unpack_image_height_ > 0 ||
        unpack_skip_pixels_ > 0 || unpack_skip_rows_ > 0 ||
        unpack_skip_images_ > 0) {
      SetGLError(GL_INVALID_OPERATION, func_name,
                 "No ES3 pack parameters with pixel unpack transfer buffer.");
      return;
    }
    DCHECK_EQ(0u, skip_size);
    GLuint offset = ToGLuint(pixels);
    BufferTracker::Buffer* buffer = GetBoundPixelTransferBufferIfValid(
        bound_pixel_unpack_transfer_buffer_id_, func_name, offset, size);
    if (buffer && buffer->shm_id() != -1) {
      helper_->TexSubImage3D(target, level, xoffset, yoffset, zoffset, width,
                             height, depth, format, type, buffer->shm_id(),
                             buffer->shm_offset() + offset, false);
      buffer->set_last_usage_token(helper_->InsertToken());
      CheckGLError();
    }
    return;
  }

  if (width == 0 || height == 0 || depth == 0) {
    // No need to worry about pixel data.
    helper_->TexSubImage3D(target, level, xoffset, yoffset, zoffset, width,
                           height, depth, format, type, 0, 0, false);
    CheckGLError();
    return;
  }

  // Compute the advance bytes per row on the service side
  // Note |size| is recomputed here if needed.
  uint32_t service_padded_row_size;
  if ((unpack_row_length_ > 0 && unpack_row_length_ != width) ||
      (unpack_image_height_ > 0 && unpack_image_height_ != height)) {
    PixelStoreParams service_params;
    service_params.alignment = unpack_alignment_;
    if (!GLES2Util::ComputeImageDataSizesES3(
            width, height, depth, format, type, service_params, &size, nullptr,
            &service_padded_row_size, nullptr, nullptr)) {
      SetGLError(GL_INVALID_VALUE, func_name, "image size too large");
      return;
    }
  } else {
    service_padded_row_size = padded_row_size;
  }

  // advance pixels pointer past the skip images/rows/pixels
  auto pixels_span = UNSAFE_TODO(base::span<const uint8_t>(
      static_cast<const uint8_t*>(pixels) + skip_size, client_pixels_size));

  ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_);
  base::CheckedNumeric<GLint> checked_xoffset = xoffset;
  checked_xoffset += width;
  if (!checked_xoffset.IsValid()) {
    SetGLError(GL_INVALID_VALUE, "TexSubImage3D", "xoffset + width overflows");
    return;
  }
  base::CheckedNumeric<GLint> checked_yoffset = yoffset;
  checked_yoffset += height;
  if (!checked_yoffset.IsValid()) {
    SetGLError(GL_INVALID_VALUE, "TexSubImage3D", "yoffset + height overflows");
    return;
  }
  base::CheckedNumeric<GLint> checked_zoffset = zoffset;
  checked_zoffset += depth;
  if (!checked_zoffset.IsValid()) {
    SetGLError(GL_INVALID_VALUE, "TexSubImage3D", "zoffset + depth overflows");
    return;
  }
  TexSubImage3DImpl(target, level, xoffset, yoffset, zoffset, width, height,
                    depth, format, type, unpadded_row_size, pixels_span,
                    padded_row_size, GL_FALSE, &buffer,
                    service_padded_row_size);
  CheckGLError();
}

static GLint ComputeNumRowsThatFitInBuffer(uint32_t padded_row_size,
                                           uint32_t unpadded_row_size,
                                           unsigned int size,
                                           GLsizei remaining_rows) {
  DCHECK_GE(unpadded_row_size, 0u);
  if (padded_row_size == 0) {
    return 1;
  }
  GLint num_rows = size / padded_row_size;
  if (num_rows + 1 == remaining_rows &&
      size - num_rows * padded_row_size >= unpadded_row_size) {
    num_rows++;
  }
  return num_rows;
}

void GLES2Implementation::TexSubImage2DImpl(GLenum target,
                                            GLint level,
                                            GLint xoffset,
                                            GLint yoffset,
                                            GLsizei width,
                                            GLsizei height,
                                            GLenum format,
                                            GLenum type,
                                            uint32_t unpadded_row_size,
                                            base::span<const uint8_t> pixels,
                                            uint32_t pixels_padded_row_size,
                                            GLboolean internal,
                                            ScopedTransferBufferPtr* buffer,
                                            uint32_t buffer_padded_row_size) {
  DCHECK(buffer);
  DCHECK_GE(level, 0);
  DCHECK_GT(height, 0);
  DCHECK_GT(width, 0);
  DCHECK_GE(xoffset, 0);
  DCHECK_GE(yoffset, 0);

  // Transfer by rows.
  uint32_t pixels_offset = 0;
  while (height) {
    unsigned int desired_size =
        buffer_padded_row_size * (height - 1) + unpadded_row_size;
    if (!buffer->valid() || buffer->size() == 0) {
      buffer->Reset(desired_size);
      if (!buffer->valid()) {
        return;
      }
    }

    GLint num_rows = ComputeNumRowsThatFitInBuffer(
        buffer_padded_row_size, unpadded_row_size, buffer->size(), height);
    num_rows = std::min(num_rows, height);
    CopyRectToBuffer(pixels.subspan(pixels_offset), num_rows, unpadded_row_size,
                     pixels_padded_row_size, buffer->as_byte_span(),
                     buffer_padded_row_size);
    helper_->TexSubImage2D(target, level, xoffset, yoffset, width, num_rows,
                           format, type, buffer->shm_id(), buffer->offset(),
                           internal);
    buffer->Release();
    yoffset += num_rows;
    height -= num_rows;
    pixels_offset += num_rows * pixels_padded_row_size;
  }
}

void GLES2Implementation::TexSubImage3DImpl(GLenum target,
                                            GLint level,
                                            GLint xoffset,
                                            GLint yoffset,
                                            GLsizei zoffset,
                                            GLsizei width,
                                            GLsizei height,
                                            GLsizei depth,
                                            GLenum format,
                                            GLenum type,
                                            uint32_t unpadded_row_size,
                                            base::span<const uint8_t> pixels,
                                            uint32_t pixels_padded_row_size,
                                            GLboolean internal,
                                            ScopedTransferBufferPtr* buffer,
                                            uint32_t buffer_padded_row_size) {
  DCHECK(buffer);
  DCHECK_GE(level, 0);
  DCHECK_GT(width, 0);
  DCHECK_GT(height, 0);
  DCHECK_GT(depth, 0);
  DCHECK_GE(xoffset, 0);
  DCHECK_GE(yoffset, 0);
  DCHECK_GE(zoffset, 0);
  GLsizei total_rows = height * depth;
  GLint row_index = 0, depth_index = 0;
  uint32_t pixels_offset = 0;
  while (total_rows) {
    // Each time, we either copy one or more images, or copy one or more rows
    // within a single image, depending on the buffer size limit.
    GLsizei max_rows;
    unsigned int desired_size;
    if (row_index > 0) {
      // We are in the middle of an image. Send the remaining of the image.
      max_rows = height - row_index;
      if (total_rows <= height) {
        // Last image, so last row is unpadded.
        desired_size =
            buffer_padded_row_size * (max_rows - 1) + unpadded_row_size;
      } else {
        desired_size = buffer_padded_row_size * max_rows;
      }
    } else {
      // Send all the remaining data if possible.
      max_rows = total_rows;
      desired_size =
          buffer_padded_row_size * (max_rows - 1) + unpadded_row_size;
    }
    if (!buffer->valid() || buffer->size() == 0) {
      buffer->Reset(desired_size);
      if (!buffer->valid()) {
        return;
      }
    }
    GLint num_rows = ComputeNumRowsThatFitInBuffer(
        buffer_padded_row_size, unpadded_row_size, buffer->size(), total_rows);
    num_rows = std::min(num_rows, max_rows);
    GLint num_images = num_rows / height;
    GLsizei my_height, my_depth;
    if (num_images > 0) {
      num_rows = num_images * height;
      my_height = height;
      my_depth = num_images;
    } else {
      my_height = num_rows;
      my_depth = 1;
    }

    if (num_images > 0) {
      auto buffer_span = buffer->as_byte_span();
      uint32_t src_height =
          unpack_image_height_ > 0 ? unpack_image_height_ : height;
      uint32_t image_size_dst = buffer_padded_row_size * height;
      uint32_t image_size_src = pixels_padded_row_size * src_height;
      for (GLint ii = 0; ii < num_images; ++ii) {
        CopyRectToBuffer(pixels.subspan(pixels_offset + ii * image_size_src),
                         my_height, unpadded_row_size, pixels_padded_row_size,
                         buffer_span.subspan(ii * image_size_dst),
                         buffer_padded_row_size);
      }
    } else {
      CopyRectToBuffer(pixels.subspan(pixels_offset), my_height,
                       unpadded_row_size, pixels_padded_row_size,
                       buffer->as_byte_span(), buffer_padded_row_size);
    }
    helper_->TexSubImage3D(target, level, xoffset, yoffset + row_index,
                           zoffset + depth_index, width, my_height, my_depth,
                           format, type, buffer->shm_id(), buffer->offset(),
                           internal);
    buffer->Release();

    total_rows -= num_rows;
    if (total_rows > 0) {
      GLint num_image_paddings;
      if (num_images > 0) {
        DCHECK_EQ(row_index, 0);
        depth_index += num_images;
        num_image_paddings = num_images;
      } else {
        row_index = (row_index + my_height) % height;
        num_image_paddings = 0;
        if (my_height > 0 && row_index == 0) {
          depth_index++;
          num_image_paddings++;
        }
      }
      uint32_t advance = num_rows * pixels_padded_row_size;
      if (unpack_image_height_ > height && num_image_paddings > 0) {
        advance += num_image_paddings * (unpack_image_height_ - height) *
                   pixels_padded_row_size;
      }
      pixels_offset += advance;
    }
  }
}

void GLES2Implementation::GetResultNameHelper(GLsizei bufsize,
                                              GLsizei* length,
                                              char* name) {
  // Length of string (without final \0) that we will write to the buffer.
  GLsizei max_length = 0;
  if (name && (bufsize > 0)) {
    std::vector<int8_t> str;
    GetBucketContents(kResultBucketId, &str);
    if (!str.empty()) {
      DCHECK_LE(str.size(), static_cast<size_t>(INT_MAX));
      // Note: both bufsize and str.size() count/include the terminating \0.
      max_length = std::min(bufsize, static_cast<GLsizei>(str.size())) - 1;
    }
    UNSAFE_TODO(memcpy(name, str.data(), max_length));
    UNSAFE_TODO(name[max_length]) = '\0';
  }
  if (length) {
    *length = max_length;
  }
}

bool GLES2Implementation::GetActiveAttribHelper(GLuint program,
                                                GLuint index,
                                                GLsizei bufsize,
                                                GLsizei* length,
                                                GLint* size,
                                                GLenum* type,
                                                char* name) {
  // Clear the bucket so if the command fails nothing will be in it.
  helper_->SetBucketSize(kResultBucketId, 0);
  typedef cmds::GetActiveAttrib::Result Result;
  auto result = GetResultAs<Result>();
  if (!result) {
    return false;
  }
  // Set as failed so if the command fails we'll recover.
  result->success = false;
  helper_->GetActiveAttrib(program, index, kResultBucketId, GetResultShmId(),
                           result.offset());
  if (!WaitForCmd()) {
    return false;
  }
  bool success = !!result->success;
  if (success) {
    if (size) {
      *size = result->size;
    }
    if (type) {
      *type = result->type;
    }
    // Note: this can invalidate |result|.
    GetResultNameHelper(bufsize, length, name);
  }
  return success;
}

void GLES2Implementation::GetActiveAttrib(GLuint program,
                                          GLuint index,
                                          GLsizei bufsize,
                                          GLsizei* length,
                                          GLint* size,
                                          GLenum* type,
                                          char* name) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetActiveAttrib(" << program
                     << ", " << index << ", " << bufsize << ", "
                     << static_cast<const void*>(length) << ", "
                     << static_cast<const void*>(size) << ", "
                     << static_cast<const void*>(type) << ", "
                     << static_cast<const void*>(name) << ", ");
  if (bufsize < 0) {
    SetGLError(GL_INVALID_VALUE, "glGetActiveAttrib", "bufsize < 0");
    return;
  }
  TRACE_EVENT0("gpu", "GLES2::GetActiveAttrib");
  bool success = share_group_->program_info_manager()->GetActiveAttrib(
      this, program, index, bufsize, length, size, type, name);
  if (success) {
    if (size) {
      GPU_CLIENT_LOG("  size: " << *size);
    }
    if (type) {
      GPU_CLIENT_LOG("  type: " << GLES2Util::GetStringEnum(*type));
    }
    if (name) {
      GPU_CLIENT_LOG("  name: " << name);
    }
  }
  CheckGLError();
}

bool GLES2Implementation::GetActiveUniformHelper(GLuint program,
                                                 GLuint index,
                                                 GLsizei bufsize,
                                                 GLsizei* length,
                                                 GLint* size,
                                                 GLenum* type,
                                                 char* name) {
  // Clear the bucket so if the command fails nothing will be in it.
  helper_->SetBucketSize(kResultBucketId, 0);
  typedef cmds::GetActiveUniform::Result Result;
  auto result = GetResultAs<Result>();
  if (!result) {
    return false;
  }
  // Set as failed so if the command fails we'll recover.
  result->success = false;
  helper_->GetActiveUniform(program, index, kResultBucketId, GetResultShmId(),
                            result.offset());
  if (!WaitForCmd()) {
    return false;
  }
  bool success = !!result->success;
  if (success) {
    if (size) {
      *size = result->size;
    }
    if (type) {
      *type = result->type;
    }
    // Note: this can invalidate |result|.
    GetResultNameHelper(bufsize, length, name);
  }
  return success;
}

void GLES2Implementation::GetActiveUniform(GLuint program,
                                           GLuint index,
                                           GLsizei bufsize,
                                           GLsizei* length,
                                           GLint* size,
                                           GLenum* type,
                                           char* name) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetActiveUniform(" << program
                     << ", " << index << ", " << bufsize << ", "
                     << static_cast<const void*>(length) << ", "
                     << static_cast<const void*>(size) << ", "
                     << static_cast<const void*>(type) << ", "
                     << static_cast<const void*>(name) << ", ");
  if (bufsize < 0) {
    SetGLError(GL_INVALID_VALUE, "glGetActiveUniform", "bufsize < 0");
    return;
  }
  TRACE_EVENT0("gpu", "GLES2::GetActiveUniform");
  bool success = share_group_->program_info_manager()->GetActiveUniform(
      this, program, index, bufsize, length, size, type, name);
  if (success) {
    if (size) {
      GPU_CLIENT_LOG("  size: " << *size);
    }
    if (type) {
      GPU_CLIENT_LOG("  type: " << GLES2Util::GetStringEnum(*type));
    }
    if (name) {
      GPU_CLIENT_LOG("  name: " << name);
    }
  }
  CheckGLError();
}

bool GLES2Implementation::GetActiveUniformBlockNameHelper(GLuint program,
                                                          GLuint index,
                                                          GLsizei bufsize,
                                                          GLsizei* length,
                                                          char* name) {
  DCHECK_LE(0, bufsize);
  // Clear the bucket so if the command fails nothing will be in it.
  helper_->SetBucketSize(kResultBucketId, 0);
  typedef cmds::GetActiveUniformBlockName::Result Result;
  auto result = GetResultAs<Result>();
  if (!result) {
    return false;
  }
  // Set as failed so if the command fails we'll recover.
  *result = 0;
  helper_->GetActiveUniformBlockName(program, index, kResultBucketId,
                                     GetResultShmId(), result.offset());
  if (!WaitForCmd()) {
    return false;
  }
  bool success = !!result;
  if (success) {
    // Note: this can invalidate |result|.
    GetResultNameHelper(bufsize, length, name);
  }
  return success;
}

void GLES2Implementation::GetActiveUniformBlockName(GLuint program,
                                                    GLuint index,
                                                    GLsizei bufsize,
                                                    GLsizei* length,
                                                    char* name) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetActiveUniformBlockName("
                     << program << ", " << index << ", " << bufsize << ", "
                     << static_cast<const void*>(length) << ", "
                     << static_cast<const void*>(name) << ")");
  if (bufsize < 0) {
    SetGLError(GL_INVALID_VALUE, "glGetActiveUniformBlockName", "bufsize < 0");
    return;
  }
  TRACE_EVENT0("gpu", "GLES2::GetActiveUniformBlockName");
  bool success =
      share_group_->program_info_manager()->GetActiveUniformBlockName(
          this, program, index, bufsize, length, name);
  if (success) {
    if (name) {
      GPU_CLIENT_LOG("  name: " << name);
    }
  }
  CheckGLError();
}

bool GLES2Implementation::GetActiveUniformBlockivHelper(GLuint program,
                                                        GLuint index,
                                                        GLenum pname,
                                                        GLint* params) {
  typedef cmds::GetActiveUniformBlockiv::Result Result;
  auto result = GetResultAs<Result>();
  if (!result) {
    return false;
  }
  result->SetNumResults(0);
  helper_->GetActiveUniformBlockiv(program, index, pname, GetResultShmId(),
                                   result.offset());
  if (!WaitForCmd()) {
    return false;
  }
  if (result->GetNumResults() > 0) {
    if (params) {
      result->CopyResult(params);
    }
    UNSAFE_TODO(GPU_CLIENT_LOG_CODE_BLOCK({
      for (int32_t i = 0; i < result->GetNumResults(); ++i) {
        GPU_CLIENT_LOG("  " << i << ": " << result->GetData()[i]);
      }
    }));
    return true;
  }
  return false;
}

void GLES2Implementation::GetActiveUniformBlockiv(GLuint program,
                                                  GLuint index,
                                                  GLenum pname,
                                                  GLint* params) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetActiveUniformBlockiv("
                     << program << ", " << index << ", "
                     << GLES2Util::GetStringUniformBlockParameter(pname) << ", "
                     << static_cast<const void*>(params) << ")");
  TRACE_EVENT0("gpu", "GLES2::GetActiveUniformBlockiv");
  bool success = share_group_->program_info_manager()->GetActiveUniformBlockiv(
      this, program, index, pname, params);
  if (success) {
    if (params) {
      // TODO(zmo): For GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, there will
      // be more than one value returned in params.
      GPU_CLIENT_LOG("  params: " << params[0]);
    }
  }
  CheckGLError();
}

bool GLES2Implementation::GetActiveUniformsivHelper(GLuint program,
                                                    GLsizei count,
                                                    const GLuint* indices,
                                                    GLenum pname,
                                                    GLint* params) {
  base::CheckedNumeric<uint32_t> bytes = count;
  bytes *= sizeof(GLuint);
  if (!bytes.IsValid()) {
    SetGLError(GL_INVALID_VALUE, "glGetActiveUniformsiv", "count overflow");
    return false;
  }
  SetBucketContents(kResultBucketId, indices, bytes.ValueOrDefault(0));
  typedef cmds::GetActiveUniformsiv::Result Result;
  auto result = GetResultAs<Result>();
  if (!result) {
    return false;
  }
  result->SetNumResults(0);
  helper_->GetActiveUniformsiv(program, kResultBucketId, pname,
                               GetResultShmId(), result.offset());
  if (!WaitForCmd()) {
    return false;
  }
  bool success = result->GetNumResults() == count;
  if (success) {
    if (params) {
      result->CopyResult(params);
    }
    UNSAFE_TODO(GPU_CLIENT_LOG_CODE_BLOCK({
      for (int32_t i = 0; i < result->GetNumResults(); ++i) {
        GPU_CLIENT_LOG("  " << i << ": " << result->GetData()[i]);
      }
    }));
  }
  helper_->SetBucketSize(kResultBucketId, 0);
  return success;
}

void GLES2Implementation::GetActiveUniformsiv(GLuint program,
                                              GLsizei count,
                                              const GLuint* indices,
                                              GLenum pname,
                                              GLint* params) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetActiveUniformsiv(" << program
                     << ", " << count << ", "
                     << static_cast<const void*>(indices) << ", "
                     << GLES2Util::GetStringUniformParameter(pname) << ", "
                     << static_cast<const void*>(params) << ")");
  TRACE_EVENT0("gpu", "GLES2::GetActiveUniformsiv");
  if (count < 0) {
    SetGLError(GL_INVALID_VALUE, "glGetActiveUniformsiv", "count < 0");
    return;
  }
  bool success = share_group_->program_info_manager()->GetActiveUniformsiv(
      this, program, count, indices, pname, params);
  if (success) {
    if (params) {
      UNSAFE_TODO(GPU_CLIENT_LOG_CODE_BLOCK({
        for (GLsizei ii = 0; ii < count; ++ii) {
          GPU_CLIENT_LOG("  " << ii << ": " << params[ii]);
        }
      }));
    }
  }
  CheckGLError();
}

void GLES2Implementation::GetAttachedShaders(GLuint program,
                                             GLsizei maxcount,
                                             GLsizei* count,
                                             GLuint* shaders) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetAttachedShaders(" << program
                     << ", " << maxcount << ", "
                     << static_cast<const void*>(count) << ", "
                     << static_cast<const void*>(shaders) << ", ");
  if (maxcount < 0) {
    SetGLError(GL_INVALID_VALUE, "glGetAttachedShaders", "maxcount < 0");
    return;
  }
  TRACE_EVENT0("gpu", "GLES2::GetAttachedShaders");
  typedef cmds::GetAttachedShaders::Result Result;
  uint32_t checked_size = 0;
  if (!Result::ComputeSize(maxcount).AssignIfValid(&checked_size)) {
    SetGLError(GL_OUT_OF_MEMORY, "glGetAttachedShaders",
               "allocation too large");
    return;
  }
  auto result_span = transfer_buffer_->Alloc(checked_size);
  if (result_span.empty()) {
    return;
  }
  Result* result = reinterpret_cast<Result*>(result_span.data());
  result->SetNumResults(0);
  helper_->GetAttachedShaders(program, transfer_buffer_->GetShmId(),
                              transfer_buffer_->GetOffset(result),
                              checked_size);
  int32_t token = helper_->InsertToken();
  if (!WaitForCmd()) {
    return;
  }
  if (count) {
    *count = result->GetNumResults();
  }
  result->CopyResult(shaders);
  UNSAFE_TODO(GPU_CLIENT_LOG_CODE_BLOCK({
    for (int32_t i = 0; i < result->GetNumResults(); ++i) {
      GPU_CLIENT_LOG("  " << i << ": " << result->GetData()[i]);
    }
  }));
  transfer_buffer_->FreePendingToken(result, token);
  CheckGLError();
}

void GLES2Implementation::GetShaderPrecisionFormat(GLenum shadertype,
                                                   GLenum precisiontype,
                                                   GLint* range,
                                                   GLint* precision) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetShaderPrecisionFormat("
                     << GLES2Util::GetStringShaderType(shadertype) << ", "
                     << GLES2Util::GetStringShaderPrecision(precisiontype)
                     << ", " << static_cast<const void*>(range) << ", "
                     << static_cast<const void*>(precision) << ", ");
  TRACE_EVENT0("gpu", "GLES2::GetShaderPrecisionFormat");
  typedef cmds::GetShaderPrecisionFormat::Result Result;
  // Limit scope of result to avoid overlap with CheckGLError()
  {
    auto result = GetResultAs<Result>();
    if (!result) {
      return;
    }

    GLStaticState::ShaderPrecisionKey key(shadertype, precisiontype);
    GLStaticState::ShaderPrecisionMap::iterator i =
        static_state_.shader_precisions.find(key);
    if (i != static_state_.shader_precisions.end()) {
      *result = i->second;
    } else {
      result->success = false;
      helper_->GetShaderPrecisionFormat(shadertype, precisiontype,
                                        GetResultShmId(), result.offset());
      if (!WaitForCmd()) {
        return;
      }
      if (result->success)
        static_state_.shader_precisions[key] = *result;
    }

    if (result->success) {
      if (range) {
        range[0] = result->min_range;
        UNSAFE_TODO(range[1]) = result->max_range;
        GPU_CLIENT_LOG("  min_range: " << range[0]);
        UNSAFE_TODO(GPU_CLIENT_LOG("  min_range: " << range[1]));
      }
      if (precision) {
        precision[0] = result->precision;
        GPU_CLIENT_LOG("  min_range: " << precision[0]);
      }
    }
  }
  CheckGLError();
}

const GLubyte* GLES2Implementation::GetStringHelper(GLenum name) {
  if (name == GL_EXTENSIONS && cached_extension_string_) {
    return reinterpret_cast<const GLubyte*>(cached_extension_string_);
  }
  const char* result = nullptr;
  // Clears the bucket so if the command fails nothing will be in it.
  helper_->SetBucketSize(kResultBucketId, 0);
  helper_->GetString(name, kResultBucketId);
  std::string str;
  if (GetBucketAsString(kResultBucketId, &str)) {
    // Adds extensions implemented on client side only.
    if (name == GL_EXTENSIONS) {
      str += std::string(str.empty() ? "" : " ") +
             "GL_CHROMIUM_map_sub "
             "GL_CHROMIUM_ordering_barrier "
             "GL_CHROMIUM_sync_point "
             "GL_EXT_unpack_subimage";
    }

    // Because of WebGL the extensions can change. We have to cache each unique
    // result since we don't know when the client will stop referring to a
    // previous one it queries.
    // TODO: Here we could save memory by defining RequestExtensions
    // invalidating the GL_EXTENSIONS string. http://crbug.com/586414
    const std::string& cache = *gl_strings_.insert(str).first;
    result = cache.c_str();

    if (name == GL_EXTENSIONS) {
      cached_extension_string_ = result;
      std::vector<std::string> extensions =
          base::SplitString(cache, base::kWhitespaceASCII,
                            base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
      for (const std::string& extension : extensions) {
        cached_extensions_.push_back(
            gl_strings_.insert(extension).first->c_str());
      }
    }
  }
  return reinterpret_cast<const GLubyte*>(result);
}

const GLubyte* GLES2Implementation::GetString(GLenum name) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetString("
                     << GLES2Util::GetStringStringType(name) << ")");
  TRACE_EVENT0("gpu", "GLES2::GetString");
  const GLubyte* result = GetStringHelper(name);
  GPU_CLIENT_LOG("  returned " << reinterpret_cast<const char*>(result));
  CheckGLError();
  return result;
}

const GLubyte* GLES2Implementation::GetStringi(GLenum name, GLuint index) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetStringi("
                     << GLES2Util::GetStringStringType(name) << "," << index
                     << ")");
  TRACE_EVENT0("gpu", "GLES2::GetStringi");
  UpdateCachedExtensionsIfNeeded();
  if (name != GL_EXTENSIONS) {
    SetGLError(GL_INVALID_ENUM, "glGetStringi", "name");
    return nullptr;
  }
  if (index >= cached_extensions_.size()) {
    SetGLError(GL_INVALID_VALUE, "glGetStringi", "index too large");
    return nullptr;
  }

  const char* result = cached_extensions_[index];
  GPU_CLIENT_LOG("  returned " << result);
  CheckGLError();
  return reinterpret_cast<const GLubyte*>(result);
}

bool GLES2Implementation::GetTransformFeedbackVaryingHelper(GLuint program,
                                                            GLuint index,
                                                            GLsizei bufsize,
                                                            GLsizei* length,
                                                            GLint* size,
                                                            GLenum* type,
                                                            char* name) {
  // Clear the bucket so if the command fails nothing will be in it.
  helper_->SetBucketSize(kResultBucketId, 0);
  typedef cmds::GetTransformFeedbackVarying::Result Result;
  auto result = GetResultAs<Result>();
  if (!result) {
    return false;
  }
  // Set as failed so if the command fails we'll recover.
  result->success = false;
  helper_->GetTransformFeedbackVarying(program, index, kResultBucketId,
                                       GetResultShmId(), result.offset());
  if (!WaitForCmd()) {
    return false;
  }
  if (result->success) {
    if (size) {
      *size = result->size;
    }
    if (type) {
      *type = result->type;
    }
    // Note: this can invalidate |result|.
    GetResultNameHelper(bufsize, length, name);
  }
  return result->success != 0;
}

void GLES2Implementation::GetTransformFeedbackVarying(GLuint program,
                                                      GLuint index,
                                                      GLsizei bufsize,
                                                      GLsizei* length,
                                                      GLint* size,
                                                      GLenum* type,
                                                      char* name) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetTransformFeedbackVarying("
                     << program << ", " << index << ", " << bufsize << ", "
                     << static_cast<const void*>(length) << ", "
                     << static_cast<const void*>(size) << ", "
                     << static_cast<const void*>(type) << ", "
                     << static_cast<const void*>(name) << ", ");
  if (bufsize < 0) {
    SetGLError(GL_INVALID_VALUE, "glGetTransformFeedbackVarying",
               "bufsize < 0");
    return;
  }
  TRACE_EVENT0("gpu", "GLES2::GetTransformFeedbackVarying");
  bool success =
      share_group_->program_info_manager()->GetTransformFeedbackVarying(
          this, program, index, bufsize, length, size, type, name);
  if (success) {
    if (size) {
      GPU_CLIENT_LOG("  size: " << *size);
    }
    if (type) {
      GPU_CLIENT_LOG("  type: " << GLES2Util::GetStringEnum(*type));
    }
    if (name) {
      GPU_CLIENT_LOG("  name: " << name);
    }
  }
  CheckGLError();
}

void GLES2Implementation::GetUniformfv(GLuint program,
                                       GLint location,
                                       GLfloat* params) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetUniformfv(" << program << ", "
                     << location << ", " << static_cast<const void*>(params)
                     << ")");
  TRACE_EVENT0("gpu", "GLES2::GetUniformfv");
  typedef cmds::GetUniformfv::Result Result;
  // Limit scope of result to avoid overlap with CheckGLError()
  {
    auto result = GetResultAs<Result>();
    if (!result) {
      return;
    }
    result->SetNumResults(0);
    helper_->GetUniformfv(program, location, GetResultShmId(), result.offset());
    if (!WaitForCmd()) {
      return;
    }
    result->CopyResult(params);
    UNSAFE_TODO(GPU_CLIENT_LOG_CODE_BLOCK({
      for (int32_t i = 0; i < result->GetNumResults(); ++i) {
        GPU_CLIENT_LOG("  " << i << ": " << result->GetData()[i]);
      }
    }));
  }
  CheckGLError();
}

void GLES2Implementation::GetUniformiv(GLuint program,
                                       GLint location,
                                       GLint* params) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetUniformiv(" << program << ", "
                     << location << ", " << static_cast<const void*>(params)
                     << ")");
  TRACE_EVENT0("gpu", "GLES2::GetUniformiv");
  typedef cmds::GetUniformiv::Result Result;
  // Limit scope of result to avoid overlap with CheckGLError()
  {
    auto result = GetResultAs<Result>();
    if (!result) {
      return;
    }
    result->SetNumResults(0);
    helper_->GetUniformiv(program, location, GetResultShmId(), result.offset());
    if (!WaitForCmd()) {
      return;
    }
    result->CopyResult(params);
    UNSAFE_TODO(GPU_CLIENT_LOG_CODE_BLOCK({
      for (int32_t i = 0; i < result->GetNumResults(); ++i) {
        GPU_CLIENT_LOG("  " << i << ": " << result->GetData()[i]);
      }
    }));
  }
  CheckGLError();
}

void GLES2Implementation::GetUniformuiv(GLuint program,
                                        GLint location,
                                        GLuint* params) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetUniformuiv(" << program
                     << ", " << location << ", "
                     << static_cast<const void*>(params) << ")");
  TRACE_EVENT0("gpu", "GLES2::GetUniformuiv");
  typedef cmds::GetUniformuiv::Result Result;
  // Limit scope of result to avoid overlap with CheckGLError()
  {
    auto result = GetResultAs<Result>();
    if (!result) {
      return;
    }
    result->SetNumResults(0);
    helper_->GetUniformuiv(program, location, GetResultShmId(),
                           result.offset());
    if (!WaitForCmd()) {
      return;
    }
    result->CopyResult(params);
    UNSAFE_TODO(GPU_CLIENT_LOG_CODE_BLOCK({
      for (int32_t i = 0; i < result->GetNumResults(); ++i) {
        GPU_CLIENT_LOG("  " << i << ": " << result->GetData()[i]);
      }
    }));
  }
  CheckGLError();
}

void GLES2Implementation::WritePixelsYUVINTERNAL(
    const GLbyte* mailbox,
    GLuint src_size_plane1,
    GLuint src_size_plane2,
    GLuint src_size_plane3,
    GLuint src_size_plane4,
    GLuint src_width,
    GLuint src_height,
    GLuint src_plane_config,
    GLuint src_subsampling,
    GLuint src_datatype,
    GLuint src_row_bytes_plane1,
    GLuint src_row_bytes_plane2,
    GLuint src_row_bytes_plane3,
    GLuint src_row_bytes_plane4,
    const void* src_pixels_plane1,
    const void* src_pixels_plane2,
    const void* src_pixels_plane3,
    const void* src_pixels_plane4) {
  CHECK(mailbox);
  // We have the following stored at offsets from `shm_address`:
  // 0: stores the destination mailbox,
  // pixels_offset_plane1: stores source pixels for plane 1,
  // pixels_offset_plane2: stores source pixels for plane 2,
  // pixels_offset_plane3: stores source pixels for plane 3,
  // pixels_offset_plane4: stores source pixels for plane 4

  const int kMaxPlanes = 4;
  std::array<GLuint, kMaxPlanes> src_sizes = {
      src_size_plane1,
      src_size_plane2,
      src_size_plane3,
      src_size_plane4,
  };
  std::array<const void*, kMaxPlanes> src_pixels = {
      src_pixels_plane1,
      src_pixels_plane2,
      src_pixels_plane3,
      src_pixels_plane4,
  };

  GLuint total_size =
      base::bits::AlignUp(sizeof(gpu::Mailbox), sizeof(uint64_t));
  for (int plane = 0; plane < kMaxPlanes; plane++) {
    if (!src_pixels[plane]) {
      // If pixels don't exist for a plane, we've copied all planes of src
      // image.
      CHECK_EQ(src_sizes[plane], 0u);
      break;
    }
    total_size += base::bits::AlignUp(src_sizes[plane],
                                      static_cast<GLuint>(sizeof(uint64_t)));
  }

  ScopedMappedMemoryPtr scoped_shared_memory(total_size, helper(),
                                             mapped_memory_.get());
  if (!scoped_shared_memory.valid()) {
    SetGLError(GL_INVALID_OPERATION, "WritePixelsYUV", "size too big");
    return;
  }

  GLint shm_id = scoped_shared_memory.shm_id();
  GLuint shm_offset = scoped_shared_memory.offset();
  void* address = scoped_shared_memory.address();

  // Copy the mailbox at `address`.
  GLuint mailbox_offset = 0;
  UNSAFE_TODO(
      memcpy(static_cast<uint8_t*>(address), mailbox, sizeof(gpu::Mailbox)));

  std::array<GLuint, kMaxPlanes> pixel_offsets = {};
  // Calculate first plane offset based on mailbox.
  pixel_offsets[0] =
      mailbox_offset + static_cast<GLuint>(base::bits::AlignUp(
                           sizeof(gpu::Mailbox), sizeof(uint64_t)));
  CHECK(src_pixels[0]);
  UNSAFE_TODO(memcpy(static_cast<uint8_t*>(address) + pixel_offsets[0],
                     src_pixels[0], src_sizes[0]));

  for (int plane = 1; plane < kMaxPlanes; plane++) {
    if (!src_pixels[plane]) {
      // If pixels don't exist for a plane, we've copied all planes of src
      // image.
      break;
    }
    // Calculate the offset based on previous plane offset and previous plane
    // size, and copy pixels for current plane starting at current plane
    // offset.
    pixel_offsets[plane] =
        pixel_offsets[plane - 1] +
        base::bits::AlignUp(src_sizes[plane - 1],
                            static_cast<GLuint>(sizeof(uint64_t)));
    UNSAFE_TODO(memcpy(static_cast<uint8_t*>(address) + pixel_offsets[plane],
                       src_pixels[plane], src_sizes[plane]));
  }

  helper_->WritePixelsYUVINTERNAL(
      src_width, src_height, src_row_bytes_plane1, src_row_bytes_plane2,
      src_row_bytes_plane3, src_row_bytes_plane4, src_plane_config,
      src_subsampling, src_datatype, shm_id, shm_offset, pixel_offsets[0],
      pixel_offsets[1], pixel_offsets[2], pixel_offsets[3]);
}

GLboolean GLES2Implementation::ReadbackARGBImagePixelsINTERNAL(
    const GLbyte* mailbox,
    const void* dst_sk_color_space,
    GLuint dst_color_space_size,
    GLuint dst_size,
    GLuint dst_width,
    GLuint dst_height,
    GLuint dst_sk_color_type,
    GLuint dst_sk_alpha_type,
    GLuint dst_row_bytes,
    GLint src_x,
    GLint src_y,
    GLint plane_index,
    void* pixels) {
  DCHECK(mailbox);
  // We can't use GetResultAs<>() to store our result because it uses
  // TransferBuffer under the hood and this function is potentially
  // asynchronous. Instead, store the result at the beginning of the shared
  // memory we allocate to transfer pixels.
  // We have the following stored at offsets from `shm_address`:
  // 0: stores ReadbackARGBImagePixelsINTERNAL::Result,
  // color_space_offset: stores destination SkColorSpace,
  // mailbox_offset: stores the gpu::Mailbox,
  // pixels_offset: stores the pixels
  GLuint color_space_offset = base::bits::AlignUp(
      sizeof(cmds::ReadbackARGBImagePixelsINTERNAL::Result), sizeof(uint64_t));

  // Add the size of the SkColorSpace while maintaining 8-byte alignment.
  GLuint mailbox_offset = color_space_offset;
  if (dst_sk_color_space) {
    mailbox_offset =
        base::bits::AlignUp(color_space_offset + dst_color_space_size,
                            static_cast<GLuint>(sizeof(uint64_t)));
  }

  // Add the size of the mailbox while maintaining 8-byte alignment.
  GLuint pixels_offset = base::bits::AlignUp(
      mailbox_offset + sizeof(gpu::Mailbox), sizeof(uint64_t));

  GLuint total_size =
      pixels_offset +
      base::bits::AlignUp(dst_size, static_cast<GLuint>(sizeof(uint64_t)));

  ScopedMappedMemoryPtr scoped_shared_memory(total_size, helper(),
                                             mapped_memory_.get());
  if (!scoped_shared_memory.valid()) {
    return GL_FALSE;
  }

  GLint shm_id = scoped_shared_memory.shm_id();
  GLuint shm_offset = scoped_shared_memory.offset();
  void* shm_address = scoped_shared_memory.address();

  // Readback success/failure result is stored at the beginning of the shared
  // memory region. Client is responsible for initialization so we do so here.
  auto* readback_result =
      static_cast<cmds::ReadbackARGBImagePixelsINTERNAL::Result*>(shm_address);
  *readback_result = 0;

  if (dst_sk_color_space) {
    // Copy destination color space to the destination color space offset.
    UNSAFE_TODO(memcpy(static_cast<uint8_t*>(shm_address) + color_space_offset,
                       dst_sk_color_space, dst_color_space_size));
  }
  // Copy shared image mailbox to the mailbox offset.
  UNSAFE_TODO(memcpy(static_cast<uint8_t*>(shm_address) + mailbox_offset,
                     mailbox, sizeof(gpu::Mailbox)));

  helper_->ReadbackARGBImagePixelsINTERNAL(
      src_x, src_y, plane_index, dst_width, dst_height, dst_row_bytes,
      dst_sk_color_type, dst_sk_alpha_type, shm_id, shm_offset,
      color_space_offset, pixels_offset, mailbox_offset);

  if (!WaitForCmd()) {
    return GL_FALSE;
  }
  if (!*readback_result) {
    return GL_FALSE;
  }
  // We need to use `RelaxedAtomicWriteMemcpy` because we might be writing into
  // memory observed by JS at the same time.
  auto dst = UNSAFE_TODO(base::span(static_cast<uint8_t*>(pixels), dst_size));
  auto src = UNSAFE_TODO(
      base::span(static_cast<uint8_t*>(shm_address) + pixels_offset, dst_size));
  base::subtle::RelaxedAtomicWriteMemcpy(dst, src);
  return GL_TRUE;
}

void GLES2Implementation::ReadPixels(GLint xoffset,
                                     GLint yoffset,
                                     GLsizei width,
                                     GLsizei height,
                                     GLenum format,
                                     GLenum type,
                                     void* pixels) {
  const char* func_name = "glReadPixels";
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glReadPixels(" << xoffset << ", "
                     << yoffset << ", " << width << ", " << height << ", "
                     << GLES2Util::GetStringReadPixelFormat(format) << ", "
                     << GLES2Util::GetStringPixelType(type) << ", "
                     << static_cast<const void*>(pixels) << ")");
  if (width < 0 || height < 0) {
    SetGLError(GL_INVALID_VALUE, func_name, "dimensions < 0");
    return;
  }

  if (pack_skip_pixels_ + width >
      (pack_row_length_ ? pack_row_length_ : width)) {
    // This is WebGL 2 specific constraints, but we do it for all ES3 contexts.
    SetGLError(GL_INVALID_OPERATION, func_name,
               "invalid pack params combination");
    return;
  }

  // glReadPixel pads the size of each row of pixels by an amount specified by
  // glPixelStorei. So, we have to take that into account both in the fact that
  // the pixels returned from the ReadPixel command will include that padding
  // and that when we copy the results to the user's buffer we need to not
  // write those padding bytes but leave them as they are.

  TRACE_EVENT0("gpu", "GLES2::ReadPixels");
  typedef cmds::ReadPixels::Result Result;

  uint32_t size;
  uint32_t unpadded_row_size;
  uint32_t padded_row_size;
  uint32_t skip_size;
  PixelStoreParams params;
  params.alignment = pack_alignment_;
  params.row_length = pack_row_length_;
  params.skip_pixels = pack_skip_pixels_;
  params.skip_rows = pack_skip_rows_;
  if (!GLES2Util::ComputeImageDataSizesES3(
          width, height, 1, format, type, params, &size, &unpadded_row_size,
          &padded_row_size, &skip_size, nullptr)) {
    SetGLError(GL_INVALID_VALUE, func_name, "size too large.");
    return;
  }

  if (bound_pixel_pack_buffer_) {
    base::CheckedNumeric<GLuint> offset = ToGLuint(pixels);
    offset += skip_size;
    if (!offset.IsValid()) {
      SetGLError(GL_INVALID_VALUE, func_name, "skip size too large.");
      return;
    }
    helper_->ReadPixels(xoffset, yoffset, width, height, format, type, 0,
                        offset.ValueOrDefault(0), 0, 0, false);
    InvalidateReadbackBufferShadowDataCHROMIUM(bound_pixel_pack_buffer_);

    CheckGLError();
    return;
  }

  uint32_t service_padded_row_size = 0;
  if (pack_row_length_ > 0 && pack_row_length_ != width) {
    if (!GLES2Util::ComputeImagePaddedRowSize(
            width, format, type, pack_alignment_, &service_padded_row_size)) {
      SetGLError(GL_INVALID_VALUE, func_name, "size too large.");
      return;
    }
  } else {
    service_padded_row_size = padded_row_size;
  }

  if (bound_pixel_pack_transfer_buffer_id_) {
    if (pack_row_length_ > 0 || pack_skip_pixels_ > 0 || pack_skip_rows_ > 0) {
      SetGLError(GL_INVALID_OPERATION, func_name,
                 "No ES3 pack parameters with pixel pack transfer buffer.");
      return;
    }
    DCHECK_EQ(0u, skip_size);
    GLuint offset = ToGLuint(pixels);
    BufferTracker::Buffer* buffer = GetBoundPixelTransferBufferIfValid(
        bound_pixel_pack_transfer_buffer_id_, func_name, offset, size);
    if (buffer && buffer->shm_id() != -1) {
      helper_->ReadPixels(xoffset, yoffset, width, height, format, type,
                          buffer->shm_id(), buffer->shm_offset() + offset, 0, 0,
                          true);
      CheckGLError();
    }
    return;
  }

  if (!pixels) {
    SetGLError(GL_INVALID_OPERATION, func_name, "pixels = NULL");
    return;
  }

  int8_t* dest = reinterpret_cast<int8_t*>(pixels);
  // Advance pixels pointer past the skip rows and skip pixels
  UNSAFE_TODO(dest += skip_size);

  // Transfer by rows.
  // The max rows we can transfer.
  GLsizei remaining_rows = height;
  GLint y_index = yoffset;
  uint32_t group_size = GLES2Util::ComputeImageGroupSize(format, type);
  uint32_t skip_row_bytes = 0;
  if (xoffset < 0) {
    skip_row_bytes = static_cast<uint32_t>(-xoffset) * group_size;
  }
  do {
    // Even if height == 0, we still need to trigger the service side handling
    // in case invalid args are passed in and a GL errro needs to be generated.
    GLsizei desired_size =
        remaining_rows == 0 ? 0
                            : service_padded_row_size * (remaining_rows - 1) +
                                  unpadded_row_size;
    ScopedTransferBufferPtr buffer(desired_size, helper_, transfer_buffer_);
    if (!buffer.valid()) {
      break;
    }
    GLint num_rows = ComputeNumRowsThatFitInBuffer(
        service_padded_row_size, unpadded_row_size, buffer.size(),
        remaining_rows);
    // NOTE: We must look up the address of the result area AFTER allocation
    // of the transfer buffer since the transfer buffer may be reallocated.
    auto result = GetResultAs<Result>();
    if (!result) {
      break;
    }
    result->success = 0;  // mark as failed.
    result->row_length = 0;
    result->num_rows = 0;
    helper_->ReadPixels(xoffset, y_index, width, num_rows, format, type,
                        buffer.shm_id(), buffer.offset(), GetResultShmId(),
                        result.offset(), false);
    if (!WaitForCmd()) {
      break;
    }
    // If it was not marked as successful exit.
    if (!result->success) {
      break;
    }
    if (remaining_rows == 0) {
      break;
    }
    const uint8_t* src = static_cast<const uint8_t*>(buffer.address());
    if (padded_row_size == unpadded_row_size &&
        (pack_row_length_ == 0 || pack_row_length_ == width) &&
        result->row_length == width && result->num_rows == num_rows) {
      // The pixels are tightly packed.
      uint32_t copy_size = unpadded_row_size * num_rows;
      UNSAFE_TODO(memcpy(dest, src, copy_size));
      UNSAFE_TODO(dest += copy_size);
    } else if (result->row_length > 0 && result->num_rows > 0) {
      uint32_t copy_row_size = result->row_length * group_size;
      uint32_t copy_last_row_size = copy_row_size;
      if (copy_row_size + skip_row_bytes > padded_row_size) {
        // We need to avoid writing into next row in case the leading pixels
        // are out-of-bounds and they need to be left untouched.
        copy_row_size = padded_row_size - skip_row_bytes;
      }
      // We have to copy 1 row at a time to avoid writing padding bytes.
      GLint copied_rows = 0;
      for (GLint yy = 0; yy < num_rows; ++yy) {
        if (y_index + yy >= 0 && copied_rows < result->num_rows) {
          if (yy + 1 == num_rows && remaining_rows == num_rows) {
            UNSAFE_TODO(memcpy(dest + skip_row_bytes, src + skip_row_bytes,
                               copy_last_row_size));
          } else {
            UNSAFE_TODO(memcpy(dest + skip_row_bytes, src + skip_row_bytes,
                               copy_row_size));
          }
          ++copied_rows;
        }
        UNSAFE_TODO(dest += padded_row_size);
        UNSAFE_TODO(src += service_padded_row_size);
      }
      DCHECK_EQ(result->num_rows, copied_rows);
    }
    y_index += num_rows;
    remaining_rows -= num_rows;
  } while (remaining_rows);
  CheckGLError();
}

void GLES2Implementation::ActiveTexture(GLenum texture) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glActiveTexture("
                     << GLES2Util::GetStringEnum(texture) << ")");
  GLuint texture_index = texture - GL_TEXTURE0;
  if (texture_index >=
      static_cast<GLuint>(gl_capabilities_.max_combined_texture_image_units)) {
    SetGLErrorInvalidEnum("glActiveTexture", texture, "texture");
    return;
  }

  active_texture_unit_ = texture_index;
  helper_->ActiveTexture(texture);
  CheckGLError();
}

void GLES2Implementation::GenBuffersHelper(GLsizei /* n */,
                                           const GLuint* /* buffers */) {}

void GLES2Implementation::GenFramebuffersHelper(
    GLsizei /* n */,
    const GLuint* /* framebuffers */) {}

void GLES2Implementation::GenRenderbuffersHelper(
    GLsizei /* n */,
    const GLuint* /* renderbuffers */) {}

void GLES2Implementation::GenTexturesHelper(GLsizei /* n */,
                                            const GLuint* /* textures */) {}

void GLES2Implementation::GenVertexArraysOESHelper(GLsizei n,
                                                   const GLuint* arrays) {
  vertex_array_object_manager_->GenVertexArrays(n, arrays);
}

void GLES2Implementation::GenQueriesEXTHelper(GLsizei /* n */,
                                              const GLuint* /* queries */) {}

void GLES2Implementation::GenSamplersHelper(GLsizei /* n */,
                                            const GLuint* /* samplers */) {}

void GLES2Implementation::GenTransformFeedbacksHelper(
    GLsizei /* n */,
    const GLuint* /* transformfeedbacks */) {}

// NOTE #1: On old versions of OpenGL, calling glBindXXX with an unused id
// generates a new resource. On newer versions of OpenGL they don't. The code
// related to binding below will need to change if we switch to the new OpenGL
// model. Specifically it assumes a bind will succeed which is always true in
// the old model but possibly not true in the new model if another context has
// deleted the resource.

// NOTE #2: There is a bug in some BindXXXHelpers, that IDs might be marked as
// used even when Bind has failed. However, the bug is minor compared to the
// overhead & duplicated checking in client side.

void GLES2Implementation::BindBufferHelper(GLenum target, GLuint buffer_id) {
  // TODO(gman): See note #1 above.
  bool changed = false;
  switch (target) {
    case GL_ARRAY_BUFFER:
      if (bound_array_buffer_ != buffer_id) {
        bound_array_buffer_ = buffer_id;
        changed = true;
      }
      break;
    case GL_COPY_READ_BUFFER:
      if (bound_copy_read_buffer_ != buffer_id) {
        bound_copy_read_buffer_ = buffer_id;
        changed = true;
      }
      break;
    case GL_COPY_WRITE_BUFFER:
      if (bound_copy_write_buffer_ != buffer_id) {
        bound_copy_write_buffer_ = buffer_id;
        changed = true;
      }
      break;
    case GL_ELEMENT_ARRAY_BUFFER:
      changed = vertex_array_object_manager_->BindElementArray(buffer_id);
      break;
    case GL_PIXEL_PACK_BUFFER:
      if (bound_pixel_pack_buffer_ != buffer_id) {
        bound_pixel_pack_buffer_ = buffer_id;
        changed = true;
      }
      break;
    case GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM:
      bound_pixel_pack_transfer_buffer_id_ = buffer_id;
      break;
    case GL_PIXEL_UNPACK_BUFFER:
      if (bound_pixel_unpack_buffer_ != buffer_id) {
        bound_pixel_unpack_buffer_ = buffer_id;
        changed = true;
      }
      break;
    case GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM:
      bound_pixel_unpack_transfer_buffer_id_ = buffer_id;
      break;
    case GL_TRANSFORM_FEEDBACK_BUFFER:
      if (bound_transform_feedback_buffer_ != buffer_id) {
        bound_transform_feedback_buffer_ = buffer_id;
        changed = true;
      }
      break;
    case GL_UNIFORM_BUFFER:
      if (bound_uniform_buffer_ != buffer_id) {
        bound_uniform_buffer_ = buffer_id;
        changed = true;
      }
      break;
    default:
      changed = true;
      break;
  }
  // TODO(gman): See note #2 above.
  if (changed) {
    GetIdHandler(SharedIdNamespaces::kBuffers)
        ->MarkAsUsedForBind(this, target, buffer_id,
                            &GLES2Implementation::BindBufferStub);
  }
}

void GLES2Implementation::BindBufferStub(GLenum target, GLuint buffer) {
  helper_->BindBuffer(target, buffer);
}

bool GLES2Implementation::UpdateIndexedBufferState(GLenum target,
                                                   GLuint index,
                                                   GLuint buffer_id,
                                                   const char* function_name) {
  switch (target) {
    case GL_TRANSFORM_FEEDBACK_BUFFER:
      if (index >=
          static_cast<GLuint>(
              gl_capabilities_.max_transform_feedback_separate_attribs)) {
        SetGLError(GL_INVALID_VALUE, function_name, "index out of range");
        return false;
      }
      bound_transform_feedback_buffer_ = buffer_id;
      break;
    case GL_UNIFORM_BUFFER:
      if (index >=
          static_cast<GLuint>(gl_capabilities_.max_uniform_buffer_bindings)) {
        SetGLError(GL_INVALID_VALUE, function_name, "index out of range");
        return false;
      }
      bound_uniform_buffer_ = buffer_id;
      break;
    default:
      SetGLError(GL_INVALID_ENUM, function_name, "invalid target");
      return false;
  }
  return true;
}

void GLES2Implementation::BindBufferBaseHelper(GLenum target,
                                               GLuint index,
                                               GLuint buffer_id) {
  // TODO(zmo): See note #1 above.
  // TODO(zmo): See note #2 above.
  if (UpdateIndexedBufferState(target, index, buffer_id, "glBindBufferBase")) {
    GetIdHandler(SharedIdNamespaces::kBuffers)
        ->MarkAsUsedForBind(this, target, index, buffer_id,
                            &GLES2Implementation::BindBufferBaseStub);
  }
}

void GLES2Implementation::BindBufferBaseStub(GLenum target,
                                             GLuint index,
                                             GLuint buffer) {
  helper_->BindBufferBase(target, index, buffer);
}

void GLES2Implementation::BindBufferRangeHelper(GLenum target,
                                                GLuint index,
                                                GLuint buffer_id,
                                                GLintptr offset,
                                                GLsizeiptr size) {
  // TODO(zmo): See note #1 above.
  // TODO(zmo): See note #2 above.
  if (UpdateIndexedBufferState(target, index, buffer_id, "glBindBufferRange")) {
    GetIdHandler(SharedIdNamespaces::kBuffers)
        ->MarkAsUsedForBind(this, target, index, buffer_id, offset, size,
                            &GLES2Implementation::BindBufferRangeStub);
  }
}

void GLES2Implementation::BindBufferRangeStub(GLenum target,
                                              GLuint index,
                                              GLuint buffer,
                                              GLintptr offset,
                                              GLsizeiptr size) {
  helper_->BindBufferRange(target, index, buffer, offset, size);
}

void GLES2Implementation::BindFramebufferHelper(GLenum target,
                                                GLuint framebuffer) {
  // TODO(gman): See note #1 above.
  bool changed = false;
  switch (target) {
    case GL_FRAMEBUFFER:
      if (bound_framebuffer_ != framebuffer ||
          bound_read_framebuffer_ != framebuffer) {
        bound_framebuffer_ = framebuffer;
        bound_read_framebuffer_ = framebuffer;
        changed = true;
      }
      break;
    case GL_READ_FRAMEBUFFER:
#if EXPENSIVE_DCHECKS_ARE_ON()
      DCHECK(gl_capabilities_.major_version >= 3 ||
             IsChromiumFramebufferMultisampleAvailable());
#endif
      if (bound_read_framebuffer_ != framebuffer) {
        bound_read_framebuffer_ = framebuffer;
        changed = true;
      }
      break;
    case GL_DRAW_FRAMEBUFFER:
#if EXPENSIVE_DCHECKS_ARE_ON()
      DCHECK(gl_capabilities_.major_version >= 3 ||
             IsChromiumFramebufferMultisampleAvailable());
#endif
      if (bound_framebuffer_ != framebuffer) {
        bound_framebuffer_ = framebuffer;
        changed = true;
      }
      break;
    default:
      SetGLErrorInvalidEnum("glBindFramebuffer", target, "target");
      return;
  }

  if (changed) {
    if (framebuffer != 0)
      GetIdAllocator(IdNamespaces::kFramebuffers)->MarkAsUsed(framebuffer);
    helper_->BindFramebuffer(target, framebuffer);
  }
}

void GLES2Implementation::BindRenderbufferHelper(GLenum target,
                                                 GLuint renderbuffer) {
  // TODO(gman): See note #1 above.
  bool changed = false;
  switch (target) {
    case GL_RENDERBUFFER:
      if (bound_renderbuffer_ != renderbuffer) {
        bound_renderbuffer_ = renderbuffer;
        changed = true;
      }
      break;
    default:
      changed = true;
      break;
  }
  // TODO(zmo): See note #2 above.
  if (changed) {
    GetIdHandler(SharedIdNamespaces::kRenderbuffers)
        ->MarkAsUsedForBind(this, target, renderbuffer,
                            &GLES2Implementation::BindRenderbufferStub);
  }
}

void GLES2Implementation::BindRenderbufferStub(GLenum target,
                                               GLuint renderbuffer) {
  helper_->BindRenderbuffer(target, renderbuffer);
}

void GLES2Implementation::BindSamplerHelper(GLuint unit, GLuint sampler) {
  helper_->BindSampler(unit, sampler);
}

void GLES2Implementation::BindTextureHelper(GLenum target, GLuint texture) {
  // TODO(gman): See note #1 above.
  bool changed = false;
  internal::TextureUnit& unit = texture_units_[active_texture_unit_];
  switch (target) {
    case GL_TEXTURE_2D:
      if (unit.bound_texture_2d != texture) {
        unit.bound_texture_2d = texture;
        changed = true;
      }
      break;
    case GL_TEXTURE_CUBE_MAP:
      if (unit.bound_texture_cube_map != texture) {
        unit.bound_texture_cube_map = texture;
        changed = true;
      }
      break;
    case GL_TEXTURE_EXTERNAL_OES:
      if (unit.bound_texture_external_oes != texture) {
        unit.bound_texture_external_oes = texture;
        changed = true;
      }
      break;
    case GL_TEXTURE_RECTANGLE_ARB:
      if (unit.bound_texture_rectangle_arb != texture) {
        unit.bound_texture_rectangle_arb = texture;
        changed = true;
      }
      break;
    default:
      changed = true;
      break;
  }
  // TODO(gman): See note #2 above.
  if (changed) {
    GetIdHandler(SharedIdNamespaces::kTextures)
        ->MarkAsUsedForBind(this, target, texture,
                            &GLES2Implementation::BindTextureStub);
  }
}

void GLES2Implementation::BindTextureStub(GLenum target, GLuint texture) {
  helper_->BindTexture(target, texture);
}

void GLES2Implementation::BindTransformFeedbackHelper(
    GLenum target,
    GLuint transformfeedback) {
  helper_->BindTransformFeedback(target, transformfeedback);
}

void GLES2Implementation::BindVertexArrayOESHelper(GLuint array) {
  bool changed = false;
  if (vertex_array_object_manager_->BindVertexArray(array, &changed)) {
    if (changed) {
      // Unlike other BindXXXHelpers we don't call MarkAsUsedForBind
      // because unlike other resources VertexArrayObject ids must
      // be generated by GenVertexArrays. A random id to Bind will not
      // generate a new object.
      helper_->BindVertexArrayOES(array);
    }
  } else {
    SetGLError(GL_INVALID_OPERATION, "glBindVertexArrayOES",
               "id was not generated with glGenVertexArrayOES");
  }
}

void GLES2Implementation::UseProgramHelper(GLuint program) {
  if (current_program_ != program) {
    current_program_ = program;
    helper_->UseProgram(program);
  }
}

bool GLES2Implementation::IsBufferReservedId(GLuint id) {
  // TODO(crbug.com/439823997): Remove callers from autogenerated code and
  // delete this function.
  return false;
}

void GLES2Implementation::DeleteBuffersHelper(GLsizei n,
                                              const GLuint* buffers) {
  if (!GetIdHandler(SharedIdNamespaces::kBuffers)
           ->FreeIds(this, n, buffers,
                     &GLES2Implementation::DeleteBuffersStub)) {
    SetGLError(GL_INVALID_VALUE, "glDeleteBuffers",
               "id not created by this context.");
    return;
  }
  for (GLsizei ii = 0; ii < n; ++ii) {
    if (UNSAFE_TODO(buffers[ii]) == bound_array_buffer_) {
      bound_array_buffer_ = 0;
    }
    if (UNSAFE_TODO(buffers[ii]) == bound_copy_read_buffer_) {
      bound_copy_read_buffer_ = 0;
    }
    if (UNSAFE_TODO(buffers[ii]) == bound_copy_write_buffer_) {
      bound_copy_write_buffer_ = 0;
    }
    if (UNSAFE_TODO(buffers[ii]) == bound_pixel_pack_buffer_) {
      bound_pixel_pack_buffer_ = 0;
    }
    if (UNSAFE_TODO(buffers[ii]) == bound_pixel_unpack_buffer_) {
      bound_pixel_unpack_buffer_ = 0;
    }
    if (UNSAFE_TODO(buffers[ii]) == bound_transform_feedback_buffer_) {
      bound_transform_feedback_buffer_ = 0;
    }
    if (UNSAFE_TODO(buffers[ii]) == bound_uniform_buffer_) {
      bound_uniform_buffer_ = 0;
    }
    vertex_array_object_manager_->UnbindBuffer(UNSAFE_TODO(buffers[ii]));

    BufferTracker::Buffer* buffer =
        buffer_tracker_->GetBuffer(UNSAFE_TODO(buffers[ii]));
    if (buffer)
      RemoveTransferBuffer(buffer);

    readback_buffer_shadow_tracker_->RemoveBuffer(UNSAFE_TODO(buffers[ii]));

    if (UNSAFE_TODO(buffers[ii]) == bound_pixel_unpack_transfer_buffer_id_) {
      bound_pixel_unpack_transfer_buffer_id_ = 0;
    }
  }
}

void GLES2Implementation::DeleteBuffersStub(GLsizei n, const GLuint* buffers) {
  helper_->DeleteBuffersImmediate(n, buffers);
}

void GLES2Implementation::DeleteFramebuffersHelper(GLsizei n,
                                                   const GLuint* framebuffers) {
  helper_->DeleteFramebuffersImmediate(n, framebuffers);
  IdAllocator* id_allocator = GetIdAllocator(IdNamespaces::kFramebuffers);
  for (GLsizei ii = 0; ii < n; ++ii) {
    id_allocator->FreeID(UNSAFE_TODO(framebuffers[ii]));
    if (UNSAFE_TODO(framebuffers[ii]) == bound_framebuffer_) {
      bound_framebuffer_ = 0;
    }
    if (UNSAFE_TODO(framebuffers[ii]) == bound_read_framebuffer_) {
      bound_read_framebuffer_ = 0;
    }
  }
}

void GLES2Implementation::DeleteRenderbuffersHelper(
    GLsizei n,
    const GLuint* renderbuffers) {
  if (!GetIdHandler(SharedIdNamespaces::kRenderbuffers)
           ->FreeIds(this, n, renderbuffers,
                     &GLES2Implementation::DeleteRenderbuffersStub)) {
    SetGLError(GL_INVALID_VALUE, "glDeleteRenderbuffers",
               "id not created by this context.");
    return;
  }
  for (GLsizei ii = 0; ii < n; ++ii) {
    if (UNSAFE_TODO(renderbuffers[ii]) == bound_renderbuffer_) {
      bound_renderbuffer_ = 0;
    }
  }
}

void GLES2Implementation::DeleteRenderbuffersStub(GLsizei n,
                                                  const GLuint* renderbuffers) {
  helper_->DeleteRenderbuffersImmediate(n, renderbuffers);
}

void GLES2Implementation::DeleteTexturesHelper(GLsizei n,
                                               const GLuint* textures) {
  if (!GetIdHandler(SharedIdNamespaces::kTextures)
           ->FreeIds(this, n, textures,
                     &GLES2Implementation::DeleteTexturesStub)) {
    SetGLError(GL_INVALID_VALUE, "glDeleteTextures",
               "id not created by this context.");
    return;
  }
  UnbindTexturesHelper(n, textures);
}

void GLES2Implementation::UnbindTexturesHelper(GLsizei n,
                                               const GLuint* textures) {
  for (GLsizei ii = 0; ii < n; ++ii) {
    for (GLint tt = 0; tt < gl_capabilities_.max_combined_texture_image_units;
         ++tt) {
      internal::TextureUnit& unit = texture_units_[tt];
      if (UNSAFE_TODO(textures[ii]) == unit.bound_texture_2d) {
        unit.bound_texture_2d = 0;
      }
      if (UNSAFE_TODO(textures[ii]) == unit.bound_texture_cube_map) {
        unit.bound_texture_cube_map = 0;
      }
      if (UNSAFE_TODO(textures[ii]) == unit.bound_texture_external_oes) {
        unit.bound_texture_external_oes = 0;
      }
      if (UNSAFE_TODO(textures[ii]) == unit.bound_texture_rectangle_arb) {
        unit.bound_texture_rectangle_arb = 0;
      }
    }
  }
}

void GLES2Implementation::DeleteTexturesStub(GLsizei n,
                                             const GLuint* textures) {
  helper_->DeleteTexturesImmediate(n, textures);
}

void GLES2Implementation::DeleteVertexArraysOESHelper(GLsizei n,
                                                      const GLuint* arrays) {
  vertex_array_object_manager_->DeleteVertexArrays(n, arrays);
  helper_->DeleteVertexArraysOESImmediate(n, arrays);
  IdAllocator* id_allocator = GetIdAllocator(IdNamespaces::kVertexArrays);
  for (GLsizei ii = 0; ii < n; ++ii)
    id_allocator->FreeID(UNSAFE_TODO(arrays[ii]));
}

void GLES2Implementation::DeleteSamplersStub(GLsizei n,
                                             const GLuint* samplers) {
  helper_->DeleteSamplersImmediate(n, samplers);
}

void GLES2Implementation::DeleteSamplersHelper(GLsizei n,
                                               const GLuint* samplers) {
  if (!GetIdHandler(SharedIdNamespaces::kSamplers)
           ->FreeIds(this, n, samplers,
                     &GLES2Implementation::DeleteSamplersStub)) {
    SetGLError(GL_INVALID_VALUE, "glDeleteSamplers",
               "id not created by this context.");
    return;
  }
}

void GLES2Implementation::DeleteTransformFeedbacksHelper(
    GLsizei n,
    const GLuint* transformfeedbacks) {
  helper_->DeleteTransformFeedbacksImmediate(n, transformfeedbacks);
  IdAllocator* id_allocator = GetIdAllocator(IdNamespaces::kTransformFeedbacks);
  for (GLsizei ii = 0; ii < n; ++ii)
    id_allocator->FreeID(UNSAFE_TODO(transformfeedbacks[ii]));
}

void GLES2Implementation::DisableVertexAttribArray(GLuint index) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDisableVertexAttribArray("
                     << index << ")");
  vertex_array_object_manager_->SetAttribEnable(index, false);
  helper_->DisableVertexAttribArray(index);
  CheckGLError();
}

void GLES2Implementation::EnableVertexAttribArray(GLuint index) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glEnableVertexAttribArray("
                     << index << ")");
  vertex_array_object_manager_->SetAttribEnable(index, true);
  helper_->EnableVertexAttribArray(index);
  CheckGLError();
}

void GLES2Implementation::DrawArrays(GLenum mode, GLint first, GLsizei count) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDrawArrays("
                     << GLES2Util::GetStringDrawMode(mode) << ", " << first
                     << ", " << count << ")");
  if (count < 0) {
    SetGLError(GL_INVALID_VALUE, "glDrawArrays", "count < 0");
    return;
  }
  helper_->DrawArrays(mode, first, count);
  CheckGLError();
}

void GLES2Implementation::GetVertexAttribfv(GLuint index,
                                            GLenum pname,
                                            GLfloat* params) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetVertexAttribfv(" << index
                     << ", " << GLES2Util::GetStringVertexAttribute(pname)
                     << ", " << static_cast<const void*>(params) << ")");
  uint32_t value = 0;
  if (vertex_array_object_manager_->GetVertexAttrib(index, pname, &value)) {
    *params = static_cast<GLfloat>(value);
    return;
  }
  TRACE_EVENT0("gpu", "GLES2::GetVertexAttribfv");
  typedef cmds::GetVertexAttribfv::Result Result;
  // Limit scope of result to avoid overlap with CheckGLError()
  {
    auto result = GetResultAs<Result>();
    if (!result) {
      return;
    }
    result->SetNumResults(0);
    helper_->GetVertexAttribfv(index, pname, GetResultShmId(), result.offset());
    if (!WaitForCmd()) {
      return;
    }
    result->CopyResult(params);
    UNSAFE_TODO(GPU_CLIENT_LOG_CODE_BLOCK({
      for (int32_t i = 0; i < result->GetNumResults(); ++i) {
        GPU_CLIENT_LOG("  " << i << ": " << result->GetData()[i]);
      }
    }));
  }
  CheckGLError();
}

void GLES2Implementation::GetVertexAttribiv(GLuint index,
                                            GLenum pname,
                                            GLint* params) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetVertexAttribiv(" << index
                     << ", " << GLES2Util::GetStringVertexAttribute(pname)
                     << ", " << static_cast<const void*>(params) << ")");
  uint32_t value = 0;
  if (vertex_array_object_manager_->GetVertexAttrib(index, pname, &value)) {
    *params = static_cast<GLint>(value);
    return;
  }
  TRACE_EVENT0("gpu", "GLES2::GetVertexAttribiv");
  typedef cmds::GetVertexAttribiv::Result Result;
  // Limit scope of result to avoid overlap with CheckGLError()
  {
    auto result = GetResultAs<Result>();
    if (!result) {
      return;
    }
    result->SetNumResults(0);
    helper_->GetVertexAttribiv(index, pname, GetResultShmId(), result.offset());
    if (!WaitForCmd()) {
      return;
    }
    result->CopyResult(params);
    UNSAFE_TODO(GPU_CLIENT_LOG_CODE_BLOCK({
      for (int32_t i = 0; i < result->GetNumResults(); ++i) {
        GPU_CLIENT_LOG("  " << i << ": " << result->GetData()[i]);
      }
    }));
  }
  CheckGLError();
}

void GLES2Implementation::GetVertexAttribIiv(GLuint index,
                                             GLenum pname,
                                             GLint* params) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetVertexAttribIiv(" << index
                     << ", " << GLES2Util::GetStringVertexAttribute(pname)
                     << ", " << static_cast<const void*>(params) << ")");
  uint32_t value = 0;
  if (vertex_array_object_manager_->GetVertexAttrib(index, pname, &value)) {
    *params = static_cast<GLint>(value);
    return;
  }
  TRACE_EVENT0("gpu", "GLES2::GetVertexAttribIiv");
  typedef cmds::GetVertexAttribiv::Result Result;
  // Limit scope of result to avoid overlap with CheckGLError()
  {
    auto result = GetResultAs<Result>();
    if (!result) {
      return;
    }
    result->SetNumResults(0);
    helper_->GetVertexAttribIiv(index, pname, GetResultShmId(),
                                result.offset());
    if (!WaitForCmd()) {
      return;
    }
    result->CopyResult(params);
    UNSAFE_TODO(GPU_CLIENT_LOG_CODE_BLOCK({
      for (int32_t i = 0; i < result->GetNumResults(); ++i) {
        GPU_CLIENT_LOG("  " << i << ": " << result->GetData()[i]);
      }
    }));
  }
  CheckGLError();
}

void GLES2Implementation::GetVertexAttribIuiv(GLuint index,
                                              GLenum pname,
                                              GLuint* params) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetVertexAttribIuiv(" << index
                     << ", " << GLES2Util::GetStringVertexAttribute(pname)
                     << ", " << static_cast<const void*>(params) << ")");
  uint32_t value = 0;
  if (vertex_array_object_manager_->GetVertexAttrib(index, pname, &value)) {
    *params = static_cast<GLuint>(value);
    return;
  }
  TRACE_EVENT0("gpu", "GLES2::GetVertexAttribIuiv");
  typedef cmds::GetVertexAttribiv::Result Result;
  // Limit scope of result to avoid overlap with CheckGLError()
  {
    auto result = GetResultAs<Result>();
    if (!result) {
      return;
    }
    result->SetNumResults(0);
    helper_->GetVertexAttribIuiv(index, pname, GetResultShmId(),
                                 result.offset());
    if (!WaitForCmd()) {
      return;
    }
    result->CopyResult(params);
    UNSAFE_TODO(GPU_CLIENT_LOG_CODE_BLOCK({
      for (int32_t i = 0; i < result->GetNumResults(); ++i) {
        GPU_CLIENT_LOG("  " << i << ": " << result->GetData()[i]);
      }
    }));
  }
  CheckGLError();
}

GLenum GLES2Implementation::GetGraphicsResetStatusKHR() {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetGraphicsResetStatusKHR()");
  // If any context (including ourselves) has seen itself become lost,
  // then it will have told the ShareGroup, so just report its status.
  if (share_group_->IsLost())
    return GL_UNKNOWN_CONTEXT_RESET_KHR;
  return GL_NO_ERROR;
}

void* GLES2Implementation::MapBufferSubDataCHROMIUM(GLuint target,
                                                    GLintptr offset,
                                                    GLsizeiptr size,
                                                    GLenum access) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glMapBufferSubDataCHROMIUM("
                     << target << ", " << offset << ", " << size << ", "
                     << GLES2Util::GetStringEnum(access) << ")");
  // NOTE: target is NOT checked because the service will check it
  // and we don't know what targets are valid.
  if (access != GL_WRITE_ONLY) {
    SetGLErrorInvalidEnum("glMapBufferSubDataCHROMIUM", access, "access");
    return nullptr;
  }
  if (!ValidateSize("glMapBufferSubDataCHROMIUM", size) ||
      !ValidateOffset("glMapBufferSubDataCHROMIUM", offset)) {
    return nullptr;
  }

  int32_t shm_id;
  unsigned int shm_offset;
  base::span<uint8_t> buffer =
      mapped_memory_->Alloc(size, &shm_id, &shm_offset);
  if (buffer.empty()) {
    SetGLError(GL_OUT_OF_MEMORY, "glMapBufferSubDataCHROMIUM", "out of memory");
    return nullptr;
  }

  std::pair<MappedBufferMap::iterator, bool> result =
      mapped_buffers_.insert(std::make_pair(
          buffer.data(), MappedBuffer(access, shm_id, buffer, shm_offset,
                                      target, offset, size)));
  DCHECK(result.second);
  GPU_CLIENT_LOG("  returned " << buffer.data());
  return buffer.data();
}

void GLES2Implementation::UnmapBufferSubDataCHROMIUM(const void* mem) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUnmapBufferSubDataCHROMIUM("
                     << mem << ")");
  MappedBufferMap::iterator it = mapped_buffers_.find(mem);
  if (it == mapped_buffers_.end()) {
    SetGLError(GL_INVALID_VALUE, "UnmapBufferSubDataCHROMIUM",
               "buffer not mapped");
    return;
  }
  const MappedBuffer& mb = it->second;
  helper_->BufferSubData(mb.target, mb.offset, mb.size, mb.shm_id,
                         mb.shm_offset);
  InvalidateReadbackBufferShadowDataCHROMIUM(GetBoundBufferHelper(mb.target));
  mapped_memory_->FreePendingToken(mb.shm_memory.data(),
                                   helper_->InsertToken());
  mapped_buffers_.erase(it);
  CheckGLError();
}

GLuint GLES2Implementation::GetBoundBufferHelper(GLenum target) {
  GLenum binding = GLES2Util::MapBufferTargetToBindingEnum(target);
  GLint id = 0;
  bool cached = GetHelper(binding, &id);
  DCHECK(cached);
  return static_cast<GLuint>(id);
}

void GLES2Implementation::ClearMappedBufferMap() {
  for (auto& buffer : mapped_buffers_) {
    if (!buffer.second.shm_memory.empty()) {
      mapped_memory_->FreePendingToken(buffer.second.shm_memory.data(),
                                       helper_->InsertToken());
    }
  }
  mapped_buffers_.clear();
}

void GLES2Implementation::ClearMappedTextureMap() {
  for (auto& texture : mapped_textures_) {
    if (!texture.second.shm_memory.empty()) {
      mapped_memory_->FreePendingToken(texture.second.shm_memory.data(),
                                       helper_->InsertToken());
    }
  }
  mapped_textures_.clear();
}

void* GLES2Implementation::MapTexSubImage2DCHROMIUM(GLenum target,
                                                    GLint level,
                                                    GLint xoffset,
                                                    GLint yoffset,
                                                    GLsizei width,
                                                    GLsizei height,
                                                    GLenum format,
                                                    GLenum type,
                                                    GLenum access) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glMapTexSubImage2DCHROMIUM("
                     << target << ", " << level << ", " << xoffset << ", "
                     << yoffset << ", " << width << ", " << height << ", "
                     << GLES2Util::GetStringTextureFormat(format) << ", "
                     << GLES2Util::GetStringPixelType(type) << ", "
                     << GLES2Util::GetStringEnum(access) << ")");
  if (access != GL_WRITE_ONLY) {
    SetGLErrorInvalidEnum("glMapTexSubImage2DCHROMIUM", access, "access");
    return nullptr;
  }
  // NOTE: target is NOT checked because the service will check it
  // and we don't know what targets are valid.
  if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0) {
    SetGLError(GL_INVALID_VALUE, "glMapTexSubImage2DCHROMIUM",
               "bad dimensions");
    return nullptr;
  }
  uint32_t size;
  if (!GLES2Util::ComputeImageDataSizes(width, height, 1, format, type,
                                        unpack_alignment_, &size, nullptr,
                                        nullptr)) {
    SetGLError(GL_INVALID_VALUE, "glMapTexSubImage2DCHROMIUM",
               "image size too large");
    return nullptr;
  }
  int32_t shm_id;
  unsigned int shm_offset;
  base::span<uint8_t> buffer =
      mapped_memory_->Alloc(size, &shm_id, &shm_offset);
  if (buffer.empty()) {
    SetGLError(GL_OUT_OF_MEMORY, "glMapTexSubImage2DCHROMIUM", "out of memory");
    return nullptr;
  }

  std::pair<MappedTextureMap::iterator, bool> result =
      mapped_textures_.insert(std::make_pair(
          buffer.data(),
          MappedTexture(access, shm_id, buffer, shm_offset, target, level,
                        xoffset, yoffset, width, height, format, type)));
  DCHECK(result.second);
  GPU_CLIENT_LOG("  returned " << buffer.data());
  return buffer.data();
}

void GLES2Implementation::UnmapTexSubImage2DCHROMIUM(const void* mem) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUnmapTexSubImage2DCHROMIUM("
                     << mem << ")");
  MappedTextureMap::iterator it = mapped_textures_.find(mem);
  if (it == mapped_textures_.end()) {
    SetGLError(GL_INVALID_VALUE, "UnmapTexSubImage2DCHROMIUM",
               "texture not mapped");
    return;
  }
  const MappedTexture& mt = it->second;
  helper_->TexSubImage2D(mt.target, mt.level, mt.xoffset, mt.yoffset, mt.width,
                         mt.height, mt.format, mt.type, mt.shm_id,
                         mt.shm_offset, GL_FALSE);
  mapped_memory_->FreePendingToken(mt.shm_memory.data(),
                                   helper_->InsertToken());
  mapped_textures_.erase(it);
  CheckGLError();
}

const GLchar* GLES2Implementation::GetRequestableExtensionsCHROMIUM() {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix()
                     << "] glGetRequestableExtensionsCHROMIUM()");
  TRACE_EVENT0("gpu",
               "GLES2Implementation::GetRequestableExtensionsCHROMIUM()");
  const char* result = nullptr;
  // Clear the bucket so if the command fails nothing will be in it.
  helper_->SetBucketSize(kResultBucketId, 0);
  helper_->GetRequestableExtensionsCHROMIUM(kResultBucketId);
  std::string str;
  if (GetBucketAsString(kResultBucketId, &str)) {
    // The set of requestable extensions shrinks as we enable
    // them. Because we don't know when the client will stop referring
    // to a previous one it queries (see GetString) we need to cache
    // the unique results.
    // TODO: Here we could save memory by defining RequestExtensions
    // invalidating the GL_EXTENSIONS string. http://crbug.com/586414
    result = gl_strings_.insert(str).first->c_str();
  }
  GPU_CLIENT_LOG("  returned " << result);
  return reinterpret_cast<const GLchar*>(result);
}

// TODO(gman): Remove this command. It's here for WebGL but is incompatible
// with VirtualGL contexts.
void GLES2Implementation::RequestExtensionCHROMIUM(const char* extension) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glRequestExtensionCHROMIUM("
                     << extension << ")");
  InvalidateCachedExtensions();
  SetBucketAsCString(kResultBucketId, extension);
  helper_->RequestExtensionCHROMIUM(kResultBucketId);
  helper_->SetBucketSize(kResultBucketId, 0);

  struct ExtensionCheck {
    const char* extension;
    raw_ptr<ExtensionStatus> status;
  };
  const auto checks = std::to_array<ExtensionCheck>({
      {
          "GL_CHROMIUM_framebuffer_multisample",
          &chromium_framebuffer_multisample_,
      },
  });
  for (const ExtensionCheck& check : checks) {
    if (*check.status == kUnavailableExtensionStatus &&
        !UNSAFE_TODO(strcmp(extension, check.extension))) {
      *check.status = kUnknownExtensionStatus;
    }
  }
}

void GLES2Implementation::GetProgramInfoCHROMIUMHelper(
    GLuint program,
    std::vector<int8_t>* result) {
  DCHECK(result);
  // Clear the bucket so if the command fails nothing will be in it.
  helper_->SetBucketSize(kResultBucketId, 0);
  helper_->GetProgramInfoCHROMIUM(program, kResultBucketId);
  GetBucketContents(kResultBucketId, result);
}

void GLES2Implementation::GetProgramInfoCHROMIUM(GLuint program,
                                                 GLsizei bufsize,
                                                 GLsizei* size,
                                                 void* info) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  if (bufsize < 0) {
    SetGLError(GL_INVALID_VALUE, "glProgramInfoCHROMIUM",
               "bufsize less than 0.");
    return;
  }
  if (size == nullptr) {
    SetGLError(GL_INVALID_VALUE, "glProgramInfoCHROMIUM", "size is null.");
    return;
  }
  // Make sure they've set size to 0 else the value will be undefined on
  // lost context.
  DCHECK_EQ(0, *size);
  std::vector<int8_t> result;
  GetProgramInfoCHROMIUMHelper(program, &result);
  if (result.empty()) {
    return;
  }
  *size = result.size();
  if (!info) {
    return;
  }
  if (static_cast<size_t>(bufsize) < result.size()) {
    SetGLError(GL_INVALID_OPERATION, "glProgramInfoCHROMIUM",
               "bufsize is too small for result.");
    return;
  }
  UNSAFE_TODO(memcpy(info, &result[0], result.size()));
}

void GLES2Implementation::GetUniformBlocksCHROMIUMHelper(
    GLuint program,
    std::vector<int8_t>* result) {
  DCHECK(result);
  // Clear the bucket so if the command fails nothing will be in it.
  helper_->SetBucketSize(kResultBucketId, 0);
  helper_->GetUniformBlocksCHROMIUM(program, kResultBucketId);
  GetBucketContents(kResultBucketId, result);
}

void GLES2Implementation::GetUniformBlocksCHROMIUM(GLuint program,
                                                   GLsizei bufsize,
                                                   GLsizei* size,
                                                   void* info) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  if (bufsize < 0) {
    SetGLError(GL_INVALID_VALUE, "glGetUniformBlocksCHROMIUM",
               "bufsize less than 0.");
    return;
  }
  if (size == nullptr) {
    SetGLError(GL_INVALID_VALUE, "glGetUniformBlocksCHROMIUM", "size is null.");
    return;
  }
  // Make sure they've set size to 0 else the value will be undefined on
  // lost context.
  DCHECK_EQ(0, *size);
  std::vector<int8_t> result;
  GetUniformBlocksCHROMIUMHelper(program, &result);
  if (result.empty()) {
    return;
  }
  *size = result.size();
  if (!info) {
    return;
  }
  if (static_cast<size_t>(bufsize) < result.size()) {
    SetGLError(GL_INVALID_OPERATION, "glGetUniformBlocksCHROMIUM",
               "bufsize is too small for result.");
    return;
  }
  UNSAFE_TODO(memcpy(info, &result[0], result.size()));
}

void GLES2Implementation::GetUniformsES3CHROMIUMHelper(
    GLuint program,
    std::vector<int8_t>* result) {
  DCHECK(result);
  // Clear the bucket so if the command fails nothing will be in it.
  helper_->SetBucketSize(kResultBucketId, 0);
  helper_->GetUniformsES3CHROMIUM(program, kResultBucketId);
  GetBucketContents(kResultBucketId, result);
}

void GLES2Implementation::GetUniformsES3CHROMIUM(GLuint program,
                                                 GLsizei bufsize,
                                                 GLsizei* size,
                                                 void* info) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  if (bufsize < 0) {
    SetGLError(GL_INVALID_VALUE, "glGetUniformsES3CHROMIUM",
               "bufsize less than 0.");
    return;
  }
  if (size == nullptr) {
    SetGLError(GL_INVALID_VALUE, "glGetUniformsES3CHROMIUM", "size is null.");
    return;
  }
  // Make sure they've set size to 0 else the value will be undefined on
  // lost context.
  DCHECK_EQ(0, *size);
  std::vector<int8_t> result;
  GetUniformsES3CHROMIUMHelper(program, &result);
  if (result.empty()) {
    return;
  }
  *size = result.size();
  if (!info) {
    return;
  }
  if (static_cast<size_t>(bufsize) < result.size()) {
    SetGLError(GL_INVALID_OPERATION, "glGetUniformsES3CHROMIUM",
               "bufsize is too small for result.");
    return;
  }
  UNSAFE_TODO(memcpy(info, &result[0], result.size()));
}

void GLES2Implementation::GetTransformFeedbackVaryingsCHROMIUMHelper(
    GLuint program,
    std::vector<int8_t>* result) {
  DCHECK(result);
  // Clear the bucket so if the command fails nothing will be in it.
  helper_->SetBucketSize(kResultBucketId, 0);
  helper_->GetTransformFeedbackVaryingsCHROMIUM(program, kResultBucketId);
  GetBucketContents(kResultBucketId, result);
}

void GLES2Implementation::GetTransformFeedbackVaryingsCHROMIUM(GLuint program,
                                                               GLsizei bufsize,
                                                               GLsizei* size,
                                                               void* info) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  if (bufsize < 0) {
    SetGLError(GL_INVALID_VALUE, "glGetTransformFeedbackVaryingsCHROMIUM",
               "bufsize less than 0.");
    return;
  }
  if (size == nullptr) {
    SetGLError(GL_INVALID_VALUE, "glGetTransformFeedbackVaryingsCHROMIUM",
               "size is null.");
    return;
  }
  // Make sure they've set size to 0 else the value will be undefined on
  // lost context.
  DCHECK_EQ(0, *size);
  std::vector<int8_t> result;
  GetTransformFeedbackVaryingsCHROMIUMHelper(program, &result);
  if (result.empty()) {
    return;
  }
  *size = result.size();
  if (!info) {
    return;
  }
  if (static_cast<size_t>(bufsize) < result.size()) {
    SetGLError(GL_INVALID_OPERATION, "glGetTransformFeedbackVaryingsCHROMIUM",
               "bufsize is too small for result.");
    return;
  }
  UNSAFE_TODO(memcpy(info, &result[0], result.size()));
}

void GLES2Implementation::DeleteQueriesEXTHelper(GLsizei n,
                                                 const GLuint* queries) {
  IdAllocator* id_allocator = GetIdAllocator(IdNamespaces::kQueries);
  for (GLsizei ii = 0; ii < n; ++ii) {
    query_tracker_->RemoveQuery(UNSAFE_TODO(queries[ii]));
    id_allocator->FreeID(UNSAFE_TODO(queries[ii]));
  }

  helper_->DeleteQueriesEXTImmediate(n, queries);
}

GLboolean GLES2Implementation::IsQueryEXT(GLuint id) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] IsQueryEXT(" << id << ")");

  // TODO(gman): To be spec compliant IDs from other contexts sharing
  // resources need to return true here even though you can't share
  // queries across contexts?
  return query_tracker_->GetQuery(id) != nullptr;
}

void GLES2Implementation::BeginQueryEXT(GLenum target, GLuint id) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] BeginQueryEXT("
                     << GLES2Util::GetStringQueryTarget(target) << ", " << id
                     << ")");

  switch (target) {
    case GL_COMMANDS_ISSUED_CHROMIUM:
    case GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM:
    case GL_GET_ERROR_QUERY_CHROMIUM:
    case GL_PROGRAM_COMPLETION_QUERY_CHROMIUM:
      break;
    case GL_READBACK_SHADOW_COPIES_UPDATED_CHROMIUM:
    case GL_COMMANDS_COMPLETED_CHROMIUM:
      if (!gl_capabilities_.sync_query) {
        SetGLError(GL_INVALID_OPERATION, "glBeginQueryEXT",
                   "not enabled for commands completed queries");
        return;
      }
      break;
    case GL_SAMPLES_PASSED_ARB:
      SetGLError(GL_INVALID_OPERATION, "glBeginQueryEXT",
                 "not enabled for occlusion queries");
      return;
    case GL_ANY_SAMPLES_PASSED:
    case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
      if (!gl_capabilities_.occlusion_query_boolean) {
        SetGLError(GL_INVALID_OPERATION, "glBeginQueryEXT",
                   "not enabled for boolean occlusion queries");
        return;
      }
      break;
    case GL_TIME_ELAPSED_EXT:
      if (!gl_capabilities_.timer_queries) {
        SetGLError(GL_INVALID_OPERATION, "glBeginQueryEXT",
                   "not enabled for timing queries");
        return;
      }
      break;
    case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
      if (gl_capabilities_.major_version >= 3) {
        break;
      }
      [[fallthrough]];
    default:
      SetGLError(GL_INVALID_ENUM, "glBeginQueryEXT", "unknown query target");
      return;
  }

  // if any outstanding queries INV_OP
  if (query_tracker_->GetCurrentQuery(target)) {
    SetGLError(GL_INVALID_OPERATION, "glBeginQueryEXT",
               "query already in progress");
    return;
  }

  if (id == 0) {
    SetGLError(GL_INVALID_OPERATION, "glBeginQueryEXT", "id is 0");
    return;
  }

  if (!GetIdAllocator(IdNamespaces::kQueries)->InUse(id)) {
    SetGLError(GL_INVALID_OPERATION, "glBeginQueryEXT", "invalid id");
    return;
  }

  // Extra setups some targets might need.
  switch (target) {
    case GL_TIME_ELAPSED_EXT:
      if (!query_tracker_->SetDisjointSync(this)) {
        SetGLError(GL_OUT_OF_MEMORY, "glBeginQueryEXT",
                   "buffer allocation failed");
        return;
      }
      break;
    default:
      break;
  }

  if (query_tracker_->BeginQuery(id, target, this))
    CheckGLError();

  if (target == GL_READBACK_SHADOW_COPIES_UPDATED_CHROMIUM) {
    AllocateShadowCopiesForReadback();
  }
}

void GLES2Implementation::AllocateShadowCopiesForReadback() {
  for (auto buffer : readback_buffer_shadow_tracker_->GetUnfencedBufferList()) {
    if (!buffer) {
      continue;
    }
    int32_t shm_id = -1;
    uint32_t shm_offset = 0;
    bool already_allocated = false;
    uint32_t size = buffer->Alloc(&shm_id, &shm_offset, &already_allocated);
    if (shm_id == -1) {
      continue;
    }
    if (already_allocated) {
      SendErrorMessage(
          "performance warning: READ-usage buffer was written, then "
          "fenced, but written again before being read back. This discarded "
          "the shadow copy that was created to accelerate readback.",
          0);
    }
    helper_->SetReadbackBufferShadowAllocationINTERNAL(buffer->id(), shm_id,
                                                       shm_offset, size);
  }
}

void GLES2Implementation::BufferShadowWrittenCallback(
    const ReadbackBufferShadowTracker::BufferList& buffers,
    uint64_t serial) {
  for (const auto& buffer : buffers) {
    if (buffer) {
      buffer->UpdateSerialTo(serial);
    }
  }
}

void GLES2Implementation::EndQueryEXT(GLenum target) {
  QueryTracker::Query* query = nullptr;
  {
    GPU_CLIENT_SINGLE_THREAD_CHECK();
    GPU_CLIENT_LOG("[" << GetLogPrefix() << "] EndQueryEXT("
                       << GLES2Util::GetStringQueryTarget(target) << ")");
    query = query_tracker_->GetCurrentQuery(target);
    if (!query_tracker_->EndQuery(target, this)) {
      return;
    }
    CheckGLError();
  }  // GPU_CLIENT_SINGLE_THREAD_CHECK ends here

  if (target == GL_READBACK_SHADOW_COPIES_UPDATED_CHROMIUM) {
    DCHECK(query);
    auto serial = readback_buffer_shadow_tracker_->buffer_shadow_serial();
    readback_buffer_shadow_tracker_->IncrementSerial();
    auto buffers = readback_buffer_shadow_tracker_->TakeUnfencedBufferList();
    query->SetCompletedCallback(
        base::BindOnce(&GLES2Implementation::BufferShadowWrittenCallback,
                       std::move(buffers), serial));
  }
}

void GLES2Implementation::QueryCounterEXT(GLuint id, GLenum target) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] QueryCounterEXT(" << id << ", "
                     << GLES2Util::GetStringQueryTarget(target) << ")");

  switch (target) {
    case GL_TIMESTAMP_EXT:
      if (!gl_capabilities_.timer_queries) {
        SetGLError(GL_INVALID_OPERATION, "glQueryCounterEXT",
                   "not enabled for timing queries");
        return;
      }
      break;
    default:
      SetGLError(GL_INVALID_ENUM, "glQueryCounterEXT", "unknown query target");
      return;
  }

  if (id == 0) {
    SetGLError(GL_INVALID_OPERATION, "glQueryCounterEXT", "id is 0");
    return;
  }

  if (!GetIdAllocator(IdNamespaces::kQueries)->InUse(id)) {
    SetGLError(GL_INVALID_OPERATION, "glQueryCounterEXT", "invalid id");
    return;
  }

  // Extra setups some targets might need.
  switch (target) {
    case GL_TIMESTAMP_EXT:
      if (!query_tracker_->SetDisjointSync(this)) {
        SetGLError(GL_OUT_OF_MEMORY, "glQueryCounterEXT",
                   "buffer allocation failed");
        return;
      }
      break;
    default:
      break;
  }

  if (query_tracker_->QueryCounter(id, target, this))
    CheckGLError();
}

void GLES2Implementation::GetQueryivEXT(GLenum target,
                                        GLenum pname,
                                        GLint* params) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] GetQueryivEXT("
                     << GLES2Util::GetStringQueryTarget(target) << ", "
                     << GLES2Util::GetStringQueryParameter(pname) << ", "
                     << static_cast<const void*>(params) << ")");
  if (pname == GL_QUERY_COUNTER_BITS_EXT) {
    switch (target) {
      case GL_TIMESTAMP_EXT:
        // Overall reliable driver support for timestamps is limited, so we
        // disable the timestamp portion of this extension to encourage use of
        // the better supported time elapsed queries.
        // TODO(crbug.com/40254878): Check the underlying driver's capability
        // instead of disabling it directly.
        *params = 0;
        break;
      case GL_TIME_ELAPSED_EXT:
        // We convert all queries to CPU time so we support 64 bits.
        *params = 64;
        break;
      default:
        SetGLErrorInvalidEnum("glGetQueryivEXT", target, "target");
        break;
    }
    return;
  } else if (pname != GL_CURRENT_QUERY_EXT) {
    SetGLErrorInvalidEnum("glGetQueryivEXT", pname, "pname");
    return;
  }
  QueryTracker::Query* query = query_tracker_->GetCurrentQuery(target);
  *params = query ? query->id() : 0;
  GPU_CLIENT_LOG("  " << *params);
  CheckGLError();
}

void GLES2Implementation::GetQueryObjectivEXT(GLuint id,
                                              GLenum pname,
                                              GLint* params) {
  GLuint64 result = 0;
  if (GetQueryObjectValueHelper("glGetQueryObjectivEXT", id, pname, &result))
    *params = base::saturated_cast<GLint>(result);
}

void GLES2Implementation::GetQueryObjectuivEXT(GLuint id,
                                               GLenum pname,
                                               GLuint* params) {
  GLuint64 result = 0;
  if (GetQueryObjectValueHelper("glGetQueryObjectuivEXT", id, pname, &result))
    *params = base::saturated_cast<GLuint>(result);
}

void GLES2Implementation::GetQueryObjecti64vEXT(GLuint id,
                                                GLenum pname,
                                                GLint64* params) {
  GLuint64 result = 0;
  if (GetQueryObjectValueHelper("glGetQueryObjectiv64vEXT", id, pname, &result))
    *params = base::saturated_cast<GLint64>(result);
}

void GLES2Implementation::GetQueryObjectui64vEXT(GLuint id,
                                                 GLenum pname,
                                                 GLuint64* params) {
  GLuint64 result = 0;
  if (GetQueryObjectValueHelper("glGetQueryObjectui64vEXT", id, pname, &result))
    *params = result;
}

void GLES2Implementation::SetDisjointValueSyncCHROMIUM() {
  query_tracker_->SetDisjointSync(this);
}

void GLES2Implementation::DrawArraysInstancedANGLE(GLenum mode,
                                                   GLint first,
                                                   GLsizei count,
                                                   GLsizei primcount) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDrawArraysInstancedANGLE("
                     << GLES2Util::GetStringDrawMode(mode) << ", " << first
                     << ", " << count << ", " << primcount << ")");
  if (count < 0) {
    SetGLError(GL_INVALID_VALUE, "glDrawArraysInstancedANGLE", "count < 0");
    return;
  }
  if (primcount < 0) {
    SetGLError(GL_INVALID_VALUE, "glDrawArraysInstancedANGLE", "primcount < 0");
    return;
  }
  if (primcount == 0) {
    return;
  }
  helper_->DrawArraysInstancedANGLE(mode, first, count, primcount);
  CheckGLError();
}

void GLES2Implementation::DrawArraysInstancedBaseInstanceANGLE(
    GLenum mode,
    GLint first,
    GLsizei count,
    GLsizei primcount,
    GLuint baseinstance) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG(
      "[" << GetLogPrefix() << "] glDrawArraysInstancedBaseInstanceANGLE("
          << GLES2Util::GetStringDrawMode(mode) << ", " << first << ", "
          << count << ", " << primcount << ", " << baseinstance << ")");
  if (count < 0) {
    SetGLError(GL_INVALID_VALUE, "glDrawArraysInstancedBaseInstanceANGLE",
               "count < 0");
    return;
  }
  if (primcount < 0) {
    SetGLError(GL_INVALID_VALUE, "glDrawArraysInstancedBaseInstanceANGLE",
               "primcount < 0");
    return;
  }
  if (primcount == 0) {
    return;
  }
  helper_->DrawArraysInstancedBaseInstanceANGLE(mode, first, count, primcount,
                                                baseinstance);
  CheckGLError();
}

void GLES2Implementation::DrawElementsInstancedANGLE(GLenum mode,
                                                     GLsizei count,
                                                     GLenum type,
                                                     const void* indices,
                                                     GLsizei primcount) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDrawElementsInstancedANGLE("
                     << GLES2Util::GetStringDrawMode(mode) << ", " << count
                     << ", " << GLES2Util::GetStringIndexType(type) << ", "
                     << static_cast<const void*>(indices) << ", " << primcount
                     << ")");
  if (count < 0) {
    SetGLError(GL_INVALID_VALUE, "glDrawElementsInstancedANGLE",
               "count less than 0.");
    return;
  }
  if (primcount < 0) {
    SetGLError(GL_INVALID_VALUE, "glDrawElementsInstancedANGLE",
               "primcount < 0");
    return;
  }
  GLuint offset = 0;
  if (count > 0 && primcount > 0) {
    if (vertex_array_object_manager_->bound_element_array_buffer() != 0 &&
        !ValidateOffset("glDrawElementsInstancedANGLE",
                        reinterpret_cast<GLintptr>(indices))) {
      return;
    }
    offset = ToGLuint(indices);
  }
  helper_->DrawElementsInstancedANGLE(mode, count, type, offset, primcount);
  CheckGLError();
}

void GLES2Implementation::DrawElementsInstancedBaseVertexBaseInstanceANGLE(
    GLenum mode,
    GLsizei count,
    GLenum type,
    const void* indices,
    GLsizei primcount,
    GLint basevertex,
    GLuint baseinstance) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix()
                     << "] glDrawElementsInstancedBaseVertexBaseInstanceANGLE("
                     << GLES2Util::GetStringDrawMode(mode) << ", " << count
                     << ", " << GLES2Util::GetStringIndexType(type) << ", "
                     << static_cast<const void*>(indices) << ", " << primcount
                     << ", " << basevertex << ", " << baseinstance << ")");
  if (count < 0) {
    SetGLError(GL_INVALID_VALUE,
               "glDrawElementsInstancedBaseVertexBaseInstanceANGLE",
               "count less than 0.");
    return;
  }
  if (primcount < 0) {
    SetGLError(GL_INVALID_VALUE,
               "glDrawElementsInstancedBaseVertexBaseInstanceANGLE",
               "primcount < 0");
    return;
  }
  GLuint offset = 0;
  if (count > 0 && primcount > 0) {
    if (vertex_array_object_manager_->bound_element_array_buffer() != 0 &&
        !ValidateOffset("glDrawElementsInstancedBaseVertexBaseInstanceANGLE",
                        reinterpret_cast<GLintptr>(indices))) {
      return;
    }
    offset = ToGLuint(indices);
  }
  helper_->DrawElementsInstancedBaseVertexBaseInstanceANGLE(
      mode, count, type, offset, primcount, basevertex, baseinstance);
  CheckGLError();
}

GLuint GLES2Implementation::CreateAndTexStorage2DSharedImageCHROMIUM(
    const GLbyte* mailbox_data) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix()
                     << "] CreateAndTexStorage2DSharedImageCHROMIUM("
                     << static_cast<const void*>(mailbox_data) << ")");
  const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(mailbox_data);
  DCHECK(mailbox.Verify()) << "CreateAndTexStorage2DSharedImageCHROMIUM was "
                              "passed an invalid mailbox.";
  GLuint client_id;
  GetIdHandler(SharedIdNamespaces::kTextures)->MakeIds(this, 1, &client_id);
  helper_->CreateAndTexStorage2DSharedImageINTERNALImmediate(client_id,
                                                             mailbox_data);
  CheckGLError();
  return client_id;
}

void GLES2Implementation::PushGroupMarkerEXT(GLsizei length,
                                             const GLchar* marker) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glPushGroupMarkerEXT(" << length
                     << ", " << marker << ")");
  if (!marker) {
    marker = "";
  }
  SetBucketAsString(kResultBucketId, (length ? std::string(marker, length)
                                             : std::string(marker)));
  helper_->PushGroupMarkerEXT(kResultBucketId);
  helper_->SetBucketSize(kResultBucketId, 0);
  debug_marker_manager_.PushGroup(length ? std::string(marker, length)
                                         : std::string(marker));
}

void GLES2Implementation::InsertEventMarkerEXT(GLsizei length,
                                               const GLchar* marker) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glInsertEventMarkerEXT(" << length
                     << ", " << marker << ")");
  if (!marker) {
    marker = "";
  }
  SetBucketAsString(kResultBucketId, (length ? std::string(marker, length)
                                             : std::string(marker)));
  helper_->InsertEventMarkerEXT(kResultBucketId);
  helper_->SetBucketSize(kResultBucketId, 0);
  debug_marker_manager_.SetMarker(length ? std::string(marker, length)
                                         : std::string(marker));
}

void GLES2Implementation::PopGroupMarkerEXT() {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glPopGroupMarkerEXT()");
  helper_->PopGroupMarkerEXT();
  debug_marker_manager_.PopGroup();
}

void GLES2Implementation::TraceBeginCHROMIUM(const char* category_name,
                                             const char* trace_name) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTraceBeginCHROMIUM("
                     << category_name << ", " << trace_name << ")");
  static constexpr size_t kMaxStrLen = 256;
  DCHECK_LE(strlen(category_name), kMaxStrLen);
  DCHECK_LE(strlen(trace_name), kMaxStrLen);
  SetBucketAsCString(kResultBucketId, category_name);
  SetBucketAsCString(kResultBucketId + 1, trace_name);
  helper_->TraceBeginCHROMIUM(kResultBucketId, kResultBucketId + 1);
  helper_->SetBucketSize(kResultBucketId, 0);
  helper_->SetBucketSize(kResultBucketId + 1, 0);
  current_trace_stack_++;
}

void GLES2Implementation::TraceEndCHROMIUM() {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTraceEndCHROMIUM("
                     << ")");
  if (current_trace_stack_ == 0) {
    SetGLError(GL_INVALID_OPERATION, "glTraceEndCHROMIUM",
               "missing begin trace");
    return;
  }
  helper_->TraceEndCHROMIUM();
  current_trace_stack_--;
}

void* GLES2Implementation::MapBufferCHROMIUM(GLuint target, GLenum access) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glMapBufferCHROMIUM(" << target
                     << ", " << GLES2Util::GetStringEnum(access) << ")");
  switch (target) {
    case GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM:
      if (access != GL_READ_ONLY) {
        SetGLError(GL_INVALID_ENUM, "glMapBufferCHROMIUM", "bad access mode");
        return nullptr;
      }
      break;
    default:
      SetGLError(GL_INVALID_ENUM, "glMapBufferCHROMIUM", "invalid target");
      return nullptr;
  }
  GLuint buffer_id;
  GetBoundPixelTransferBuffer(target, "glMapBufferCHROMIUM", &buffer_id);
  if (!buffer_id) {
    return nullptr;
  }
  BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffer_id);
  if (!buffer) {
    SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", "invalid buffer");
    return nullptr;
  }
  if (buffer->mapped()) {
    SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", "already mapped");
    return nullptr;
  }
  // Here we wait for previous transfer operations to be finished.
  if (buffer->last_usage_token()) {
    helper_->WaitForToken(buffer->last_usage_token());
    buffer->set_last_usage_token(0);
  }
  buffer->set_mapped(true);

  GPU_CLIENT_LOG("  returned " << buffer->address());
  CheckGLError();
  return buffer->address();
}

GLboolean GLES2Implementation::UnmapBufferCHROMIUM(GLuint target) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUnmapBufferCHROMIUM(" << target
                     << ")");
  GLuint buffer_id;
  if (!GetBoundPixelTransferBuffer(target, "glMapBufferCHROMIUM", &buffer_id)) {
    SetGLError(GL_INVALID_ENUM, "glUnmapBufferCHROMIUM", "invalid target");
  }
  if (!buffer_id) {
    return false;
  }
  BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffer_id);
  if (!buffer) {
    SetGLError(GL_INVALID_OPERATION, "glUnmapBufferCHROMIUM", "invalid buffer");
    return false;
  }
  if (!buffer->mapped()) {
    SetGLError(GL_INVALID_OPERATION, "glUnmapBufferCHROMIUM", "not mapped");
    return false;
  }
  buffer->set_mapped(false);
  CheckGLError();
  return true;
}

void GLES2Implementation::SetErrorMessageCallback(
    base::RepeatingCallback<void(const char*, int32_t)> callback) {
  error_message_callback_ = std::move(callback);
}

base::span<uint8_t> GLES2Implementation::MapTransferCacheEntry(
    uint32_t serialized_size) {
  NOTREACHED();
}

void GLES2Implementation::UnmapAndCreateTransferCacheEntry(uint32_t type,
                                                           uint32_t id) {
  NOTREACHED();
}

bool GLES2Implementation::ThreadsafeLockTransferCacheEntry(uint32_t type,
                                                           uint32_t id) {
  NOTREACHED();
}

void GLES2Implementation::UnlockTransferCacheEntries(
    const std::vector<std::pair<uint32_t, uint32_t>>& entries) {
  NOTREACHED();
}

void GLES2Implementation::DeleteTransferCacheEntry(uint32_t type, uint32_t id) {
  NOTREACHED();
}

unsigned int GLES2Implementation::GetTransferBufferFreeSize() const {
  NOTREACHED();
}

bool GLES2Implementation::ValidateSize(const char* func, GLsizeiptr size) {
  if (size < 0) {
    SetGLError(GL_INVALID_VALUE, func, "size < 0");
    return false;
  }
  if (!base::IsValueInRangeForNumericType<int32_t>(size)) {
    SetGLError(GL_INVALID_OPERATION, func, "size more than 32-bit");
    return false;
  }
  return true;
}

bool GLES2Implementation::ValidateOffset(const char* func, GLintptr offset) {
  if (offset < 0) {
    SetGLError(GL_INVALID_VALUE, func, "offset < 0");
    return false;
  }
  if (!base::IsValueInRangeForNumericType<int32_t>(offset)) {
    SetGLError(GL_INVALID_OPERATION, func, "offset more than 32-bit");
    return false;
  }
  return true;
}

bool GLES2Implementation::GetSamplerParameterfvHelper(GLuint /* sampler */,
                                                      GLenum /* pname */,
                                                      GLfloat* /* params */) {
  // TODO(zmo): Implement client side caching.
  return false;
}

bool GLES2Implementation::GetSamplerParameterivHelper(GLuint /* sampler */,
                                                      GLenum /* pname */,
                                                      GLint* /* params */) {
  // TODO(zmo): Implement client side caching.
  return false;
}

bool GLES2Implementation::PackStringsToBucket(GLsizei count,
                                              const char* const* str,
                                              const GLint* length,
                                              const char* func_name) {
  DCHECK_LE(0, count);
  // Compute the total size.
  base::CheckedNumeric<uint32_t> total_size = count;
  total_size += 1;
  total_size *= sizeof(GLint);
  uint32_t header_size = 0;
  if (!total_size.AssignIfValid(&header_size)) {
    SetGLError(GL_INVALID_VALUE, func_name, "overflow");
    return false;
  }
  std::vector<GLint> header(count + 1);
  header[0] = static_cast<GLint>(count);
  for (GLsizei ii = 0; ii < count; ++ii) {
    GLint len = 0;
    if (UNSAFE_TODO(str[ii])) {
      len = (length && UNSAFE_TODO(length[ii]) >= 0)
                ? UNSAFE_TODO(length[ii])
                : base::checked_cast<GLint>(strlen(UNSAFE_TODO(str[ii])));
    }
    total_size += len;
    total_size += 1;  // NULL at the end of each char array.
    header[ii + 1] = len;
  }
  // Pack data into a bucket on the service.
  uint32_t validated_size = 0;
  if (!total_size.AssignIfValid(&validated_size)) {
    SetGLError(GL_INVALID_VALUE, func_name, "overflow");
    return false;
  }
  helper_->SetBucketSize(kResultBucketId, validated_size);
  uint32_t offset = 0;
  for (GLsizei ii = 0; ii <= count; ++ii) {
    const char* src = (ii == 0) ? reinterpret_cast<const char*>(&header[0])
                                : UNSAFE_TODO(str[ii - 1]);
    uint32_t size = (ii == 0) ? header_size : header[ii];
    if (ii > 0) {
      size += 1;  // NULL in the end.
    }
    while (size) {
      ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_);
      if (!buffer.valid() || buffer.size() == 0) {
        SetGLError(GL_OUT_OF_MEMORY, func_name, "too large");
        return false;
      }
      uint32_t copy_size = buffer.size();
      if (ii > 0 && buffer.size() == size)
        --copy_size;
      if (copy_size)
        UNSAFE_TODO(memcpy(buffer.address(), src, copy_size));
      if (copy_size < buffer.size()) {
        // Append NULL in the end.
        DCHECK(copy_size + 1 == buffer.size());
        UNSAFE_TODO(reinterpret_cast<char*>(buffer.address())[copy_size]) = 0;
      }
      helper_->SetBucketData(kResultBucketId, offset, buffer.size(),
                             buffer.shm_id(), buffer.offset());
      offset += buffer.size();
      UNSAFE_TODO(src += buffer.size());
      size -= buffer.size();
    }
  }
  DCHECK_EQ(total_size.ValueOrDefault(0), offset);
  return true;
}

void GLES2Implementation::UniformBlockBinding(GLuint program,
                                              GLuint index,
                                              GLuint binding) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniformBlockBinding(" << program
                     << ", " << index << ", " << binding << ")");
  share_group_->program_info_manager()->UniformBlockBinding(this, program,
                                                            index, binding);
  helper_->UniformBlockBinding(program, index, binding);
  CheckGLError();
}

GLenum GLES2Implementation::ClientWaitSync(GLsync sync,
                                           GLbitfield flags,
                                           GLuint64 timeout) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glClientWaitSync(" << sync << ", "
                     << flags << ", " << timeout << ")");
  typedef cmds::ClientWaitSync::Result Result;
  // Limit scope of result to avoid overlap with CheckGLError()
  Result localResult;
  {
    auto result = GetResultAs<Result>();
    if (!result) {
      SetGLError(GL_OUT_OF_MEMORY, "ClientWaitSync", "");
      return GL_WAIT_FAILED;
    }
    *result = GL_WAIT_FAILED;
    helper_->ClientWaitSync(ToGLuint(sync), flags, timeout, GetResultShmId(),
                            result.offset());
    if (!WaitForCmd()) {
      return GL_WAIT_FAILED;
    }
    localResult = *result;
    GPU_CLIENT_LOG("returned " << localResult);
  }
  CheckGLError();
  return localResult;
}

void GLES2Implementation::CopyBufferSubData(GLenum readtarget,
                                            GLenum writetarget,
                                            GLintptr readoffset,
                                            GLintptr writeoffset,
                                            GLsizeiptr size) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCopyBufferSubData("
                     << GLES2Util::GetStringBufferTarget(readtarget) << ", "
                     << GLES2Util::GetStringBufferTarget(writetarget) << ", "
                     << readoffset << ", " << writeoffset << ", " << size
                     << ")");
  if (readoffset < 0) {
    SetGLError(GL_INVALID_VALUE, "glCopyBufferSubData", "readoffset < 0");
    return;
  }
  if (writeoffset < 0) {
    SetGLError(GL_INVALID_VALUE, "glCopyBufferSubData", "writeoffset < 0");
    return;
  }
  if (size < 0) {
    SetGLError(GL_INVALID_VALUE, "glCopyBufferSubData", "size < 0");
    return;
  }
  helper_->CopyBufferSubData(readtarget, writetarget, readoffset, writeoffset,
                             size);
  InvalidateReadbackBufferShadowDataCHROMIUM(GetBoundBufferHelper(writetarget));
  CheckGLError();
}

void GLES2Implementation::WaitSync(GLsync sync,
                                   GLbitfield flags,
                                   GLuint64 timeout) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glWaitSync(" << sync << ", "
                     << flags << ", " << timeout << ")");
  helper_->WaitSync(ToGLuint(sync), flags, timeout);
  CheckGLError();
}

void GLES2Implementation::GetInternalformativ(GLenum target,
                                              GLenum format,
                                              GLenum pname,
                                              GLsizei buf_size,
                                              GLint* params) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION(GLint, params);
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetInternalformativ("
                     << GLES2Util::GetStringRenderBufferTarget(target) << ", "
                     << GLES2Util::GetStringRenderBufferFormat(format) << ", "
                     << GLES2Util::GetStringInternalFormatParameter(pname)
                     << ", " << buf_size << ", "
                     << static_cast<const void*>(params) << ")");
  if (buf_size < 0) {
    SetGLError(GL_INVALID_VALUE, "glGetInternalformativ", "bufSize < 0");
    return;
  }
  TRACE_EVENT0("gpu", "GLES2Implementation::GetInternalformativ");
  if (GetInternalformativHelper(target, format, pname, buf_size, params)) {
    return;
  }
  typedef cmds::GetInternalformativ::Result Result;
  // Limit scope of result to avoid overlap with CheckGLError()
  {
    auto result = GetResultAs<Result>();
    if (!result) {
      return;
    }
    result->SetNumResults(0);
    helper_->GetInternalformativ(target, format, pname, GetResultShmId(),
                                 result.offset());
    if (!WaitForCmd()) {
      return;
    }
    UNSAFE_TODO(GPU_CLIENT_LOG_CODE_BLOCK({
      for (int32_t i = 0; i < result->GetNumResults(); ++i) {
        GPU_CLIENT_LOG("  " << i << ": " << result->GetData()[i]);
      }
    }));
    if (buf_size > 0 && params) {
      GLint* data = result->GetData();
      if (buf_size >= result->GetNumResults()) {
        buf_size = result->GetNumResults();
      }
      for (GLsizei ii = 0; ii < buf_size; ++ii) {
        UNSAFE_TODO(params[ii]) = UNSAFE_TODO(data[ii]);
      }
    }
  }
  CheckGLError();
}

void GLES2Implementation::UpdateCachedExtensionsIfNeeded() {
  if (cached_extension_string_) {
    return;
  }
  GetStringHelper(GL_EXTENSIONS);
}

void GLES2Implementation::InvalidateCachedExtensions() {
  cached_extension_string_ = nullptr;
  cached_extensions_.clear();
}

void GLES2Implementation::Viewport(GLint x,
                                   GLint y,
                                   GLsizei width,
                                   GLsizei height) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glViewport(" << x << ", " << y
                     << ", " << width << ", " << height << ")");
  if (width < 0 || height < 0) {
    SetGLError(GL_INVALID_VALUE, "glViewport", "negative width/height");
    return;
  }
  state_.SetViewport(x, y, width, height);
  helper_->Viewport(x, y, width, height);
  CheckGLError();
}

void GLES2Implementation::IssueBeginQuery(GLenum target,
                                          GLuint id,
                                          uint32_t sync_data_shm_id,
                                          uint32_t sync_data_shm_offset) {
  helper_->BeginQueryEXT(target, id, sync_data_shm_id, sync_data_shm_offset);
}

void GLES2Implementation::IssueEndQuery(GLenum target, GLuint submit_count) {
  helper_->EndQueryEXT(target, submit_count);
}

void GLES2Implementation::IssueQueryCounter(GLuint id,
                                            GLenum target,
                                            uint32_t sync_data_shm_id,
                                            uint32_t sync_data_shm_offset,
                                            GLuint submit_count) {
  helper_->QueryCounterEXT(id, target, sync_data_shm_id, sync_data_shm_offset,
                           submit_count);
}

void GLES2Implementation::IssueSetDisjointValueSync(
    uint32_t sync_data_shm_id,
    uint32_t sync_data_shm_offset) {
  helper_->SetDisjointValueSyncCHROMIUM(sync_data_shm_id, sync_data_shm_offset);
}

GLenum GLES2Implementation::GetClientSideGLError() {
  if (error_bits_ == 0) {
    return GL_NO_ERROR;
  }

  GLenum error = GL_NO_ERROR;
  for (uint32_t mask = 1; mask != 0; mask = mask << 1) {
    if ((error_bits_ & mask) != 0) {
      error = GLES2Util::GLErrorBitToGLError(mask);
      break;
    }
  }
  error_bits_ &= ~GLES2Util::GLErrorToErrorBit(error);
  return error;
}

CommandBufferHelper* GLES2Implementation::cmd_buffer_helper() {
  return helper_;
}

CommandBuffer* GLES2Implementation::command_buffer() const {
  return helper_->command_buffer();
}

void GLES2Implementation::SetActiveURLCHROMIUM(const char* url) {
  DCHECK(url);
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glSetActiveURLCHROMIUM(" << url);

  if (last_active_url_ == url)
    return;

  last_active_url_ = url;
  static constexpr uint32_t kMaxStrLen = 1024;
  size_t len = strlen(url);
  if (len == 0)
    return;

  SetBucketContents(kResultBucketId, url,
                    base::CheckMin(len, kMaxStrLen).ValueOrDie());
  helper_->SetActiveURLCHROMIUM(kResultBucketId);
  helper_->SetBucketSize(kResultBucketId, 0);
}

void GLES2Implementation::GetBufferSubDataCHROMIUM(GLenum target,
                                                   GLintptr offset,
                                                   GLsizeiptr size,
                                                   void* data) {
  GPU_CLIENT_SINGLE_THREAD_CHECK();
  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetBufferSubDataCHROMIUM("
                     << GLES2Util::GetStringEnum(target) << ", " << offset
                     << ", " << size << ", " << data << ")");
  if (!ValidateSize("glGetBufferSubDataCHROMIUM", size) ||
      !ValidateOffset("glGetBufferSubDataCHROMIUM", offset)) {
    return;
  }

  int32_t shm_id = 0;
  unsigned int shm_offset = 0;
  base::span<uint8_t> span_buffer =
      mapped_memory_->Alloc(size, &shm_id, &shm_offset);
  if (span_buffer.empty()) {
    SetGLError(GL_OUT_OF_MEMORY, "glGetBufferSubDataCHROMIUM", "out of memory");
    return;
  }

  // Zero-initialize the buffer. The GPU process will not write to the buffer in
  // case of an error.
  std::ranges::fill(span_buffer, 0);

  helper_->GetBufferSubDataCHROMIUM(target, offset, size, shm_id, shm_offset);

  if (!WaitForCmd()) {
    return;
  }

  UNSAFE_TODO(memcpy(data, span_buffer.data(), size));
  mapped_memory_->Free(span_buffer.data());
}

// Include the auto-generated part of this file. We split this because it means
// we can easily edit the non-auto generated parts right here in this file
// instead of having to edit some template or the code generator.
#include "gpu/command_buffer/client/gles2_implementation_impl_autogen.h"

}  // namespace gles2
}  // namespace gpu
