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

#include "cc/test/test_web_graphics_context_3d.h"

#include <stddef.h>
#include <stdint.h>

#include <algorithm>
#include <string>

#include "base/bind.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/message_loop/message_loop.h"
#include "base/numerics/safe_conversions.h"
#include "cc/test/test_context_support.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/khronos/GLES2/gl2ext.h"

namespace cc {

static unsigned s_context_id = 1;

const GLuint TestWebGraphicsContext3D::kExternalTextureId = 1337;

static base::LazyInstance<base::Lock>::Leaky
    g_shared_namespace_lock = LAZY_INSTANCE_INITIALIZER;

TestWebGraphicsContext3D::Namespace*
    TestWebGraphicsContext3D::shared_namespace_ = nullptr;

TestWebGraphicsContext3D::Namespace::Namespace()
    : next_buffer_id(1),
      next_image_id(1),
      next_texture_id(1),
      next_renderbuffer_id(1) {
}

TestWebGraphicsContext3D::Namespace::~Namespace() {
  g_shared_namespace_lock.Get().AssertAcquired();
  if (shared_namespace_ == this)
    shared_namespace_ = nullptr;
}

// static
std::unique_ptr<TestWebGraphicsContext3D> TestWebGraphicsContext3D::Create() {
  return base::WrapUnique(new TestWebGraphicsContext3D());
}

TestWebGraphicsContext3D::TestWebGraphicsContext3D()
    : context_id_(s_context_id++),
      times_bind_texture_succeeds_(-1),
      times_end_query_succeeds_(-1),
      context_lost_(false),
      times_map_buffer_chromium_succeeds_(-1),
      next_program_id_(1000),
      next_shader_id_(2000),
      next_framebuffer_id_(1),
      current_framebuffer_(0),
      max_texture_size_(2048),
      reshape_called_(false),
      width_(0),
      height_(0),
      scale_factor_(-1.f),
      test_support_(nullptr),
      last_update_type_(NO_UPDATE),
      next_insert_fence_sync_(1),
      unpack_alignment_(4),
      weak_ptr_factory_(this) {
  CreateNamespace();
  set_have_extension_egl_image(true);  // For stream textures.
}

TestWebGraphicsContext3D::~TestWebGraphicsContext3D() {
  base::AutoLock lock(g_shared_namespace_lock.Get());
  namespace_ = nullptr;
}

void TestWebGraphicsContext3D::CreateNamespace() {
  base::AutoLock lock(g_shared_namespace_lock.Get());
  if (shared_namespace_) {
    namespace_ = shared_namespace_;
  } else {
    namespace_ = new Namespace;
    shared_namespace_ = namespace_.get();
  }
}

void TestWebGraphicsContext3D::reshapeWithScaleFactor(
    int width, int height, float scale_factor) {
  reshape_called_ = true;
  width_ = width;
  height_ = height;
  scale_factor_ = scale_factor;
}

bool TestWebGraphicsContext3D::isContextLost() {
  return context_lost_;
}

GLenum TestWebGraphicsContext3D::checkFramebufferStatus(
    GLenum target) {
  if (context_lost_)
    return GL_FRAMEBUFFER_UNDEFINED_OES;
  return GL_FRAMEBUFFER_COMPLETE;
}

GLint TestWebGraphicsContext3D::getUniformLocation(
    GLuint program,
    const GLchar* name) {
  return 0;
}

GLsizeiptr TestWebGraphicsContext3D::getVertexAttribOffset(
    GLuint index,
    GLenum pname) {
  return 0;
}

GLboolean TestWebGraphicsContext3D::isBuffer(
    GLuint buffer) {
  return false;
}

GLboolean TestWebGraphicsContext3D::isEnabled(
    GLenum cap) {
  return false;
}

GLboolean TestWebGraphicsContext3D::isFramebuffer(
    GLuint framebuffer) {
  return false;
}

GLboolean TestWebGraphicsContext3D::isProgram(
    GLuint program) {
  return false;
}

GLboolean TestWebGraphicsContext3D::isRenderbuffer(
    GLuint renderbuffer) {
  return false;
}

GLboolean TestWebGraphicsContext3D::isShader(
    GLuint shader) {
  return false;
}

GLboolean TestWebGraphicsContext3D::isTexture(
    GLuint texture) {
  return false;
}

void TestWebGraphicsContext3D::genBuffers(GLsizei count, GLuint* ids) {
  for (int i = 0; i < count; ++i)
    ids[i] = NextBufferId();
}

void TestWebGraphicsContext3D::genFramebuffers(
    GLsizei count, GLuint* ids) {
  for (int i = 0; i < count; ++i)
    ids[i] = NextFramebufferId();
}

void TestWebGraphicsContext3D::genRenderbuffers(
    GLsizei count, GLuint* ids) {
  for (int i = 0; i < count; ++i)
    ids[i] = NextRenderbufferId();
}

void TestWebGraphicsContext3D::genTextures(GLsizei count, GLuint* ids) {
  for (int i = 0; i < count; ++i) {
    ids[i] = NextTextureId();
    DCHECK_NE(ids[i], kExternalTextureId);
  }
  base::AutoLock lock(namespace_->lock);
  for (int i = 0; i < count; ++i)
    namespace_->textures.Append(ids[i], new TestTexture());
}

void TestWebGraphicsContext3D::deleteBuffers(GLsizei count, const GLuint* ids) {
  for (int i = 0; i < count; ++i)
    RetireBufferId(ids[i]);
}

void TestWebGraphicsContext3D::deleteFramebuffers(GLsizei count,
                                                  const GLuint* ids) {
  for (int i = 0; i < count; ++i) {
    if (ids[i]) {
      RetireFramebufferId(ids[i]);
      if (ids[i] == current_framebuffer_)
        current_framebuffer_ = 0;
    }
  }
}

void TestWebGraphicsContext3D::deleteRenderbuffers(GLsizei count,
                                                   const GLuint* ids) {
  for (int i = 0; i < count; ++i)
    RetireRenderbufferId(ids[i]);
}

void TestWebGraphicsContext3D::deleteTextures(GLsizei count,
                                              const GLuint* ids) {
  for (int i = 0; i < count; ++i)
    RetireTextureId(ids[i]);
  base::AutoLock lock(namespace_->lock);
  for (int i = 0; i < count; ++i) {
    namespace_->textures.Remove(ids[i]);
    texture_targets_.UnbindTexture(ids[i]);
  }
}

GLuint TestWebGraphicsContext3D::createBuffer() {
  GLuint id;
  genBuffers(1, &id);
  return id;
}

GLuint TestWebGraphicsContext3D::createFramebuffer() {
  GLuint id;
  genFramebuffers(1, &id);
  return id;
}

GLuint TestWebGraphicsContext3D::createRenderbuffer() {
  GLuint id;
  genRenderbuffers(1, &id);
  return id;
}

GLuint TestWebGraphicsContext3D::createTexture() {
  GLuint id;
  genTextures(1, &id);
  return id;
}

void TestWebGraphicsContext3D::deleteBuffer(GLuint id) {
  deleteBuffers(1, &id);
}

void TestWebGraphicsContext3D::deleteFramebuffer(GLuint id) {
  deleteFramebuffers(1, &id);
}

void TestWebGraphicsContext3D::deleteRenderbuffer(GLuint id) {
  deleteRenderbuffers(1, &id);
}

void TestWebGraphicsContext3D::deleteTexture(GLuint id) {
  deleteTextures(1, &id);
}

unsigned TestWebGraphicsContext3D::createProgram() {
  unsigned program = next_program_id_++ | context_id_ << 16;
  program_set_.insert(program);
  return program;
}

GLuint TestWebGraphicsContext3D::createShader(GLenum) {
  unsigned shader = next_shader_id_++ | context_id_ << 16;
  shader_set_.insert(shader);
  return shader;
}

GLuint TestWebGraphicsContext3D::createExternalTexture() {
  base::AutoLock lock(namespace_->lock);
  namespace_->textures.Append(kExternalTextureId, new TestTexture());
  return kExternalTextureId;
}

void TestWebGraphicsContext3D::deleteProgram(GLuint id) {
  if (!program_set_.count(id))
    ADD_FAILURE() << "deleteProgram called on unknown program " << id;
  program_set_.erase(id);
}

void TestWebGraphicsContext3D::deleteShader(GLuint id) {
  if (!shader_set_.count(id))
    ADD_FAILURE() << "deleteShader called on unknown shader " << id;
  shader_set_.erase(id);
}

void TestWebGraphicsContext3D::attachShader(GLuint program, GLuint shader) {
  if (!program_set_.count(program))
    ADD_FAILURE() << "attachShader called with unknown program " << program;
  if (!shader_set_.count(shader))
    ADD_FAILURE() << "attachShader called with unknown shader " << shader;
}

void TestWebGraphicsContext3D::useProgram(GLuint program) {
  if (!program)
    return;
  if (!program_set_.count(program))
    ADD_FAILURE() << "useProgram called on unknown program " << program;
}

void TestWebGraphicsContext3D::bindFramebuffer(
    GLenum target, GLuint framebuffer) {
  base::AutoLock lock_for_framebuffer_access(namespace_->lock);
  if (framebuffer != 0 &&
      framebuffer_set_.find(framebuffer) == framebuffer_set_.end()) {
    ADD_FAILURE() << "bindFramebuffer called with unknown framebuffer";
  } else if (framebuffer != 0 && (framebuffer >> 16) != context_id_) {
    ADD_FAILURE()
        << "bindFramebuffer called with framebuffer from other context";
  } else {
    current_framebuffer_ = framebuffer;
  }
}

void TestWebGraphicsContext3D::bindRenderbuffer(
      GLenum target, GLuint renderbuffer) {
  if (!renderbuffer)
    return;
  base::AutoLock lock_for_renderbuffer_access(namespace_->lock);
  if (renderbuffer != 0 &&
      namespace_->renderbuffer_set.find(renderbuffer) ==
          namespace_->renderbuffer_set.end()) {
    ADD_FAILURE() << "bindRenderbuffer called with unknown renderbuffer";
  } else if ((renderbuffer >> 16) != context_id_) {
    ADD_FAILURE()
        << "bindRenderbuffer called with renderbuffer from other context";
  }
}

void TestWebGraphicsContext3D::bindTexture(
    GLenum target, GLuint texture_id) {
  if (times_bind_texture_succeeds_ >= 0) {
    if (!times_bind_texture_succeeds_) {
      loseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB,
                          GL_INNOCENT_CONTEXT_RESET_ARB);
    }
    --times_bind_texture_succeeds_;
  }

