// Copyright (c) 2012 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.

// Tests for GLES2Implementation.

#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 <stddef.h>
#include <stdint.h>

#include <memory>

#include "base/compiler_specific.h"
#include "gpu/command_buffer/client/client_test_helper.h"
#include "gpu/command_buffer/client/gles2_cmd_helper.h"
#include "gpu/command_buffer/client/program_info_manager.h"
#include "gpu/command_buffer/client/query_tracker.h"
#include "gpu/command_buffer/client/ring_buffer.h"
#include "gpu/command_buffer/client/shared_memory_limits.h"
#include "gpu/command_buffer/client/transfer_buffer.h"
#include "gpu/command_buffer/common/command_buffer.h"
#include "gpu/command_buffer/common/sync_token.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

#if !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
#define GLES2_SUPPORT_CLIENT_SIDE_ARRAYS
#endif

using testing::_;
using testing::AtLeast;
using testing::AnyNumber;
using testing::DoAll;
using testing::InSequence;
using testing::Invoke;
using testing::Mock;
using testing::Pointee;
using testing::SaveArg;
using testing::Sequence;
using testing::StrictMock;
using testing::Truly;
using testing::Return;

namespace gpu {
namespace gles2 {

ACTION_P2(SetMemory, dst, obj) {
  memcpy(dst, &obj, sizeof(obj));
}

ACTION_P3(SetMemoryFromArray, dst, array, size) {
  memcpy(dst, array, size);
}

// Used to help set the transfer buffer result to SizedResult of a single value.
template <typename T>
class SizedResultHelper {
 public:
  explicit SizedResultHelper(T result)
      : size_(sizeof(result)) {
    memcpy(result_, &result, sizeof(T));
  }

 private:
  uint32_t size_;
  char result_[sizeof(T)];
};

// Struct to make it easy to pass a vec4 worth of floats.
struct FourFloats {
  FourFloats(float _x, float _y, float _z, float _w)
      : x(_x),
        y(_y),
        z(_z),
        w(_w) {
  }

  float x;
  float y;
  float z;
  float w;
};

#pragma pack(push, 1)
// Struct that holds 7 characters.
struct Str7 {
  char str[7];
};
#pragma pack(pop)

class MockTransferBuffer : public TransferBufferInterface {
 public:
  struct ExpectedMemoryInfo {
    uint32_t offset;
    int32_t id;
    uint8_t* ptr;
  };

  MockTransferBuffer(
      CommandBuffer* command_buffer,
      unsigned int size,
      unsigned int result_size,
      unsigned int alignment,
      bool initialize_fail)
      : command_buffer_(command_buffer),
        size_(size),
        result_size_(result_size),
        alignment_(alignment),
        actual_buffer_index_(0),
        expected_buffer_index_(0),
        last_alloc_(NULL),
        expected_offset_(result_size),
        actual_offset_(result_size),
        initialize_fail_(initialize_fail) {
    // We have to allocate the buffers here because
    // we need to know their address before GLES2Implementation::Initialize
    // is called.
    for (int ii = 0; ii < kNumBuffers; ++ii) {
      buffers_[ii] = command_buffer_->CreateTransferBuffer(
          size_ + ii * alignment_,
          &buffer_ids_[ii]);
      EXPECT_NE(-1, buffer_ids_[ii]);
    }
  }

  ~MockTransferBuffer() override {}

  bool Initialize(unsigned int starting_buffer_size,
                  unsigned int result_size,
                  unsigned int /* min_buffer_size */,
                  unsigned int /* max_buffer_size */,
                  unsigned int alignment,
                  unsigned int size_to_flush) override;
  int GetShmId() override;
  void* GetResultBuffer() override;
  int GetResultOffset() override;
  void Free() override;
  bool HaveBuffer() const override;
  void* AllocUpTo(unsigned int size, unsigned int* size_allocated) override;
  void* Alloc(unsigned int size) override;
  RingBuffer::Offset GetOffset(void* pointer) const override;
  void DiscardBlock(void* p) override;
  void FreePendingToken(void* p, unsigned int /* token */) override;
  unsigned int GetSize() const override;
  unsigned int GetFreeSize() const override;

  size_t MaxTransferBufferSize() {
    return size_ - result_size_;
  }

  unsigned int RoundToAlignment(unsigned int size) {
    return (size + alignment_ - 1) & ~(alignment_ - 1);
  }

  bool InSync() {
    return expected_buffer_index_ == actual_buffer_index_ &&
           expected_offset_ == actual_offset_;
  }

  ExpectedMemoryInfo GetExpectedMemory(size_t size) {
    ExpectedMemoryInfo mem;
    mem.offset = AllocateExpectedTransferBuffer(size);
    mem.id = GetExpectedTransferBufferId();
    mem.ptr = static_cast<uint8_t*>(
        GetExpectedTransferAddressFromOffset(mem.offset, size));
    return mem;
  }

  ExpectedMemoryInfo GetExpectedResultMemory(size_t size) {
    ExpectedMemoryInfo mem;
    mem.offset = GetExpectedResultBufferOffset();
    mem.id = GetExpectedResultBufferId();
    mem.ptr = static_cast<uint8_t*>(
        GetExpectedTransferAddressFromOffset(mem.offset, size));
    return mem;
  }

 private:
  static const int kNumBuffers = 2;

  uint8_t* actual_buffer() const {
    return static_cast<uint8_t*>(buffers_[actual_buffer_index_]->memory());
  }

  uint8_t* expected_buffer() const {
    return static_cast<uint8_t*>(buffers_[expected_buffer_index_]->memory());
  }

  uint32_t AllocateExpectedTransferBuffer(size_t size) {
    EXPECT_LE(size, MaxTransferBufferSize());

    // Toggle which buffer we get each time to simulate the buffer being
    // reallocated.
    expected_buffer_index_ = (expected_buffer_index_ + 1) % kNumBuffers;

    if (expected_offset_ + size > size_) {
      expected_offset_ = result_size_;
    }
    uint32_t offset = expected_offset_;
    expected_offset_ += RoundToAlignment(size);

    // Make sure each buffer has a different offset.
    return offset + expected_buffer_index_ * alignment_;
  }

  void* GetExpectedTransferAddressFromOffset(uint32_t offset, size_t size) {
    EXPECT_GE(offset, expected_buffer_index_ * alignment_);
    EXPECT_LE(offset + size, size_ + expected_buffer_index_ * alignment_);
    return expected_buffer() + offset;
  }

  int GetExpectedResultBufferId() {
    return buffer_ids_[expected_buffer_index_];
  }

  uint32_t GetExpectedResultBufferOffset() {
    return expected_buffer_index_ * alignment_;
  }

  int GetExpectedTransferBufferId() {
    return buffer_ids_[expected_buffer_index_];
  }

  CommandBuffer* command_buffer_;
  size_t size_;
  size_t result_size_;
  uint32_t alignment_;
  int buffer_ids_[kNumBuffers];
  scoped_refptr<Buffer> buffers_[kNumBuffers];
  int actual_buffer_index_;
  int expected_buffer_index_;
  void* last_alloc_;
  uint32_t expected_offset_;
  uint32_t actual_offset_;
  bool initialize_fail_;

  DISALLOW_COPY_AND_ASSIGN(MockTransferBuffer);
};

bool MockTransferBuffer::Initialize(
    unsigned int starting_buffer_size,
    unsigned int result_size,
    unsigned int /* min_buffer_size */,
    unsigned int /* max_buffer_size */,
    unsigned int alignment,
    unsigned int /* size_to_flush */) {
  // Just check they match.
  return size_ == starting_buffer_size &&
         result_size_ == result_size &&
         alignment_ == alignment && !initialize_fail_;
};

int MockTransferBuffer::GetShmId() {
  return buffer_ids_[actual_buffer_index_];
}

void* MockTransferBuffer::GetResultBuffer() {
  return actual_buffer() + actual_buffer_index_ * alignment_;
}

int MockTransferBuffer::GetResultOffset() {
  return actual_buffer_index_ * alignment_;
}

void MockTransferBuffer::Free() {
  NOTREACHED();
}

bool MockTransferBuffer::HaveBuffer() const {
  return true;
}

void* MockTransferBuffer::AllocUpTo(
    unsigned int size, unsigned int* size_allocated) {
  EXPECT_TRUE(size_allocated != NULL);
  EXPECT_TRUE(last_alloc_ == NULL);

  // Toggle which buffer we get each time to simulate the buffer being
  // reallocated.
  actual_buffer_index_ = (actual_buffer_index_ + 1) % kNumBuffers;

  size = std::min(static_cast<size_t>(size), MaxTransferBufferSize());
  if (actual_offset_ + size > size_) {
    actual_offset_ = result_size_;
  }
  uint32_t offset = actual_offset_;
  actual_offset_ += RoundToAlignment(size);
  *size_allocated = size;

  // Make sure each buffer has a different offset.
  last_alloc_ = actual_buffer() + offset + actual_buffer_index_ * alignment_;
  return last_alloc_;
}

void* MockTransferBuffer::Alloc(unsigned int size) {
  EXPECT_LE(size, MaxTransferBufferSize());
  unsigned int temp = 0;
  void* p = AllocUpTo(size, &temp);
  EXPECT_EQ(temp, size);
  return p;
}

RingBuffer::Offset MockTransferBuffer::GetOffset(void* pointer) const {
  // Make sure each buffer has a different offset.
  return static_cast<uint8_t*>(pointer) - actual_buffer();
}

void MockTransferBuffer::DiscardBlock(void* p) {
  EXPECT_EQ(last_alloc_, p);
  last_alloc_ = NULL;
}

void MockTransferBuffer::FreePendingToken(void* p, unsigned int /* token */) {
  EXPECT_EQ(last_alloc_, p);
  last_alloc_ = NULL;
}

unsigned int MockTransferBuffer::GetSize() const {
  return 0;
}

unsigned int MockTransferBuffer::GetFreeSize() const {
  return 0;
}

// API wrapper for Buffers.
class GenBuffersAPI {
 public:
  static void Gen(GLES2Implementation* gl_impl, GLsizei n, GLuint* ids) {
    gl_impl->GenBuffers(n, ids);
  }

  static void Delete(GLES2Implementation* gl_impl,
                     GLsizei n,
                     const GLuint* ids) {
    gl_impl->DeleteBuffers(n, ids);
  }
};

// API wrapper for Framebuffers.
class GenFramebuffersAPI {
 public:
  static void Gen(GLES2Implementation* gl_impl, GLsizei n, GLuint* ids) {
    gl_impl->GenFramebuffers(n, ids);
  }

  static void Delete(GLES2Implementation* gl_impl,
                     GLsizei n,
                     const GLuint* ids) {
    gl_impl->DeleteFramebuffers(n, ids);
  }
};

// API wrapper for Renderbuffers.
class GenRenderbuffersAPI {
 public:
  static void Gen(GLES2Implementation* gl_impl, GLsizei n, GLuint* ids) {
    gl_impl->GenRenderbuffers(n, ids);
  }

  static void Delete(GLES2Implementation* gl_impl,
                     GLsizei n,
                     const GLuint* ids) {
    gl_impl->DeleteRenderbuffers(n, ids);
  }
};

// API wrapper for Textures.
class GenTexturesAPI {
 public:
  static void Gen(GLES2Implementation* gl_impl, GLsizei n, GLuint* ids) {
    gl_impl->GenTextures(n, ids);
  }

  static void Delete(GLES2Implementation* gl_impl,
                     GLsizei n,
                     const GLuint* ids) {
    gl_impl->DeleteTextures(n, ids);
  }
};

class GLES2ImplementationTest : public testing::Test {
 protected:
  static const int kNumTestContexts = 2;
  static const uint8_t kInitialValue = 0xBD;
  static const int32_t kNumCommandEntries = 500;
  static const int32_t kCommandBufferSizeBytes =
      kNumCommandEntries * sizeof(CommandBufferEntry);
  static const size_t kTransferBufferSize = 512;

  static const GLint kMaxCombinedTextureImageUnits = 8;
  static const GLint kMaxCubeMapTextureSize = 64;
  static const GLint kMaxFragmentUniformVectors = 16;
  static const GLint kMaxRenderbufferSize = 64;
  static const GLint kMaxTextureImageUnits = 8;
  static const GLint kMaxTextureSize = 128;
  static const GLint kMaxVaryingVectors = 8;
  static const GLint kMaxVertexAttribs = 8;
  static const GLint kMaxVertexTextureImageUnits = 0;
  static const GLint kMaxVertexUniformVectors = 128;
  static const GLint kNumCompressedTextureFormats = 0;
  static const GLint kNumShaderBinaryFormats = 0;
  static const GLuint kMaxTransformFeedbackSeparateAttribs = 4;
  static const GLuint kMaxUniformBufferBindings = 36;
  static const GLuint kStartId = 1024;
  static const GLuint kBuffersStartId = 1;
  static const GLuint kFramebuffersStartId = 1;
  static const GLuint kProgramsAndShadersStartId = 1;
  static const GLuint kRenderbuffersStartId = 1;
  static const GLuint kSamplersStartId = 1;
  static const GLuint kTexturesStartId = 1;
  static const GLuint kTransformFeedbacksStartId = 1;
  static const GLuint kQueriesStartId = 1;
  static const GLuint kVertexArraysStartId = 1;

  typedef MockTransferBuffer::ExpectedMemoryInfo ExpectedMemoryInfo;

  class TestContext {
   public:
    TestContext() : commands_(NULL), token_(0) {}

    bool Initialize(ShareGroup* share_group,
                    bool bind_generates_resource_client,
                    bool bind_generates_resource_service,
                    bool lose_context_when_out_of_memory,
                    bool transfer_buffer_initialize_fail,
                    bool sync_query,
                    bool occlusion_query_boolean,
                    bool timer_queries,
                    int major_version,
                    int minor_version) {
      command_buffer_.reset(new StrictMock<MockClientCommandBuffer>());

      transfer_buffer_.reset(
          new MockTransferBuffer(command_buffer_.get(),
                                 kTransferBufferSize,
                                 GLES2Implementation::kStartingOffset,
                                 GLES2Implementation::kAlignment,
                                 transfer_buffer_initialize_fail));

      helper_.reset(new GLES2CmdHelper(command_buffer()));
      helper_->Initialize(kCommandBufferSizeBytes);

      gpu_control_.reset(new StrictMock<MockClientGpuControl>());
      Capabilities capabilities;
      capabilities.VisitPrecisions(
          [](GLenum shader, GLenum type,
             Capabilities::ShaderPrecision* precision) {
            precision->min_range = 3;
            precision->max_range = 5;
            precision->precision = 7;
          });
      capabilities.max_combined_texture_image_units =
          kMaxCombinedTextureImageUnits;
      capabilities.max_cube_map_texture_size = kMaxCubeMapTextureSize;
      capabilities.max_fragment_uniform_vectors = kMaxFragmentUniformVectors;
      capabilities.max_renderbuffer_size = kMaxRenderbufferSize;
      capabilities.max_texture_image_units = kMaxTextureImageUnits;
      capabilities.max_texture_size = kMaxTextureSize;
      capabilities.max_varying_vectors = kMaxVaryingVectors;
      capabilities.max_vertex_attribs = kMaxVertexAttribs;
      capabilities.max_vertex_texture_image_units = kMaxVertexTextureImageUnits;
      capabilities.max_vertex_uniform_vectors = kMaxVertexUniformVectors;
      capabilities.num_compressed_texture_formats =
          kNumCompressedTextureFormats;
      capabilities.num_shader_binary_formats = kNumShaderBinaryFormats;
      capabilities.max_transform_feedback_separate_attribs =
          kMaxTransformFeedbackSeparateAttribs;
      capabilities.max_uniform_buffer_bindings = kMaxUniformBufferBindings;
      capabilities.bind_generates_resource_chromium =
          bind_generates_resource_service ? 1 : 0;
      capabilities.sync_query = sync_query;
      capabilities.occlusion_query_boolean = occlusion_query_boolean;
      capabilities.timer_queries = timer_queries;
      capabilities.major_version = major_version;
      capabilities.minor_version = minor_version;
      EXPECT_CALL(*gpu_control_, GetCapabilities())
          .WillOnce(Return(capabilities));

      {
        InSequence sequence;

        const bool support_client_side_arrays = true;
        gl_.reset(new GLES2Implementation(helper_.get(),
                                          share_group,
                                          transfer_buffer_.get(),
                                          bind_generates_resource_client,
                                          lose_context_when_out_of_memory,
                                          support_client_side_arrays,
                                          gpu_control_.get()));
      }

      // The client should be set to something non-null.
      EXPECT_CALL(*gpu_control_, SetGpuControlClient(gl_.get())).Times(1);

      if (!gl_->Initialize(kTransferBufferSize, kTransferBufferSize,
                           kTransferBufferSize, SharedMemoryLimits::kNoLimit))
        return false;

      helper_->CommandBufferHelper::Finish();
      Mock::VerifyAndClearExpectations(gl_.get());

      scoped_refptr<Buffer> ring_buffer = helper_->get_ring_buffer();
      commands_ = static_cast<CommandBufferEntry*>(ring_buffer->memory()) +
                  command_buffer()->GetPutOffset();
      ClearCommands();
      EXPECT_TRUE(transfer_buffer_->InSync());

      Mock::VerifyAndClearExpectations(command_buffer());
      return true;
    }

    void TearDown() {
      Mock::VerifyAndClear(gl_.get());
      EXPECT_CALL(*command_buffer(), OnFlush()).Times(AnyNumber());
      // For command buffer.
      EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
          .Times(AtLeast(1));
      // The client should be unset.
      EXPECT_CALL(*gpu_control_, SetGpuControlClient(nullptr)).Times(1);
      gl_.reset();
    }

    MockClientCommandBuffer* command_buffer() const {
      return command_buffer_.get();
    }

    int GetNextToken() { return ++token_; }

    void ClearCommands() {
      scoped_refptr<Buffer> ring_buffer = helper_->get_ring_buffer();
      memset(ring_buffer->memory(), kInitialValue, ring_buffer->size());
    }

    std::unique_ptr<MockClientCommandBuffer> command_buffer_;
    std::unique_ptr<MockClientGpuControl> gpu_control_;
    std::unique_ptr<GLES2CmdHelper> helper_;
    std::unique_ptr<MockTransferBuffer> transfer_buffer_;
    std::unique_ptr<GLES2Implementation> gl_;
    CommandBufferEntry* commands_;
    int token_;
  };

  GLES2ImplementationTest() : commands_(NULL) {}

  void SetUp() override;
  void TearDown() override;

  bool NoCommandsWritten() {
    scoped_refptr<Buffer> ring_buffer = helper_->get_ring_buffer();
    const uint8_t* cmds =
        reinterpret_cast<const uint8_t*>(ring_buffer->memory());
    const uint8_t* end = cmds + ring_buffer->size();
    for (; cmds < end; ++cmds) {
      if (*cmds != kInitialValue) {
        return false;
      }
    }
    return true;
  }

  QueryTracker::Query* GetQuery(GLuint id) {
    return gl_->query_tracker_->GetQuery(id);
  }

  QueryTracker* GetQueryTracker() {
    return gl_->query_tracker_.get();
  }

  struct ContextInitOptions {
    ContextInitOptions()
        : bind_generates_resource_client(true),
          bind_generates_resource_service(true),
          lose_context_when_out_of_memory(false),
          transfer_buffer_initialize_fail(false),
          sync_query(true),
          occlusion_query_boolean(true),
          timer_queries(true),
          major_version(2),
          minor_version(0) {}

    bool bind_generates_resource_client;
    bool bind_generates_resource_service;
    bool lose_context_when_out_of_memory;
    bool transfer_buffer_initialize_fail;
    bool sync_query;
    bool occlusion_query_boolean;
    bool timer_queries;
    int major_version;
    int minor_version;
  };

  bool Initialize(const ContextInitOptions& init_options) {
    bool success = true;
    share_group_ = new ShareGroup(init_options.bind_generates_resource_client,
                                  0 /* tracing_id */);

    for (int i = 0; i < kNumTestContexts; i++) {
      if (!test_contexts_[i].Initialize(
              share_group_.get(),
              init_options.bind_generates_resource_client,
              init_options.bind_generates_resource_service,
              init_options.lose_context_when_out_of_memory,
              init_options.transfer_buffer_initialize_fail,
              init_options.sync_query,
              init_options.occlusion_query_boolean,
              init_options.timer_queries,
              init_options.major_version,
              init_options.minor_version))
        success = false;
    }

    // Default to test context 0.
    gpu_control_ = test_contexts_[0].gpu_control_.get();
    helper_ = test_contexts_[0].helper_.get();
    transfer_buffer_ = test_contexts_[0].transfer_buffer_.get();
    gl_ = test_contexts_[0].gl_.get();
    commands_ = test_contexts_[0].commands_;
    return success;
  }

  MockClientCommandBuffer* command_buffer() const {
    return test_contexts_[0].command_buffer_.get();
  }

  int GetNextToken() { return test_contexts_[0].GetNextToken(); }

  const void* GetPut() {
    return helper_->GetSpace(0);
  }

  void ClearCommands() {
    scoped_refptr<Buffer> ring_buffer = helper_->get_ring_buffer();
    memset(ring_buffer->memory(), kInitialValue, ring_buffer->size());
  }

  size_t MaxTransferBufferSize() {
    return transfer_buffer_->MaxTransferBufferSize();
  }

  void SetMappedMemoryLimit(size_t limit) {
    gl_->mapped_memory_->set_max_allocated_bytes(limit);
  }

  ExpectedMemoryInfo GetExpectedMemory(size_t size) {
    return transfer_buffer_->GetExpectedMemory(size);
  }

  ExpectedMemoryInfo GetExpectedResultMemory(size_t size) {
    return transfer_buffer_->GetExpectedResultMemory(size);
  }

  ExpectedMemoryInfo GetExpectedMappedMemory(size_t size) {
    ExpectedMemoryInfo mem;

    // Temporarily allocate memory and expect that memory block to be reused.
    mem.ptr = static_cast<uint8_t*>(
        gl_->mapped_memory_->Alloc(size, &mem.id, &mem.offset));
    gl_->mapped_memory_->Free(mem.ptr);

    return mem;
  }

  // Sets the ProgramInfoManager. The manager will be owned
  // by the ShareGroup.
  void SetProgramInfoManager(ProgramInfoManager* manager) {
    gl_->share_group()->SetProgramInfoManagerForTesting(manager);
  }

  int CheckError() {
    ExpectedMemoryInfo result =
        GetExpectedResultMemory(sizeof(cmds::GetError::Result));
    EXPECT_CALL(*command_buffer(), OnFlush())
        .WillOnce(SetMemory(result.ptr, GLuint(GL_NO_ERROR)))
        .RetiresOnSaturation();
    return gl_->GetError();
  }

  const std::string& GetLastError() {
    return gl_->GetLastError();
  }

  bool GetBucketContents(uint32_t bucket_id, std::vector<int8_t>* data) {
    return gl_->GetBucketContents(bucket_id, data);
  }

  bool AllowExtraTransferBufferSize() {
    return gl_->max_extra_transfer_buffer_size_ > 0;
  }

  TestContext test_contexts_[kNumTestContexts];

  scoped_refptr<ShareGroup> share_group_;
  MockClientGpuControl* gpu_control_;
  GLES2CmdHelper* helper_;
  MockTransferBuffer* transfer_buffer_;
  GLES2Implementation* gl_;
  CommandBufferEntry* commands_;
};

void GLES2ImplementationTest::SetUp() {
  ContextInitOptions init_options;
  ASSERT_TRUE(Initialize(init_options));
}

void GLES2ImplementationTest::TearDown() {
  for (int i = 0; i < kNumTestContexts; i++)
    test_contexts_[i].TearDown();
}

class GLES2ImplementationManualInitTest : public GLES2ImplementationTest {
 protected:
  void SetUp() override {}
};

class GLES2ImplementationStrictSharedTest : public GLES2ImplementationTest {
 protected:
  void SetUp() override;