  if (!texture_id)
    return;
  base::AutoLock lock(namespace_->lock);
  DCHECK(namespace_->textures.ContainsId(texture_id));
  texture_targets_.BindTexture(target, texture_id);
  used_textures_.insert(texture_id);
}

GLuint TestWebGraphicsContext3D::BoundTextureId(
    GLenum target) {
  return texture_targets_.BoundTexture(target);
}

scoped_refptr<TestTexture> TestWebGraphicsContext3D::BoundTexture(
    GLenum target) {
  // The caller is expected to lock the namespace for texture access.
  namespace_->lock.AssertAcquired();
  return namespace_->textures.TextureForId(BoundTextureId(target));
}

scoped_refptr<TestTexture> TestWebGraphicsContext3D::UnboundTexture(
    GLuint texture) {
  // The caller is expected to lock the namespace for texture access.
  namespace_->lock.AssertAcquired();
  return namespace_->textures.TextureForId(texture);
}

void TestWebGraphicsContext3D::CheckTextureIsBound(GLenum target) {
  DCHECK(BoundTextureId(target));
}

GLuint TestWebGraphicsContext3D::createQueryEXT() { return 1u; }

void TestWebGraphicsContext3D::endQueryEXT(GLenum target) {
  if (times_end_query_succeeds_ >= 0) {
    if (!times_end_query_succeeds_) {
      loseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB,
                          GL_INNOCENT_CONTEXT_RESET_ARB);
    }
    --times_end_query_succeeds_;
  }
}

void TestWebGraphicsContext3D::getQueryObjectuivEXT(
    GLuint query,
    GLenum pname,
    GLuint* params) {
  // If the context is lost, behave as if result is available.
  if (pname == GL_QUERY_RESULT_AVAILABLE_EXT)
    *params = 1;
}

void TestWebGraphicsContext3D::getIntegerv(
    GLenum pname,
    GLint* value) {
  if (pname == GL_MAX_TEXTURE_SIZE)
    *value = max_texture_size_;
  else if (pname == GL_ACTIVE_TEXTURE)
    *value = GL_TEXTURE0;
  else if (pname == GL_UNPACK_ALIGNMENT)
    *value = unpack_alignment_;
  else if (pname == GL_FRAMEBUFFER_BINDING)
    *value = current_framebuffer_;
  else if (pname == GL_MAX_SAMPLES)
    *value = test_capabilities_.max_samples;
}

void TestWebGraphicsContext3D::getProgramiv(GLuint program,
                                            GLenum pname,
                                            GLint* value) {
  if (pname == GL_LINK_STATUS)
    *value = 1;
}

void TestWebGraphicsContext3D::getShaderiv(GLuint shader,
                                           GLenum pname,
                                           GLint* value) {
  if (pname == GL_COMPILE_STATUS)
    *value = 1;
}