  template <class ResApi>
  void FlushGenerationTest() {
    GLuint id1, id2, id3;

    // Generate valid id.
    ResApi::Gen(gl_, 1, &id1);
    EXPECT_NE(id1, 0u);

    // Delete id1 and generate id2.  id1 should not be reused.
    ResApi::Delete(gl_, 1, &id1);
    ResApi::Gen(gl_, 1, &id2);
    EXPECT_NE(id2, 0u);
    EXPECT_NE(id2, id1);

    // Expect id1 reuse after Flush.
    gl_->Flush();
    ResApi::Gen(gl_, 1, &id3);
    EXPECT_EQ(id3, id1);
  }

  // Ids should not be reused unless the |Deleting| context does a Flush()
  // AND triggers a lazy release after that.
  template <class ResApi>
  void CrossContextGenerationTest() {
    GLES2Implementation* gl1 = test_contexts_[0].gl_.get();
    GLES2Implementation* gl2 = test_contexts_[1].gl_.get();
    GLuint id1, id2, id3;

    // Delete, no flush on context 1.  No reuse.
    ResApi::Gen(gl1, 1, &id1);
    ResApi::Delete(gl1, 1, &id1);
    ResApi::Gen(gl1, 1, &id2);
    EXPECT_NE(id1, id2);

    // Flush context 2.  Still no reuse.
    gl2->Flush();
    ResApi::Gen(gl2, 1, &id3);
    EXPECT_NE(id1, id3);
    EXPECT_NE(id2, id3);

    // Flush on context 1, but no lazy release.  Still no reuse.
    gl1->Flush();
    ResApi::Gen(gl2, 1, &id3);
    EXPECT_NE(id1, id3);

    // Lazy release triggered by another Delete.  Should reuse id1.
    ResApi::Delete(gl1, 1, &id2);
    ResApi::Gen(gl2, 1, &id3);
    EXPECT_EQ(id1, id3);
  }

  // Same as CrossContextGenerationTest(), but triggers an Auto Flush on
  // the Delete().  Tests an edge case regression.
  template <class ResApi>
  void CrossContextGenerationAutoFlushTest() {
    GLES2Implementation* gl1 = test_contexts_[0].gl_.get();
    GLES2Implementation* gl2 = test_contexts_[1].gl_.get();
    GLuint id1, id2, id3;

    // Delete, no flush on context 1.  No reuse.
    // By half filling the buffer, an internal flush is forced on the Delete().
    ResApi::Gen(gl1, 1, &id1);
    gl1->helper()->Noop(kNumCommandEntries / 2);
    ResApi::Delete(gl1, 1, &id1);
    ResApi::Gen(gl1, 1, &id2);
    EXPECT_NE(id1, id2);

    // Flush context 2.  Still no reuse.
    gl2->Flush();
    ResApi::Gen(gl2, 1, &id3);
    EXPECT_NE(id1, id3);
    EXPECT_NE(id2, id3);

    // Flush on context 1, but no lazy release.  Still no reuse.
    gl1->Flush();
    ResApi::Gen(gl2, 1, &id3);
    EXPECT_NE(id1, id3);

    // Lazy release triggered by another Delete.  Should reuse id1.
    ResApi::Delete(gl1, 1, &id2);
    ResApi::Gen(gl2, 1, &id3);
    EXPECT_EQ(id1, id3);
  }
};

void GLES2ImplementationStrictSharedTest::SetUp() {
  ContextInitOptions init_options;
  init_options.bind_generates_resource_client = false;
  init_options.bind_generates_resource_service = false;
  ASSERT_TRUE(Initialize(init_options));
}

class GLES3ImplementationTest : public GLES2ImplementationTest {
 protected:
  void SetUp() override;
};

void GLES3ImplementationTest::SetUp() {
  ContextInitOptions init_options;
  init_options.major_version = 3;
  init_options.minor_version = 0;
  ASSERT_TRUE(Initialize(init_options));
}

// GCC requires these declarations, but MSVC requires they not be present
#ifndef _MSC_VER
const uint8_t GLES2ImplementationTest::kInitialValue;
const int32_t GLES2ImplementationTest::kNumCommandEntries;
const int32_t GLES2ImplementationTest::kCommandBufferSizeBytes;
const size_t GLES2ImplementationTest::kTransferBufferSize;
const GLint GLES2ImplementationTest::kMaxCombinedTextureImageUnits;
const GLint GLES2ImplementationTest::kMaxCubeMapTextureSize;
const GLint GLES2ImplementationTest::kMaxFragmentUniformVectors;
const GLint GLES2ImplementationTest::kMaxRenderbufferSize;
const GLint GLES2ImplementationTest::kMaxTextureImageUnits;
const GLint GLES2ImplementationTest::kMaxTextureSize;
const GLint GLES2ImplementationTest::kMaxVaryingVectors;
const GLint GLES2ImplementationTest::kMaxVertexAttribs;
const GLint GLES2ImplementationTest::kMaxVertexTextureImageUnits;
const GLint GLES2ImplementationTest::kMaxVertexUniformVectors;
const GLint GLES2ImplementationTest::kNumCompressedTextureFormats;
const GLint GLES2ImplementationTest::kNumShaderBinaryFormats;
const GLuint GLES2ImplementationTest::kStartId;
const GLuint GLES2ImplementationTest::kBuffersStartId;
const GLuint GLES2ImplementationTest::kFramebuffersStartId;
const GLuint GLES2ImplementationTest::kProgramsAndShadersStartId;
const GLuint GLES2ImplementationTest::kRenderbuffersStartId;
const GLuint GLES2ImplementationTest::kSamplersStartId;
const GLuint GLES2ImplementationTest::kTexturesStartId;
const GLuint GLES2ImplementationTest::kTransformFeedbacksStartId;
const GLuint GLES2ImplementationTest::kQueriesStartId;
const GLuint GLES2ImplementationTest::kVertexArraysStartId;
#endif

TEST_F(GLES2ImplementationTest, Basic) {
  EXPECT_TRUE(gl_->share_group());
}

TEST_F(GLES2ImplementationTest, GetBucketContents) {
  const uint32_t kBucketId = GLES2Implementation::kResultBucketId;
  const uint32_t kTestSize = MaxTransferBufferSize() + 32;

  std::unique_ptr<uint8_t[]> buf(new uint8_t[kTestSize]);
  uint8_t* expected_data = buf.get();
  for (uint32_t ii = 0; ii < kTestSize; ++ii) {
    expected_data[ii] = ii * 3;
  }

  struct Cmds {
    cmd::GetBucketStart get_bucket_start;
    cmd::SetToken set_token1;
    cmd::GetBucketData get_bucket_data;
    cmd::SetToken set_token2;
    cmd::SetBucketSize set_bucket_size2;
  };

  ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
  ExpectedMemoryInfo result1 = GetExpectedResultMemory(sizeof(uint32_t));
  ExpectedMemoryInfo mem2 = GetExpectedMemory(
      kTestSize - MaxTransferBufferSize());

  Cmds expected;
  expected.get_bucket_start.Init(
      kBucketId, result1.id, result1.offset,
      MaxTransferBufferSize(), mem1.id, mem1.offset);
  expected.set_token1.Init(GetNextToken());
  expected.get_bucket_data.Init(
      kBucketId, MaxTransferBufferSize(),
      kTestSize - MaxTransferBufferSize(), mem2.id, mem2.offset);
  expected.set_bucket_size2.Init(kBucketId, 0);
  expected.set_token2.Init(GetNextToken());

  EXPECT_CALL(*command_buffer(), OnFlush())
      .WillOnce(DoAll(
          SetMemory(result1.ptr, kTestSize),
          SetMemoryFromArray(
              mem1.ptr, expected_data, MaxTransferBufferSize())))
      .WillOnce(SetMemoryFromArray(
          mem2.ptr, expected_data + MaxTransferBufferSize(),
          kTestSize - MaxTransferBufferSize()))
      .RetiresOnSaturation();

  std::vector<int8_t> data;
  GetBucketContents(kBucketId, &data);
  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
  ASSERT_EQ(kTestSize, data.size());
  EXPECT_EQ(0, memcmp(expected_data, &data[0], data.size()));
}

TEST_F(GLES2ImplementationTest, GetShaderPrecisionFormat) {
  struct Cmds {
    cmds::GetShaderPrecisionFormat cmd;
  };
  typedef cmds::GetShaderPrecisionFormat::Result Result;
  const unsigned kDummyType1 = 3;
  const unsigned kDummyType2 = 4;

  // The first call for dummy type 1 should trigger a command buffer request.
  GLint range1[2] = {0, 0};
  GLint precision1 = 0;
  Cmds expected1;
  ExpectedMemoryInfo client_result1 = GetExpectedResultMemory(4);
  expected1.cmd.Init(GL_FRAGMENT_SHADER, kDummyType1, client_result1.id,
                     client_result1.offset);
  Result server_result1 = {true, 14, 14, 10};
  EXPECT_CALL(*command_buffer(), OnFlush())
      .WillOnce(SetMemory(client_result1.ptr, server_result1))
      .RetiresOnSaturation();
  gl_->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER, kDummyType1, range1,
                                &precision1);
  const void* commands2 = GetPut();
  EXPECT_NE(commands_, commands2);
  EXPECT_EQ(0, memcmp(&expected1, commands_, sizeof(expected1)));
  EXPECT_EQ(range1[0], 14);
  EXPECT_EQ(range1[1], 14);
  EXPECT_EQ(precision1, 10);

  // The second call for dummy type 1 should use the cached value and avoid
  // triggering a command buffer request, so we do not expect a call to
  // OnFlush() here. We do expect the results to be correct though.
  GLint range2[2] = {0, 0};
  GLint precision2 = 0;
  gl_->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER, kDummyType1, range2,
                                &precision2);
  const void* commands3 = GetPut();
  EXPECT_EQ(commands2, commands3);
  EXPECT_EQ(range2[0], 14);
  EXPECT_EQ(range2[1], 14);
  EXPECT_EQ(precision2, 10);

  // If we then make a request for dummy type 2, we should get another command
  // buffer request since it hasn't been cached yet.
  GLint range3[2] = {0, 0};
  GLint precision3 = 0;
  Cmds expected3;
  ExpectedMemoryInfo result3 = GetExpectedResultMemory(4);
  expected3.cmd.Init(GL_FRAGMENT_SHADER, kDummyType2, result3.id,
                     result3.offset);
  Result result3_source = {true, 62, 62, 16};
  EXPECT_CALL(*command_buffer(), OnFlush())
      .WillOnce(SetMemory(result3.ptr, result3_source))
      .RetiresOnSaturation();
  gl_->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER, kDummyType2, range3,
                                &precision3);
  const void* commands4 = GetPut();
  EXPECT_NE(commands3, commands4);
  EXPECT_EQ(0, memcmp(&expected3, commands3, sizeof(expected3)));
  EXPECT_EQ(range3[0], 62);
  EXPECT_EQ(range3[1], 62);
  EXPECT_EQ(precision3, 16);

  // Any call for predefined types should use the cached value from the
  // Capabilities  and avoid triggering a command buffer request, so we do not
  // expect a call to OnFlush() here. We do expect the results to be correct
  // though.
  GLint range4[2] = {0, 0};
  GLint precision4 = 0;
  gl_->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_MEDIUM_FLOAT, range4,
                                &precision4);
  const void* commands5 = GetPut();
  EXPECT_EQ(commands4, commands5);
  EXPECT_EQ(range4[0], 3);
  EXPECT_EQ(range4[1], 5);
  EXPECT_EQ(precision4, 7);
}

TEST_F(GLES2ImplementationTest, GetShaderSource) {
  const uint32_t kBucketId = GLES2Implementation::kResultBucketId;
  const GLuint kShaderId = 456;
  const Str7 kString = {"foobar"};
  const char kBad = 0x12;
  struct Cmds {
    cmd::SetBucketSize set_bucket_size1;
    cmds::GetShaderSource get_shader_source;
    cmd::GetBucketStart get_bucket_start;
    cmd::SetToken set_token1;
    cmd::SetBucketSize set_bucket_size2;
  };

  ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
  ExpectedMemoryInfo result1 = GetExpectedResultMemory(sizeof(uint32_t));

  Cmds expected;
  expected.set_bucket_size1.Init(kBucketId, 0);
  expected.get_shader_source.Init(kShaderId, kBucketId);
  expected.get_bucket_start.Init(
      kBucketId, result1.id, result1.offset,
      MaxTransferBufferSize(), mem1.id, mem1.offset);
  expected.set_token1.Init(GetNextToken());
  expected.set_bucket_size2.Init(kBucketId, 0);
  char buf[sizeof(kString) + 1];
  memset(buf, kBad, sizeof(buf));

  EXPECT_CALL(*command_buffer(), OnFlush())
      .WillOnce(DoAll(SetMemory(result1.ptr, uint32_t(sizeof(kString))),
                      SetMemory(mem1.ptr, kString)))
      .RetiresOnSaturation();

  GLsizei length = 0;
  gl_->GetShaderSource(kShaderId, sizeof(buf), &length, buf);
  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
  EXPECT_EQ(sizeof(kString) - 1, static_cast<size_t>(length));
  EXPECT_STREQ(kString.str, buf);
  EXPECT_EQ(buf[sizeof(kString)], kBad);
}

#if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)

TEST_F(GLES2ImplementationTest, DrawArraysClientSideBuffers) {
  static const float verts[][4] = {
    { 12.0f, 23.0f, 34.0f, 45.0f, },
    { 56.0f, 67.0f, 78.0f, 89.0f, },
    { 13.0f, 24.0f, 35.0f, 46.0f, },
  };
  struct Cmds {
    cmds::EnableVertexAttribArray enable1;
    cmds::EnableVertexAttribArray enable2;
    cmds::BindBuffer bind_to_emu;
    cmds::BufferData set_size;
    cmds::BufferSubData copy_data1;
    cmd::SetToken set_token1;
    cmds::VertexAttribPointer set_pointer1;
    cmds::BufferSubData copy_data2;
    cmd::SetToken set_token2;
    cmds::VertexAttribPointer set_pointer2;
    cmds::DrawArrays draw;
    cmds::BindBuffer restore;
  };
  const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
  const GLuint kAttribIndex1 = 1;
  const GLuint kAttribIndex2 = 3;
  const GLint kNumComponents1 = 3;
  const GLint kNumComponents2 = 2;
  const GLsizei kClientStride = sizeof(verts[0]);
  const GLint kFirst = 1;
  const GLsizei kCount = 2;
  const GLsizei kSize1 =
      arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
  const GLsizei kSize2 =
      arraysize(verts) * kNumComponents2 * sizeof(verts[0][0]);
  const GLsizei kEmuOffset1 = 0;
  const GLsizei kEmuOffset2 = kSize1;
  const GLsizei kTotalSize = kSize1 + kSize2;

  ExpectedMemoryInfo mem1 = GetExpectedMemory(kSize1);
  ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize2);

  Cmds expected;
  expected.enable1.Init(kAttribIndex1);
  expected.enable2.Init(kAttribIndex2);
  expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
  expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
  expected.copy_data1.Init(
      GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem1.id, mem1.offset);
  expected.set_token1.Init(GetNextToken());
  expected.set_pointer1.Init(
      kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
  expected.copy_data2.Init(
      GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem2.id, mem2.offset);
  expected.set_token2.Init(GetNextToken());
  expected.set_pointer2.Init(
      kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
  expected.draw.Init(GL_POINTS, kFirst, kCount);
  expected.restore.Init(GL_ARRAY_BUFFER, 0);
  gl_->EnableVertexAttribArray(kAttribIndex1);
  gl_->EnableVertexAttribArray(kAttribIndex2);
  gl_->VertexAttribPointer(
      kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, kClientStride, verts);
  gl_->VertexAttribPointer(
      kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, kClientStride, verts);
  gl_->DrawArrays(GL_POINTS, kFirst, kCount);
  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
}

TEST_F(GLES2ImplementationTest, DrawArraysInstancedANGLEClientSideBuffers) {
  static const float verts[][4] = {
    { 12.0f, 23.0f, 34.0f, 45.0f, },
    { 56.0f, 67.0f, 78.0f, 89.0f, },
    { 13.0f, 24.0f, 35.0f, 46.0f, },
  };
  struct Cmds {
    cmds::EnableVertexAttribArray enable1;
    cmds::EnableVertexAttribArray enable2;
    cmds::VertexAttribDivisorANGLE divisor;
    cmds::BindBuffer bind_to_emu;
    cmds::BufferData set_size;
    cmds::BufferSubData copy_data1;
    cmd::SetToken set_token1;
    cmds::VertexAttribPointer set_pointer1;
    cmds::BufferSubData copy_data2;
    cmd::SetToken set_token2;
    cmds::VertexAttribPointer set_pointer2;
    cmds::DrawArraysInstancedANGLE draw;
    cmds::BindBuffer restore;
  };
  const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
  const GLuint kAttribIndex1 = 1;
  const GLuint kAttribIndex2 = 3;
  const GLint kNumComponents1 = 3;
  const GLint kNumComponents2 = 2;
  const GLsizei kClientStride = sizeof(verts[0]);
  const GLint kFirst = 1;
  const GLsizei kCount = 2;
  const GLuint kDivisor = 1;
  const GLsizei kSize1 =
      arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
  const GLsizei kSize2 =
      1 * kNumComponents2 * sizeof(verts[0][0]);
  const GLsizei kEmuOffset1 = 0;
  const GLsizei kEmuOffset2 = kSize1;
  const GLsizei kTotalSize = kSize1 + kSize2;

  ExpectedMemoryInfo mem1 = GetExpectedMemory(kSize1);
  ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize2);

  Cmds expected;
  expected.enable1.Init(kAttribIndex1);
  expected.enable2.Init(kAttribIndex2);
  expected.divisor.Init(kAttribIndex2, kDivisor);
  expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
  expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
  expected.copy_data1.Init(
      GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem1.id, mem1.offset);
  expected.set_token1.Init(GetNextToken());
  expected.set_pointer1.Init(
      kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
  expected.copy_data2.Init(
      GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem2.id, mem2.offset);
  expected.set_token2.Init(GetNextToken());
  expected.set_pointer2.Init(
      kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
  expected.draw.Init(GL_POINTS, kFirst, kCount, 1);
  expected.restore.Init(GL_ARRAY_BUFFER, 0);
  gl_->EnableVertexAttribArray(kAttribIndex1);
  gl_->EnableVertexAttribArray(kAttribIndex2);
  gl_->VertexAttribPointer(
      kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, kClientStride, verts);
  gl_->VertexAttribPointer(
      kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, kClientStride, verts);
  gl_->VertexAttribDivisorANGLE(kAttribIndex2, kDivisor);
  gl_->DrawArraysInstancedANGLE(GL_POINTS, kFirst, kCount, 1);
  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
}

TEST_F(GLES2ImplementationTest, DrawElementsClientSideBuffers) {
  static const float verts[][4] = {
    { 12.0f, 23.0f, 34.0f, 45.0f, },
    { 56.0f, 67.0f, 78.0f, 89.0f, },
    { 13.0f, 24.0f, 35.0f, 46.0f, },
  };
  static const uint16_t indices[] = {
      1, 2,
  };
  struct Cmds {
    cmds::EnableVertexAttribArray enable1;
    cmds::EnableVertexAttribArray enable2;
    cmds::BindBuffer bind_to_index_emu;
    cmds::BufferData set_index_size;
    cmds::BufferSubData copy_data0;
    cmd::SetToken set_token0;
    cmds::BindBuffer bind_to_emu;
    cmds::BufferData set_size;
    cmds::BufferSubData copy_data1;
    cmd::SetToken set_token1;
    cmds::VertexAttribPointer set_pointer1;
    cmds::BufferSubData copy_data2;
    cmd::SetToken set_token2;
    cmds::VertexAttribPointer set_pointer2;
    cmds::DrawElements draw;
    cmds::BindBuffer restore;
    cmds::BindBuffer restore_element;
  };
  const GLsizei kIndexSize = sizeof(indices);
  const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
  const GLuint kEmuIndexBufferId =
      GLES2Implementation::kClientSideElementArrayId;
  const GLuint kAttribIndex1 = 1;
  const GLuint kAttribIndex2 = 3;
  const GLint kNumComponents1 = 3;
  const GLint kNumComponents2 = 2;
  const GLsizei kClientStride = sizeof(verts[0]);
  const GLsizei kCount = 2;
  const GLsizei kSize1 =
      arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
  const GLsizei kSize2 =
      arraysize(verts) * kNumComponents2 * sizeof(verts[0][0]);
  const GLsizei kEmuOffset1 = 0;
  const GLsizei kEmuOffset2 = kSize1;
  const GLsizei kTotalSize = kSize1 + kSize2;

  ExpectedMemoryInfo mem1 = GetExpectedMemory(kIndexSize);
  ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize1);
  ExpectedMemoryInfo mem3 = GetExpectedMemory(kSize2);

  Cmds expected;
  expected.enable1.Init(kAttribIndex1);
  expected.enable2.Init(kAttribIndex2);
  expected.bind_to_index_emu.Init(GL_ELEMENT_ARRAY_BUFFER, kEmuIndexBufferId);
  expected.set_index_size.Init(
      GL_ELEMENT_ARRAY_BUFFER, kIndexSize, 0, 0, GL_DYNAMIC_DRAW);
  expected.copy_data0.Init(
      GL_ELEMENT_ARRAY_BUFFER, 0, kIndexSize, mem1.id, mem1.offset);
  expected.set_token0.Init(GetNextToken());
  expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
  expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
  expected.copy_data1.Init(
      GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem2.id, mem2.offset);
  expected.set_token1.Init(GetNextToken());
  expected.set_pointer1.Init(
      kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
  expected.copy_data2.Init(
      GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem3.id, mem3.offset);
  expected.set_token2.Init(GetNextToken());
  expected.set_pointer2.Init(kAttribIndex2, kNumComponents2,
                             GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
  expected.draw.Init(GL_POINTS, kCount, GL_UNSIGNED_SHORT, 0);
  expected.restore.Init(GL_ARRAY_BUFFER, 0);
  expected.restore_element.Init(GL_ELEMENT_ARRAY_BUFFER, 0);
  gl_->EnableVertexAttribArray(kAttribIndex1);
  gl_->EnableVertexAttribArray(kAttribIndex2);
  gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
                           GL_FLOAT, GL_FALSE, kClientStride, verts);
  gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
                           GL_FLOAT, GL_FALSE, kClientStride, verts);
  gl_->DrawElements(GL_POINTS, kCount, GL_UNSIGNED_SHORT, indices);
  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
}

TEST_F(GLES2ImplementationTest, DrawElementsClientSideBuffersIndexUint) {
  static const float verts[][4] = {
    { 12.0f, 23.0f, 34.0f, 45.0f, },
    { 56.0f, 67.0f, 78.0f, 89.0f, },
    { 13.0f, 24.0f, 35.0f, 46.0f, },
  };
  static const uint32_t indices[] = {
      1, 2,
  };
  struct Cmds {
    cmds::EnableVertexAttribArray enable1;
    cmds::EnableVertexAttribArray enable2;
    cmds::BindBuffer bind_to_index_emu;
    cmds::BufferData set_index_size;
    cmds::BufferSubData copy_data0;
    cmd::SetToken set_token0;
    cmds::BindBuffer bind_to_emu;
    cmds::BufferData set_size;
    cmds::BufferSubData copy_data1;
    cmd::SetToken set_token1;
    cmds::VertexAttribPointer set_pointer1;
    cmds::BufferSubData copy_data2;
    cmd::SetToken set_token2;
    cmds::VertexAttribPointer set_pointer2;
    cmds::DrawElements draw;
    cmds::BindBuffer restore;
    cmds::BindBuffer restore_element;
  };
  const GLsizei kIndexSize = sizeof(indices);
  const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
  const GLuint kEmuIndexBufferId =
      GLES2Implementation::kClientSideElementArrayId;
  const GLuint kAttribIndex1 = 1;
  const GLuint kAttribIndex2 = 3;
  const GLint kNumComponents1 = 3;
  const GLint kNumComponents2 = 2;
  const GLsizei kClientStride = sizeof(verts[0]);
  const GLsizei kCount = 2;
  const GLsizei kSize1 =
      arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
  const GLsizei kSize2 =
      arraysize(verts) * kNumComponents2 * sizeof(verts[0][0]);
  const GLsizei kEmuOffset1 = 0;
  const GLsizei kEmuOffset2 = kSize1;
  const GLsizei kTotalSize = kSize1 + kSize2;

  ExpectedMemoryInfo mem1 = GetExpectedMemory(kIndexSize);
  ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize1);
  ExpectedMemoryInfo mem3 = GetExpectedMemory(kSize2);

  Cmds expected;
  expected.enable1.Init(kAttribIndex1);
  expected.enable2.Init(kAttribIndex2);
  expected.bind_to_index_emu.Init(GL_ELEMENT_ARRAY_BUFFER, kEmuIndexBufferId);
  expected.set_index_size.Init(
      GL_ELEMENT_ARRAY_BUFFER, kIndexSize, 0, 0, GL_DYNAMIC_DRAW);
  expected.copy_data0.Init(
      GL_ELEMENT_ARRAY_BUFFER, 0, kIndexSize, mem1.id, mem1.offset);
  expected.set_token0.Init(GetNextToken());
  expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
  expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
  expected.copy_data1.Init(
      GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem2.id, mem2.offset);
  expected.set_token1.Init(GetNextToken());
  expected.set_pointer1.Init(
      kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
  expected.copy_data2.Init(
      GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem3.id, mem3.offset);
  expected.set_token2.Init(GetNextToken());
  expected.set_pointer2.Init(kAttribIndex2, kNumComponents2,
                             GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
  expected.draw.Init(GL_POINTS, kCount, GL_UNSIGNED_INT, 0);
  expected.restore.Init(GL_ARRAY_BUFFER, 0);
  expected.restore_element.Init(GL_ELEMENT_ARRAY_BUFFER, 0);
  gl_->EnableVertexAttribArray(kAttribIndex1);
  gl_->EnableVertexAttribArray(kAttribIndex2);
  gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
                           GL_FLOAT, GL_FALSE, kClientStride, verts);
  gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
                           GL_FLOAT, GL_FALSE, kClientStride, verts);
  gl_->DrawElements(GL_POINTS, kCount, GL_UNSIGNED_INT, indices);
  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
}

TEST_F(GLES2ImplementationTest, DrawElementsClientSideBuffersInvalidIndexUint) {
  static const float verts[][4] = {
    { 12.0f, 23.0f, 34.0f, 45.0f, },
    { 56.0f, 67.0f, 78.0f, 89.0f, },
    { 13.0f, 24.0f, 35.0f, 46.0f, },
  };
  static const uint32_t indices[] = {1, 0x90000000};

  const GLuint kAttribIndex1 = 1;
  const GLuint kAttribIndex2 = 3;
  const GLint kNumComponents1 = 3;
  const GLint kNumComponents2 = 2;
  const GLsizei kClientStride = sizeof(verts[0]);
  const GLsizei kCount = 2;

  EXPECT_CALL(*command_buffer(), OnFlush())
      .Times(1)
      .RetiresOnSaturation();

  gl_->EnableVertexAttribArray(kAttribIndex1);
  gl_->EnableVertexAttribArray(kAttribIndex2);
  gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
                           GL_FLOAT, GL_FALSE, kClientStride, verts);
  gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
                           GL_FLOAT, GL_FALSE, kClientStride, verts);
  gl_->DrawElements(GL_POINTS, kCount, GL_UNSIGNED_INT, indices);

  EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), gl_->GetError());
}

TEST_F(GLES2ImplementationTest,
       DrawElementsClientSideBuffersServiceSideIndices) {
  static const float verts[][4] = {
    { 12.0f, 23.0f, 34.0f, 45.0f, },
    { 56.0f, 67.0f, 78.0f, 89.0f, },
    { 13.0f, 24.0f, 35.0f, 46.0f, },
  };
  struct Cmds {
    cmds::EnableVertexAttribArray enable1;
    cmds::EnableVertexAttribArray enable2;
    cmds::BindBuffer bind_to_index;
    cmds::GetMaxValueInBufferCHROMIUM get_max;
    cmds::BindBuffer bind_to_emu;
    cmds::BufferData set_size;
    cmds::BufferSubData copy_data1;
    cmd::SetToken set_token1;
    cmds::VertexAttribPointer set_pointer1;
    cmds::BufferSubData copy_data2;
    cmd::SetToken set_token2;
    cmds::VertexAttribPointer set_pointer2;
    cmds::DrawElements draw;
    cmds::BindBuffer restore;
  };
  const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
  const GLuint kClientIndexBufferId = 0x789;
  const GLuint kIndexOffset = 0x40;
  const GLuint kMaxIndex = 2;
  const GLuint kAttribIndex1 = 1;
  const GLuint kAttribIndex2 = 3;
  const GLint kNumComponents1 = 3;
  const GLint kNumComponents2 = 2;
  const GLsizei kClientStride = sizeof(verts[0]);
  const GLsizei kCount = 2;
  const GLsizei kSize1 =
      arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
  const GLsizei kSize2 =
      arraysize(verts) * kNumComponents2 * sizeof(verts[0][0]);
  const GLsizei kEmuOffset1 = 0;
  const GLsizei kEmuOffset2 = kSize1;
  const GLsizei kTotalSize = kSize1 + kSize2;

  ExpectedMemoryInfo mem1 = GetExpectedResultMemory(sizeof(uint32_t));
  ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize1);
  ExpectedMemoryInfo mem3 = GetExpectedMemory(kSize2);


  Cmds expected;
  expected.enable1.Init(kAttribIndex1);
  expected.enable2.Init(kAttribIndex2);
  expected.bind_to_index.Init(GL_ELEMENT_ARRAY_BUFFER, kClientIndexBufferId);
  expected.get_max.Init(kClientIndexBufferId, kCount, GL_UNSIGNED_SHORT,
                        kIndexOffset, mem1.id, mem1.offset);
  expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
  expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
  expected.copy_data1.Init(
      GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem2.id, mem2.offset);
  expected.set_token1.Init(GetNextToken());
  expected.set_pointer1.Init(kAttribIndex1, kNumComponents1,
                             GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
  expected.copy_data2.Init(
      GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem3.id, mem3.offset);
  expected.set_token2.Init(GetNextToken());
  expected.set_pointer2.Init(kAttribIndex2, kNumComponents2,
                             GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
  expected.draw.Init(GL_POINTS, kCount, GL_UNSIGNED_SHORT, kIndexOffset);
  expected.restore.Init(GL_ARRAY_BUFFER, 0);

  EXPECT_CALL(*command_buffer(), OnFlush())
      .WillOnce(SetMemory(mem1.ptr,kMaxIndex))
      .RetiresOnSaturation();

  gl_->EnableVertexAttribArray(kAttribIndex1);
  gl_->EnableVertexAttribArray(kAttribIndex2);
  gl_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, kClientIndexBufferId);
  gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
                           GL_FLOAT, GL_FALSE, kClientStride, verts);
  gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
                           GL_FLOAT, GL_FALSE, kClientStride, verts);
  gl_->DrawElements(GL_POINTS, kCount, GL_UNSIGNED_SHORT,
                    reinterpret_cast<const void*>(kIndexOffset));
  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
}

TEST_F(GLES2ImplementationTest, DrawElementsInstancedANGLEClientSideBuffers) {
  static const float verts[][4] = {
    { 12.0f, 23.0f, 34.0f, 45.0f, },
    { 56.0f, 67.0f, 78.0f, 89.0f, },
    { 13.0f, 24.0f, 35.0f, 46.0f, },
  };
  static const uint16_t indices[] = {
      1, 2,
  };
  struct Cmds {
    cmds::EnableVertexAttribArray enable1;
    cmds::EnableVertexAttribArray enable2;
    cmds::VertexAttribDivisorANGLE divisor;
    cmds::BindBuffer bind_to_index_emu;
    cmds::BufferData set_index_size;
    cmds::BufferSubData copy_data0;
    cmd::SetToken set_token0;
    cmds::BindBuffer bind_to_emu;
    cmds::BufferData set_size;
    cmds::BufferSubData copy_data1;
    cmd::SetToken set_token1;
    cmds::VertexAttribPointer set_pointer1;
    cmds::BufferSubData copy_data2;
    cmd::SetToken set_token2;
    cmds::VertexAttribPointer set_pointer2;
    cmds::DrawElementsInstancedANGLE draw;
    cmds::BindBuffer restore;
    cmds::BindBuffer restore_element;
  };
  const GLsizei kIndexSize = sizeof(indices);
  const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
  const GLuint kEmuIndexBufferId =
      GLES2Implementation::kClientSideElementArrayId;
  const GLuint kAttribIndex1 = 1;
  const GLuint kAttribIndex2 = 3;
  const GLint kNumComponents1 = 3;
  const GLint kNumComponents2 = 2;
  const GLsizei kClientStride = sizeof(verts[0]);
  const GLsizei kCount = 2;
  const GLsizei kSize1 =
      arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
  const GLsizei kSize2 =
      1 * kNumComponents2 * sizeof(verts[0][0]);
  const GLuint kDivisor = 1;
  const GLsizei kEmuOffset1 = 0;
  const GLsizei kEmuOffset2 = kSize1;
  const GLsizei kTotalSize = kSize1 + kSize2;

  ExpectedMemoryInfo mem1 = GetExpectedMemory(kIndexSize);
  ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize1);
  ExpectedMemoryInfo mem3 = GetExpectedMemory(kSize2);

  Cmds expected;
  expected.enable1.Init(kAttribIndex1);
  expected.enable2.Init(kAttribIndex2);
  expected.divisor.Init(kAttribIndex2, kDivisor);
  expected.bind_to_index_emu.Init(GL_ELEMENT_ARRAY_BUFFER, kEmuIndexBufferId);
  expected.set_index_size.Init(
      GL_ELEMENT_ARRAY_BUFFER, kIndexSize, 0, 0, GL_DYNAMIC_DRAW);
  expected.copy_data0.Init(
      GL_ELEMENT_ARRAY_BUFFER, 0, kIndexSize, mem1.id, mem1.offset);
  expected.set_token0.Init(GetNextToken());
  expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
  expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
  expected.copy_data1.Init(
      GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem2.id, mem2.offset);
  expected.set_token1.Init(GetNextToken());
  expected.set_pointer1.Init(
      kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
  expected.copy_data2.Init(
      GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem3.id, mem3.offset);
  expected.set_token2.Init(GetNextToken());
  expected.set_pointer2.Init(kAttribIndex2, kNumComponents2,
                             GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
  expected.draw.Init(GL_POINTS, kCount, GL_UNSIGNED_SHORT, 0, 1);
  expected.restore.Init(GL_ARRAY_BUFFER, 0);
  expected.restore_element.Init(GL_ELEMENT_ARRAY_BUFFER, 0);
  gl_->EnableVertexAttribArray(kAttribIndex1);
  gl_->EnableVertexAttribArray(kAttribIndex2);
  gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
                           GL_FLOAT, GL_FALSE, kClientStride, verts);
  gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
                           GL_FLOAT, GL_FALSE, kClientStride, verts);
  gl_->VertexAttribDivisorANGLE(kAttribIndex2, kDivisor);
  gl_->DrawElementsInstancedANGLE(
      GL_POINTS, kCount, GL_UNSIGNED_SHORT, indices, 1);
  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
}

TEST_F(GLES2ImplementationTest, GetVertexBufferPointerv) {
  static const float verts[1] = { 0.0f, };
  const GLuint kAttribIndex1 = 1;
  const GLuint kAttribIndex2 = 3;
  const GLint kNumComponents1 = 3;
  const GLint kNumComponents2 = 2;
  const GLsizei kStride1 = 12;
  const GLsizei kStride2 = 0;
  const GLuint kBufferId = 0x123;
  const GLint kOffset2 = 0x456;

  // It's all cached on the client side so no get commands are issued.
  struct Cmds {
    cmds::BindBuffer bind;
    cmds::VertexAttribPointer set_pointer;
  };

  Cmds expected;
  expected.bind.Init(GL_ARRAY_BUFFER, kBufferId);
  expected.set_pointer.Init(kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE,
                            kStride2, kOffset2);

  // Set one client side buffer.
  gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
                           GL_FLOAT, GL_FALSE, kStride1, verts);
  // Set one VBO
  gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);
  gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
                           GL_FLOAT, GL_FALSE, kStride2,
                           reinterpret_cast<const void*>(kOffset2));
  // now get them both.
  void* ptr1 = NULL;
  void* ptr2 = NULL;

  gl_->GetVertexAttribPointerv(
      kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_POINTER, &ptr1);
  gl_->GetVertexAttribPointerv(
      kAttribIndex2, GL_VERTEX_ATTRIB_ARRAY_POINTER, &ptr2);

  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
  EXPECT_TRUE(static_cast<const void*>(&verts) == ptr1);
  EXPECT_TRUE(ptr2 == reinterpret_cast<void*>(kOffset2));
}

TEST_F(GLES2ImplementationTest, GetVertexAttrib) {
  static const float verts[1] = { 0.0f, };
  const GLuint kAttribIndex1 = 1;
  const GLuint kAttribIndex2 = 3;
  const GLint kNumComponents1 = 3;
  const GLint kNumComponents2 = 2;
  const GLsizei kStride1 = 12;
  const GLsizei kStride2 = 0;
  const GLuint kBufferId = 0x123;
  const GLint kOffset2 = 0x456;

  // Only one set and one get because the client side buffer's info is stored
  // on the client side.
  struct Cmds {
    cmds::EnableVertexAttribArray enable;
    cmds::BindBuffer bind;
    cmds::VertexAttribPointer set_pointer;
    cmds::GetVertexAttribfv get2;  // for getting the value from attrib1
  };

  ExpectedMemoryInfo mem2 = GetExpectedResultMemory(16);

  Cmds expected;
  expected.enable.Init(kAttribIndex1);
  expected.bind.Init(GL_ARRAY_BUFFER, kBufferId);
  expected.set_pointer.Init(kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE,
                            kStride2, kOffset2);
  expected.get2.Init(kAttribIndex1,
                     GL_CURRENT_VERTEX_ATTRIB,
                     mem2.id, mem2.offset);

  FourFloats current_attrib(1.2f, 3.4f, 5.6f, 7.8f);

  // One call to flush to wait for last call to GetVertexAttribiv
  // as others are all cached.
  EXPECT_CALL(*command_buffer(), OnFlush())
      .WillOnce(SetMemory(
          mem2.ptr, SizedResultHelper<FourFloats>(current_attrib)))
      .RetiresOnSaturation();

  gl_->EnableVertexAttribArray(kAttribIndex1);
  // Set one client side buffer.
  gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
                           GL_FLOAT, GL_FALSE, kStride1, verts);
  // Set one VBO
  gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);
  gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
                           GL_FLOAT, GL_FALSE, kStride2,
                           reinterpret_cast<const void*>(kOffset2));
  // first get the service side once to see that we make a command
  GLint buffer_id = 0;
  GLint enabled = 0;
  GLint size = 0;
  GLint stride = 0;
  GLint type = 0;
  GLint normalized = 1;
  float current[4] = { 0.0f, };

  gl_->GetVertexAttribiv(
      kAttribIndex2, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &buffer_id);
  EXPECT_EQ(kBufferId, static_cast<GLuint>(buffer_id));
  gl_->GetVertexAttribiv(
      kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &buffer_id);
  gl_->GetVertexAttribiv(
      kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &enabled);
  gl_->GetVertexAttribiv(
      kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_SIZE, &size);
  gl_->GetVertexAttribiv(
      kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &stride);
  gl_->GetVertexAttribiv(
      kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_TYPE, &type);
  gl_->GetVertexAttribiv(
      kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &normalized);
  gl_->GetVertexAttribfv(
      kAttribIndex1, GL_CURRENT_VERTEX_ATTRIB, &current[0]);

  EXPECT_EQ(0, buffer_id);
  EXPECT_EQ(GL_TRUE, enabled);
  EXPECT_EQ(kNumComponents1, size);
  EXPECT_EQ(kStride1, stride);
  EXPECT_EQ(GL_FLOAT, type);
  EXPECT_EQ(GL_FALSE, normalized);
  EXPECT_EQ(0, memcmp(&current_attrib, &current, sizeof(current_attrib)));

  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
}

TEST_F(GLES2ImplementationTest, ReservedIds) {
  // Only the get error command should be issued.
  struct Cmds {
    cmds::GetError get;
  };
  Cmds expected;

  ExpectedMemoryInfo mem1 = GetExpectedResultMemory(
      sizeof(cmds::GetError::Result));

  expected.get.Init(mem1.id, mem1.offset);

  // One call to flush to wait for GetError
  EXPECT_CALL(*command_buffer(), OnFlush())
      .WillOnce(SetMemory(mem1.ptr, GLuint(GL_NO_ERROR)))
      .RetiresOnSaturation();

  gl_->BindBuffer(
      GL_ARRAY_BUFFER,
      GLES2Implementation::kClientSideArrayId);
  gl_->BindBuffer(
      GL_ARRAY_BUFFER,
      GLES2Implementation::kClientSideElementArrayId);
  GLenum err = gl_->GetError();
  EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), err);
  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
}

#endif  // defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)

TEST_F(GLES2ImplementationTest, ReadPixels2Reads) {
  struct Cmds {
    cmds::ReadPixels read1;
    cmd::SetToken set_token1;
    cmds::ReadPixels read2;
    cmd::SetToken set_token2;
  };
  const GLint kBytesPerPixel = 4;
  const GLint kWidth =
      (kTransferBufferSize - GLES2Implementation::kStartingOffset) /
      kBytesPerPixel;
  const GLint kHeight = 2;
  const GLenum kFormat = GL_RGBA;
  const GLenum kType = GL_UNSIGNED_BYTE;

  ExpectedMemoryInfo mem1 =
      GetExpectedMemory(kWidth * kHeight / 2 * kBytesPerPixel);
  ExpectedMemoryInfo result1 =
      GetExpectedResultMemory(sizeof(cmds::ReadPixels::Result));
  ExpectedMemoryInfo mem2 =
      GetExpectedMemory(kWidth * kHeight / 2 * kBytesPerPixel);
  ExpectedMemoryInfo result2 =
      GetExpectedResultMemory(sizeof(cmds::ReadPixels::Result));

  Cmds expected;
  expected.read1.Init(
      0, 0, kWidth, kHeight / 2, kFormat, kType,
      mem1.id, mem1.offset, result1.id, result1.offset,
      false);
  expected.set_token1.Init(GetNextToken());
  expected.read2.Init(
      0, kHeight / 2, kWidth, kHeight / 2, kFormat, kType,
      mem2.id, mem2.offset, result2.id, result2.offset, false);
  expected.set_token2.Init(GetNextToken());
  std::unique_ptr<int8_t[]> buffer(
      new int8_t[kWidth * kHeight * kBytesPerPixel]);

  EXPECT_CALL(*command_buffer(), OnFlush())
      .WillOnce(SetMemory(result1.ptr, static_cast<uint32_t>(1)))
      .WillOnce(SetMemory(result2.ptr, static_cast<uint32_t>(1)))
      .RetiresOnSaturation();

  gl_->ReadPixels(0, 0, kWidth, kHeight, kFormat, kType, buffer.get());
  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
}

TEST_F(GLES2ImplementationTest, ReadPixelsBadFormatType) {
  struct Cmds {
    cmds::ReadPixels read;
    cmd::SetToken set_token;
  };
  const GLint kBytesPerPixel = 4;
  const GLint kWidth = 2;
  const GLint kHeight = 2;
  const GLenum kFormat = 0;
  const GLenum kType = 0;

  ExpectedMemoryInfo mem1 =
      GetExpectedMemory(kWidth * kHeight * kBytesPerPixel);
  ExpectedMemoryInfo result1 =
      GetExpectedResultMemory(sizeof(cmds::ReadPixels::Result));

  Cmds expected;
  expected.read.Init(
      0, 0, kWidth, kHeight, kFormat, kType,
      mem1.id, mem1.offset, result1.id, result1.offset, false);
  expected.set_token.Init(GetNextToken());
  std::unique_ptr<int8_t[]> buffer(
      new int8_t[kWidth * kHeight * kBytesPerPixel]);

  EXPECT_CALL(*command_buffer(), OnFlush())
      .Times(1)
      .RetiresOnSaturation();

  gl_->ReadPixels(0, 0, kWidth, kHeight, kFormat, kType, buffer.get());
}

TEST_F(GLES2ImplementationTest, FreeUnusedSharedMemory) {
  struct Cmds {
    cmds::BufferSubData buf;
    cmd::SetToken set_token;
  };
  const GLenum kTarget = GL_ELEMENT_ARRAY_BUFFER;
  const GLintptr kOffset = 15;
  const GLsizeiptr kSize = 16;

  ExpectedMemoryInfo mem1 = GetExpectedMemory(kSize);

  Cmds expected;
  expected.buf.Init(
    kTarget, kOffset, kSize, mem1.id, mem1.offset);
  expected.set_token.Init(GetNextToken());

  void* mem = gl_->MapBufferSubDataCHROMIUM(
      kTarget, kOffset, kSize, GL_WRITE_ONLY);
  ASSERT_TRUE(mem != NULL);
  gl_->UnmapBufferSubDataCHROMIUM(mem);
  EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
      .Times(1)
      .RetiresOnSaturation();
  gl_->FreeUnusedSharedMemory();
}

TEST_F(GLES2ImplementationTest, MapUnmapBufferSubDataCHROMIUM) {
  struct Cmds {
    cmds::BufferSubData buf;
    cmd::SetToken set_token;
  };
  const GLenum kTarget = GL_ELEMENT_ARRAY_BUFFER;
  const GLintptr kOffset = 15;
  const GLsizeiptr kSize = 16;

  uint32_t offset = 0;
  Cmds expected;
  expected.buf.Init(
      kTarget, kOffset, kSize,
      command_buffer()->GetNextFreeTransferBufferId(), offset);
  expected.set_token.Init(GetNextToken());

  void* mem = gl_->MapBufferSubDataCHROMIUM(
      kTarget, kOffset, kSize, GL_WRITE_ONLY);
  ASSERT_TRUE(mem != NULL);
  gl_->UnmapBufferSubDataCHROMIUM(mem);
  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
}

TEST_F(GLES2ImplementationTest, MapUnmapBufferSubDataCHROMIUMBadArgs) {
  const GLenum kTarget = GL_ELEMENT_ARRAY_BUFFER;
  const GLintptr kOffset = 15;
  const GLsizeiptr kSize = 16;

  ExpectedMemoryInfo result1 =
      GetExpectedResultMemory(sizeof(cmds::GetError::Result));
  ExpectedMemoryInfo result2 =
      GetExpectedResultMemory(sizeof(cmds::GetError::Result));
  ExpectedMemoryInfo result3 =
      GetExpectedResultMemory(sizeof(cmds::GetError::Result));
  ExpectedMemoryInfo result4 =
      GetExpectedResultMemory(sizeof(cmds::GetError::Result));

  // Calls to flush to wait for GetError
  EXPECT_CALL(*command_buffer(), OnFlush())
      .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
      .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
      .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR)))
      .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR)))
      .RetiresOnSaturation();

  void* mem;
  mem = gl_->MapBufferSubDataCHROMIUM(kTarget, -1, kSize, GL_WRITE_ONLY);
  ASSERT_TRUE(mem == NULL);
  EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
  mem = gl_->MapBufferSubDataCHROMIUM(kTarget, kOffset, -1, GL_WRITE_ONLY);
  ASSERT_TRUE(mem == NULL);
  EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
  mem = gl_->MapBufferSubDataCHROMIUM(kTarget, kOffset, kSize, GL_READ_ONLY);
  ASSERT_TRUE(mem == NULL);
  EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), gl_->GetError());
  const char* kPtr = "something";
  gl_->UnmapBufferSubDataCHROMIUM(kPtr);
  EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
}