void TestWebGraphicsContext3D::getShaderPrecisionFormat(GLenum shadertype,
                                                        GLenum precisiontype,
                                                        GLint* range,
                                                        GLint* precision) {
  // Return the minimum precision requirements of the GLES2
  // specification.
  switch (precisiontype) {
    case GL_LOW_INT:
      range[0] = 8;
      range[1] = 8;
      *precision = 0;
      break;
    case GL_MEDIUM_INT:
      range[0] = 10;
      range[1] = 10;
      *precision = 0;
      break;
    case GL_HIGH_INT:
      range[0] = 16;
      range[1] = 16;
      *precision = 0;
      break;
    case GL_LOW_FLOAT:
      range[0] = 8;
      range[1] = 8;
      *precision = 8;
      break;
    case GL_MEDIUM_FLOAT:
      range[0] = 14;
      range[1] = 14;
      *precision = 10;
      break;
    case GL_HIGH_FLOAT:
      range[0] = 62;
      range[1] = 62;
      *precision = 16;
      break;
    default:
      NOTREACHED();
      break;
  }
}

void TestWebGraphicsContext3D::genMailboxCHROMIUM(GLbyte* mailbox) {
  static char mailbox_name1 = '1';
  static char mailbox_name2 = '1';
  mailbox[0] = mailbox_name1;
  mailbox[1] = mailbox_name2;
  mailbox[2] = '\0';
  if (++mailbox_name1 == 0) {
    mailbox_name1 = '1';
    ++mailbox_name2;
  }
}

GLuint TestWebGraphicsContext3D::createAndConsumeTextureCHROMIUM(
    const GLbyte* mailbox) {
  return createTexture();
}

void TestWebGraphicsContext3D::loseContextCHROMIUM(GLenum current,
                                                   GLenum other) {
  if (context_lost_)
    return;
  context_lost_ = true;
  if (!context_lost_callback_.is_null())
    context_lost_callback_.Run();

  for (size_t i = 0; i < shared_contexts_.size(); ++i)
    shared_contexts_[i]->loseContextCHROMIUM(current, other);
  shared_contexts_.clear();
}

void TestWebGraphicsContext3D::finish() {
  test_support_->CallAllSyncPointCallbacks();
}

void TestWebGraphicsContext3D::flush() {
  test_support_->CallAllSyncPointCallbacks();
}

void TestWebGraphicsContext3D::shallowFinishCHROMIUM() {
  test_support_->CallAllSyncPointCallbacks();
}

GLint TestWebGraphicsContext3D::getAttribLocation(GLuint program,
                                                  const GLchar* name) {
  return 0;
}

GLenum TestWebGraphicsContext3D::getError() { return GL_NO_ERROR; }

void TestWebGraphicsContext3D::bindBuffer(GLenum target,
                                          GLuint buffer) {
  bound_buffer_[target] = buffer;
  if (!buffer)
    return;
  unsigned context_id = buffer >> 16;
  unsigned buffer_id = buffer & 0xffff;
  base::AutoLock lock(namespace_->lock);
  DCHECK(buffer_id);
  DCHECK_LT(buffer_id, namespace_->next_buffer_id);
  DCHECK_EQ(context_id, context_id_);

  std::unordered_map<unsigned, std::unique_ptr<Buffer>>& buffers =
      namespace_->buffers;
  if (buffers.count(bound_buffer_[target]) == 0)
    buffers[bound_buffer_[target]] = base::WrapUnique(new Buffer);

  buffers[bound_buffer_[target]]->target = target;
}

void TestWebGraphicsContext3D::bufferData(GLenum target,
                                          GLsizeiptr size,
                                          const void* data,
                                          GLenum usage) {
  base::AutoLock lock(namespace_->lock);
  std::unordered_map<unsigned, std::unique_ptr<Buffer>>& buffers =
      namespace_->buffers;
  DCHECK_GT(bound_buffer_.count(target), 0u);
  DCHECK_GT(buffers.count(bound_buffer_[target]), 0u);
  DCHECK_EQ(target, buffers[bound_buffer_[target]]->target);
  Buffer* buffer = buffers[bound_buffer_[target]].get();
  if (context_lost_) {
    buffer->pixels = nullptr;
    return;
  }

  buffer->pixels.reset(new uint8_t[size]);
  buffer->size = size;
  if (data != nullptr)
    memcpy(buffer->pixels.get(), data, size);
}

void TestWebGraphicsContext3D::pixelStorei(GLenum pname, GLint param) {
  switch (pname) {
    case GL_UNPACK_ALIGNMENT:
      // Param should be a power of two <= 8.
      EXPECT_EQ(0, param & (param - 1));
      EXPECT_GE(8, param);
      switch (param) {
        case 1:
        case 2:
        case 4:
        case 8:
          unpack_alignment_ = param;
          break;
        default:
          break;
      }
      break;
    default:
      break;
  }
}

void* TestWebGraphicsContext3D::mapBufferCHROMIUM(GLenum target,
                                                  GLenum access) {
  base::AutoLock lock(namespace_->lock);
  std::unordered_map<unsigned, std::unique_ptr<Buffer>>& buffers =
      namespace_->buffers;
  DCHECK_GT(bound_buffer_.count(target), 0u);
  DCHECK_GT(buffers.count(bound_buffer_[target]), 0u);
  DCHECK_EQ(target, buffers[bound_buffer_[target]]->target);
  if (times_map_buffer_chromium_succeeds_ >= 0) {
    if (!times_map_buffer_chromium_succeeds_) {
      return nullptr;
    }
    --times_map_buffer_chromium_succeeds_;
  }

  return buffers[bound_buffer_[target]]->pixels.get();
}

GLboolean TestWebGraphicsContext3D::unmapBufferCHROMIUM(
    GLenum target) {
  base::AutoLock lock(namespace_->lock);
  std::unordered_map<unsigned, std::unique_ptr<Buffer>>& buffers =
      namespace_->buffers;
  DCHECK_GT(bound_buffer_.count(target), 0u);
  DCHECK_GT(buffers.count(bound_buffer_[target]), 0u);
  DCHECK_EQ(target, buffers[bound_buffer_[target]]->target);
  buffers[bound_buffer_[target]]->pixels = nullptr;
  return true;
}

GLuint TestWebGraphicsContext3D::createImageCHROMIUM(ClientBuffer buffer,
                                                     GLsizei width,
                                                     GLsizei height,
                                                     GLenum internalformat) {
  DCHECK(internalformat == GL_RGB || internalformat == GL_RGBA ||
         (test_capabilities_.texture_format_bgra8888 &&
          internalformat == GL_BGRA_EXT));
  GLuint image_id = NextImageId();
  base::AutoLock lock(namespace_->lock);
  std::unordered_set<unsigned>& images = namespace_->images;
  images.insert(image_id);
  return image_id;
}

void TestWebGraphicsContext3D::destroyImageCHROMIUM(
    GLuint id) {
  RetireImageId(id);
  base::AutoLock lock(namespace_->lock);
  std::unordered_set<unsigned>& images = namespace_->images;
  if (!images.count(id))
    ADD_FAILURE() << "destroyImageCHROMIUM called on unknown image " << id;
  images.erase(id);
}