TEST_F(GLES2ImplementationTest, MapUnmapTexSubImage2DCHROMIUM) {
  struct Cmds {
    cmds::TexSubImage2D tex;
    cmd::SetToken set_token;
  };
  const GLint kLevel = 1;
  const GLint kXOffset = 2;
  const GLint kYOffset = 3;
  const GLint kWidth = 4;
  const GLint kHeight = 5;
  const GLenum kFormat = GL_RGBA;
  const GLenum kType = GL_UNSIGNED_BYTE;

  uint32_t offset = 0;
  Cmds expected;
  expected.tex.Init(
      GL_TEXTURE_2D, kLevel, kXOffset, kYOffset, kWidth, kHeight, kFormat,
      kType,
      command_buffer()->GetNextFreeTransferBufferId(), offset, GL_FALSE);
  expected.set_token.Init(GetNextToken());

  void* mem = gl_->MapTexSubImage2DCHROMIUM(
      GL_TEXTURE_2D,
      kLevel,
      kXOffset,
      kYOffset,
      kWidth,
      kHeight,
      kFormat,
      kType,
      GL_WRITE_ONLY);
  ASSERT_TRUE(mem != NULL);
  gl_->UnmapTexSubImage2DCHROMIUM(mem);
  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
}

TEST_F(GLES2ImplementationTest, MapUnmapTexSubImage2DCHROMIUMBadArgs) {
  const GLint kLevel = 1;
  const GLint kXOffset = 2;
  const GLint kYOffset = 3;
  const GLint kWidth = 4;
  const GLint kHeight = 5;
  const GLenum kFormat = GL_RGBA;
  const GLenum kType = GL_UNSIGNED_BYTE;

  ExpectedMemoryInfo result1 =
      GetExpectedResultMemory(sizeof(cmds::GetError::Result));
  ExpectedMemoryInfo result2 =
      GetExpectedResultMemory(sizeof(cmds::GetError::Result));
  ExpectedMemoryInfo result3 =
      GetExpectedResultMemory(sizeof(cmds::GetError::Result));
  ExpectedMemoryInfo result4 =
      GetExpectedResultMemory(sizeof(cmds::GetError::Result));
  ExpectedMemoryInfo result5 =
      GetExpectedResultMemory(sizeof(cmds::GetError::Result));
  ExpectedMemoryInfo result6 =
      GetExpectedResultMemory(sizeof(cmds::GetError::Result));
  ExpectedMemoryInfo result7 =
      GetExpectedResultMemory(sizeof(cmds::GetError::Result));

  // Calls to flush to wait for GetError
  EXPECT_CALL(*command_buffer(), OnFlush())
      .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
      .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
      .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR)))
      .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR)))
      .WillOnce(SetMemory(result5.ptr, GLuint(GL_NO_ERROR)))
      .WillOnce(SetMemory(result6.ptr, GLuint(GL_NO_ERROR)))
      .WillOnce(SetMemory(result7.ptr, GLuint(GL_NO_ERROR)))
      .RetiresOnSaturation();

  void* mem;
  mem = gl_->MapTexSubImage2DCHROMIUM(
    GL_TEXTURE_2D,
    -1,
    kXOffset,
    kYOffset,
    kWidth,
    kHeight,
    kFormat,
    kType,
    GL_WRITE_ONLY);
  EXPECT_TRUE(mem == NULL);
  EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
  mem = gl_->MapTexSubImage2DCHROMIUM(
    GL_TEXTURE_2D,
    kLevel,
    -1,
    kYOffset,
    kWidth,
    kHeight,
    kFormat,
    kType,
    GL_WRITE_ONLY);
  EXPECT_TRUE(mem == NULL);
  EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
  mem = gl_->MapTexSubImage2DCHROMIUM(
    GL_TEXTURE_2D,
    kLevel,
    kXOffset,
    -1,
    kWidth,
    kHeight,
    kFormat,
    kType,
    GL_WRITE_ONLY);
  EXPECT_TRUE(mem == NULL);
  EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
  mem = gl_->MapTexSubImage2DCHROMIUM(
    GL_TEXTURE_2D,
    kLevel,
    kXOffset,
    kYOffset,
    -1,
    kHeight,
    kFormat,
    kType,
    GL_WRITE_ONLY);
  EXPECT_TRUE(mem == NULL);
  EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
  mem = gl_->MapTexSubImage2DCHROMIUM(
    GL_TEXTURE_2D,
    kLevel,
    kXOffset,
    kYOffset,
    kWidth,
    -1,
    kFormat,
    kType,
    GL_WRITE_ONLY);
  EXPECT_TRUE(mem == NULL);
  EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
  mem = gl_->MapTexSubImage2DCHROMIUM(
    GL_TEXTURE_2D,
    kLevel,
    kXOffset,
    kYOffset,
    kWidth,
    kHeight,
    kFormat,
    kType,
    GL_READ_ONLY);
  EXPECT_TRUE(mem == NULL);
  EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), gl_->GetError());
  const char* kPtr = "something";
  gl_->UnmapTexSubImage2DCHROMIUM(kPtr);
  EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
}

TEST_F(GLES2ImplementationTest, GetProgramInfoCHROMIUMGoodArgs) {
  const uint32_t kBucketId = GLES2Implementation::kResultBucketId;
  const GLuint kProgramId = 123;
  const char kBad = 0x12;
  GLsizei size = 0;
  const Str7 kString = {"foobar"};
  char buf[20];

  ExpectedMemoryInfo mem1 =
      GetExpectedMemory(MaxTransferBufferSize());
  ExpectedMemoryInfo result1 =
      GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result));
  ExpectedMemoryInfo result2 =
      GetExpectedResultMemory(sizeof(cmds::GetError::Result));

  memset(buf, kBad, sizeof(buf));
  EXPECT_CALL(*command_buffer(), OnFlush())
      .WillOnce(DoAll(SetMemory(result1.ptr, uint32_t(sizeof(kString))),
                      SetMemory(mem1.ptr, kString)))
      .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
      .RetiresOnSaturation();

  struct Cmds {
    cmd::SetBucketSize set_bucket_size1;
    cmds::GetProgramInfoCHROMIUM get_program_info;
    cmd::GetBucketStart get_bucket_start;
    cmd::SetToken set_token1;
    cmd::SetBucketSize set_bucket_size2;
  };
  Cmds expected;
  expected.set_bucket_size1.Init(kBucketId, 0);
  expected.get_program_info.Init(kProgramId, kBucketId);
  expected.get_bucket_start.Init(
      kBucketId, result1.id, result1.offset,
      MaxTransferBufferSize(), mem1.id, mem1.offset);
  expected.set_token1.Init(GetNextToken());
  expected.set_bucket_size2.Init(kBucketId, 0);
  gl_->GetProgramInfoCHROMIUM(kProgramId, sizeof(buf), &size, &buf);
  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
  EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError());
  EXPECT_EQ(sizeof(kString), static_cast<size_t>(size));
  EXPECT_STREQ(kString.str, buf);
  EXPECT_EQ(buf[sizeof(kString)], kBad);
}

TEST_F(GLES2ImplementationTest, GetProgramInfoCHROMIUMBadArgs) {
  const uint32_t kBucketId = GLES2Implementation::kResultBucketId;
  const GLuint kProgramId = 123;
  GLsizei size = 0;
  const Str7 kString = {"foobar"};
  char buf[20];

  ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
  ExpectedMemoryInfo result1 =
      GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result));
  ExpectedMemoryInfo result2 =
      GetExpectedResultMemory(sizeof(cmds::GetError::Result));
  ExpectedMemoryInfo result3 =
      GetExpectedResultMemory(sizeof(cmds::GetError::Result));
  ExpectedMemoryInfo result4 =
      GetExpectedResultMemory(sizeof(cmds::GetError::Result));

  EXPECT_CALL(*command_buffer(), OnFlush())
      .WillOnce(DoAll(SetMemory(result1.ptr, uint32_t(sizeof(kString))),
                      SetMemory(mem1.ptr, kString)))
      .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
      .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR)))
      .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR)))
      .RetiresOnSaturation();

  // try bufsize not big enough.
  struct Cmds {
    cmd::SetBucketSize set_bucket_size1;
    cmds::GetProgramInfoCHROMIUM get_program_info;
    cmd::GetBucketStart get_bucket_start;
    cmd::SetToken set_token1;
    cmd::SetBucketSize set_bucket_size2;
  };
  Cmds expected;
  expected.set_bucket_size1.Init(kBucketId, 0);
  expected.get_program_info.Init(kProgramId, kBucketId);
  expected.get_bucket_start.Init(
      kBucketId, result1.id, result1.offset,
      MaxTransferBufferSize(), mem1.id, mem1.offset);
  expected.set_token1.Init(GetNextToken());
  expected.set_bucket_size2.Init(kBucketId, 0);
  gl_->GetProgramInfoCHROMIUM(kProgramId, 6, &size, &buf);
  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
  EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), gl_->GetError());
  ClearCommands();

  // try bad bufsize
  gl_->GetProgramInfoCHROMIUM(kProgramId, -1, &size, &buf);
  EXPECT_TRUE(NoCommandsWritten());
  EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
  ClearCommands();
  // try no size ptr.
  gl_->GetProgramInfoCHROMIUM(kProgramId, sizeof(buf), NULL, &buf);
  EXPECT_TRUE(NoCommandsWritten());
  EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
}

TEST_F(GLES2ImplementationTest, GetUniformBlocksCHROMIUMGoodArgs) {
  const uint32_t kBucketId = GLES2Implementation::kResultBucketId;
  const GLuint kProgramId = 123;
  const char kBad = 0x12;
  GLsizei size = 0;
  const Str7 kString = {"foobar"};
  char buf[20];

  ExpectedMemoryInfo mem1 =
      GetExpectedMemory(MaxTransferBufferSize());
  ExpectedMemoryInfo result1 =
      GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result));
  ExpectedMemoryInfo result2 =
      GetExpectedResultMemory(sizeof(cmds::GetError::Result));

  memset(buf, kBad, sizeof(buf));
  EXPECT_CALL(*command_buffer(), OnFlush())
      .WillOnce(DoAll(SetMemory(result1.ptr, uint32_t(sizeof(kString))),
                      SetMemory(mem1.ptr, kString)))
      .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
      .RetiresOnSaturation();

  struct Cmds {
    cmd::SetBucketSize set_bucket_size1;
    cmds::GetUniformBlocksCHROMIUM get_uniform_blocks;
    cmd::GetBucketStart get_bucket_start;
    cmd::SetToken set_token1;
    cmd::SetBucketSize set_bucket_size2;
  };
  Cmds expected;
  expected.set_bucket_size1.Init(kBucketId, 0);
  expected.get_uniform_blocks.Init(kProgramId, kBucketId);
  expected.get_bucket_start.Init(
      kBucketId, result1.id, result1.offset,
      MaxTransferBufferSize(), mem1.id, mem1.offset);
  expected.set_token1.Init(GetNextToken());
  expected.set_bucket_size2.Init(kBucketId, 0);
  gl_->GetUniformBlocksCHROMIUM(kProgramId, sizeof(buf), &size, &buf);
  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
  EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError());
  EXPECT_EQ(sizeof(kString), static_cast<size_t>(size));
  EXPECT_STREQ(kString.str, buf);
  EXPECT_EQ(buf[sizeof(kString)], kBad);
}

TEST_F(GLES2ImplementationTest, GetUniformBlocksCHROMIUMBadArgs) {
  const uint32_t kBucketId = GLES2Implementation::kResultBucketId;
  const GLuint kProgramId = 123;
  GLsizei size = 0;
  const Str7 kString = {"foobar"};
  char buf[20];

  ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
  ExpectedMemoryInfo result1 =
      GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result));
  ExpectedMemoryInfo result2 =
      GetExpectedResultMemory(sizeof(cmds::GetError::Result));
  ExpectedMemoryInfo result3 =
      GetExpectedResultMemory(sizeof(cmds::GetError::Result));
  ExpectedMemoryInfo result4 =
      GetExpectedResultMemory(sizeof(cmds::GetError::Result));

  EXPECT_CALL(*command_buffer(), OnFlush())
      .WillOnce(DoAll(SetMemory(result1.ptr, uint32_t(sizeof(kString))),
                      SetMemory(mem1.ptr, kString)))
      .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
      .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR)))
      .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR)))
      .RetiresOnSaturation();

  // try bufsize not big enough.
  struct Cmds {
    cmd::SetBucketSize set_bucket_size1;
    cmds::GetUniformBlocksCHROMIUM get_uniform_blocks;
    cmd::GetBucketStart get_bucket_start;
    cmd::SetToken set_token1;
    cmd::SetBucketSize set_bucket_size2;
  };
  Cmds expected;
  expected.set_bucket_size1.Init(kBucketId, 0);
  expected.get_uniform_blocks.Init(kProgramId, kBucketId);
  expected.get_bucket_start.Init(
      kBucketId, result1.id, result1.offset,
      MaxTransferBufferSize(), mem1.id, mem1.offset);
  expected.set_token1.Init(GetNextToken());
  expected.set_bucket_size2.Init(kBucketId, 0);
  gl_->GetUniformBlocksCHROMIUM(kProgramId, 6, &size, &buf);
  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
  EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), gl_->GetError());
  ClearCommands();

  // try bad bufsize
  gl_->GetUniformBlocksCHROMIUM(kProgramId, -1, &size, &buf);
  EXPECT_TRUE(NoCommandsWritten());
  EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
  ClearCommands();
  // try no size ptr.
  gl_->GetUniformBlocksCHROMIUM(kProgramId, sizeof(buf), NULL, &buf);
  EXPECT_TRUE(NoCommandsWritten());
  EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
}

// Test that things are cached
TEST_F(GLES2ImplementationTest, GetIntegerCacheRead) {
  struct PNameValue {
    GLenum pname;
    GLint expected;
  };
  const PNameValue pairs[] = {
      {GL_ACTIVE_TEXTURE, GL_TEXTURE0, },
      {GL_TEXTURE_BINDING_2D, 0, },
      {GL_TEXTURE_BINDING_CUBE_MAP, 0, },
      {GL_TEXTURE_BINDING_EXTERNAL_OES, 0, },
      {GL_FRAMEBUFFER_BINDING, 0, },
      {GL_RENDERBUFFER_BINDING, 0, },
      {GL_ARRAY_BUFFER_BINDING, 0, },
      {GL_ELEMENT_ARRAY_BUFFER_BINDING, 0, },
      {GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, kMaxCombinedTextureImageUnits, },
      {GL_MAX_CUBE_MAP_TEXTURE_SIZE, kMaxCubeMapTextureSize, },
      {GL_MAX_FRAGMENT_UNIFORM_VECTORS, kMaxFragmentUniformVectors, },
      {GL_MAX_RENDERBUFFER_SIZE, kMaxRenderbufferSize, },
      {GL_MAX_TEXTURE_IMAGE_UNITS, kMaxTextureImageUnits, },
      {GL_MAX_TEXTURE_SIZE, kMaxTextureSize, },
      {GL_MAX_VARYING_VECTORS, kMaxVaryingVectors, },
      {GL_MAX_VERTEX_ATTRIBS, kMaxVertexAttribs, },
      {GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, kMaxVertexTextureImageUnits, },
      {GL_MAX_VERTEX_UNIFORM_VECTORS, kMaxVertexUniformVectors, },
      {GL_NUM_COMPRESSED_TEXTURE_FORMATS, kNumCompressedTextureFormats, },
      {GL_NUM_SHADER_BINARY_FORMATS, kNumShaderBinaryFormats, }, };
  size_t num_pairs = sizeof(pairs) / sizeof(pairs[0]);
  for (size_t ii = 0; ii < num_pairs; ++ii) {
    const PNameValue& pv = pairs[ii];
    GLint v = -1;
    gl_->GetIntegerv(pv.pname, &v);
    EXPECT_TRUE(NoCommandsWritten());
    EXPECT_EQ(pv.expected, v);
  }

  ExpectedMemoryInfo result1 =
      GetExpectedResultMemory(sizeof(cmds::GetError::Result));

  EXPECT_CALL(*command_buffer(), OnFlush())
      .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
      .RetiresOnSaturation();
  EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError());
}

TEST_F(GLES2ImplementationTest, GetIntegerDisjointValue) {
  ExpectedMemoryInfo mem = GetExpectedMappedMemory(sizeof(DisjointValueSync));
  gl_->SetDisjointValueSyncCHROMIUM();
  ASSERT_EQ(mem.id, GetQueryTracker()->DisjointCountSyncShmID());
  ASSERT_EQ(mem.offset, GetQueryTracker()->DisjointCountSyncShmOffset());
  DisjointValueSync* disjoint_sync =
      reinterpret_cast<DisjointValueSync*>(mem.ptr);

  ClearCommands();
  GLint disjoint_value = -1;
  gl_->GetIntegerv(GL_GPU_DISJOINT_EXT, &disjoint_value);
  EXPECT_TRUE(NoCommandsWritten());
  EXPECT_EQ(0, disjoint_value);

  // After setting disjoint, it should be true.
  disjoint_value = -1;
  disjoint_sync->SetDisjointCount(1);
  gl_->GetIntegerv(GL_GPU_DISJOINT_EXT, &disjoint_value);
  EXPECT_TRUE(NoCommandsWritten());
  EXPECT_EQ(1, disjoint_value);

  // After checking disjoint, it should be false again.
  disjoint_value = -1;
  gl_->GetIntegerv(GL_GPU_DISJOINT_EXT, &disjoint_value);
  EXPECT_TRUE(NoCommandsWritten());
  EXPECT_EQ(0, disjoint_value);

  // Check for errors.
  ExpectedMemoryInfo result1 =
      GetExpectedResultMemory(sizeof(cmds::GetError::Result));
  EXPECT_CALL(*command_buffer(), OnFlush())
      .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
      .RetiresOnSaturation();
  EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError());
}

TEST_F(GLES2ImplementationTest, GetIntegerCacheWrite) {
  struct PNameValue {
    GLenum pname;
    GLint expected;
  };
  gl_->ActiveTexture(GL_TEXTURE4);
  gl_->BindBuffer(GL_ARRAY_BUFFER, 2);
  gl_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 3);
  gl_->BindFramebuffer(GL_FRAMEBUFFER, 4);
  gl_->BindRenderbuffer(GL_RENDERBUFFER, 5);
  gl_->BindTexture(GL_TEXTURE_2D, 6);
  gl_->BindTexture(GL_TEXTURE_CUBE_MAP, 7);
  gl_->BindTexture(GL_TEXTURE_EXTERNAL_OES, 8);

  const PNameValue pairs[] = {{GL_ACTIVE_TEXTURE, GL_TEXTURE4, },
                              {GL_ARRAY_BUFFER_BINDING, 2, },
                              {GL_ELEMENT_ARRAY_BUFFER_BINDING, 3, },
                              {GL_FRAMEBUFFER_BINDING, 4, },
                              {GL_RENDERBUFFER_BINDING, 5, },
                              {GL_TEXTURE_BINDING_2D, 6, },
                              {GL_TEXTURE_BINDING_CUBE_MAP, 7, },
                              {GL_TEXTURE_BINDING_EXTERNAL_OES, 8, }, };
  size_t num_pairs = sizeof(pairs) / sizeof(pairs[0]);
  for (size_t ii = 0; ii < num_pairs; ++ii) {
    const PNameValue& pv = pairs[ii];
    GLint v = -1;
    gl_->GetIntegerv(pv.pname, &v);
    EXPECT_EQ(pv.expected, v);
  }

  ExpectedMemoryInfo result1 =
      GetExpectedResultMemory(sizeof(cmds::GetError::Result));

  EXPECT_CALL(*command_buffer(), OnFlush())
      .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
      .RetiresOnSaturation();
  EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError());
}

static bool CheckRect(int width,
                      int height,
                      GLenum format,
                      GLenum type,
                      int alignment,
                      const uint8_t* r1,
                      const uint8_t* r2) {
  uint32_t size = 0;
  uint32_t unpadded_row_size = 0;
  uint32_t padded_row_size = 0;
  if (!GLES2Util::ComputeImageDataSizes(
      width, height, 1, format, type, alignment, &size, &unpadded_row_size,
      &padded_row_size)) {
    return false;
  }

  int r2_stride = static_cast<int>(padded_row_size);

  for (int y = 0; y < height; ++y) {
    if (memcmp(r1, r2, unpadded_row_size) != 0) {
      return false;
    }
    r1 += padded_row_size;
    r2 += r2_stride;
  }
  return true;
}

ACTION_P7(CheckRectAction, width, height, format, type, alignment, r1, r2) {
  EXPECT_TRUE(CheckRect(
      width, height, format, type, alignment, r1, r2));
}

TEST_F(GLES2ImplementationTest, TexImage2D) {
  struct Cmds {
    cmds::TexImage2D tex_image_2d;
    cmd::SetToken set_token;
  };
  struct Cmds2 {
    cmds::TexImage2D tex_image_2d;
    cmd::SetToken set_token;
  };
  const GLenum kTarget = GL_TEXTURE_2D;
  const GLint kLevel = 0;
  const GLenum kFormat = GL_RGB;
  const GLsizei kWidth = 3;
  const GLsizei kHeight = 4;
  const GLint kBorder = 0;
  const GLenum kType = GL_UNSIGNED_BYTE;
  const GLint kPixelStoreUnpackAlignment = 4;
  static uint8_t pixels[] = {
      11, 12, 13, 13,  14,  15,  15,  16,  17,  101, 102, 103, 21, 22, 23,
      23, 24, 25, 25,  26,  27,  201, 202, 203, 31,  32,  33,  33, 34, 35,
      35, 36, 37, 123, 124, 125, 41,  42,  43,  43,  44,  45,  45, 46, 47,
  };

  ExpectedMemoryInfo mem1 = GetExpectedMemory(sizeof(pixels));

  Cmds expected;
  expected.tex_image_2d.Init(
      kTarget, kLevel, kFormat, kWidth, kHeight, kFormat, kType,
      mem1.id, mem1.offset);
  expected.set_token.Init(GetNextToken());
  gl_->TexImage2D(
      kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
      pixels);
  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
  EXPECT_TRUE(CheckRect(
      kWidth, kHeight, kFormat, kType, kPixelStoreUnpackAlignment,
      pixels, mem1.ptr));
}

TEST_F(GLES2ImplementationTest, TexImage2DViaMappedMem) {
  if (!AllowExtraTransferBufferSize()) {
    LOG(WARNING) << "Low memory device do not support MappedMem. Skipping test";
    return;
  }

  struct Cmds {
    cmds::TexImage2D tex_image_2d;
    cmd::SetToken set_token;
  };
  const GLenum kTarget = GL_TEXTURE_2D;
  const GLint kLevel = 0;
  const GLenum kFormat = GL_RGB;
  const GLsizei kWidth = 3;
  const GLint kBorder = 0;
  const GLenum kType = GL_UNSIGNED_BYTE;
  const GLint kPixelStoreUnpackAlignment = 4;

  uint32_t size = 0;
  uint32_t unpadded_row_size = 0;
  uint32_t padded_row_size = 0;
  ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
      kWidth, 2, 1, kFormat, kType, kPixelStoreUnpackAlignment,
      &size, &unpadded_row_size, &padded_row_size));
  const GLsizei kMaxHeight = (MaxTransferBufferSize() / padded_row_size) * 2;
  const GLsizei kHeight = kMaxHeight * 2;
  ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
      kWidth, kHeight, 1, kFormat, kType, kPixelStoreUnpackAlignment,
      &size, &unpadded_row_size, &padded_row_size));

  std::unique_ptr<uint8_t[]> pixels(new uint8_t[size]);
  for (uint32_t ii = 0; ii < size; ++ii) {
    pixels[ii] = static_cast<uint8_t>(ii);
  }

  ExpectedMemoryInfo mem1 = GetExpectedMappedMemory(size);

  Cmds expected;
  expected.tex_image_2d.Init(
      kTarget, kLevel, kFormat, kWidth, kHeight, kFormat, kType,
      mem1.id, mem1.offset);
  expected.set_token.Init(GetNextToken());
  gl_->TexImage2D(
      kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
      pixels.get());
  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
  EXPECT_TRUE(CheckRect(
      kWidth, kHeight, kFormat, kType, kPixelStoreUnpackAlignment,
      pixels.get(), mem1.ptr));
}