GLuint TestWebGraphicsContext3D::createGpuMemoryBufferImageCHROMIUM(
    GLsizei width,
    GLsizei height,
    GLenum internalformat,
    GLenum usage) {
  DCHECK(internalformat == GL_RGB || internalformat == GL_RGBA ||
         (test_capabilities_.texture_format_bgra8888 &&
          internalformat == GL_BGRA_EXT));
  GLuint image_id = NextImageId();
  base::AutoLock lock(namespace_->lock);
  std::unordered_set<unsigned>& images = namespace_->images;
  images.insert(image_id);
  return image_id;
}

void TestWebGraphicsContext3D::genSyncToken(GLbyte* sync_token) {
  // Don't return a valid sync token if context is lost. This matches behavior
  // of CommandBufferProxyImpl.
  if (context_lost_)
    return;
  gpu::SyncToken sync_token_data(gpu::CommandBufferNamespace::GPU_IO,
                                 gpu::CommandBufferId(),
                                 next_insert_fence_sync_++);
  sync_token_data.SetVerifyFlush();
  memcpy(sync_token, &sync_token_data, sizeof(sync_token_data));
}

void TestWebGraphicsContext3D::waitSyncToken(const GLbyte* sync_token) {
  if (sync_token) {
    gpu::SyncToken sync_token_data;
    memcpy(sync_token_data.GetData(), sync_token, sizeof(sync_token_data));
    if (sync_token_data.HasData())
      last_waited_sync_token_ = sync_token_data;
  }
}

void TestWebGraphicsContext3D::verifySyncTokens(GLbyte** sync_tokens,
                                                GLsizei count) {
  for (GLsizei i = 0; i < count; ++i) {
    gpu::SyncToken sync_token_data;
    memcpy(sync_token_data.GetData(), sync_tokens[i], sizeof(sync_token_data));
    sync_token_data.SetVerifyFlush();
    memcpy(sync_tokens[i], &sync_token_data, sizeof(sync_token_data));
  }
}

size_t TestWebGraphicsContext3D::NumTextures() const {
  base::AutoLock lock(namespace_->lock);
  return namespace_->textures.Size();
}

GLuint TestWebGraphicsContext3D::TextureAt(int i) const {
  base::AutoLock lock(namespace_->lock);
  return namespace_->textures.IdAt(i);
}

GLuint TestWebGraphicsContext3D::NextTextureId() {
  base::AutoLock lock(namespace_->lock);
  GLuint texture_id = namespace_->next_texture_id++;
  DCHECK(texture_id < (1 << 16));
  texture_id |= context_id_ << 16;
  return texture_id;
}

void TestWebGraphicsContext3D::RetireTextureId(GLuint id) {
  base::AutoLock lock(namespace_->lock);
  unsigned context_id = id >> 16;
  unsigned texture_id = id & 0xffff;
  DCHECK(texture_id);
  DCHECK_LT(texture_id, namespace_->next_texture_id);
  DCHECK_EQ(context_id, context_id_);
}

GLuint TestWebGraphicsContext3D::NextBufferId() {
  base::AutoLock lock(namespace_->lock);
  GLuint buffer_id = namespace_->next_buffer_id++;
  DCHECK(buffer_id < (1 << 16));
  buffer_id |= context_id_ << 16;
  return buffer_id;
}

void TestWebGraphicsContext3D::RetireBufferId(GLuint id) {
  base::AutoLock lock(namespace_->lock);
  unsigned context_id = id >> 16;
  unsigned buffer_id = id & 0xffff;
  DCHECK(buffer_id);
  DCHECK_LT(buffer_id, namespace_->next_buffer_id);
  DCHECK_EQ(context_id, context_id_);
}

GLuint TestWebGraphicsContext3D::NextImageId() {
  base::AutoLock lock(namespace_->lock);
  GLuint image_id = namespace_->next_image_id++;
  DCHECK(image_id < (1 << 16));
  image_id |= context_id_ << 16;
  return image_id;
}

void TestWebGraphicsContext3D::RetireImageId(GLuint id) {
  base::AutoLock lock(namespace_->lock);
  unsigned context_id = id >> 16;
  unsigned image_id = id & 0xffff;
  DCHECK(image_id);
  DCHECK_LT(image_id, namespace_->next_image_id);
  DCHECK_EQ(context_id, context_id_);
}