// Test TexImage2D with 2 writes
TEST_F(GLES2ImplementationTest, TexImage2DViaTexSubImage2D) {
  // Set limit to 1 to effectively disable mapped memory.
  SetMappedMemoryLimit(1);

  struct Cmds {
    cmds::TexImage2D tex_image_2d;
    cmds::TexSubImage2D tex_sub_image_2d1;
    cmd::SetToken set_token1;
    cmds::TexSubImage2D tex_sub_image_2d2;
    cmd::SetToken set_token2;
  };
  const GLenum kTarget = GL_TEXTURE_2D;
  const GLint kLevel = 0;
  const GLenum kFormat = GL_RGB;
  const GLint kBorder = 0;
  const GLenum kType = GL_UNSIGNED_BYTE;
  const GLint kPixelStoreUnpackAlignment = 4;
  const GLsizei kWidth = 3;

  uint32_t size = 0;
  uint32_t unpadded_row_size = 0;
  uint32_t padded_row_size = 0;
  ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
      kWidth, 2, 1, kFormat, kType, kPixelStoreUnpackAlignment,
      &size, &unpadded_row_size, &padded_row_size));
  const GLsizei kHeight = (MaxTransferBufferSize() / padded_row_size) * 2;
  ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
      kWidth, kHeight, 1, kFormat, kType, kPixelStoreUnpackAlignment,
      &size, NULL, NULL));
  uint32_t half_size = 0;
  ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
      kWidth, kHeight / 2, 1, kFormat, kType, kPixelStoreUnpackAlignment,
      &half_size, NULL, NULL));

  std::unique_ptr<uint8_t[]> pixels(new uint8_t[size]);
  for (uint32_t ii = 0; ii < size; ++ii) {
    pixels[ii] = static_cast<uint8_t>(ii);
  }

  ExpectedMemoryInfo mem1 = GetExpectedMemory(half_size);
  ExpectedMemoryInfo mem2 = GetExpectedMemory(half_size);

  Cmds expected;
  expected.tex_image_2d.Init(
      kTarget, kLevel, kFormat, kWidth, kHeight, kFormat, kType,
      0, 0);
  expected.tex_sub_image_2d1.Init(
      kTarget, kLevel, 0, 0, kWidth, kHeight / 2, kFormat, kType,
      mem1.id, mem1.offset, true);
  expected.set_token1.Init(GetNextToken());
  expected.tex_sub_image_2d2.Init(
      kTarget, kLevel, 0, kHeight / 2, kWidth, kHeight / 2, kFormat, kType,
      mem2.id, mem2.offset, true);
  expected.set_token2.Init(GetNextToken());

  // TODO(gman): Make it possible to run this test
  // EXPECT_CALL(*command_buffer(), OnFlush())
  //     .WillOnce(CheckRectAction(
  //         kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment,
  //         false, pixels.get(),
  //         GetExpectedTransferAddressFromOffsetAs<uint8_t>(offset1,
  //         half_size)))
  //     .RetiresOnSaturation();

  gl_->TexImage2D(
      kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
      pixels.get());
  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
  EXPECT_TRUE(CheckRect(
      kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment,
      pixels.get() + kHeight / 2 * padded_row_size, mem2.ptr));
}

TEST_F(GLES2ImplementationTest, SubImage2DUnpack) {
  static const GLint unpack_alignments[] = { 1, 2, 4, 8 };

  static const GLenum kFormat = GL_RGB;
  static const GLenum kType = GL_UNSIGNED_BYTE;
  static const GLint kLevel = 0;
  static const GLint kBorder = 0;
  // We're testing using the unpack params to pull a subimage out of a larger
  // source of pixels. Here we specify the subimage by its border rows /
  // columns.
  static const GLint kSrcWidth = 33;
  static const GLint kSrcSubImageX0 = 11;
  static const GLint kSrcSubImageX1 = 20;
  static const GLint kSrcSubImageY0 = 18;
  static const GLint kSrcSubImageY1 = 23;
  static const GLint kSrcSubImageWidth = kSrcSubImageX1 - kSrcSubImageX0;
  static const GLint kSrcSubImageHeight = kSrcSubImageY1 - kSrcSubImageY0;

  // these are only used in the texsubimage tests
  static const GLint kTexWidth = 1023;
  static const GLint kTexHeight = 511;
  static const GLint kTexSubXOffset = 419;
  static const GLint kTexSubYOffset = 103;

  struct {
    cmds::PixelStorei pixel_store_i;
    cmds::TexImage2D tex_image_2d;
  } texImageExpected;

  struct  {
    cmds::PixelStorei pixel_store_i;
    cmds::TexImage2D tex_image_2d;
    cmds::TexSubImage2D tex_sub_image_2d;
  } texSubImageExpected;

  uint32_t pixel_size;
  PixelStoreParams pixel_params;
  // Makes sure the pixels size is large enough for all tests.
  pixel_params.alignment = 8;
  ASSERT_TRUE(GLES2Util::ComputeImageDataSizesES3(
      kSrcWidth, kSrcSubImageY1, 1, kFormat, kType,
      pixel_params, &pixel_size, nullptr, nullptr, nullptr, nullptr));
  std::unique_ptr<uint8_t[]> src_pixels;
  src_pixels.reset(new uint8_t[pixel_size]);
  for (size_t i = 0; i < pixel_size; ++i) {
    src_pixels[i] = static_cast<uint8_t>(i % 255);
  }

  for (int sub = 0; sub < 2; ++sub) {
    for (size_t a = 0; a < arraysize(unpack_alignments); ++a) {
      const void* commands = GetPut();

      GLint alignment = unpack_alignments[a];
      gl_->PixelStorei(GL_UNPACK_ALIGNMENT, alignment);
      gl_->PixelStorei(GL_UNPACK_ROW_LENGTH, kSrcWidth);
      gl_->PixelStorei(GL_UNPACK_SKIP_PIXELS, kSrcSubImageX0);
      gl_->PixelStorei(GL_UNPACK_SKIP_ROWS, kSrcSubImageY0);

      uint32_t client_size;
      uint32_t client_unpadded_row_size;
      uint32_t client_padded_row_size;
      uint32_t client_skip_size;
      {
        PixelStoreParams params;
        params.alignment = alignment;
        params.row_length = kSrcWidth;
        params.skip_pixels = kSrcSubImageX0;
        params.skip_rows = kSrcSubImageY0;
        ASSERT_TRUE(GLES2Util::ComputeImageDataSizesES3(
            kSrcSubImageWidth, kSrcSubImageHeight, 1, kFormat, kType, params,
            &client_size, &client_unpadded_row_size, &client_padded_row_size,
            &client_skip_size, nullptr));
        ASSERT_TRUE(client_size + client_skip_size <= pixel_size);
      }

      uint32_t service_size;
      uint32_t service_unpadded_row_size;
      uint32_t service_padded_row_size;
      uint32_t service_skip_size;
      {
        PixelStoreParams params;
        // For pixels we send to service side, we already applied all unpack
        // parameters except for UNPACK_ALIGNMENT.
        params.alignment = alignment;
        ASSERT_TRUE(GLES2Util::ComputeImageDataSizesES3(
            kSrcSubImageWidth, kSrcSubImageHeight, 1, kFormat, kType, params,
            &service_size, &service_unpadded_row_size, &service_padded_row_size,
            &service_skip_size, nullptr));
        ASSERT_TRUE(service_size <= MaxTransferBufferSize());
        ASSERT_TRUE(service_skip_size == 0);
        ASSERT_TRUE(client_unpadded_row_size == service_unpadded_row_size);
      }

      ExpectedMemoryInfo mem = GetExpectedMemory(service_size);
      if (sub) {
        gl_->TexImage2D(
            GL_TEXTURE_2D, kLevel, kFormat, kTexWidth, kTexHeight, kBorder,
            kFormat, kType, nullptr);
        gl_->TexSubImage2D(
            GL_TEXTURE_2D, kLevel, kTexSubXOffset, kTexSubYOffset,
            kSrcSubImageWidth, kSrcSubImageHeight, kFormat, kType,
            src_pixels.get());
        texSubImageExpected.pixel_store_i.Init(GL_UNPACK_ALIGNMENT, alignment);
        texSubImageExpected.tex_image_2d.Init(
            GL_TEXTURE_2D, kLevel, kFormat, kTexWidth, kTexHeight,
            kFormat, kType, 0, 0);
        texSubImageExpected.tex_sub_image_2d.Init(
            GL_TEXTURE_2D, kLevel, kTexSubXOffset, kTexSubYOffset,
            kSrcSubImageWidth, kSrcSubImageHeight, kFormat, kType, mem.id,
            mem.offset, GL_FALSE);
        EXPECT_EQ(0, memcmp(&texSubImageExpected, commands,
                            sizeof(texSubImageExpected)));
      } else {
        gl_->TexImage2D(
            GL_TEXTURE_2D, kLevel, kFormat,
            kSrcSubImageWidth, kSrcSubImageHeight, kBorder, kFormat, kType,
            src_pixels.get());
        texImageExpected.pixel_store_i.Init(GL_UNPACK_ALIGNMENT, alignment);
        texImageExpected.tex_image_2d.Init(
            GL_TEXTURE_2D, kLevel, kFormat, kSrcSubImageWidth,
            kSrcSubImageHeight, kFormat, kType, mem.id, mem.offset);
        EXPECT_EQ(0, memcmp(&texImageExpected, commands,
                            sizeof(texImageExpected)));
      }
      for (int y = 0; y < kSrcSubImageHeight; ++y) {
        const uint8_t* src_row =
            src_pixels.get() + client_skip_size + y * client_padded_row_size;
        const uint8_t* dst_row = mem.ptr + y * service_padded_row_size;
        EXPECT_EQ(0, memcmp(src_row, dst_row, service_unpadded_row_size));
      }
      ClearCommands();
    }
  }
}

TEST_F(GLES3ImplementationTest, SubImage3DUnpack) {
  static const GLint unpack_alignments[] = { 1, 2, 4, 8 };

  static const GLenum kFormat = GL_RGB;
  static const GLenum kType = GL_UNSIGNED_BYTE;
  static const GLint kLevel = 0;
  static const GLint kBorder = 0;
  // We're testing using the unpack params to pull a subimage out of a larger
  // source of pixels. Here we specify the subimage by its border rows /
  // columns.
  static const GLint kSrcWidth = 23;
  static const GLint kSrcHeight = 7;
  static const GLint kSrcSubImageX0 = 11;
  static const GLint kSrcSubImageX1 = 16;
  static const GLint kSrcSubImageY0 = 1;
  static const GLint kSrcSubImageY1 = 4;
  static const GLint kSrcSubImageZ0 = 2;
  static const GLint kSrcSubImageZ1 = 5;
  static const GLint kSrcSubImageWidth = kSrcSubImageX1 - kSrcSubImageX0;
  static const GLint kSrcSubImageHeight = kSrcSubImageY1 - kSrcSubImageY0;
  static const GLint kSrcSubImageDepth = kSrcSubImageZ1 - kSrcSubImageZ0;

  // these are only used in the texsubimage tests
  static const GLint kTexWidth = 255;
  static const GLint kTexHeight = 127;
  static const GLint kTexDepth = 11;
  static const GLint kTexSubXOffset = 119;
  static const GLint kTexSubYOffset = 63;
  static const GLint kTexSubZOffset = 1;

  struct {
    cmds::PixelStorei pixel_store_i[3];
    cmds::TexImage3D tex_image_3d;
  } texImageExpected;

  struct  {
    cmds::PixelStorei pixel_store_i[3];
    cmds::TexImage3D tex_image_3d;
    cmds::TexSubImage3D tex_sub_image_3d;
  } texSubImageExpected;

  uint32_t pixel_size;
  PixelStoreParams pixel_params;
  // Makes sure the pixels size is large enough for all tests.
  pixel_params.alignment = 8;
  ASSERT_TRUE(GLES2Util::ComputeImageDataSizesES3(
      kSrcWidth, kSrcHeight, kSrcSubImageZ1, kFormat, kType,
      pixel_params, &pixel_size, nullptr, nullptr, nullptr, nullptr));
  std::unique_ptr<uint8_t[]> src_pixels;
  src_pixels.reset(new uint8_t[pixel_size]);
  for (size_t i = 0; i < pixel_size; ++i) {
    src_pixels[i] = static_cast<uint8_t>(i % 255);
  }

  for (int sub = 0; sub < 2; ++sub) {
    for (size_t a = 0; a < arraysize(unpack_alignments); ++a) {
      const void* commands = GetPut();

      GLint alignment = unpack_alignments[a];
      gl_->PixelStorei(GL_UNPACK_ALIGNMENT, alignment);
      gl_->PixelStorei(GL_UNPACK_ROW_LENGTH, kSrcWidth);
      gl_->PixelStorei(GL_UNPACK_IMAGE_HEIGHT, kSrcHeight);
      gl_->PixelStorei(GL_UNPACK_SKIP_PIXELS, kSrcSubImageX0);
      gl_->PixelStorei(GL_UNPACK_SKIP_ROWS, kSrcSubImageY0);
      gl_->PixelStorei(GL_UNPACK_SKIP_IMAGES, kSrcSubImageZ0);

      uint32_t client_size;
      uint32_t client_unpadded_row_size;
      uint32_t client_padded_row_size;
      uint32_t client_skip_size;
      {
        PixelStoreParams params;
        params.alignment = alignment;
        params.row_length = kSrcWidth;
        params.image_height = kSrcHeight;
        params.skip_pixels = kSrcSubImageX0;
        params.skip_rows = kSrcSubImageY0;
        params.skip_images = kSrcSubImageZ0;
        ASSERT_TRUE(GLES2Util::ComputeImageDataSizesES3(
            kSrcSubImageWidth, kSrcSubImageHeight, kSrcSubImageDepth,
            kFormat, kType, params,
            &client_size, &client_unpadded_row_size, &client_padded_row_size,
            &client_skip_size, nullptr));
        ASSERT_TRUE(client_size + client_skip_size <= pixel_size);
      }

      uint32_t service_size;
      uint32_t service_unpadded_row_size;
      uint32_t service_padded_row_size;
      uint32_t service_skip_size;
      {
        PixelStoreParams params;
        // For pixels we send to service side, we already applied all unpack
        // parameters except for UNPACK_ALIGNMENT.
        params.alignment = alignment;
        ASSERT_TRUE(GLES2Util::ComputeImageDataSizesES3(
            kSrcSubImageWidth, kSrcSubImageHeight, kSrcSubImageDepth,
            kFormat, kType, params,
            &service_size, &service_unpadded_row_size, &service_padded_row_size,
            &service_skip_size, nullptr));
        ASSERT_TRUE(service_size <= MaxTransferBufferSize());
        ASSERT_TRUE(service_skip_size == 0);
        ASSERT_TRUE(client_unpadded_row_size == service_unpadded_row_size);
      }

      ExpectedMemoryInfo mem = GetExpectedMemory(service_size);
      if (sub) {
        gl_->TexImage3D(
            GL_TEXTURE_3D, kLevel, kFormat, kTexWidth, kTexHeight, kTexDepth,
            kBorder, kFormat, kType, nullptr);
        gl_->TexSubImage3D(
            GL_TEXTURE_3D, kLevel,
            kTexSubXOffset, kTexSubYOffset, kTexSubZOffset,
            kSrcSubImageWidth, kSrcSubImageHeight, kSrcSubImageDepth,
            kFormat, kType, src_pixels.get());
        texSubImageExpected.pixel_store_i[0].Init(
            GL_UNPACK_ALIGNMENT, alignment);
        texSubImageExpected.pixel_store_i[1].Init(
            GL_UNPACK_ROW_LENGTH, kSrcWidth);
        texSubImageExpected.pixel_store_i[2].Init(
            GL_UNPACK_IMAGE_HEIGHT, kSrcHeight);
        texSubImageExpected.tex_image_3d.Init(
            GL_TEXTURE_3D, kLevel, kFormat, kTexWidth, kTexHeight, kTexDepth,
            kFormat, kType, 0, 0);
        texSubImageExpected.tex_sub_image_3d.Init(
            GL_TEXTURE_3D, kLevel,
            kTexSubXOffset, kTexSubYOffset, kTexSubZOffset,
            kSrcSubImageWidth, kSrcSubImageHeight, kSrcSubImageDepth,
            kFormat, kType, mem.id, mem.offset, GL_FALSE);
        EXPECT_EQ(0, memcmp(&texSubImageExpected, commands,
                            sizeof(texSubImageExpected)));
      } else {
        gl_->TexImage3D(
            GL_TEXTURE_3D, kLevel, kFormat,
            kSrcSubImageWidth, kSrcSubImageHeight, kSrcSubImageDepth,
            kBorder, kFormat, kType, src_pixels.get());
        texImageExpected.pixel_store_i[0].Init(GL_UNPACK_ALIGNMENT, alignment);
        texImageExpected.pixel_store_i[1].Init(
            GL_UNPACK_ROW_LENGTH, kSrcWidth);
        texImageExpected.pixel_store_i[2].Init(
            GL_UNPACK_IMAGE_HEIGHT, kSrcHeight);
        texImageExpected.tex_image_3d.Init(
            GL_TEXTURE_3D, kLevel, kFormat,
            kSrcSubImageWidth, kSrcSubImageHeight, kSrcSubImageDepth,
            kFormat, kType, mem.id, mem.offset);
        EXPECT_EQ(0, memcmp(&texImageExpected, commands,
                            sizeof(texImageExpected)));
      }
      for (int z = 0; z < kSrcSubImageDepth; ++z) {
        for (int y = 0; y < kSrcSubImageHeight; ++y) {
          const uint8_t* src_row =  src_pixels.get() + client_skip_size +
              (kSrcHeight * z + y) * client_padded_row_size;
          const uint8_t* dst_row = mem.ptr +
              (kSrcSubImageHeight * z + y) * service_padded_row_size;
          EXPECT_EQ(0, memcmp(src_row, dst_row, service_unpadded_row_size));
        }
      }
      ClearCommands();
    }
  }
}

// Test texture related calls with invalid arguments.
TEST_F(GLES2ImplementationTest, TextureInvalidArguments) {
  struct Cmds {
    cmds::TexImage2D tex_image_2d;
    cmd::SetToken set_token;
  };
  const GLenum kTarget = GL_TEXTURE_2D;
  const GLint kLevel = 0;
  const GLenum kFormat = GL_RGB;
  const GLsizei kWidth = 3;
  const GLsizei kHeight = 4;
  const GLint kBorder = 0;
  const GLint kInvalidBorder = 1;
  const GLenum kType = GL_UNSIGNED_BYTE;
  const GLint kPixelStoreUnpackAlignment = 4;
  static uint8_t pixels[] = {
      11, 12, 13, 13,  14,  15,  15,  16,  17,  101, 102, 103, 21, 22, 23,
      23, 24, 25, 25,  26,  27,  201, 202, 203, 31,  32,  33,  33, 34, 35,
      35, 36, 37, 123, 124, 125, 41,  42,  43,  43,  44,  45,  45, 46, 47,
  };

  // Verify that something works.

  ExpectedMemoryInfo mem1 = GetExpectedMemory(sizeof(pixels));

  Cmds expected;
  expected.tex_image_2d.Init(
      kTarget, kLevel, kFormat, kWidth, kHeight, kFormat, kType,
      mem1.id, mem1.offset);
  expected.set_token.Init(GetNextToken());
  gl_->TexImage2D(
      kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
      pixels);
  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
  EXPECT_TRUE(CheckRect(
      kWidth, kHeight, kFormat, kType, kPixelStoreUnpackAlignment,
      pixels, mem1.ptr));

  ClearCommands();

  // Use invalid border.
  gl_->TexImage2D(
      kTarget, kLevel, kFormat, kWidth, kHeight, kInvalidBorder, kFormat, kType,
      pixels);

  EXPECT_TRUE(NoCommandsWritten());
  EXPECT_EQ(GL_INVALID_VALUE, CheckError());

  ClearCommands();

  // Checking for CompressedTexImage2D argument validation is a bit tricky due
  // to (runtime-detected) compression formats. Try to infer the error with an
  // aux check.
  const GLenum kCompressedFormat = GL_ETC1_RGB8_OES;
  gl_->CompressedTexImage2D(
      kTarget, kLevel, kCompressedFormat, kWidth, kHeight, kBorder,
      arraysize(pixels), pixels);

  // In the above, kCompressedFormat and arraysize(pixels) are possibly wrong
  // values. First ensure that these do not cause failures at the client. If
  // this check ever fails, it probably means that client checks more than at
  // the time of writing of this test. In this case, more code needs to be
  // written for this test.
  EXPECT_FALSE(NoCommandsWritten());

  ClearCommands();

  // Changing border to invalid border should make the call fail at the client
  // checks.
  gl_->CompressedTexImage2D(
      kTarget, kLevel, kCompressedFormat, kWidth, kHeight, kInvalidBorder,
      arraysize(pixels), pixels);
  EXPECT_TRUE(NoCommandsWritten());
  EXPECT_EQ(GL_INVALID_VALUE, CheckError());
}

TEST_F(GLES2ImplementationTest, TexImage3DSingleCommand) {
  struct Cmds {
    cmds::TexImage3D tex_image_3d;
  };
  const GLenum kTarget = GL_TEXTURE_3D;
  const GLint kLevel = 0;
  const GLint kBorder = 0;
  const GLenum kFormat = GL_RGB;
  const GLenum kType = GL_UNSIGNED_BYTE;
  const GLint kPixelStoreUnpackAlignment = 4;
  const GLsizei kWidth = 3;
  const GLsizei kDepth = 2;

  uint32_t size = 0;
  uint32_t unpadded_row_size = 0;
  uint32_t padded_row_size = 0;
  ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
      kWidth, 2, kDepth, kFormat, kType, kPixelStoreUnpackAlignment,
      &size, &unpadded_row_size, &padded_row_size));
  // Makes sure we can just send over the data in one command.
  const GLsizei kHeight = MaxTransferBufferSize() / padded_row_size / kDepth;
  ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
      kWidth, kHeight, kDepth, kFormat, kType, kPixelStoreUnpackAlignment,
      &size, NULL, NULL));

  std::unique_ptr<uint8_t[]> pixels(new uint8_t[size]);
  for (uint32_t ii = 0; ii < size; ++ii) {
    pixels[ii] = static_cast<uint8_t>(ii);
  }

  ExpectedMemoryInfo mem = GetExpectedMemory(size);

  Cmds expected;
  expected.tex_image_3d.Init(
      kTarget, kLevel, kFormat, kWidth, kHeight, kDepth,
      kFormat, kType, mem.id, mem.offset);

  gl_->TexImage3D(
      kTarget, kLevel, kFormat, kWidth, kHeight, kDepth, kBorder,
      kFormat, kType, pixels.get());

  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
  EXPECT_TRUE(CheckRect(kWidth, kHeight * kDepth, kFormat, kType,
                        kPixelStoreUnpackAlignment,
                        reinterpret_cast<uint8_t*>(pixels.get()), mem.ptr));
}

TEST_F(GLES2ImplementationTest, TexImage3DViaMappedMem) {
  if (!AllowExtraTransferBufferSize()) {
    LOG(WARNING) << "Low memory device do not support MappedMem. Skipping test";
    return;
  }

  struct Cmds {
    cmds::TexImage3D tex_image_3d;
  };
  const GLenum kTarget = GL_TEXTURE_3D;
  const GLint kLevel = 0;
  const GLint kBorder = 0;
  const GLenum kFormat = GL_RGB;
  const GLenum kType = GL_UNSIGNED_BYTE;
  const GLint kPixelStoreUnpackAlignment = 4;
  const GLsizei kWidth = 3;
  const GLsizei kDepth = 2;

  uint32_t size = 0;
  uint32_t unpadded_row_size = 0;
  uint32_t padded_row_size = 0;
  ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
      kWidth, 2, kDepth, kFormat, kType, kPixelStoreUnpackAlignment,
      &size, &unpadded_row_size, &padded_row_size));
  // Makes sure we can just send over the data in one command.
  const GLsizei kMaxHeight = MaxTransferBufferSize() / padded_row_size / kDepth;
  const GLsizei kHeight = kMaxHeight * 2;
  ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
      kWidth, kHeight, kDepth, kFormat, kType, kPixelStoreUnpackAlignment,
      &size, NULL, NULL));

  std::unique_ptr<uint8_t[]> pixels(new uint8_t[size]);
  for (uint32_t ii = 0; ii < size; ++ii) {
    pixels[ii] = static_cast<uint8_t>(ii);
  }

  ExpectedMemoryInfo mem = GetExpectedMappedMemory(size);

  Cmds expected;
  expected.tex_image_3d.Init(
      kTarget, kLevel, kFormat, kWidth, kHeight, kDepth,
      kFormat, kType, mem.id, mem.offset);

  gl_->TexImage3D(
      kTarget, kLevel, kFormat, kWidth, kHeight, kDepth, kBorder,
      kFormat, kType, pixels.get());

  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
  EXPECT_TRUE(CheckRect(kWidth, kHeight * kDepth, kFormat, kType,
                        kPixelStoreUnpackAlignment,
                        reinterpret_cast<uint8_t*>(pixels.get()), mem.ptr));
}

TEST_F(GLES2ImplementationTest, TexImage3DViaTexSubImage3D) {
  // Set limit to 1 to effectively disable mapped memory.
  SetMappedMemoryLimit(1);

  struct Cmds {
    cmds::TexImage3D tex_image_3d;
    cmds::TexSubImage3D tex_sub_image_3d1;
    cmd::SetToken set_token;
    cmds::TexSubImage3D tex_sub_image_3d2;
  };
  const GLenum kTarget = GL_TEXTURE_3D;
  const GLint kLevel = 0;
  const GLint kBorder = 0;
  const GLenum kFormat = GL_RGB;
  const GLenum kType = GL_UNSIGNED_BYTE;
  const GLint kPixelStoreUnpackAlignment = 4;
  const GLsizei kWidth = 3;

  uint32_t size = 0;
  uint32_t unpadded_row_size = 0;
  uint32_t padded_row_size = 0;
  ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
      kWidth, 2, 1, kFormat, kType, kPixelStoreUnpackAlignment,
      &size, &unpadded_row_size, &padded_row_size));
  // Makes sure the data is more than one command can hold.
  const GLsizei kHeight = MaxTransferBufferSize() / padded_row_size + 3;
  ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
      kWidth, kHeight, 1, kFormat, kType, kPixelStoreUnpackAlignment,
      &size, NULL, NULL));
  uint32_t first_size = padded_row_size * (kHeight - 3);
  uint32_t second_size =
      padded_row_size * 3 - (padded_row_size - unpadded_row_size);
  EXPECT_EQ(size, first_size + second_size);
  ExpectedMemoryInfo mem1 = GetExpectedMemory(first_size);
  ExpectedMemoryInfo mem2 = GetExpectedMemory(second_size);
  std::unique_ptr<uint8_t[]> pixels(new uint8_t[size]);
  for (uint32_t ii = 0; ii < size; ++ii) {
    pixels[ii] = static_cast<uint8_t>(ii);
  }

  Cmds expected;
  expected.tex_image_3d.Init(
      kTarget, kLevel, kFormat, kWidth, kHeight, 1, kFormat, kType, 0, 0);
  expected.tex_sub_image_3d1.Init(
      kTarget, kLevel, 0, 0, 0, kWidth, kHeight - 3, 1, kFormat, kType,
      mem1.id, mem1.offset, GL_TRUE);
  expected.tex_sub_image_3d2.Init(
      kTarget, kLevel, 0, kHeight - 3, 0, kWidth, 3, 1, kFormat, kType,
      mem2.id, mem2.offset, GL_TRUE);
  expected.set_token.Init(GetNextToken());

  gl_->TexImage3D(
      kTarget, kLevel, kFormat, kWidth, kHeight, 1, kBorder,
      kFormat, kType, pixels.get());
  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
}

// Test TexSubImage3D with 4 writes
TEST_F(GLES2ImplementationTest, TexSubImage3D4Writes) {
  struct Cmds {
    cmds::TexSubImage3D tex_sub_image_3d1_1;
    cmd::SetToken set_token1;
    cmds::TexSubImage3D tex_sub_image_3d1_2;
    cmd::SetToken set_token2;
    cmds::TexSubImage3D tex_sub_image_3d2_1;
    cmd::SetToken set_token3;
    cmds::TexSubImage3D tex_sub_image_3d2_2;
  };
  const GLenum kTarget = GL_TEXTURE_3D;
  const GLint kLevel = 0;
  const GLint kXOffset = 0;
  const GLint kYOffset = 0;
  const GLint kZOffset = 0;
  const GLenum kFormat = GL_RGB;
  const GLenum kType = GL_UNSIGNED_BYTE;
  const GLint kPixelStoreUnpackAlignment = 4;
  const GLsizei kWidth = 3;
  const GLsizei kDepth = 2;

  uint32_t size = 0;
  uint32_t unpadded_row_size = 0;
  uint32_t padded_row_size = 0;
  ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
      kWidth, 2, 1, kFormat, kType, kPixelStoreUnpackAlignment,
      &size, &unpadded_row_size, &padded_row_size));
  const GLsizei kHeight = MaxTransferBufferSize() / padded_row_size + 2;
  ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
      kWidth, kHeight, kDepth, kFormat, kType, kPixelStoreUnpackAlignment,
      &size, NULL, NULL));
  uint32_t first_size = (kHeight - 2) * padded_row_size;
  uint32_t second_size = 2 * padded_row_size;
  uint32_t third_size = first_size;
  uint32_t fourth_size = second_size - (padded_row_size - unpadded_row_size);
  EXPECT_EQ(size, first_size + second_size + third_size + fourth_size);

  std::unique_ptr<uint8_t[]> pixels(new uint8_t[size]);
  for (uint32_t ii = 0; ii < size; ++ii) {
    pixels[ii] = static_cast<uint8_t>(ii);
  }

  ExpectedMemoryInfo mem1_1 = GetExpectedMemory(first_size);
  ExpectedMemoryInfo mem1_2 = GetExpectedMemory(second_size);
  ExpectedMemoryInfo mem2_1 = GetExpectedMemory(third_size);
  ExpectedMemoryInfo mem2_2 = GetExpectedMemory(fourth_size);

  Cmds expected;
  expected.tex_sub_image_3d1_1.Init(
      kTarget, kLevel, kXOffset, kYOffset, kZOffset,
      kWidth, kHeight - 2, 1, kFormat, kType,
      mem1_1.id, mem1_1.offset, GL_FALSE);
  expected.tex_sub_image_3d1_2.Init(
      kTarget, kLevel, kXOffset, kYOffset + kHeight - 2, kZOffset,
      kWidth, 2, 1, kFormat, kType, mem1_2.id, mem1_2.offset, GL_FALSE);
  expected.tex_sub_image_3d2_1.Init(
      kTarget, kLevel, kXOffset, kYOffset, kZOffset + 1,
      kWidth, kHeight - 2, 1, kFormat, kType,
      mem2_1.id, mem2_1.offset, GL_FALSE);
  expected.tex_sub_image_3d2_2.Init(
      kTarget, kLevel, kXOffset, kYOffset + kHeight - 2, kZOffset + 1,
      kWidth, 2, 1, kFormat, kType, mem2_2.id, mem2_2.offset, GL_FALSE);
  expected.set_token1.Init(GetNextToken());
  expected.set_token2.Init(GetNextToken());
  expected.set_token3.Init(GetNextToken());

  gl_->TexSubImage3D(
      kTarget, kLevel, kXOffset, kYOffset, kZOffset, kWidth, kHeight, kDepth,
      kFormat, kType, pixels.get());

  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
  uint32_t offset_to_last = first_size + second_size + third_size;
  EXPECT_TRUE(CheckRect(
      kWidth, 2, kFormat, kType, kPixelStoreUnpackAlignment,
      reinterpret_cast<uint8_t*>(pixels.get()) + offset_to_last, mem2_2.ptr));
}

// glGen* Ids must not be reused until glDelete* commands have been
// flushed by glFlush.
TEST_F(GLES2ImplementationStrictSharedTest, FlushGenerationTestBuffers) {
  FlushGenerationTest<GenBuffersAPI>();
}
TEST_F(GLES2ImplementationStrictSharedTest, FlushGenerationTestFramebuffers) {
  FlushGenerationTest<GenFramebuffersAPI>();
}
TEST_F(GLES2ImplementationStrictSharedTest, FlushGenerationTestRenderbuffers) {
  FlushGenerationTest<GenRenderbuffersAPI>();
}
TEST_F(GLES2ImplementationStrictSharedTest, FlushGenerationTestTextures) {
  FlushGenerationTest<GenTexturesAPI>();
}

// glGen* Ids must not be reused cross-context until glDelete* commands are
// flushed by glFlush, and the Ids are lazily freed after.
TEST_F(GLES2ImplementationStrictSharedTest, CrossContextGenerationTestBuffers) {
  CrossContextGenerationTest<GenBuffersAPI>();
}
TEST_F(GLES2ImplementationStrictSharedTest,
       CrossContextGenerationTestFramebuffers) {
  CrossContextGenerationTest<GenFramebuffersAPI>();
}
TEST_F(GLES2ImplementationStrictSharedTest,
       CrossContextGenerationTestRenderbuffers) {
  CrossContextGenerationTest<GenRenderbuffersAPI>();
}
TEST_F(GLES2ImplementationStrictSharedTest,
       CrossContextGenerationTestTextures) {
  CrossContextGenerationTest<GenTexturesAPI>();
}

// Test Delete which causes auto flush.  Tests a regression case that occurred
// in testing.
TEST_F(GLES2ImplementationStrictSharedTest,
       CrossContextGenerationAutoFlushTestBuffers) {
  CrossContextGenerationAutoFlushTest<GenBuffersAPI>();
}
TEST_F(GLES2ImplementationStrictSharedTest,
       CrossContextGenerationAutoFlushTestFramebuffers) {
  CrossContextGenerationAutoFlushTest<GenFramebuffersAPI>();
}
TEST_F(GLES2ImplementationStrictSharedTest,
       CrossContextGenerationAutoFlushTestRenderbuffers) {
  CrossContextGenerationAutoFlushTest<GenRenderbuffersAPI>();
}
TEST_F(GLES2ImplementationStrictSharedTest,
       CrossContextGenerationAutoFlushTestTextures) {
  CrossContextGenerationAutoFlushTest<GenTexturesAPI>();
}

TEST_F(GLES2ImplementationTest, GetString) {
  const uint32_t kBucketId = GLES2Implementation::kResultBucketId;
  const Str7 kString = {"foobar"};
  // GL_CHROMIUM_map_sub is hard coded into GLES2Implementation.
  const char* expected_str =
      "foobar "
      "GL_EXT_unpack_subimage "
      "GL_CHROMIUM_map_sub";
  const char kBad = 0x12;
  struct Cmds {
    cmd::SetBucketSize set_bucket_size1;
    cmds::GetString get_string;
    cmd::GetBucketStart get_bucket_start;
    cmd::SetToken set_token1;
    cmd::SetBucketSize set_bucket_size2;
  };
  ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
  ExpectedMemoryInfo result1 =
      GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result));
  Cmds expected;
  expected.set_bucket_size1.Init(kBucketId, 0);
  expected.get_string.Init(GL_EXTENSIONS, kBucketId);
  expected.get_bucket_start.Init(
      kBucketId, result1.id, result1.offset,
      MaxTransferBufferSize(), mem1.id, mem1.offset);
  expected.set_token1.Init(GetNextToken());
  expected.set_bucket_size2.Init(kBucketId, 0);
  char buf[sizeof(kString) + 1];
  memset(buf, kBad, sizeof(buf));

  EXPECT_CALL(*command_buffer(), OnFlush())
      .WillOnce(DoAll(SetMemory(result1.ptr, uint32_t(sizeof(kString))),
                      SetMemory(mem1.ptr, kString)))
      .RetiresOnSaturation();

  const GLubyte* result = gl_->GetString(GL_EXTENSIONS);
  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
  EXPECT_STREQ(expected_str, reinterpret_cast<const char*>(result));
}

TEST_F(GLES2ImplementationTest, CreateProgram) {
  struct Cmds {
    cmds::CreateProgram cmd;
  };

  Cmds expected;
  expected.cmd.Init(kProgramsAndShadersStartId);
  GLuint id = gl_->CreateProgram();
  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
  EXPECT_EQ(kProgramsAndShadersStartId, id);
}

TEST_F(GLES2ImplementationTest, BufferDataLargerThanTransferBuffer) {
  struct Cmds {
    cmds::BufferData set_size;
    cmds::BufferSubData copy_data1;
    cmd::SetToken set_token1;
    cmds::BufferSubData copy_data2;
    cmd::SetToken set_token2;
  };
  const unsigned kUsableSize =
      kTransferBufferSize - GLES2Implementation::kStartingOffset;
  uint8_t buf[kUsableSize * 2] = {
      0,
  };

  ExpectedMemoryInfo mem1 = GetExpectedMemory(kUsableSize);
  ExpectedMemoryInfo mem2 = GetExpectedMemory(kUsableSize);

  Cmds expected;
  expected.set_size.Init(
      GL_ARRAY_BUFFER, arraysize(buf), 0, 0, GL_DYNAMIC_DRAW);
  expected.copy_data1.Init(
      GL_ARRAY_BUFFER, 0, kUsableSize, mem1.id, mem1.offset);
  expected.set_token1.Init(GetNextToken());
  expected.copy_data2.Init(
      GL_ARRAY_BUFFER, kUsableSize, kUsableSize, mem2.id, mem2.offset);
  expected.set_token2.Init(GetNextToken());
  gl_->BufferData(GL_ARRAY_BUFFER, arraysize(buf), buf, GL_DYNAMIC_DRAW);
  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
}

TEST_F(GLES2ImplementationTest, CapabilitiesAreCached) {
  static const GLenum kStates[] = {
    GL_DITHER,
    GL_BLEND,
    GL_CULL_FACE,
    GL_DEPTH_TEST,
    GL_POLYGON_OFFSET_FILL,
    GL_SAMPLE_ALPHA_TO_COVERAGE,
    GL_SAMPLE_COVERAGE,
    GL_SCISSOR_TEST,
    GL_STENCIL_TEST,
  };
  struct Cmds {
    cmds::Enable enable_cmd;
  };
  Cmds expected;

  for (size_t ii = 0; ii < arraysize(kStates); ++ii) {
    GLenum state = kStates[ii];
    expected.enable_cmd.Init(state);
    GLboolean result = gl_->IsEnabled(state);
    EXPECT_EQ(static_cast<GLboolean>(ii == 0), result);
    EXPECT_TRUE(NoCommandsWritten());
    const void* commands = GetPut();
    if (!result) {
      gl_->Enable(state);
      EXPECT_EQ(0, memcmp(&expected, commands, sizeof(expected)));
    }
    ClearCommands();
    result = gl_->IsEnabled(state);
    EXPECT_TRUE(result);
    EXPECT_TRUE(NoCommandsWritten());
  }
}

TEST_F(GLES2ImplementationTest, BindVertexArrayOES) {
  GLuint id = 0;
  gl_->GenVertexArraysOES(1, &id);
  ClearCommands();

  struct Cmds {
    cmds::BindVertexArrayOES cmd;
  };
  Cmds expected;
  expected.cmd.Init(id);

  const void* commands = GetPut();
  gl_->BindVertexArrayOES(id);
  EXPECT_EQ(0, memcmp(&expected, commands, sizeof(expected)));
  ClearCommands();
  gl_->BindVertexArrayOES(id);
  EXPECT_TRUE(NoCommandsWritten());
}

TEST_F(GLES2ImplementationTest, BeginEndQueryEXT) {
  // Test GetQueryivEXT returns 0 if no current query.
  GLint param = -1;
  gl_->GetQueryivEXT(GL_ANY_SAMPLES_PASSED_EXT, GL_CURRENT_QUERY_EXT, &param);
  EXPECT_EQ(0, param);

  GLuint expected_ids[2] = { 1, 2 }; // These must match what's actually genned.
  struct GenCmds {
    cmds::GenQueriesEXTImmediate gen;
    GLuint data[2];
  };
  GenCmds expected_gen_cmds;
  expected_gen_cmds.gen.Init(arraysize(expected_ids), &expected_ids[0]);
  GLuint ids[arraysize(expected_ids)] = { 0, };
  gl_->GenQueriesEXT(arraysize(expected_ids), &ids[0]);
  EXPECT_EQ(0, memcmp(
      &expected_gen_cmds, commands_, sizeof(expected_gen_cmds)));
  GLuint id1 = ids[0];
  GLuint id2 = ids[1];
  ClearCommands();

  // Test BeginQueryEXT fails if id = 0.
  gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, 0);
  EXPECT_TRUE(NoCommandsWritten());
  EXPECT_EQ(GL_INVALID_OPERATION, CheckError());

  // Test BeginQueryEXT inserts command.
  struct BeginCmds {
    cmds::BeginQueryEXT begin_query;
  };
  BeginCmds expected_begin_cmds;
  const void* commands = GetPut();
  gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, id1);
  QueryTracker::Query* query = GetQuery(id1);
  ASSERT_TRUE(query != NULL);
  expected_begin_cmds.begin_query.Init(
      GL_ANY_SAMPLES_PASSED_EXT, id1, query->shm_id(), query->shm_offset());
  EXPECT_EQ(0, memcmp(
      &expected_begin_cmds, commands, sizeof(expected_begin_cmds)));
  ClearCommands();

  // Test GetQueryivEXT returns id.
  param = -1;
  gl_->GetQueryivEXT(GL_ANY_SAMPLES_PASSED_EXT, GL_CURRENT_QUERY_EXT, &param);
  EXPECT_EQ(id1, static_cast<GLuint>(param));
  gl_->GetQueryivEXT(
      GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, GL_CURRENT_QUERY_EXT, &param);
  EXPECT_EQ(0, param);

  // Test BeginQueryEXT fails if between Begin/End.
  gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, id2);
  EXPECT_TRUE(NoCommandsWritten());
  EXPECT_EQ(GL_INVALID_OPERATION, CheckError());

  // Test EndQueryEXT fails if target not same as current query.
  ClearCommands();
  gl_->EndQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT);
  EXPECT_TRUE(NoCommandsWritten());
  EXPECT_EQ(GL_INVALID_OPERATION, CheckError());

  // Test EndQueryEXT sends command
  struct EndCmds {
    cmds::EndQueryEXT end_query;
  };
  EndCmds expected_end_cmds;
  expected_end_cmds.end_query.Init(
      GL_ANY_SAMPLES_PASSED_EXT, query->submit_count());
  commands = GetPut();
  gl_->EndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
  EXPECT_EQ(0, memcmp(
      &expected_end_cmds, commands, sizeof(expected_end_cmds)));

  // Test EndQueryEXT fails if no current query.
  ClearCommands();
  gl_->EndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
  EXPECT_TRUE(NoCommandsWritten());
  EXPECT_EQ(GL_INVALID_OPERATION, CheckError());

  // Test 2nd Begin/End increments count.
  base::subtle::Atomic32 old_submit_count = query->submit_count();
  gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, id1);
  EXPECT_NE(old_submit_count, query->submit_count());
  expected_end_cmds.end_query.Init(
      GL_ANY_SAMPLES_PASSED_EXT, query->submit_count());
  commands = GetPut();
  gl_->EndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
  EXPECT_EQ(0, memcmp(
      &expected_end_cmds, commands, sizeof(expected_end_cmds)));

  // Test BeginQueryEXT fails if target changed.
  ClearCommands();
  gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, id1);
  EXPECT_TRUE(NoCommandsWritten());
  EXPECT_EQ(GL_INVALID_OPERATION, CheckError());

  // Test GetQueryObjectuivEXT fails if unused id
  GLuint available = 0xBDu;
  ClearCommands();
  gl_->GetQueryObjectuivEXT(id2, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
  EXPECT_TRUE(NoCommandsWritten());
  EXPECT_EQ(0xBDu, available);
  EXPECT_EQ(GL_INVALID_OPERATION, CheckError());

  // Test GetQueryObjectuivEXT fails if bad id
  ClearCommands();
  gl_->GetQueryObjectuivEXT(4567, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
  EXPECT_TRUE(NoCommandsWritten());
  EXPECT_EQ(0xBDu, available);
  EXPECT_EQ(GL_INVALID_OPERATION, CheckError());

  // Test GetQueryObjectuivEXT CheckResultsAvailable
  ClearCommands();
  gl_->GetQueryObjectuivEXT(id1, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
  EXPECT_EQ(0u, available);

  // Test GetQueryObjectui64vEXT fails if unused id
  GLuint64 available2 = 0xBDu;
  ClearCommands();
  gl_->GetQueryObjectui64vEXT(id2, GL_QUERY_RESULT_AVAILABLE_EXT, &available2);
  EXPECT_TRUE(NoCommandsWritten());
  EXPECT_EQ(0xBDu, available2);
  EXPECT_EQ(GL_INVALID_OPERATION, CheckError());

  // Test GetQueryObjectui64vEXT fails if bad id
  ClearCommands();
  gl_->GetQueryObjectui64vEXT(4567, GL_QUERY_RESULT_AVAILABLE_EXT, &available2);
  EXPECT_TRUE(NoCommandsWritten());
  EXPECT_EQ(0xBDu, available2);
  EXPECT_EQ(GL_INVALID_OPERATION, CheckError());

  // Test GetQueryObjectui64vEXT CheckResultsAvailable
  ClearCommands();
  gl_->GetQueryObjectui64vEXT(id1, GL_QUERY_RESULT_AVAILABLE_EXT, &available2);
  EXPECT_EQ(0u, available2);
}

TEST_F(GLES2ImplementationManualInitTest, BadQueryTargets) {
  ContextInitOptions init_options;
  init_options.sync_query = false;
  init_options.occlusion_query_boolean = false;
  init_options.timer_queries = false;
  ASSERT_TRUE(Initialize(init_options));

  GLuint id = 0;
  gl_->GenQueriesEXT(1, &id);
  ClearCommands();

  gl_->BeginQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM, id);
  EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
  EXPECT_EQ(nullptr, GetQuery(id));

  gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED, id);
  EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
  EXPECT_EQ(nullptr, GetQuery(id));

  gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE, id);
  EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
  EXPECT_EQ(nullptr, GetQuery(id));

  gl_->BeginQueryEXT(GL_TIME_ELAPSED_EXT, id);
  EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
  EXPECT_EQ(nullptr, GetQuery(id));

  gl_->BeginQueryEXT(0x123, id);
  EXPECT_EQ(GL_INVALID_ENUM, CheckError());
  EXPECT_EQ(nullptr, GetQuery(id));

  gl_->QueryCounterEXT(id, GL_TIMESTAMP_EXT);
  EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
  EXPECT_EQ(nullptr, GetQuery(id));

  gl_->QueryCounterEXT(id, 0x123);
  EXPECT_EQ(GL_INVALID_ENUM, CheckError());
  EXPECT_EQ(nullptr, GetQuery(id));
}

TEST_F(GLES2ImplementationTest, SetDisjointSync) {
  struct SetDisjointSyncCmd {
    cmds::SetDisjointValueSyncCHROMIUM disjoint_sync;
  };
  SetDisjointSyncCmd expected_disjoint_sync_cmd;
  const void* commands = GetPut();
  gl_->SetDisjointValueSyncCHROMIUM();
  expected_disjoint_sync_cmd.disjoint_sync.Init(
      GetQueryTracker()->DisjointCountSyncShmID(),
      GetQueryTracker()->DisjointCountSyncShmOffset());

  EXPECT_EQ(0, memcmp(&expected_disjoint_sync_cmd, commands,
                      sizeof(expected_disjoint_sync_cmd)));
}