GLuint TestWebGraphicsContext3D::NextFramebufferId() {
  base::AutoLock lock_for_framebuffer_access(namespace_->lock);
  GLuint id = next_framebuffer_id_++;
  DCHECK(id < (1 << 16));
  id |= context_id_ << 16;
  framebuffer_set_.insert(id);
  return id;
}

void TestWebGraphicsContext3D::RetireFramebufferId(GLuint id) {
  base::AutoLock lock_for_framebuffer_access(namespace_->lock);
  DCHECK(framebuffer_set_.find(id) != framebuffer_set_.end());
  framebuffer_set_.erase(id);
}

GLuint TestWebGraphicsContext3D::NextRenderbufferId() {
  base::AutoLock lock_for_renderbuffer_access(namespace_->lock);
  GLuint id = namespace_->next_renderbuffer_id++;
  DCHECK(id < (1 << 16));
  id |= context_id_ << 16;
  namespace_->renderbuffer_set.insert(id);
  return id;
}

void TestWebGraphicsContext3D::RetireRenderbufferId(GLuint id) {
  base::AutoLock lock_for_renderbuffer_access(namespace_->lock);
  DCHECK(namespace_->renderbuffer_set.find(id) !=
         namespace_->renderbuffer_set.end());
  namespace_->renderbuffer_set.erase(id);
}

void TestWebGraphicsContext3D::SetMaxSamples(int max_samples) {
  test_capabilities_.max_samples = max_samples;
}

size_t TestWebGraphicsContext3D::NumFramebuffers() const {
  base::AutoLock lock_for_framebuffer_access(namespace_->lock);
  return framebuffer_set_.size();
}

size_t TestWebGraphicsContext3D::NumRenderbuffers() const {
  base::AutoLock lock_for_renderbuffer_access(namespace_->lock);
  return namespace_->renderbuffer_set.size();
}

TestWebGraphicsContext3D::TextureTargets::TextureTargets() {
  // Initialize default bindings.
  bound_textures_[GL_TEXTURE_2D] = 0;
  bound_textures_[GL_TEXTURE_EXTERNAL_OES] = 0;
  bound_textures_[GL_TEXTURE_RECTANGLE_ARB] = 0;
}

TestWebGraphicsContext3D::TextureTargets::~TextureTargets() = default;

void TestWebGraphicsContext3D::TextureTargets::BindTexture(
    GLenum target,
    GLuint id) {
  // Make sure this is a supported target by seeing if it was bound to before.
  DCHECK(bound_textures_.find(target) != bound_textures_.end());
  bound_textures_[target] = id;
}

void TestWebGraphicsContext3D::texParameteri(GLenum target,
                                             GLenum pname,
                                             GLint param) {
  CheckTextureIsBound(target);
  base::AutoLock lock_for_texture_access(namespace_->lock);
  scoped_refptr<TestTexture> texture = BoundTexture(target);
  DCHECK(texture->IsValidParameter(pname));
  texture->params[pname] = param;
}

void TestWebGraphicsContext3D::getTexParameteriv(GLenum target,
                                                 GLenum pname,
                                                 GLint* value) {
  CheckTextureIsBound(target);
  base::AutoLock lock_for_texture_access(namespace_->lock);
  scoped_refptr<TestTexture> texture = BoundTexture(target);
  DCHECK(texture->IsValidParameter(pname));
  TestTexture::TextureParametersMap::iterator it = texture->params.find(pname);
  if (it != texture->params.end())
    *value = it->second;
}

void TestWebGraphicsContext3D::TextureTargets::UnbindTexture(
    GLuint id) {
  // Bind zero to any targets that the id is bound to.
  for (TargetTextureMap::iterator it = bound_textures_.begin();
       it != bound_textures_.end();
       it++) {
    if (it->second == id)
      it->second = 0;
  }
}

GLuint TestWebGraphicsContext3D::TextureTargets::BoundTexture(
    GLenum target) {
  DCHECK(bound_textures_.find(target) != bound_textures_.end());
  return bound_textures_[target];
}

TestWebGraphicsContext3D::Buffer::Buffer() : target(0), size(0) {}

TestWebGraphicsContext3D::Buffer::~Buffer() = default;

TestWebGraphicsContext3D::Image::Image() = default;

TestWebGraphicsContext3D::Image::~Image() = default;

}  // namespace cc