TEST_F(GLES2ImplementationTest, QueryCounterEXT) {
  GLuint expected_ids[2] = { 1, 2 }; // These must match what's actually genned.
  struct GenCmds {
    cmds::GenQueriesEXTImmediate gen;
    GLuint data[2];
  };
  GenCmds expected_gen_cmds;
  expected_gen_cmds.gen.Init(arraysize(expected_ids), &expected_ids[0]);
  GLuint ids[arraysize(expected_ids)] = { 0, };
  gl_->GenQueriesEXT(arraysize(expected_ids), &ids[0]);
  EXPECT_EQ(0, memcmp(
      &expected_gen_cmds, commands_, sizeof(expected_gen_cmds)));
  GLuint id1 = ids[0];
  GLuint id2 = ids[1];
  ClearCommands();

  // Make sure disjoint value is synchronized already.
  gl_->SetDisjointValueSyncCHROMIUM();
  ClearCommands();

  // Test QueryCounterEXT fails if id = 0.
  gl_->QueryCounterEXT(0, GL_TIMESTAMP_EXT);
  EXPECT_TRUE(NoCommandsWritten());
  EXPECT_EQ(GL_INVALID_OPERATION, CheckError());

  // Test QueryCounterEXT fails if target is unknown.
  ClearCommands();
  gl_->QueryCounterEXT(id1, GL_TIME_ELAPSED_EXT);
  EXPECT_TRUE(NoCommandsWritten());
  EXPECT_EQ(GL_INVALID_ENUM, CheckError());

  // Test QueryCounterEXT inserts command.
  struct QueryCounterCmds {
    cmds::QueryCounterEXT query_counter;
  };
  QueryCounterCmds expected_query_counter_cmds;
  const void* commands = GetPut();
  gl_->QueryCounterEXT(id1, GL_TIMESTAMP_EXT);
  EXPECT_EQ(GL_NO_ERROR, CheckError());
  QueryTracker::Query* query = GetQuery(id1);
  ASSERT_TRUE(query != NULL);
  expected_query_counter_cmds.query_counter.Init(
      id1, GL_TIMESTAMP_EXT, query->shm_id(), query->shm_offset(),
      query->submit_count());
  EXPECT_EQ(0, memcmp(&expected_query_counter_cmds, commands,
                      sizeof(expected_query_counter_cmds)));
  ClearCommands();

  // Test 2nd QueryCounterEXT succeeds.
  commands = GetPut();
  gl_->QueryCounterEXT(id2, GL_TIMESTAMP_EXT);
  EXPECT_EQ(GL_NO_ERROR, CheckError());
  QueryTracker::Query* query2 = GetQuery(id2);
  ASSERT_TRUE(query2 != NULL);
  expected_query_counter_cmds.query_counter.Init(
      id2, GL_TIMESTAMP_EXT, query2->shm_id(), query2->shm_offset(),
      query2->submit_count());
  EXPECT_EQ(0, memcmp(&expected_query_counter_cmds, commands,
                      sizeof(expected_query_counter_cmds)));
  ClearCommands();

  // Test QueryCounterEXT increments count.
  base::subtle::Atomic32 old_submit_count = query->submit_count();
  commands = GetPut();
  gl_->QueryCounterEXT(id1, GL_TIMESTAMP_EXT);
  EXPECT_EQ(GL_NO_ERROR, CheckError());
  EXPECT_NE(old_submit_count, query->submit_count());
  expected_query_counter_cmds.query_counter.Init(
      id1, GL_TIMESTAMP_EXT, query->shm_id(), query->shm_offset(),
      query->submit_count());
  EXPECT_EQ(0, memcmp(&expected_query_counter_cmds, commands,
                      sizeof(expected_query_counter_cmds)));
  ClearCommands();

  // Test GetQueryObjectuivEXT CheckResultsAvailable
  GLuint available = 0xBDu;
  ClearCommands();
  gl_->GetQueryObjectuivEXT(id1, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
  EXPECT_EQ(0u, available);

  // Test GetQueryObjectui64vEXT CheckResultsAvailable
  GLuint64 available2 = 0xBDu;
  ClearCommands();
  gl_->GetQueryObjectui64vEXT(id1, GL_QUERY_RESULT_AVAILABLE_EXT, &available2);
  EXPECT_EQ(0u, available2);
}

TEST_F(GLES2ImplementationTest, ErrorQuery) {
  GLuint id = 0;
  gl_->GenQueriesEXT(1, &id);
  ClearCommands();

  // Test BeginQueryEXT does NOT insert commands.
  gl_->BeginQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM, id);
  EXPECT_TRUE(NoCommandsWritten());
  QueryTracker::Query* query = GetQuery(id);
  ASSERT_TRUE(query != NULL);

  // Test EndQueryEXT sends both begin and end command
  struct EndCmds {
    cmds::BeginQueryEXT begin_query;
    cmds::EndQueryEXT end_query;
  };
  EndCmds expected_end_cmds;
  expected_end_cmds.begin_query.Init(
      GL_GET_ERROR_QUERY_CHROMIUM, id, query->shm_id(), query->shm_offset());
  expected_end_cmds.end_query.Init(
      GL_GET_ERROR_QUERY_CHROMIUM, query->submit_count());
  const void* commands = GetPut();
  gl_->EndQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM);
  EXPECT_EQ(0, memcmp(
      &expected_end_cmds, commands, sizeof(expected_end_cmds)));
  ClearCommands();

  // Check result is not yet available.
  GLuint available = 0xBDu;
  gl_->GetQueryObjectuivEXT(id, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
  EXPECT_TRUE(NoCommandsWritten());
  EXPECT_EQ(0u, available);

  // Test no commands are sent if there is a client side error.

  // Generate a client side error
  gl_->ActiveTexture(GL_TEXTURE0 - 1);

  gl_->BeginQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM, id);
  gl_->EndQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM);
  EXPECT_TRUE(NoCommandsWritten());

  // Check result is available.
  gl_->GetQueryObjectuivEXT(id, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
  EXPECT_TRUE(NoCommandsWritten());
  EXPECT_NE(0u, available);

  // Check result.
  GLuint result = 0xBDu;
  gl_->GetQueryObjectuivEXT(id, GL_QUERY_RESULT_EXT, &result);
  EXPECT_TRUE(NoCommandsWritten());
  EXPECT_EQ(static_cast<GLuint>(GL_INVALID_ENUM), result);
}

#if !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
TEST_F(GLES2ImplementationTest, VertexArrays) {
  const GLuint kAttribIndex1 = 1;
  const GLint kNumComponents1 = 3;
  const GLsizei kClientStride = 12;

  GLuint id = 0;
  gl_->GenVertexArraysOES(1, &id);
  ClearCommands();

  gl_->BindVertexArrayOES(id);

  // Test that VertexAttribPointer cannot be called with a bound buffer of 0
  // unless the offset is NULL
  gl_->BindBuffer(GL_ARRAY_BUFFER, 0);

  gl_->VertexAttribPointer(
      kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, kClientStride,
      reinterpret_cast<const void*>(4));
  EXPECT_EQ(GL_INVALID_OPERATION, CheckError());

  gl_->VertexAttribPointer(
      kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, kClientStride, NULL);
  EXPECT_EQ(GL_NO_ERROR, CheckError());
}
#endif

TEST_F(GLES2ImplementationTest, Disable) {
  struct Cmds {
    cmds::Disable cmd;
  };
  Cmds expected;
  expected.cmd.Init(GL_DITHER);  // Note: DITHER defaults to enabled.

  gl_->Disable(GL_DITHER);
  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
  // Check it's cached and not called again.
  ClearCommands();
  gl_->Disable(GL_DITHER);
  EXPECT_TRUE(NoCommandsWritten());
}

TEST_F(GLES2ImplementationTest, Enable) {
  struct Cmds {
    cmds::Enable cmd;
  };
  Cmds expected;
  expected.cmd.Init(GL_BLEND);  // Note: BLEND defaults to disabled.

  gl_->Enable(GL_BLEND);
  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
  // Check it's cached and not called again.
  ClearCommands();
  gl_->Enable(GL_BLEND);
  EXPECT_TRUE(NoCommandsWritten());
}

TEST_F(GLES2ImplementationTest, ConsumeTextureCHROMIUM) {
  struct Cmds {
    cmds::ConsumeTextureCHROMIUMImmediate cmd;
    GLbyte data[64];
  };

  Mailbox mailbox = Mailbox::Generate();
  Cmds expected;
  expected.cmd.Init(GL_TEXTURE_2D, mailbox.name);
  gl_->ConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
}

TEST_F(GLES2ImplementationTest, CreateAndConsumeTextureCHROMIUM) {
  struct Cmds {
    cmds::CreateAndConsumeTextureCHROMIUMImmediate cmd;
    GLbyte data[64];
  };

  Mailbox mailbox = Mailbox::Generate();
  Cmds expected;
  expected.cmd.Init(GL_TEXTURE_2D, kTexturesStartId, mailbox.name);
  GLuint id = gl_->CreateAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
  EXPECT_EQ(kTexturesStartId, id);
}

TEST_F(GLES2ImplementationTest, ProduceTextureCHROMIUM) {
  struct Cmds {
    cmds::ProduceTextureCHROMIUMImmediate cmd;
    GLbyte data[64];
  };

  Mailbox mailbox = Mailbox::Generate();
  Cmds expected;
  expected.cmd.Init(GL_TEXTURE_2D, mailbox.name);
  gl_->ProduceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
}

TEST_F(GLES2ImplementationTest, ProduceTextureDirectCHROMIUM) {
  struct Cmds {
    cmds::ProduceTextureDirectCHROMIUMImmediate cmd;
    GLbyte data[64];
  };

  Mailbox mailbox = Mailbox::Generate();
  Cmds expected;
  expected.cmd.Init(kTexturesStartId, GL_TEXTURE_2D, mailbox.name);
  gl_->ProduceTextureDirectCHROMIUM(
      kTexturesStartId, GL_TEXTURE_2D, mailbox.name);
  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
}

TEST_F(GLES2ImplementationTest, LimitSizeAndOffsetTo32Bit) {
  GLsizeiptr size;
  GLintptr offset;
  if (sizeof(size) <= 4 || sizeof(offset) <= 4)
    return;
  // The below two casts should be no-op, as we return early if
  // it's 32-bit system.
  int64_t value64 = 0x100000000;
  size = static_cast<GLsizeiptr>(value64);
  offset = static_cast<GLintptr>(value64);

  const char kSizeOverflowMessage[] = "size more than 32-bit";
  const char kOffsetOverflowMessage[] = "offset more than 32-bit";

  const GLfloat buf[] = { 1.0, 1.0, 1.0, 1.0 };
  const GLubyte indices[] = { 0 };

  const GLuint kClientArrayBufferId = 0x789;
  const GLuint kClientElementArrayBufferId = 0x790;
  gl_->BindBuffer(GL_ARRAY_BUFFER, kClientArrayBufferId);
  gl_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, kClientElementArrayBufferId);
  EXPECT_EQ(GL_NO_ERROR, CheckError());

  // Call BufferData() should succeed with legal paramaters.
  gl_->BufferData(GL_ARRAY_BUFFER, sizeof(buf), buf, GL_DYNAMIC_DRAW);
  gl_->BufferData(
      GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_DYNAMIC_DRAW);
  EXPECT_EQ(GL_NO_ERROR, CheckError());

  // BufferData: size
  gl_->BufferData(GL_ARRAY_BUFFER, size, buf, GL_DYNAMIC_DRAW);
  EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
  EXPECT_STREQ(kSizeOverflowMessage, GetLastError().c_str());

  // Call BufferSubData() should succeed with legal paramaters.
  gl_->BufferSubData(GL_ARRAY_BUFFER, 0, sizeof(buf[0]), buf);
  EXPECT_EQ(GL_NO_ERROR, CheckError());

  // BufferSubData: offset
  gl_->BufferSubData(GL_ARRAY_BUFFER, offset, 1, buf);
  EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
  EXPECT_STREQ(kOffsetOverflowMessage, GetLastError().c_str());

  // BufferSubData: size
  EXPECT_EQ(GL_NO_ERROR, CheckError());
  gl_->BufferSubData(GL_ARRAY_BUFFER, 0, size, buf);
  EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
  EXPECT_STREQ(kSizeOverflowMessage, GetLastError().c_str());

  // Call MapBufferSubDataCHROMIUM() should succeed with legal paramaters.
  void* mem =
      gl_->MapBufferSubDataCHROMIUM(GL_ARRAY_BUFFER, 0, 1, GL_WRITE_ONLY);
  EXPECT_TRUE(NULL != mem);
  EXPECT_EQ(GL_NO_ERROR, CheckError());
  gl_->UnmapBufferSubDataCHROMIUM(mem);

  // MapBufferSubDataCHROMIUM: offset
  EXPECT_TRUE(NULL == gl_->MapBufferSubDataCHROMIUM(
      GL_ARRAY_BUFFER, offset, 1, GL_WRITE_ONLY));
  EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
  EXPECT_STREQ(kOffsetOverflowMessage, GetLastError().c_str());

  // MapBufferSubDataCHROMIUM: size
  EXPECT_EQ(GL_NO_ERROR, CheckError());
  EXPECT_TRUE(NULL == gl_->MapBufferSubDataCHROMIUM(
      GL_ARRAY_BUFFER, 0, size, GL_WRITE_ONLY));
  EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
  EXPECT_STREQ(kSizeOverflowMessage, GetLastError().c_str());

  // Call DrawElements() should succeed with legal paramaters.
  gl_->DrawElements(GL_POINTS, 1, GL_UNSIGNED_BYTE, NULL);
  EXPECT_EQ(GL_NO_ERROR, CheckError());

  // DrawElements: offset
  gl_->DrawElements(
      GL_POINTS, 1, GL_UNSIGNED_BYTE, reinterpret_cast<void*>(offset));
  EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
  EXPECT_STREQ(kOffsetOverflowMessage, GetLastError().c_str());

  // Call DrawElementsInstancedANGLE() should succeed with legal paramaters.
  gl_->DrawElementsInstancedANGLE(GL_POINTS, 1, GL_UNSIGNED_BYTE, NULL, 1);
  EXPECT_EQ(GL_NO_ERROR, CheckError());

  // DrawElementsInstancedANGLE: offset
  gl_->DrawElementsInstancedANGLE(
      GL_POINTS, 1, GL_UNSIGNED_BYTE, reinterpret_cast<void*>(offset), 1);
  EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
  EXPECT_STREQ(kOffsetOverflowMessage, GetLastError().c_str());

  // Call VertexAttribPointer() should succeed with legal paramaters.
  const GLuint kAttribIndex = 1;
  const GLsizei kStride = 4;
  gl_->VertexAttribPointer(
      kAttribIndex, 1, GL_FLOAT, GL_FALSE, kStride, NULL);
  EXPECT_EQ(GL_NO_ERROR, CheckError());

  // VertexAttribPointer: offset
  gl_->VertexAttribPointer(
      kAttribIndex, 1, GL_FLOAT, GL_FALSE, kStride,
      reinterpret_cast<void*>(offset));
  EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
  EXPECT_STREQ(kOffsetOverflowMessage, GetLastError().c_str());
}

TEST_F(GLES2ImplementationTest, TraceBeginCHROMIUM) {
  const uint32_t kCategoryBucketId = GLES2Implementation::kResultBucketId;
  const uint32_t kNameBucketId = GLES2Implementation::kResultBucketId + 1;
  const std::string category_name = "test category";
  const std::string trace_name = "test trace";
  const size_t kPaddedString1Size =
      transfer_buffer_->RoundToAlignment(category_name.size() + 1);
  const size_t kPaddedString2Size =
      transfer_buffer_->RoundToAlignment(trace_name.size() + 1);

  gl_->TraceBeginCHROMIUM(category_name.c_str(), trace_name.c_str());
  EXPECT_EQ(GL_NO_ERROR, CheckError());

  struct Cmds {
    cmd::SetBucketSize category_size1;
    cmd::SetBucketData category_data;
    cmd::SetToken set_token1;
    cmd::SetBucketSize name_size1;
    cmd::SetBucketData name_data;
    cmd::SetToken set_token2;
    cmds::TraceBeginCHROMIUM trace_call_begin;
    cmd::SetBucketSize category_size2;
    cmd::SetBucketSize name_size2;
  };

  ExpectedMemoryInfo mem1 = GetExpectedMemory(kPaddedString1Size);
  ExpectedMemoryInfo mem2 = GetExpectedMemory(kPaddedString2Size);

  ASSERT_STREQ(category_name.c_str(), reinterpret_cast<char*>(mem1.ptr));
  ASSERT_STREQ(trace_name.c_str(), reinterpret_cast<char*>(mem2.ptr));

  Cmds expected;
  expected.category_size1.Init(kCategoryBucketId, category_name.size() + 1);
  expected.category_data.Init(
      kCategoryBucketId, 0, category_name.size() + 1, mem1.id, mem1.offset);
  expected.set_token1.Init(GetNextToken());
  expected.name_size1.Init(kNameBucketId, trace_name.size() + 1);
  expected.name_data.Init(
      kNameBucketId, 0, trace_name.size() + 1, mem2.id, mem2.offset);
  expected.set_token2.Init(GetNextToken());
  expected.trace_call_begin.Init(kCategoryBucketId, kNameBucketId);
  expected.category_size2.Init(kCategoryBucketId, 0);
  expected.name_size2.Init(kNameBucketId, 0);

  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
}

TEST_F(GLES2ImplementationTest, AllowNestedTracesCHROMIUM) {
  const std::string category1_name = "test category 1";
  const std::string trace1_name = "test trace 1";
  const std::string category2_name = "test category 2";
  const std::string trace2_name = "test trace 2";

  gl_->TraceBeginCHROMIUM(category1_name.c_str(), trace1_name.c_str());
  EXPECT_EQ(GL_NO_ERROR, CheckError());

  gl_->TraceBeginCHROMIUM(category2_name.c_str(), trace2_name.c_str());
  EXPECT_EQ(GL_NO_ERROR, CheckError());

  gl_->TraceEndCHROMIUM();
  EXPECT_EQ(GL_NO_ERROR, CheckError());

  gl_->TraceEndCHROMIUM();
  EXPECT_EQ(GL_NO_ERROR, CheckError());

  // No more corresponding begin tracer marker should error.
  gl_->TraceEndCHROMIUM();
  EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
}

TEST_F(GLES2ImplementationTest, InsertFenceSyncCHROMIUM) {
  const GLuint64 kFenceSync = 123u;
  EXPECT_CALL(*gpu_control_, GenerateFenceSyncRelease())
      .WillOnce(Return(kFenceSync));

  struct Cmds {
    cmds::InsertFenceSyncCHROMIUM insert_fence_sync;
  };
  Cmds expected;
  expected.insert_fence_sync.Init(kFenceSync);

  const GLuint64 fence_sync = gl_->InsertFenceSyncCHROMIUM();
  EXPECT_EQ(kFenceSync, fence_sync);
  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
}

TEST_F(GLES2ImplementationTest, GenSyncTokenCHROMIUM) {
  const CommandBufferNamespace kNamespaceId = CommandBufferNamespace::GPU_IO;
  const CommandBufferId kCommandBufferId =
      CommandBufferId::FromUnsafeValue(234u);
  const GLuint64 kFenceSync = 123u;
  GLbyte sync_token_data[GL_SYNC_TOKEN_SIZE_CHROMIUM];

  EXPECT_CALL(*gpu_control_, GetNamespaceID())
      .WillRepeatedly(Return(kNamespaceId));
  EXPECT_CALL(*gpu_control_, GetCommandBufferID())
      .WillRepeatedly(Return(kCommandBufferId));
  EXPECT_CALL(*gpu_control_, GetExtraCommandBufferData())
      .WillRepeatedly(Return(0));

  gl_->GenSyncTokenCHROMIUM(kFenceSync, nullptr);
  EXPECT_EQ(GL_INVALID_VALUE, CheckError());

  EXPECT_CALL(*gpu_control_, IsFenceSyncRelease(kFenceSync))
      .WillOnce(Return(false));
  gl_->GenSyncTokenCHROMIUM(kFenceSync, sync_token_data);
  EXPECT_EQ(GL_INVALID_VALUE, CheckError());

  EXPECT_CALL(*gpu_control_, IsFenceSyncRelease(kFenceSync))
      .WillOnce(Return(true));
  EXPECT_CALL(*gpu_control_, IsFenceSyncFlushReceived(kFenceSync))
      .WillOnce(Return(false));
  gl_->GenSyncTokenCHROMIUM(kFenceSync, sync_token_data);
  EXPECT_EQ(GL_INVALID_OPERATION, CheckError());

  EXPECT_CALL(*gpu_control_, IsFenceSyncRelease(kFenceSync))
      .WillOnce(Return(true));
  EXPECT_CALL(*gpu_control_, IsFenceSyncFlushReceived(kFenceSync))
      .WillOnce(Return(true));
  ClearCommands();
  gl_->GenSyncTokenCHROMIUM(kFenceSync, sync_token_data);
  EXPECT_TRUE(NoCommandsWritten());
  EXPECT_EQ(GL_NO_ERROR, CheckError());

  SyncToken sync_token;
  memcpy(&sync_token, sync_token_data, sizeof(SyncToken));
  EXPECT_TRUE(sync_token.verified_flush());
  EXPECT_EQ(kNamespaceId, sync_token.namespace_id());
  EXPECT_EQ(kCommandBufferId, sync_token.command_buffer_id());
  EXPECT_EQ(kFenceSync, sync_token.release_count());
}

TEST_F(GLES2ImplementationTest, GenUnverifiedSyncTokenCHROMIUM) {
  const CommandBufferNamespace kNamespaceId = CommandBufferNamespace::GPU_IO;
  const CommandBufferId kCommandBufferId =
      CommandBufferId::FromUnsafeValue(234u);
  const GLuint64 kFenceSync = 123u;
  GLbyte sync_token_data[GL_SYNC_TOKEN_SIZE_CHROMIUM];

  EXPECT_CALL(*gpu_control_, GetNamespaceID())
      .WillRepeatedly(Return(kNamespaceId));
  EXPECT_CALL(*gpu_control_, GetCommandBufferID())
      .WillRepeatedly(Return(kCommandBufferId));
  EXPECT_CALL(*gpu_control_, GetExtraCommandBufferData())
      .WillRepeatedly(Return(0));

  gl_->GenUnverifiedSyncTokenCHROMIUM(kFenceSync, nullptr);
  EXPECT_EQ(GL_INVALID_VALUE, CheckError());

  EXPECT_CALL(*gpu_control_, IsFenceSyncRelease(kFenceSync))
      .WillOnce(Return(false));
  gl_->GenUnverifiedSyncTokenCHROMIUM(kFenceSync, sync_token_data);
  EXPECT_EQ(GL_INVALID_VALUE, CheckError());

  EXPECT_CALL(*gpu_control_, IsFenceSyncRelease(kFenceSync))
      .WillOnce(Return(true));
  EXPECT_CALL(*gpu_control_, IsFenceSyncFlushed(kFenceSync))
      .WillOnce(Return(false));
  gl_->GenUnverifiedSyncTokenCHROMIUM(kFenceSync, sync_token_data);
  EXPECT_EQ(GL_INVALID_OPERATION, CheckError());

  EXPECT_CALL(*gpu_control_, IsFenceSyncRelease(kFenceSync))
      .WillOnce(Return(true));
  EXPECT_CALL(*gpu_control_, IsFenceSyncFlushed(kFenceSync))
      .WillOnce(Return(true));
  ClearCommands();
  gl_->GenUnverifiedSyncTokenCHROMIUM(kFenceSync, sync_token_data);
  EXPECT_TRUE(NoCommandsWritten());
  EXPECT_EQ(GL_NO_ERROR, CheckError());

  SyncToken sync_token;
  memcpy(&sync_token, sync_token_data, sizeof(SyncToken));
  EXPECT_FALSE(sync_token.verified_flush());
  EXPECT_EQ(kNamespaceId, sync_token.namespace_id());
  EXPECT_EQ(kCommandBufferId, sync_token.command_buffer_id());
  EXPECT_EQ(kFenceSync, sync_token.release_count());
}

TEST_F(GLES2ImplementationTest, VerifySyncTokensCHROMIUM) {
  ExpectedMemoryInfo result =
      GetExpectedResultMemory(sizeof(cmds::GetError::Result));
  EXPECT_CALL(*command_buffer(), OnFlush())
      .WillRepeatedly(SetMemory(result.ptr, GLuint(GL_NO_ERROR)))
      .RetiresOnSaturation();

  const CommandBufferNamespace kNamespaceId = CommandBufferNamespace::GPU_IO;
  const CommandBufferId kCommandBufferId =
      CommandBufferId::FromUnsafeValue(234u);
  const GLuint64 kFenceSync = 123u;
  gpu::SyncToken sync_token;
  GLbyte* sync_token_datas[] = { sync_token.GetData() };

  EXPECT_CALL(*gpu_control_, GetNamespaceID())
      .WillRepeatedly(Return(kNamespaceId));
  EXPECT_CALL(*gpu_control_, GetCommandBufferID())
      .WillRepeatedly(Return(kCommandBufferId));
  EXPECT_CALL(*gpu_control_, GetExtraCommandBufferData())
      .WillRepeatedly(Return(0));

  EXPECT_CALL(*gpu_control_, IsFenceSyncRelease(kFenceSync))
      .WillOnce(Return(true));
  EXPECT_CALL(*gpu_control_, IsFenceSyncFlushed(kFenceSync))
      .WillOnce(Return(true));
  gl_->GenUnverifiedSyncTokenCHROMIUM(kFenceSync, sync_token.GetData());
  ASSERT_TRUE(sync_token.HasData());
  ASSERT_FALSE(sync_token.verified_flush());

  ClearCommands();
  EXPECT_CALL(*gpu_control_, CanWaitUnverifiedSyncToken(_))
      .WillOnce(Return(false));
  gl_->VerifySyncTokensCHROMIUM(sync_token_datas, 1);
  EXPECT_TRUE(NoCommandsWritten());
  EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
  EXPECT_FALSE(sync_token.verified_flush());

  ClearCommands();
  EXPECT_CALL(*gpu_control_, CanWaitUnverifiedSyncToken(_))
      .WillOnce(Return(true));
  EXPECT_CALL(*gpu_control_, EnsureWorkVisible());
  gl_->VerifySyncTokensCHROMIUM(sync_token_datas, arraysize(sync_token_datas));
  EXPECT_TRUE(NoCommandsWritten());
  EXPECT_EQ(GL_NO_ERROR, CheckError());

  EXPECT_EQ(kNamespaceId, sync_token.namespace_id());
  EXPECT_EQ(kCommandBufferId, sync_token.command_buffer_id());
  EXPECT_EQ(kFenceSync, sync_token.release_count());
  EXPECT_TRUE(sync_token.verified_flush());
}

TEST_F(GLES2ImplementationTest, VerifySyncTokensCHROMIUM_Sequence) {
  // To verify sync tokens, the sync tokens must all be verified after
  // CanWaitUnverifiedSyncTokens() are called. This test ensures the right
  // sequence.
  ExpectedMemoryInfo result =
      GetExpectedResultMemory(sizeof(cmds::GetError::Result));
  EXPECT_CALL(*command_buffer(), OnFlush())
      .WillRepeatedly(SetMemory(result.ptr, GLuint(GL_NO_ERROR)))
      .RetiresOnSaturation();

  const CommandBufferNamespace kNamespaceId = CommandBufferNamespace::GPU_IO;
  const CommandBufferId kCommandBufferId =
      CommandBufferId::FromUnsafeValue(234u);
  const GLuint64 kFenceSync1 = 123u;
  const GLuint64 kFenceSync2 = 234u;
  gpu::SyncToken sync_token1;
  gpu::SyncToken sync_token2;
  GLbyte* sync_token_datas[] = { sync_token1.GetData(), sync_token2.GetData() };

  EXPECT_CALL(*gpu_control_, GetNamespaceID())
      .WillRepeatedly(Return(kNamespaceId));
  EXPECT_CALL(*gpu_control_, GetCommandBufferID())
      .WillRepeatedly(Return(kCommandBufferId));
  EXPECT_CALL(*gpu_control_, GetExtraCommandBufferData())
      .WillRepeatedly(Return(0));

  // Generate sync token 1.
  EXPECT_CALL(*gpu_control_, IsFenceSyncRelease(kFenceSync1))
      .WillOnce(Return(true));
  EXPECT_CALL(*gpu_control_, IsFenceSyncFlushed(kFenceSync1))
      .WillOnce(Return(true));
  gl_->GenUnverifiedSyncTokenCHROMIUM(kFenceSync1, sync_token1.GetData());
  ASSERT_TRUE(sync_token1.HasData());
  ASSERT_FALSE(sync_token1.verified_flush());

  // Generate sync token 2.
  EXPECT_CALL(*gpu_control_, IsFenceSyncRelease(kFenceSync2))
      .WillOnce(Return(true));
  EXPECT_CALL(*gpu_control_, IsFenceSyncFlushed(kFenceSync2))
      .WillOnce(Return(true));
  gl_->GenUnverifiedSyncTokenCHROMIUM(kFenceSync2, sync_token2.GetData());
  ASSERT_TRUE(sync_token2.HasData());
  ASSERT_FALSE(sync_token2.verified_flush());

  // Ensure proper sequence of checking and validating.
  Sequence sequence;
  EXPECT_CALL(*gpu_control_, CanWaitUnverifiedSyncToken(Pointee(sync_token1)))
      .InSequence(sequence)
      .WillOnce(Return(true));
  EXPECT_CALL(*gpu_control_, CanWaitUnverifiedSyncToken(Pointee(sync_token2)))
      .InSequence(sequence)
      .WillOnce(Return(true));
  EXPECT_CALL(*gpu_control_, EnsureWorkVisible())
      .InSequence(sequence);
  gl_->VerifySyncTokensCHROMIUM(sync_token_datas, arraysize(sync_token_datas));
  EXPECT_TRUE(NoCommandsWritten());
  EXPECT_EQ(GL_NO_ERROR, CheckError());

  EXPECT_TRUE(sync_token1.verified_flush());
  EXPECT_TRUE(sync_token2.verified_flush());
}

TEST_F(GLES2ImplementationTest, WaitSyncTokenCHROMIUM) {
  const CommandBufferNamespace kNamespaceId = CommandBufferNamespace::GPU_IO;
  const CommandBufferId kCommandBufferId =
      CommandBufferId::FromUnsafeValue(234u);
  const GLuint64 kFenceSync = 456u;
  GLbyte sync_token[GL_SYNC_TOKEN_SIZE_CHROMIUM];

  EXPECT_CALL(*gpu_control_, IsFenceSyncRelease(kFenceSync))
      .WillOnce(Return(true));
  EXPECT_CALL(*gpu_control_, IsFenceSyncFlushReceived(kFenceSync))
      .WillOnce(Return(true));
  EXPECT_CALL(*gpu_control_, GetNamespaceID()).WillOnce(Return(kNamespaceId));
  EXPECT_CALL(*gpu_control_, GetCommandBufferID())
      .WillOnce(Return(kCommandBufferId));
  EXPECT_CALL(*gpu_control_, GetExtraCommandBufferData()).WillOnce(Return(0));
  gl_->GenSyncTokenCHROMIUM(kFenceSync, sync_token);

  struct Cmds {
    cmds::WaitSyncTokenCHROMIUM wait_sync_token;
  };
  Cmds expected;
  expected.wait_sync_token.Init(kNamespaceId, kCommandBufferId.GetUnsafeValue(),
                                kFenceSync);

  gl_->WaitSyncTokenCHROMIUM(sync_token);
  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
}

TEST_F(GLES2ImplementationTest, WaitSyncTokenCHROMIUMErrors) {
  ExpectedMemoryInfo result =
      GetExpectedResultMemory(sizeof(cmds::GetError::Result));
  EXPECT_CALL(*command_buffer(), OnFlush())
      .WillRepeatedly(SetMemory(result.ptr, GLuint(GL_NO_ERROR)))
      .RetiresOnSaturation();

  // Empty sync tokens should be produce no error and be a nop.
  ClearCommands();
  gl_->WaitSyncTokenCHROMIUM(nullptr);
  EXPECT_TRUE(NoCommandsWritten());
  EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError());

  // Invalid sync tokens should produce no error and be a nop.
  ClearCommands();
  gpu::SyncToken invalid_sync_token;
  gl_->WaitSyncTokenCHROMIUM(invalid_sync_token.GetConstData());
  EXPECT_TRUE(NoCommandsWritten());
  EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError());

  // Unverified sync token should produce INVALID_OPERATION.
  ClearCommands();
  gpu::SyncToken unverified_sync_token(CommandBufferNamespace::GPU_IO, 0,
                                       gpu::CommandBufferId(), 0);
  EXPECT_CALL(*gpu_control_, CanWaitUnverifiedSyncToken(_))
      .WillOnce(Return(false));
  gl_->WaitSyncTokenCHROMIUM(unverified_sync_token.GetConstData());
  EXPECT_TRUE(NoCommandsWritten());
  EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
}

TEST_F(GLES2ImplementationTest, IsEnabled) {
  // If we use a valid enum, its state is cached on client side, so no command
  // is actually generated, and this test will fail.
  // TODO(zmo): it seems we never need the command. Maybe remove it.
  GLenum kCap = 1;
  struct Cmds {
    cmds::IsEnabled cmd;
  };

  Cmds expected;
  ExpectedMemoryInfo result1 =
      GetExpectedResultMemory(sizeof(cmds::IsEnabled::Result));
  expected.cmd.Init(kCap, result1.id, result1.offset);

  EXPECT_CALL(*command_buffer(), OnFlush())
      .WillOnce(SetMemory(result1.ptr, uint32_t(GL_TRUE)))
      .RetiresOnSaturation();

  GLboolean result = gl_->IsEnabled(kCap);
  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
  EXPECT_TRUE(result);
}

TEST_F(GLES2ImplementationTest, ClientWaitSync) {
  const GLuint client_sync_id = 36;
  struct Cmds {
    cmds::ClientWaitSync cmd;
  };

  Cmds expected;
  ExpectedMemoryInfo result1 =
      GetExpectedResultMemory(sizeof(cmds::ClientWaitSync::Result));
  const GLuint64 kTimeout = 0xABCDEF0123456789;
  expected.cmd.Init(client_sync_id, GL_SYNC_FLUSH_COMMANDS_BIT,
                    kTimeout, result1.id, result1.offset);

  EXPECT_CALL(*command_buffer(), OnFlush())
      .WillOnce(SetMemory(result1.ptr, uint32_t(GL_CONDITION_SATISFIED)))
      .RetiresOnSaturation();

  GLenum result = gl_->ClientWaitSync(
      reinterpret_cast<GLsync>(client_sync_id), GL_SYNC_FLUSH_COMMANDS_BIT,
      kTimeout);
  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
  EXPECT_EQ(static_cast<GLenum>(GL_CONDITION_SATISFIED), result);
}

TEST_F(GLES2ImplementationTest, WaitSync) {
  const GLuint kClientSyncId = 36;
  struct Cmds {
    cmds::WaitSync cmd;
  };
  Cmds expected;
  const GLuint64 kTimeout = GL_TIMEOUT_IGNORED;
  expected.cmd.Init(kClientSyncId, 0, kTimeout);

  gl_->WaitSync(reinterpret_cast<GLsync>(kClientSyncId), 0, kTimeout);
  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
}

TEST_F(GLES2ImplementationTest, MapBufferRangeUnmapBufferWrite) {
  ExpectedMemoryInfo result =
      GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result));

  EXPECT_CALL(*command_buffer(), OnFlush())
      .WillOnce(SetMemory(result.ptr, uint32_t(1)))
      .RetiresOnSaturation();

  const GLuint kBufferId = 123;
  gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);

  void* mem = gl_->MapBufferRange(GL_ARRAY_BUFFER, 10, 64, GL_MAP_WRITE_BIT);
  EXPECT_TRUE(mem != nullptr);

  EXPECT_TRUE(gl_->UnmapBuffer(GL_ARRAY_BUFFER));
}

TEST_F(GLES2ImplementationTest, MapBufferRangeWriteWithInvalidateBit) {
  ExpectedMemoryInfo result =
      GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result));

  EXPECT_CALL(*command_buffer(), OnFlush())
      .WillOnce(SetMemory(result.ptr, uint32_t(1)))
      .RetiresOnSaturation();

  const GLuint kBufferId = 123;
  gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);

  GLsizeiptr kSize = 64;
  void* mem = gl_->MapBufferRange(
      GL_ARRAY_BUFFER, 10, kSize,
      GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT);
  EXPECT_TRUE(mem != nullptr);
  std::vector<int8_t> zero(kSize);
  memset(&zero[0], 0, kSize);
  EXPECT_EQ(0, memcmp(mem, &zero[0], kSize));
}

TEST_F(GLES2ImplementationTest, MapBufferRangeWriteWithGLError) {
  ExpectedMemoryInfo result =
      GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result));

  // Return a result of 0 to indicate an GL error.
  EXPECT_CALL(*command_buffer(), OnFlush())
      .WillOnce(SetMemory(result.ptr, uint32_t(0)))
      .RetiresOnSaturation();

  const GLuint kBufferId = 123;
  gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);

  void* mem = gl_->MapBufferRange(GL_ARRAY_BUFFER, 10, 64, GL_MAP_WRITE_BIT);
  EXPECT_TRUE(mem == nullptr);
}

TEST_F(GLES2ImplementationTest, MapBufferRangeUnmapBufferRead) {
  ExpectedMemoryInfo result =
      GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result));

  EXPECT_CALL(*command_buffer(), OnFlush())
      .WillOnce(SetMemory(result.ptr, uint32_t(1)))
      .RetiresOnSaturation();

  const GLuint kBufferId = 123;
  gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);

  void* mem = gl_->MapBufferRange(GL_ARRAY_BUFFER, 10, 64, GL_MAP_READ_BIT);
  EXPECT_TRUE(mem != nullptr);

  EXPECT_TRUE(gl_->UnmapBuffer(GL_ARRAY_BUFFER));
}

TEST_F(GLES2ImplementationTest, MapBufferRangeReadWithGLError) {
  ExpectedMemoryInfo result =
      GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result));

  // Return a result of 0 to indicate an GL error.
  EXPECT_CALL(*command_buffer(), OnFlush())
      .WillOnce(SetMemory(result.ptr, uint32_t(0)))
      .RetiresOnSaturation();

  const GLuint kBufferId = 123;
  gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);

  void* mem = gl_->MapBufferRange(GL_ARRAY_BUFFER, 10, 64, GL_MAP_READ_BIT);
  EXPECT_TRUE(mem == nullptr);
}

TEST_F(GLES2ImplementationTest, UnmapBufferFails) {
  // No bound buffer.
  EXPECT_FALSE(gl_->UnmapBuffer(GL_ARRAY_BUFFER));
  EXPECT_EQ(GL_INVALID_OPERATION, CheckError());

  const GLuint kBufferId = 123;
  gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);

  // Buffer is unmapped.
  EXPECT_FALSE(gl_->UnmapBuffer(GL_ARRAY_BUFFER));
  EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
}

TEST_F(GLES2ImplementationTest, BufferDataUnmapsDataStore) {
  ExpectedMemoryInfo result =
      GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result));

  EXPECT_CALL(*command_buffer(), OnFlush())
      .WillOnce(SetMemory(result.ptr, uint32_t(1)))
      .RetiresOnSaturation();

  const GLuint kBufferId = 123;
  gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);

  void* mem = gl_->MapBufferRange(GL_ARRAY_BUFFER, 10, 64, GL_MAP_WRITE_BIT);
  EXPECT_TRUE(mem != nullptr);

  std::vector<uint8_t> data(16);
  // BufferData unmaps the data store.
  gl_->BufferData(GL_ARRAY_BUFFER, 16, &data[0], GL_STREAM_DRAW);

  EXPECT_FALSE(gl_->UnmapBuffer(GL_ARRAY_BUFFER));
  EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
}

TEST_F(GLES2ImplementationTest, DeleteBuffersUnmapsDataStore) {
  ExpectedMemoryInfo result =
      GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result));

  EXPECT_CALL(*command_buffer(), OnFlush())
      .WillOnce(SetMemory(result.ptr, uint32_t(1)))
      .RetiresOnSaturation();

  const GLuint kBufferId = 123;
  gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);

  void* mem = gl_->MapBufferRange(GL_ARRAY_BUFFER, 10, 64, GL_MAP_WRITE_BIT);
  EXPECT_TRUE(mem != nullptr);

  std::vector<uint8_t> data(16);
  // DeleteBuffers unmaps the data store.
  gl_->DeleteBuffers(1, &kBufferId);

  EXPECT_FALSE(gl_->UnmapBuffer(GL_ARRAY_BUFFER));
  EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
}

TEST_F(GLES2ImplementationTest, GetInternalformativ) {
  const GLint kNumSampleCounts = 8;
  struct Cmds {
    cmds::GetInternalformativ cmd;
  };
  typedef cmds::GetInternalformativ::Result::Type ResultType;
  ResultType result = 0;
  Cmds expected;
  ExpectedMemoryInfo result1 =
      GetExpectedResultMemory(sizeof(uint32_t) + sizeof(ResultType));
  expected.cmd.Init(123, GL_RGBA8, GL_NUM_SAMPLE_COUNTS,
                    result1.id, result1.offset);
  EXPECT_CALL(*command_buffer(), OnFlush())
      .WillOnce(SetMemory(result1.ptr,
                          SizedResultHelper<ResultType>(kNumSampleCounts)))
      .RetiresOnSaturation();
  gl_->GetInternalformativ(123, GL_RGBA8, GL_NUM_SAMPLE_COUNTS, 1, &result);
  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
  EXPECT_EQ(static_cast<ResultType>(kNumSampleCounts), result);
}

static void CountCallback(int* count) {
  (*count)++;
}

TEST_F(GLES2ImplementationTest, SignalSyncToken) {
  EXPECT_CALL(*gpu_control_, GenerateFenceSyncRelease()).WillOnce(Return(1));
  const uint64_t fence_sync = gl_->InsertFenceSyncCHROMIUM();
  gl_->ShallowFlushCHROMIUM();

  EXPECT_CALL(*gpu_control_, IsFenceSyncRelease(fence_sync))
      .WillOnce(Return(true));
  EXPECT_CALL(*gpu_control_, IsFenceSyncFlushReceived(fence_sync))
      .WillOnce(Return(true));
  EXPECT_CALL(*gpu_control_, GetNamespaceID()).WillOnce(Return(GPU_IO));
  EXPECT_CALL(*gpu_control_, GetExtraCommandBufferData()).WillOnce(Return(0));
  EXPECT_CALL(*gpu_control_, GetCommandBufferID())
      .WillOnce(Return(CommandBufferId::FromUnsafeValue(1)));
  gpu::SyncToken sync_token;
  gl_->GenSyncTokenCHROMIUM(fence_sync, sync_token.GetData());

  int signaled_count = 0;

  // Request a signal sync token, which gives a callback to the GpuControl to
  // run when the sync token is reached.
  base::Closure signal_closure;
  EXPECT_CALL(*gpu_control_, SignalSyncToken(_, _))
      .WillOnce(SaveArg<1>(&signal_closure));
  gl_->SignalSyncToken(sync_token, base::Bind(&CountCallback, &signaled_count));
  EXPECT_EQ(0, signaled_count);

  // When GpuControl runs the callback, the original callback we gave to
  // GLES2Implementation is run.
  signal_closure.Run();
  EXPECT_EQ(1, signaled_count);
}

TEST_F(GLES2ImplementationTest, SignalSyncTokenAfterContextLoss) {
  EXPECT_CALL(*gpu_control_, GenerateFenceSyncRelease()).WillOnce(Return(1));
  const uint64_t fence_sync = gl_->InsertFenceSyncCHROMIUM();
  gl_->ShallowFlushCHROMIUM();

  EXPECT_CALL(*gpu_control_, IsFenceSyncRelease(fence_sync))
      .WillOnce(Return(true));
  EXPECT_CALL(*gpu_control_, IsFenceSyncFlushReceived(fence_sync))
      .WillOnce(Return(true));
  EXPECT_CALL(*gpu_control_, GetNamespaceID()).WillOnce(Return(GPU_IO));
  EXPECT_CALL(*gpu_control_, GetExtraCommandBufferData()).WillOnce(Return(0));
  EXPECT_CALL(*gpu_control_, GetCommandBufferID())
      .WillOnce(Return(CommandBufferId::FromUnsafeValue(1)));
  gpu::SyncToken sync_token;
  gl_->GenSyncTokenCHROMIUM(fence_sync, sync_token.GetData());

  int signaled_count = 0;

  // Request a signal sync token, which gives a callback to the GpuControl to
  // run when the sync token is reached.
  base::Closure signal_closure;
  EXPECT_CALL(*gpu_control_, SignalSyncToken(_, _))
      .WillOnce(SaveArg<1>(&signal_closure));
  gl_->SignalSyncToken(sync_token, base::Bind(&CountCallback, &signaled_count));
  EXPECT_EQ(0, signaled_count);

  // Inform the GLES2Implementation that the context is lost.
  GpuControlClient* gl_as_client = gl_;
  gl_as_client->OnGpuControlLostContext();

  // When GpuControl runs the callback, the original callback we gave to
  // GLES2Implementation is *not* run, since the context is lost and we
  // have already run the lost context callback.
  signal_closure.Run();
  EXPECT_EQ(0, signaled_count);
}

TEST_F(GLES2ImplementationTest, ReportLoss) {
  GpuControlClient* gl_as_client = gl_;
  int lost_count = 0;
  gl_->SetLostContextCallback(base::Bind(&CountCallback, &lost_count));
  EXPECT_EQ(0, lost_count);

  EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetGraphicsResetStatusKHR());
  gl_as_client->OnGpuControlLostContext();
  EXPECT_NE(static_cast<GLenum>(GL_NO_ERROR), gl_->GetGraphicsResetStatusKHR());
  // The lost context callback should be run when GLES2Implementation is
  // notified of the loss.
  EXPECT_EQ(1, lost_count);
}

TEST_F(GLES2ImplementationTest, ReportLossReentrant) {
  GpuControlClient* gl_as_client = gl_;
  int lost_count = 0;
  gl_->SetLostContextCallback(base::Bind(&CountCallback, &lost_count));
  EXPECT_EQ(0, lost_count);

  EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetGraphicsResetStatusKHR());
  gl_as_client->OnGpuControlLostContextMaybeReentrant();
  EXPECT_NE(static_cast<GLenum>(GL_NO_ERROR), gl_->GetGraphicsResetStatusKHR());
  // The lost context callback should not be run yet to avoid calling back into
  // clients re-entrantly, and having them re-enter GLES2Implementation.
  EXPECT_EQ(0, lost_count);
}

TEST_F(GLES2ImplementationManualInitTest, LoseContextOnOOM) {
  ContextInitOptions init_options;
  init_options.lose_context_when_out_of_memory = true;
  ASSERT_TRUE(Initialize(init_options));

  struct Cmds {
    cmds::LoseContextCHROMIUM cmd;
  };

  GLsizei max = std::numeric_limits<GLsizei>::max();
  EXPECT_CALL(*gpu_control_, CreateGpuMemoryBufferImage(max, max, _, _))
      .WillOnce(Return(-1));
  gl_->CreateGpuMemoryBufferImageCHROMIUM(max, max, GL_RGBA,
                                          GL_READ_WRITE_CHROMIUM);
  // The context should be lost.
  Cmds expected;
  expected.cmd.Init(GL_GUILTY_CONTEXT_RESET_ARB, GL_UNKNOWN_CONTEXT_RESET_ARB);
  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
}

TEST_F(GLES2ImplementationManualInitTest, NoLoseContextOnOOM) {
  ContextInitOptions init_options;
  ASSERT_TRUE(Initialize(init_options));

  struct Cmds {
    cmds::LoseContextCHROMIUM cmd;
  };

  GLsizei max = std::numeric_limits<GLsizei>::max();
  EXPECT_CALL(*gpu_control_, CreateGpuMemoryBufferImage(max, max, _, _))
      .WillOnce(Return(-1));
  gl_->CreateGpuMemoryBufferImageCHROMIUM(max, max, GL_RGBA,
                                          GL_READ_WRITE_CHROMIUM);
  // The context should not be lost.
  EXPECT_TRUE(NoCommandsWritten());
}

TEST_F(GLES2ImplementationManualInitTest, FailInitOnBGRMismatch1) {
  ContextInitOptions init_options;
  init_options.bind_generates_resource_client = false;
  init_options.bind_generates_resource_service = true;
  EXPECT_FALSE(Initialize(init_options));
}

TEST_F(GLES2ImplementationManualInitTest, FailInitOnBGRMismatch2) {
  ContextInitOptions init_options;
  init_options.bind_generates_resource_client = true;
  init_options.bind_generates_resource_service = false;
  EXPECT_FALSE(Initialize(init_options));
}

TEST_F(GLES2ImplementationManualInitTest, FailInitOnTransferBufferFail) {
  ContextInitOptions init_options;
  init_options.transfer_buffer_initialize_fail = true;
  EXPECT_FALSE(Initialize(init_options));
}

#include "base/macros.h"
#include "gpu/command_buffer/client/gles2_implementation_unittest_autogen.h"

}  // namespace gles2
}  // namespace gpu
