Home | History | Annotate | Download | only in client
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // Tests for GLES2Implementation.
      6 
      7 #include "gpu/command_buffer/client/gles2_implementation.h"
      8 
      9 #include <limits>
     10 
     11 #include <GLES2/gl2ext.h>
     12 #include <GLES2/gl2extchromium.h>
     13 #include "base/compiler_specific.h"
     14 #include "gpu/command_buffer/client/client_test_helper.h"
     15 #include "gpu/command_buffer/client/program_info_manager.h"
     16 #include "gpu/command_buffer/client/transfer_buffer.h"
     17 #include "gpu/command_buffer/common/command_buffer.h"
     18 #include "testing/gtest/include/gtest/gtest.h"
     19 #include "testing/gmock/include/gmock/gmock.h"
     20 
     21 #if !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
     22 #define GLES2_SUPPORT_CLIENT_SIDE_ARRAYS
     23 #endif
     24 
     25 using testing::_;
     26 using testing::AtLeast;
     27 using testing::AnyNumber;
     28 using testing::DoAll;
     29 using testing::InSequence;
     30 using testing::Invoke;
     31 using testing::Mock;
     32 using testing::Sequence;
     33 using testing::StrictMock;
     34 using testing::Truly;
     35 using testing::Return;
     36 
     37 namespace gpu {
     38 namespace gles2 {
     39 
     40 ACTION_P2(SetMemory, dst, obj) {
     41   memcpy(dst, &obj, sizeof(obj));
     42 }
     43 
     44 ACTION_P3(SetMemoryFromArray, dst, array, size) {
     45   memcpy(dst, array, size);
     46 }
     47 
     48 // Used to help set the transfer buffer result to SizedResult of a single value.
     49 template <typename T>
     50 class SizedResultHelper {
     51  public:
     52   explicit SizedResultHelper(T result)
     53       : size_(sizeof(result)),
     54         result_(result) {
     55   }
     56 
     57  private:
     58   uint32 size_;
     59   T result_;
     60 };
     61 
     62 // Struct to make it easy to pass a vec4 worth of floats.
     63 struct FourFloats {
     64   FourFloats(float _x, float _y, float _z, float _w)
     65       : x(_x),
     66         y(_y),
     67         z(_z),
     68         w(_w) {
     69   }
     70 
     71   float x;
     72   float y;
     73   float z;
     74   float w;
     75 };
     76 
     77 #pragma pack(push, 1)
     78 // Struct that holds 7 characters.
     79 struct Str7 {
     80   char str[7];
     81 };
     82 #pragma pack(pop)
     83 
     84 class MockTransferBuffer : public TransferBufferInterface {
     85  public:
     86   struct ExpectedMemoryInfo {
     87     uint32 offset;
     88     int32 id;
     89     uint8* ptr;
     90   };
     91 
     92   MockTransferBuffer(
     93       CommandBuffer* command_buffer,
     94       unsigned int size,
     95       unsigned int result_size,
     96       unsigned int alignment)
     97       : command_buffer_(command_buffer),
     98         size_(size),
     99         result_size_(result_size),
    100         alignment_(alignment),
    101         actual_buffer_index_(0),
    102         expected_buffer_index_(0),
    103         last_alloc_(NULL),
    104         expected_offset_(result_size),
    105         actual_offset_(result_size) {
    106     // We have to allocate the buffers here because
    107     // we need to know their address before GLES2Implementation::Initialize
    108     // is called.
    109     for (int ii = 0; ii < kNumBuffers; ++ii) {
    110       buffers_[ii] = command_buffer_->CreateTransferBuffer(
    111           size_ + ii * alignment_,
    112           &buffer_ids_[ii]);
    113       EXPECT_NE(-1, buffer_ids_[ii]);
    114     }
    115   }
    116 
    117   virtual ~MockTransferBuffer() { }
    118 
    119   virtual bool Initialize(
    120       unsigned int starting_buffer_size,
    121       unsigned int result_size,
    122       unsigned int /* min_buffer_size */,
    123       unsigned int /* max_buffer_size */,
    124       unsigned int alignment,
    125       unsigned int size_to_flush) OVERRIDE;
    126   virtual int GetShmId() OVERRIDE;
    127   virtual void* GetResultBuffer() OVERRIDE;
    128   virtual int GetResultOffset() OVERRIDE;
    129   virtual void Free() OVERRIDE;
    130   virtual bool HaveBuffer() const OVERRIDE;
    131   virtual void* AllocUpTo(
    132       unsigned int size, unsigned int* size_allocated) OVERRIDE;
    133   virtual void* Alloc(unsigned int size) OVERRIDE;
    134   virtual RingBuffer::Offset GetOffset(void* pointer) const OVERRIDE;
    135   virtual void FreePendingToken(void* p, unsigned int /* token */) OVERRIDE;
    136 
    137   size_t MaxTransferBufferSize() {
    138     return size_ - result_size_;
    139   }
    140 
    141   unsigned int RoundToAlignment(unsigned int size) {
    142     return (size + alignment_ - 1) & ~(alignment_ - 1);
    143   }
    144 
    145   bool InSync() {
    146     return expected_buffer_index_ == actual_buffer_index_ &&
    147            expected_offset_ == actual_offset_;
    148   }
    149 
    150   ExpectedMemoryInfo GetExpectedMemory(size_t size) {
    151     ExpectedMemoryInfo mem;
    152     mem.offset = AllocateExpectedTransferBuffer(size);
    153     mem.id = GetExpectedTransferBufferId();
    154     mem.ptr = static_cast<uint8*>(
    155        GetExpectedTransferAddressFromOffset(mem.offset, size));
    156     return mem;
    157   }
    158 
    159   ExpectedMemoryInfo GetExpectedResultMemory(size_t size) {
    160     ExpectedMemoryInfo mem;
    161     mem.offset = GetExpectedResultBufferOffset();
    162     mem.id = GetExpectedResultBufferId();
    163     mem.ptr = static_cast<uint8*>(
    164         GetExpectedTransferAddressFromOffset(mem.offset, size));
    165     return mem;
    166   }
    167 
    168  private:
    169   static const int kNumBuffers = 2;
    170 
    171   uint8* actual_buffer() const {
    172     return static_cast<uint8*>(buffers_[actual_buffer_index_]->memory());
    173   }
    174 
    175   uint8* expected_buffer() const {
    176     return static_cast<uint8*>(buffers_[expected_buffer_index_]->memory());
    177   }
    178 
    179   uint32 AllocateExpectedTransferBuffer(size_t size) {
    180     EXPECT_LE(size, MaxTransferBufferSize());
    181 
    182     // Toggle which buffer we get each time to simulate the buffer being
    183     // reallocated.
    184     expected_buffer_index_ = (expected_buffer_index_ + 1) % kNumBuffers;
    185 
    186     if (expected_offset_ + size > size_) {
    187       expected_offset_ = result_size_;
    188     }
    189     uint32 offset = expected_offset_;
    190     expected_offset_ += RoundToAlignment(size);
    191 
    192     // Make sure each buffer has a different offset.
    193     return offset + expected_buffer_index_ * alignment_;
    194   }
    195 
    196   void* GetExpectedTransferAddressFromOffset(uint32 offset, size_t size) {
    197     EXPECT_GE(offset, expected_buffer_index_ * alignment_);
    198     EXPECT_LE(offset + size, size_ + expected_buffer_index_ * alignment_);
    199     return expected_buffer() + offset;
    200   }
    201 
    202   int GetExpectedResultBufferId() {
    203     return buffer_ids_[expected_buffer_index_];
    204   }
    205 
    206   uint32 GetExpectedResultBufferOffset() {
    207     return expected_buffer_index_ * alignment_;
    208   }
    209 
    210   int GetExpectedTransferBufferId() {
    211     return buffer_ids_[expected_buffer_index_];
    212   }
    213 
    214   CommandBuffer* command_buffer_;
    215   size_t size_;
    216   size_t result_size_;
    217   uint32 alignment_;
    218   int buffer_ids_[kNumBuffers];
    219   scoped_refptr<Buffer> buffers_[kNumBuffers];
    220   int actual_buffer_index_;
    221   int expected_buffer_index_;
    222   void* last_alloc_;
    223   uint32 expected_offset_;
    224   uint32 actual_offset_;
    225 
    226   DISALLOW_COPY_AND_ASSIGN(MockTransferBuffer);
    227 };
    228 
    229 bool MockTransferBuffer::Initialize(
    230     unsigned int starting_buffer_size,
    231     unsigned int result_size,
    232     unsigned int /* min_buffer_size */,
    233     unsigned int /* max_buffer_size */,
    234     unsigned int alignment,
    235     unsigned int /* size_to_flush */) {
    236   // Just check they match.
    237   return size_ == starting_buffer_size &&
    238          result_size_ == result_size &&
    239          alignment_ == alignment;
    240 };
    241 
    242 int MockTransferBuffer::GetShmId() {
    243   return buffer_ids_[actual_buffer_index_];
    244 }
    245 
    246 void* MockTransferBuffer::GetResultBuffer() {
    247   return actual_buffer() + actual_buffer_index_ * alignment_;
    248 }
    249 
    250 int MockTransferBuffer::GetResultOffset() {
    251   return actual_buffer_index_ * alignment_;
    252 }
    253 
    254 void MockTransferBuffer::Free() {
    255   NOTREACHED();
    256 }
    257 
    258 bool MockTransferBuffer::HaveBuffer() const {
    259   return true;
    260 }
    261 
    262 void* MockTransferBuffer::AllocUpTo(
    263     unsigned int size, unsigned int* size_allocated) {
    264   EXPECT_TRUE(size_allocated != NULL);
    265   EXPECT_TRUE(last_alloc_ == NULL);
    266 
    267   // Toggle which buffer we get each time to simulate the buffer being
    268   // reallocated.
    269   actual_buffer_index_ = (actual_buffer_index_ + 1) % kNumBuffers;
    270 
    271   size = std::min(static_cast<size_t>(size), MaxTransferBufferSize());
    272   if (actual_offset_ + size > size_) {
    273     actual_offset_ = result_size_;
    274   }
    275   uint32 offset = actual_offset_;
    276   actual_offset_ += RoundToAlignment(size);
    277   *size_allocated = size;
    278 
    279   // Make sure each buffer has a different offset.
    280   last_alloc_ = actual_buffer() + offset + actual_buffer_index_ * alignment_;
    281   return last_alloc_;
    282 }
    283 
    284 void* MockTransferBuffer::Alloc(unsigned int size) {
    285   EXPECT_LE(size, MaxTransferBufferSize());
    286   unsigned int temp = 0;
    287   void* p = AllocUpTo(size, &temp);
    288   EXPECT_EQ(temp, size);
    289   return p;
    290 }
    291 
    292 RingBuffer::Offset MockTransferBuffer::GetOffset(void* pointer) const {
    293   // Make sure each buffer has a different offset.
    294   return static_cast<uint8*>(pointer) - actual_buffer();
    295 }
    296 
    297 void MockTransferBuffer::FreePendingToken(void* p, unsigned int /* token */) {
    298   EXPECT_EQ(last_alloc_, p);
    299   last_alloc_ = NULL;
    300 }
    301 
    302 // API wrapper for Buffers.
    303 class GenBuffersAPI {
    304  public:
    305   static void Gen(GLES2Implementation* gl_impl, GLsizei n, GLuint* ids) {
    306     gl_impl->GenBuffers(n, ids);
    307   }
    308 
    309   static void Delete(GLES2Implementation* gl_impl,
    310                      GLsizei n,
    311                      const GLuint* ids) {
    312     gl_impl->DeleteBuffers(n, ids);
    313   }
    314 };
    315 
    316 // API wrapper for Framebuffers.
    317 class GenFramebuffersAPI {
    318  public:
    319   static void Gen(GLES2Implementation* gl_impl, GLsizei n, GLuint* ids) {
    320     gl_impl->GenFramebuffers(n, ids);
    321   }
    322 
    323   static void Delete(GLES2Implementation* gl_impl,
    324                      GLsizei n,
    325                      const GLuint* ids) {
    326     gl_impl->DeleteFramebuffers(n, ids);
    327   }
    328 };
    329 
    330 // API wrapper for Renderbuffers.
    331 class GenRenderbuffersAPI {
    332  public:
    333   static void Gen(GLES2Implementation* gl_impl, GLsizei n, GLuint* ids) {
    334     gl_impl->GenRenderbuffers(n, ids);
    335   }
    336 
    337   static void Delete(GLES2Implementation* gl_impl,
    338                      GLsizei n,
    339                      const GLuint* ids) {
    340     gl_impl->DeleteRenderbuffers(n, ids);
    341   }
    342 };
    343 
    344 // API wrapper for Textures.
    345 class GenTexturesAPI {
    346  public:
    347   static void Gen(GLES2Implementation* gl_impl, GLsizei n, GLuint* ids) {
    348     gl_impl->GenTextures(n, ids);
    349   }
    350 
    351   static void Delete(GLES2Implementation* gl_impl,
    352                      GLsizei n,
    353                      const GLuint* ids) {
    354     gl_impl->DeleteTextures(n, ids);
    355   }
    356 };
    357 
    358 class GLES2ImplementationTest : public testing::Test {
    359  protected:
    360   static const int kNumTestContexts = 2;
    361   static const uint8 kInitialValue = 0xBD;
    362   static const int32 kNumCommandEntries = 500;
    363   static const int32 kCommandBufferSizeBytes =
    364       kNumCommandEntries * sizeof(CommandBufferEntry);
    365   static const size_t kTransferBufferSize = 512;
    366 
    367   static const GLint kMaxCombinedTextureImageUnits = 8;
    368   static const GLint kMaxCubeMapTextureSize = 64;
    369   static const GLint kMaxFragmentUniformVectors = 16;
    370   static const GLint kMaxRenderbufferSize = 64;
    371   static const GLint kMaxTextureImageUnits = 8;
    372   static const GLint kMaxTextureSize = 128;
    373   static const GLint kMaxVaryingVectors = 8;
    374   static const GLint kMaxVertexAttribs = 8;
    375   static const GLint kMaxVertexTextureImageUnits = 0;
    376   static const GLint kMaxVertexUniformVectors = 128;
    377   static const GLint kNumCompressedTextureFormats = 0;
    378   static const GLint kNumShaderBinaryFormats = 0;
    379   static const GLuint kStartId = 1024;
    380   static const GLuint kBuffersStartId =
    381       GLES2Implementation::kClientSideArrayId + 2 * kNumTestContexts;
    382   static const GLuint kFramebuffersStartId = 1;
    383   static const GLuint kProgramsAndShadersStartId = 1;
    384   static const GLuint kRenderbuffersStartId = 1;
    385   static const GLuint kTexturesStartId = 1;
    386   static const GLuint kQueriesStartId = 1;
    387   static const GLuint kVertexArraysStartId = 1;
    388 
    389   typedef MockTransferBuffer::ExpectedMemoryInfo ExpectedMemoryInfo;
    390 
    391   class TestContext {
    392    public:
    393     TestContext() : commands_(NULL), token_(0) {}
    394 
    395     bool Initialize(ShareGroup* share_group,
    396                     bool bind_generates_resource_client,
    397                     bool bind_generates_resource_service,
    398                     bool lose_context_when_out_of_memory) {
    399       command_buffer_.reset(new StrictMock<MockClientCommandBuffer>());
    400       if (!command_buffer_->Initialize())
    401         return false;
    402 
    403       transfer_buffer_.reset(
    404           new MockTransferBuffer(command_buffer_.get(),
    405                                  kTransferBufferSize,
    406                                  GLES2Implementation::kStartingOffset,
    407                                  GLES2Implementation::kAlignment));
    408 
    409       helper_.reset(new GLES2CmdHelper(command_buffer()));
    410       helper_->Initialize(kCommandBufferSizeBytes);
    411 
    412       gpu_control_.reset(new StrictMock<MockClientGpuControl>());
    413       EXPECT_CALL(*gpu_control_, GetCapabilities())
    414           .WillOnce(testing::Return(Capabilities()));
    415 
    416       GLES2Implementation::GLStaticState state;
    417       GLES2Implementation::GLStaticState::IntState& int_state = state.int_state;
    418       int_state.max_combined_texture_image_units =
    419           kMaxCombinedTextureImageUnits;
    420       int_state.max_cube_map_texture_size = kMaxCubeMapTextureSize;
    421       int_state.max_fragment_uniform_vectors = kMaxFragmentUniformVectors;
    422       int_state.max_renderbuffer_size = kMaxRenderbufferSize;
    423       int_state.max_texture_image_units = kMaxTextureImageUnits;
    424       int_state.max_texture_size = kMaxTextureSize;
    425       int_state.max_varying_vectors = kMaxVaryingVectors;
    426       int_state.max_vertex_attribs = kMaxVertexAttribs;
    427       int_state.max_vertex_texture_image_units = kMaxVertexTextureImageUnits;
    428       int_state.max_vertex_uniform_vectors = kMaxVertexUniformVectors;
    429       int_state.num_compressed_texture_formats = kNumCompressedTextureFormats;
    430       int_state.num_shader_binary_formats = kNumShaderBinaryFormats;
    431       int_state.bind_generates_resource_chromium =
    432           bind_generates_resource_service ? 1 : 0;
    433 
    434       // This just happens to work for now because IntState has 1 GLint per
    435       // state.
    436       // If IntState gets more complicated this code will need to get more
    437       // complicated.
    438       ExpectedMemoryInfo mem1 = transfer_buffer_->GetExpectedMemory(
    439           sizeof(GLES2Implementation::GLStaticState::IntState) * 2 +
    440           sizeof(cmds::GetShaderPrecisionFormat::Result) * 12);
    441 
    442       {
    443         InSequence sequence;
    444 
    445         EXPECT_CALL(*command_buffer_, OnFlush())
    446             .WillOnce(SetMemory(mem1.ptr + sizeof(int_state), int_state))
    447             .RetiresOnSaturation();
    448         GetNextToken();  // eat the token that starting up will use.
    449 
    450         gl_.reset(new GLES2Implementation(helper_.get(),
    451                                           share_group,
    452                                           transfer_buffer_.get(),
    453                                           bind_generates_resource_client,
    454                                           lose_context_when_out_of_memory,
    455                                           gpu_control_.get()));
    456 
    457         if (!gl_->Initialize(kTransferBufferSize,
    458                              kTransferBufferSize,
    459                              kTransferBufferSize,
    460                              GLES2Implementation::kNoLimit))
    461           return false;
    462       }
    463 
    464       EXPECT_CALL(*command_buffer_, OnFlush()).Times(1).RetiresOnSaturation();
    465       helper_->CommandBufferHelper::Finish();
    466       ::testing::Mock::VerifyAndClearExpectations(gl_.get());
    467 
    468       scoped_refptr<Buffer> ring_buffer = helper_->get_ring_buffer();
    469       commands_ = static_cast<CommandBufferEntry*>(ring_buffer->memory()) +
    470                   command_buffer()->GetLastState().put_offset;
    471       ClearCommands();
    472       EXPECT_TRUE(transfer_buffer_->InSync());
    473 
    474       ::testing::Mock::VerifyAndClearExpectations(command_buffer());
    475       return true;
    476     }
    477 
    478     void TearDown() {
    479       Mock::VerifyAndClear(gl_.get());
    480       EXPECT_CALL(*command_buffer(), OnFlush()).Times(AnyNumber());
    481       // For command buffer.
    482       EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
    483           .Times(AtLeast(1));
    484       gl_.reset();
    485     }
    486 
    487     MockClientCommandBuffer* command_buffer() const {
    488       return command_buffer_.get();
    489     }
    490 
    491     int GetNextToken() { return ++token_; }
    492 
    493     void ClearCommands() {
    494       scoped_refptr<Buffer> ring_buffer = helper_->get_ring_buffer();
    495       memset(ring_buffer->memory(), kInitialValue, ring_buffer->size());
    496     }
    497 
    498     scoped_ptr<MockClientCommandBuffer> command_buffer_;
    499     scoped_ptr<MockClientGpuControl> gpu_control_;
    500     scoped_ptr<GLES2CmdHelper> helper_;
    501     scoped_ptr<MockTransferBuffer> transfer_buffer_;
    502     scoped_ptr<GLES2Implementation> gl_;
    503     CommandBufferEntry* commands_;
    504     int token_;
    505   };
    506 
    507   GLES2ImplementationTest() : commands_(NULL) {}
    508 
    509   virtual void SetUp() OVERRIDE;
    510   virtual void TearDown() OVERRIDE;
    511 
    512   bool NoCommandsWritten() {
    513     scoped_refptr<Buffer> ring_buffer = helper_->get_ring_buffer();
    514     const uint8* cmds = reinterpret_cast<const uint8*>(ring_buffer->memory());
    515     const uint8* end = cmds + ring_buffer->size();
    516     for (; cmds < end; ++cmds) {
    517       if (*cmds != kInitialValue) {
    518         return false;
    519       }
    520     }
    521     return true;
    522   }
    523 
    524   QueryTracker::Query* GetQuery(GLuint id) {
    525     return gl_->query_tracker_->GetQuery(id);
    526   }
    527 
    528   struct ContextInitOptions {
    529     ContextInitOptions()
    530         : bind_generates_resource_client(true),
    531           bind_generates_resource_service(true),
    532           lose_context_when_out_of_memory(false) {}
    533 
    534     bool bind_generates_resource_client;
    535     bool bind_generates_resource_service;
    536     bool lose_context_when_out_of_memory;
    537   };
    538 
    539   bool Initialize(const ContextInitOptions& init_options) {
    540     bool success = true;
    541     share_group_ = new ShareGroup(init_options.bind_generates_resource_client);
    542 
    543     for (int i = 0; i < kNumTestContexts; i++) {
    544       if (!test_contexts_[i].Initialize(
    545               share_group_.get(),
    546               init_options.bind_generates_resource_client,
    547               init_options.bind_generates_resource_service,
    548               init_options.lose_context_when_out_of_memory))
    549         success = false;
    550     }
    551 
    552     // Default to test context 0.
    553     gpu_control_ = test_contexts_[0].gpu_control_.get();
    554     helper_ = test_contexts_[0].helper_.get();
    555     transfer_buffer_ = test_contexts_[0].transfer_buffer_.get();
    556     gl_ = test_contexts_[0].gl_.get();
    557     commands_ = test_contexts_[0].commands_;
    558     return success;
    559   }
    560 
    561   MockClientCommandBuffer* command_buffer() const {
    562     return test_contexts_[0].command_buffer_.get();
    563   }
    564 
    565   int GetNextToken() { return test_contexts_[0].GetNextToken(); }
    566 
    567   const void* GetPut() {
    568     return helper_->GetSpace(0);
    569   }
    570 
    571   void ClearCommands() {
    572     scoped_refptr<Buffer> ring_buffer = helper_->get_ring_buffer();
    573     memset(ring_buffer->memory(), kInitialValue, ring_buffer->size());
    574   }
    575 
    576   size_t MaxTransferBufferSize() {
    577     return transfer_buffer_->MaxTransferBufferSize();
    578   }
    579 
    580   ExpectedMemoryInfo GetExpectedMemory(size_t size) {
    581     return transfer_buffer_->GetExpectedMemory(size);
    582   }
    583 
    584   ExpectedMemoryInfo GetExpectedResultMemory(size_t size) {
    585     return transfer_buffer_->GetExpectedResultMemory(size);
    586   }
    587 
    588   // Sets the ProgramInfoManager. The manager will be owned
    589   // by the ShareGroup.
    590   void SetProgramInfoManager(ProgramInfoManager* manager) {
    591     gl_->share_group()->set_program_info_manager(manager);
    592   }
    593 
    594   int CheckError() {
    595     ExpectedMemoryInfo result =
    596         GetExpectedResultMemory(sizeof(cmds::GetError::Result));
    597     EXPECT_CALL(*command_buffer(), OnFlush())
    598         .WillOnce(SetMemory(result.ptr, GLuint(GL_NO_ERROR)))
    599         .RetiresOnSaturation();
    600     return gl_->GetError();
    601   }
    602 
    603   const std::string& GetLastError() {
    604     return gl_->GetLastError();
    605   }
    606 
    607   bool GetBucketContents(uint32 bucket_id, std::vector<int8>* data) {
    608     return gl_->GetBucketContents(bucket_id, data);
    609   }
    610 
    611   TestContext test_contexts_[kNumTestContexts];
    612 
    613   scoped_refptr<ShareGroup> share_group_;
    614   MockClientGpuControl* gpu_control_;
    615   GLES2CmdHelper* helper_;
    616   MockTransferBuffer* transfer_buffer_;
    617   GLES2Implementation* gl_;
    618   CommandBufferEntry* commands_;
    619 };
    620 
    621 void GLES2ImplementationTest::SetUp() {
    622   ContextInitOptions init_options;
    623   ASSERT_TRUE(Initialize(init_options));
    624 }
    625 
    626 void GLES2ImplementationTest::TearDown() {
    627   for (int i = 0; i < kNumTestContexts; i++)
    628     test_contexts_[i].TearDown();
    629 }
    630 
    631 class GLES2ImplementationManualInitTest : public GLES2ImplementationTest {
    632  protected:
    633   virtual void SetUp() OVERRIDE {}
    634 };
    635 
    636 class GLES2ImplementationStrictSharedTest : public GLES2ImplementationTest {
    637  protected:
    638   virtual void SetUp() OVERRIDE;
    639 
    640   template <class ResApi>
    641   void FlushGenerationTest() {
    642     GLuint id1, id2, id3;
    643 
    644     // Generate valid id.
    645     ResApi::Gen(gl_, 1, &id1);
    646     EXPECT_NE(id1, 0u);
    647 
    648     // Delete id1 and generate id2.  id1 should not be reused.
    649     ResApi::Delete(gl_, 1, &id1);
    650     ResApi::Gen(gl_, 1, &id2);
    651     EXPECT_NE(id2, 0u);
    652     EXPECT_NE(id2, id1);
    653 
    654     // Expect id1 reuse after Flush.
    655     gl_->Flush();
    656     ResApi::Gen(gl_, 1, &id3);
    657     EXPECT_EQ(id3, id1);
    658   }
    659 
    660   // Ids should not be reused unless the |Deleting| context does a Flush()
    661   // AND triggers a lazy release after that.
    662   template <class ResApi>
    663   void CrossContextGenerationTest() {
    664     GLES2Implementation* gl1 = test_contexts_[0].gl_.get();
    665     GLES2Implementation* gl2 = test_contexts_[1].gl_.get();
    666     GLuint id1, id2, id3;
    667 
    668     // Delete, no flush on context 1.  No reuse.
    669     ResApi::Gen(gl1, 1, &id1);
    670     ResApi::Delete(gl1, 1, &id1);
    671     ResApi::Gen(gl1, 1, &id2);
    672     EXPECT_NE(id1, id2);
    673 
    674     // Flush context 2.  Still no reuse.
    675     gl2->Flush();
    676     ResApi::Gen(gl2, 1, &id3);
    677     EXPECT_NE(id1, id3);
    678     EXPECT_NE(id2, id3);
    679 
    680     // Flush on context 1, but no lazy release.  Still no reuse.
    681     gl1->Flush();
    682     ResApi::Gen(gl2, 1, &id3);
    683     EXPECT_NE(id1, id3);
    684 
    685     // Lazy release triggered by another Delete.  Should reuse id1.
    686     ResApi::Delete(gl1, 1, &id2);
    687     ResApi::Gen(gl2, 1, &id3);
    688     EXPECT_EQ(id1, id3);
    689   }
    690 
    691   // Same as CrossContextGenerationTest(), but triggers an Auto Flush on
    692   // the Delete().  Tests an edge case regression.
    693   template <class ResApi>
    694   void CrossContextGenerationAutoFlushTest() {
    695     GLES2Implementation* gl1 = test_contexts_[0].gl_.get();
    696     GLES2Implementation* gl2 = test_contexts_[1].gl_.get();
    697     GLuint id1, id2, id3;
    698 
    699     // Delete, no flush on context 1.  No reuse.
    700     // By half filling the buffer, an internal flush is forced on the Delete().
    701     ResApi::Gen(gl1, 1, &id1);
    702     gl1->helper()->Noop(kNumCommandEntries / 2);
    703     ResApi::Delete(gl1, 1, &id1);
    704     ResApi::Gen(gl1, 1, &id2);
    705     EXPECT_NE(id1, id2);
    706 
    707     // Flush context 2.  Still no reuse.
    708     gl2->Flush();
    709     ResApi::Gen(gl2, 1, &id3);
    710     EXPECT_NE(id1, id3);
    711     EXPECT_NE(id2, id3);
    712 
    713     // Flush on context 1, but no lazy release.  Still no reuse.
    714     gl1->Flush();
    715     ResApi::Gen(gl2, 1, &id3);
    716     EXPECT_NE(id1, id3);
    717 
    718     // Lazy release triggered by another Delete.  Should reuse id1.
    719     ResApi::Delete(gl1, 1, &id2);
    720     ResApi::Gen(gl2, 1, &id3);
    721     EXPECT_EQ(id1, id3);
    722   }
    723 };
    724 
    725 void GLES2ImplementationStrictSharedTest::SetUp() {
    726   ContextInitOptions init_options;
    727   init_options.bind_generates_resource_client = false;
    728   init_options.bind_generates_resource_service = false;
    729   ASSERT_TRUE(Initialize(init_options));
    730 }
    731 
    732 // GCC requires these declarations, but MSVC requires they not be present
    733 #ifndef _MSC_VER
    734 const uint8 GLES2ImplementationTest::kInitialValue;
    735 const int32 GLES2ImplementationTest::kNumCommandEntries;
    736 const int32 GLES2ImplementationTest::kCommandBufferSizeBytes;
    737 const size_t GLES2ImplementationTest::kTransferBufferSize;
    738 const GLint GLES2ImplementationTest::kMaxCombinedTextureImageUnits;
    739 const GLint GLES2ImplementationTest::kMaxCubeMapTextureSize;
    740 const GLint GLES2ImplementationTest::kMaxFragmentUniformVectors;
    741 const GLint GLES2ImplementationTest::kMaxRenderbufferSize;
    742 const GLint GLES2ImplementationTest::kMaxTextureImageUnits;
    743 const GLint GLES2ImplementationTest::kMaxTextureSize;
    744 const GLint GLES2ImplementationTest::kMaxVaryingVectors;
    745 const GLint GLES2ImplementationTest::kMaxVertexAttribs;
    746 const GLint GLES2ImplementationTest::kMaxVertexTextureImageUnits;
    747 const GLint GLES2ImplementationTest::kMaxVertexUniformVectors;
    748 const GLint GLES2ImplementationTest::kNumCompressedTextureFormats;
    749 const GLint GLES2ImplementationTest::kNumShaderBinaryFormats;
    750 const GLuint GLES2ImplementationTest::kStartId;
    751 const GLuint GLES2ImplementationTest::kBuffersStartId;
    752 const GLuint GLES2ImplementationTest::kFramebuffersStartId;
    753 const GLuint GLES2ImplementationTest::kProgramsAndShadersStartId;
    754 const GLuint GLES2ImplementationTest::kRenderbuffersStartId;
    755 const GLuint GLES2ImplementationTest::kTexturesStartId;
    756 const GLuint GLES2ImplementationTest::kQueriesStartId;
    757 const GLuint GLES2ImplementationTest::kVertexArraysStartId;
    758 #endif
    759 
    760 TEST_F(GLES2ImplementationTest, Basic) {
    761   EXPECT_TRUE(gl_->share_group() != NULL);
    762 }
    763 
    764 TEST_F(GLES2ImplementationTest, GetBucketContents) {
    765   const uint32 kBucketId = GLES2Implementation::kResultBucketId;
    766   const uint32 kTestSize = MaxTransferBufferSize() + 32;
    767 
    768   scoped_ptr<uint8[]> buf(new uint8 [kTestSize]);
    769   uint8* expected_data = buf.get();
    770   for (uint32 ii = 0; ii < kTestSize; ++ii) {
    771     expected_data[ii] = ii * 3;
    772   }
    773 
    774   struct Cmds {
    775     cmd::GetBucketStart get_bucket_start;
    776     cmd::SetToken set_token1;
    777     cmd::GetBucketData get_bucket_data;
    778     cmd::SetToken set_token2;
    779     cmd::SetBucketSize set_bucket_size2;
    780   };
    781 
    782   ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
    783   ExpectedMemoryInfo result1 = GetExpectedResultMemory(sizeof(uint32));
    784   ExpectedMemoryInfo mem2 = GetExpectedMemory(
    785       kTestSize - MaxTransferBufferSize());
    786 
    787   Cmds expected;
    788   expected.get_bucket_start.Init(
    789       kBucketId, result1.id, result1.offset,
    790       MaxTransferBufferSize(), mem1.id, mem1.offset);
    791   expected.set_token1.Init(GetNextToken());
    792   expected.get_bucket_data.Init(
    793       kBucketId, MaxTransferBufferSize(),
    794       kTestSize - MaxTransferBufferSize(), mem2.id, mem2.offset);
    795   expected.set_bucket_size2.Init(kBucketId, 0);
    796   expected.set_token2.Init(GetNextToken());
    797 
    798   EXPECT_CALL(*command_buffer(), OnFlush())
    799       .WillOnce(DoAll(
    800           SetMemory(result1.ptr, kTestSize),
    801           SetMemoryFromArray(
    802               mem1.ptr, expected_data, MaxTransferBufferSize())))
    803       .WillOnce(SetMemoryFromArray(
    804           mem2.ptr, expected_data + MaxTransferBufferSize(),
    805           kTestSize - MaxTransferBufferSize()))
    806       .RetiresOnSaturation();
    807 
    808   std::vector<int8> data;
    809   GetBucketContents(kBucketId, &data);
    810   EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
    811   ASSERT_EQ(kTestSize, data.size());
    812   EXPECT_EQ(0, memcmp(expected_data, &data[0], data.size()));
    813 }
    814 
    815 TEST_F(GLES2ImplementationTest, GetShaderPrecisionFormat) {
    816   struct Cmds {
    817     cmds::GetShaderPrecisionFormat cmd;
    818   };
    819   typedef cmds::GetShaderPrecisionFormat::Result Result;
    820 
    821   // The first call for mediump should trigger a command buffer request.
    822   GLint range1[2] = {0, 0};
    823   GLint precision1 = 0;
    824   Cmds expected1;
    825   ExpectedMemoryInfo client_result1 = GetExpectedResultMemory(4);
    826   expected1.cmd.Init(GL_FRAGMENT_SHADER, GL_MEDIUM_FLOAT,
    827                      client_result1.id, client_result1.offset);
    828   Result server_result1 = {true, 14, 14, 10};
    829   EXPECT_CALL(*command_buffer(), OnFlush())
    830       .WillOnce(SetMemory(client_result1.ptr, server_result1))
    831       .RetiresOnSaturation();
    832   gl_->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_MEDIUM_FLOAT,
    833                                 range1, &precision1);
    834   const void* commands2 = GetPut();
    835   EXPECT_NE(commands_, commands2);
    836   EXPECT_EQ(0, memcmp(&expected1, commands_, sizeof(expected1)));
    837   EXPECT_EQ(range1[0], 14);
    838   EXPECT_EQ(range1[1], 14);
    839   EXPECT_EQ(precision1, 10);
    840 
    841   // The second call for mediump should use the cached value and avoid
    842   // triggering a command buffer request, so we do not expect a call to
    843   // OnFlush() here. We do expect the results to be correct though.
    844   GLint range2[2] = {0, 0};
    845   GLint precision2 = 0;
    846   gl_->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_MEDIUM_FLOAT,
    847                                 range2, &precision2);
    848   const void* commands3 = GetPut();
    849   EXPECT_EQ(commands2, commands3);
    850   EXPECT_EQ(range2[0], 14);
    851   EXPECT_EQ(range2[1], 14);
    852   EXPECT_EQ(precision2, 10);
    853 
    854   // If we then make a request for highp, we should get another command
    855   // buffer request since it hasn't been cached yet.
    856   GLint range3[2] = {0, 0};
    857   GLint precision3 = 0;
    858   Cmds expected3;
    859   ExpectedMemoryInfo result3 = GetExpectedResultMemory(4);
    860   expected3.cmd.Init(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT,
    861                      result3.id, result3.offset);
    862   Result result3_source = {true, 62, 62, 16};
    863   EXPECT_CALL(*command_buffer(), OnFlush())
    864       .WillOnce(SetMemory(result3.ptr, result3_source))
    865       .RetiresOnSaturation();
    866   gl_->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT,
    867                                 range3, &precision3);
    868   const void* commands4 = GetPut();
    869   EXPECT_NE(commands3, commands4);
    870   EXPECT_EQ(0, memcmp(&expected3, commands3, sizeof(expected3)));
    871   EXPECT_EQ(range3[0], 62);
    872   EXPECT_EQ(range3[1], 62);
    873   EXPECT_EQ(precision3, 16);
    874 }
    875 
    876 TEST_F(GLES2ImplementationTest, ShaderSource) {
    877   const uint32 kBucketId = GLES2Implementation::kResultBucketId;
    878   const GLuint kShaderId = 456;
    879   const char* kString1 = "foobar";
    880   const char* kString2 = "barfoo";
    881   const size_t kString1Size = strlen(kString1);
    882   const size_t kString2Size = strlen(kString2);
    883   const size_t kString3Size = 1;  // Want the NULL;
    884   const size_t kSourceSize = kString1Size + kString2Size + kString3Size;
    885   const size_t kPaddedString1Size =
    886       transfer_buffer_->RoundToAlignment(kString1Size);
    887   const size_t kPaddedString2Size =
    888       transfer_buffer_->RoundToAlignment(kString2Size);
    889   const size_t kPaddedString3Size =
    890       transfer_buffer_->RoundToAlignment(kString3Size);
    891   struct Cmds {
    892     cmd::SetBucketSize set_bucket_size;
    893     cmd::SetBucketData set_bucket_data1;
    894     cmd::SetToken set_token1;
    895     cmd::SetBucketData set_bucket_data2;
    896     cmd::SetToken set_token2;
    897     cmd::SetBucketData set_bucket_data3;
    898     cmd::SetToken set_token3;
    899     cmds::ShaderSourceBucket shader_source_bucket;
    900     cmd::SetBucketSize clear_bucket_size;
    901   };
    902 
    903   ExpectedMemoryInfo mem1 = GetExpectedMemory(kPaddedString1Size);
    904   ExpectedMemoryInfo mem2 = GetExpectedMemory(kPaddedString2Size);
    905   ExpectedMemoryInfo mem3 = GetExpectedMemory(kPaddedString3Size);
    906 
    907   Cmds expected;
    908   expected.set_bucket_size.Init(kBucketId, kSourceSize);
    909   expected.set_bucket_data1.Init(
    910       kBucketId, 0, kString1Size, mem1.id, mem1.offset);
    911   expected.set_token1.Init(GetNextToken());
    912   expected.set_bucket_data2.Init(
    913       kBucketId, kString1Size, kString2Size, mem2.id, mem2.offset);
    914   expected.set_token2.Init(GetNextToken());
    915   expected.set_bucket_data3.Init(
    916       kBucketId, kString1Size + kString2Size,
    917       kString3Size, mem3.id, mem3.offset);
    918   expected.set_token3.Init(GetNextToken());
    919   expected.shader_source_bucket.Init(kShaderId, kBucketId);
    920   expected.clear_bucket_size.Init(kBucketId, 0);
    921   const char* strings[] = {
    922     kString1,
    923     kString2,
    924   };
    925   gl_->ShaderSource(kShaderId, 2, strings, NULL);
    926   EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
    927 }
    928 
    929 TEST_F(GLES2ImplementationTest, GetShaderSource) {
    930   const uint32 kBucketId = GLES2Implementation::kResultBucketId;
    931   const GLuint kShaderId = 456;
    932   const Str7 kString = {"foobar"};
    933   const char kBad = 0x12;
    934   struct Cmds {
    935     cmd::SetBucketSize set_bucket_size1;
    936     cmds::GetShaderSource get_shader_source;
    937     cmd::GetBucketStart get_bucket_start;
    938     cmd::SetToken set_token1;
    939     cmd::SetBucketSize set_bucket_size2;
    940   };
    941 
    942   ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
    943   ExpectedMemoryInfo result1 = GetExpectedResultMemory(sizeof(uint32));
    944 
    945   Cmds expected;
    946   expected.set_bucket_size1.Init(kBucketId, 0);
    947   expected.get_shader_source.Init(kShaderId, kBucketId);
    948   expected.get_bucket_start.Init(
    949       kBucketId, result1.id, result1.offset,
    950       MaxTransferBufferSize(), mem1.id, mem1.offset);
    951   expected.set_token1.Init(GetNextToken());
    952   expected.set_bucket_size2.Init(kBucketId, 0);
    953   char buf[sizeof(kString) + 1];
    954   memset(buf, kBad, sizeof(buf));
    955 
    956   EXPECT_CALL(*command_buffer(), OnFlush())
    957       .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))),
    958                       SetMemory(mem1.ptr, kString)))
    959       .RetiresOnSaturation();
    960 
    961   GLsizei length = 0;
    962   gl_->GetShaderSource(kShaderId, sizeof(buf), &length, buf);
    963   EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
    964   EXPECT_EQ(sizeof(kString) - 1, static_cast<size_t>(length));
    965   EXPECT_STREQ(kString.str, buf);
    966   EXPECT_EQ(buf[sizeof(kString)], kBad);
    967 }
    968 
    969 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
    970 
    971 TEST_F(GLES2ImplementationTest, DrawArraysClientSideBuffers) {
    972   static const float verts[][4] = {
    973     { 12.0f, 23.0f, 34.0f, 45.0f, },
    974     { 56.0f, 67.0f, 78.0f, 89.0f, },
    975     { 13.0f, 24.0f, 35.0f, 46.0f, },
    976   };
    977   struct Cmds {
    978     cmds::EnableVertexAttribArray enable1;
    979     cmds::EnableVertexAttribArray enable2;
    980     cmds::BindBuffer bind_to_emu;
    981     cmds::BufferData set_size;
    982     cmds::BufferSubData copy_data1;
    983     cmd::SetToken set_token1;
    984     cmds::VertexAttribPointer set_pointer1;
    985     cmds::BufferSubData copy_data2;
    986     cmd::SetToken set_token2;
    987     cmds::VertexAttribPointer set_pointer2;
    988     cmds::DrawArrays draw;
    989     cmds::BindBuffer restore;
    990   };
    991   const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
    992   const GLuint kAttribIndex1 = 1;
    993   const GLuint kAttribIndex2 = 3;
    994   const GLint kNumComponents1 = 3;
    995   const GLint kNumComponents2 = 2;
    996   const GLsizei kClientStride = sizeof(verts[0]);
    997   const GLint kFirst = 1;
    998   const GLsizei kCount = 2;
    999   const GLsizei kSize1 =
   1000       arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
   1001   const GLsizei kSize2 =
   1002       arraysize(verts) * kNumComponents2 * sizeof(verts[0][0]);
   1003   const GLsizei kEmuOffset1 = 0;
   1004   const GLsizei kEmuOffset2 = kSize1;
   1005   const GLsizei kTotalSize = kSize1 + kSize2;
   1006 
   1007   ExpectedMemoryInfo mem1 = GetExpectedMemory(kSize1);
   1008   ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize2);
   1009 
   1010   Cmds expected;
   1011   expected.enable1.Init(kAttribIndex1);
   1012   expected.enable2.Init(kAttribIndex2);
   1013   expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
   1014   expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
   1015   expected.copy_data1.Init(
   1016       GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem1.id, mem1.offset);
   1017   expected.set_token1.Init(GetNextToken());
   1018   expected.set_pointer1.Init(
   1019       kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
   1020   expected.copy_data2.Init(
   1021       GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem2.id, mem2.offset);
   1022   expected.set_token2.Init(GetNextToken());
   1023   expected.set_pointer2.Init(
   1024       kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
   1025   expected.draw.Init(GL_POINTS, kFirst, kCount);
   1026   expected.restore.Init(GL_ARRAY_BUFFER, 0);
   1027   gl_->EnableVertexAttribArray(kAttribIndex1);
   1028   gl_->EnableVertexAttribArray(kAttribIndex2);
   1029   gl_->VertexAttribPointer(
   1030       kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, kClientStride, verts);
   1031   gl_->VertexAttribPointer(
   1032       kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, kClientStride, verts);
   1033   gl_->DrawArrays(GL_POINTS, kFirst, kCount);
   1034   EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
   1035 }
   1036 
   1037 TEST_F(GLES2ImplementationTest, DrawArraysInstancedANGLEClientSideBuffers) {
   1038   static const float verts[][4] = {
   1039     { 12.0f, 23.0f, 34.0f, 45.0f, },
   1040     { 56.0f, 67.0f, 78.0f, 89.0f, },
   1041     { 13.0f, 24.0f, 35.0f, 46.0f, },
   1042   };
   1043   struct Cmds {
   1044     cmds::EnableVertexAttribArray enable1;
   1045     cmds::EnableVertexAttribArray enable2;
   1046     cmds::VertexAttribDivisorANGLE divisor;
   1047     cmds::BindBuffer bind_to_emu;
   1048     cmds::BufferData set_size;
   1049     cmds::BufferSubData copy_data1;
   1050     cmd::SetToken set_token1;
   1051     cmds::VertexAttribPointer set_pointer1;
   1052     cmds::BufferSubData copy_data2;
   1053     cmd::SetToken set_token2;
   1054     cmds::VertexAttribPointer set_pointer2;
   1055     cmds::DrawArraysInstancedANGLE draw;
   1056     cmds::BindBuffer restore;
   1057   };
   1058   const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
   1059   const GLuint kAttribIndex1 = 1;
   1060   const GLuint kAttribIndex2 = 3;
   1061   const GLint kNumComponents1 = 3;
   1062   const GLint kNumComponents2 = 2;
   1063   const GLsizei kClientStride = sizeof(verts[0]);
   1064   const GLint kFirst = 1;
   1065   const GLsizei kCount = 2;
   1066   const GLuint kDivisor = 1;
   1067   const GLsizei kSize1 =
   1068       arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
   1069   const GLsizei kSize2 =
   1070       1 * kNumComponents2 * sizeof(verts[0][0]);
   1071   const GLsizei kEmuOffset1 = 0;
   1072   const GLsizei kEmuOffset2 = kSize1;
   1073   const GLsizei kTotalSize = kSize1 + kSize2;
   1074 
   1075   ExpectedMemoryInfo mem1 = GetExpectedMemory(kSize1);
   1076   ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize2);
   1077 
   1078   Cmds expected;
   1079   expected.enable1.Init(kAttribIndex1);
   1080   expected.enable2.Init(kAttribIndex2);
   1081   expected.divisor.Init(kAttribIndex2, kDivisor);
   1082   expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
   1083   expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
   1084   expected.copy_data1.Init(
   1085       GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem1.id, mem1.offset);
   1086   expected.set_token1.Init(GetNextToken());
   1087   expected.set_pointer1.Init(
   1088       kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
   1089   expected.copy_data2.Init(
   1090       GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem2.id, mem2.offset);
   1091   expected.set_token2.Init(GetNextToken());
   1092   expected.set_pointer2.Init(
   1093       kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
   1094   expected.draw.Init(GL_POINTS, kFirst, kCount, 1);
   1095   expected.restore.Init(GL_ARRAY_BUFFER, 0);
   1096   gl_->EnableVertexAttribArray(kAttribIndex1);
   1097   gl_->EnableVertexAttribArray(kAttribIndex2);
   1098   gl_->VertexAttribPointer(
   1099       kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, kClientStride, verts);
   1100   gl_->VertexAttribPointer(
   1101       kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, kClientStride, verts);
   1102   gl_->VertexAttribDivisorANGLE(kAttribIndex2, kDivisor);
   1103   gl_->DrawArraysInstancedANGLE(GL_POINTS, kFirst, kCount, 1);
   1104   EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
   1105 }
   1106 
   1107 TEST_F(GLES2ImplementationTest, DrawElementsClientSideBuffers) {
   1108   static const float verts[][4] = {
   1109     { 12.0f, 23.0f, 34.0f, 45.0f, },
   1110     { 56.0f, 67.0f, 78.0f, 89.0f, },
   1111     { 13.0f, 24.0f, 35.0f, 46.0f, },
   1112   };
   1113   static const uint16 indices[] = {
   1114     1, 2,
   1115   };
   1116   struct Cmds {
   1117     cmds::EnableVertexAttribArray enable1;
   1118     cmds::EnableVertexAttribArray enable2;
   1119     cmds::BindBuffer bind_to_index_emu;
   1120     cmds::BufferData set_index_size;
   1121     cmds::BufferSubData copy_data0;
   1122     cmd::SetToken set_token0;
   1123     cmds::BindBuffer bind_to_emu;
   1124     cmds::BufferData set_size;
   1125     cmds::BufferSubData copy_data1;
   1126     cmd::SetToken set_token1;
   1127     cmds::VertexAttribPointer set_pointer1;
   1128     cmds::BufferSubData copy_data2;
   1129     cmd::SetToken set_token2;
   1130     cmds::VertexAttribPointer set_pointer2;
   1131     cmds::DrawElements draw;
   1132     cmds::BindBuffer restore;
   1133     cmds::BindBuffer restore_element;
   1134   };
   1135   const GLsizei kIndexSize = sizeof(indices);
   1136   const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
   1137   const GLuint kEmuIndexBufferId =
   1138       GLES2Implementation::kClientSideElementArrayId;
   1139   const GLuint kAttribIndex1 = 1;
   1140   const GLuint kAttribIndex2 = 3;
   1141   const GLint kNumComponents1 = 3;
   1142   const GLint kNumComponents2 = 2;
   1143   const GLsizei kClientStride = sizeof(verts[0]);
   1144   const GLsizei kCount = 2;
   1145   const GLsizei kSize1 =
   1146       arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
   1147   const GLsizei kSize2 =
   1148       arraysize(verts) * kNumComponents2 * sizeof(verts[0][0]);
   1149   const GLsizei kEmuOffset1 = 0;
   1150   const GLsizei kEmuOffset2 = kSize1;
   1151   const GLsizei kTotalSize = kSize1 + kSize2;
   1152 
   1153   ExpectedMemoryInfo mem1 = GetExpectedMemory(kIndexSize);
   1154   ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize1);
   1155   ExpectedMemoryInfo mem3 = GetExpectedMemory(kSize2);
   1156 
   1157   Cmds expected;
   1158   expected.enable1.Init(kAttribIndex1);
   1159   expected.enable2.Init(kAttribIndex2);
   1160   expected.bind_to_index_emu.Init(GL_ELEMENT_ARRAY_BUFFER, kEmuIndexBufferId);
   1161   expected.set_index_size.Init(
   1162       GL_ELEMENT_ARRAY_BUFFER, kIndexSize, 0, 0, GL_DYNAMIC_DRAW);
   1163   expected.copy_data0.Init(
   1164       GL_ELEMENT_ARRAY_BUFFER, 0, kIndexSize, mem1.id, mem1.offset);
   1165   expected.set_token0.Init(GetNextToken());
   1166   expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
   1167   expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
   1168   expected.copy_data1.Init(
   1169       GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem2.id, mem2.offset);
   1170   expected.set_token1.Init(GetNextToken());
   1171   expected.set_pointer1.Init(
   1172       kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
   1173   expected.copy_data2.Init(
   1174       GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem3.id, mem3.offset);
   1175   expected.set_token2.Init(GetNextToken());
   1176   expected.set_pointer2.Init(kAttribIndex2, kNumComponents2,
   1177                              GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
   1178   expected.draw.Init(GL_POINTS, kCount, GL_UNSIGNED_SHORT, 0);
   1179   expected.restore.Init(GL_ARRAY_BUFFER, 0);
   1180   expected.restore_element.Init(GL_ELEMENT_ARRAY_BUFFER, 0);
   1181   gl_->EnableVertexAttribArray(kAttribIndex1);
   1182   gl_->EnableVertexAttribArray(kAttribIndex2);
   1183   gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
   1184                            GL_FLOAT, GL_FALSE, kClientStride, verts);
   1185   gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
   1186                            GL_FLOAT, GL_FALSE, kClientStride, verts);
   1187   gl_->DrawElements(GL_POINTS, kCount, GL_UNSIGNED_SHORT, indices);
   1188   EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
   1189 }
   1190 
   1191 TEST_F(GLES2ImplementationTest, DrawElementsClientSideBuffersIndexUint) {
   1192   static const float verts[][4] = {
   1193     { 12.0f, 23.0f, 34.0f, 45.0f, },
   1194     { 56.0f, 67.0f, 78.0f, 89.0f, },
   1195     { 13.0f, 24.0f, 35.0f, 46.0f, },
   1196   };
   1197   static const uint32 indices[] = {
   1198     1, 2,
   1199   };
   1200   struct Cmds {
   1201     cmds::EnableVertexAttribArray enable1;
   1202     cmds::EnableVertexAttribArray enable2;
   1203     cmds::BindBuffer bind_to_index_emu;
   1204     cmds::BufferData set_index_size;
   1205     cmds::BufferSubData copy_data0;
   1206     cmd::SetToken set_token0;
   1207     cmds::BindBuffer bind_to_emu;
   1208     cmds::BufferData set_size;
   1209     cmds::BufferSubData copy_data1;
   1210     cmd::SetToken set_token1;
   1211     cmds::VertexAttribPointer set_pointer1;
   1212     cmds::BufferSubData copy_data2;
   1213     cmd::SetToken set_token2;
   1214     cmds::VertexAttribPointer set_pointer2;
   1215     cmds::DrawElements draw;
   1216     cmds::BindBuffer restore;
   1217     cmds::BindBuffer restore_element;
   1218   };
   1219   const GLsizei kIndexSize = sizeof(indices);
   1220   const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
   1221   const GLuint kEmuIndexBufferId =
   1222       GLES2Implementation::kClientSideElementArrayId;
   1223   const GLuint kAttribIndex1 = 1;
   1224   const GLuint kAttribIndex2 = 3;
   1225   const GLint kNumComponents1 = 3;
   1226   const GLint kNumComponents2 = 2;
   1227   const GLsizei kClientStride = sizeof(verts[0]);
   1228   const GLsizei kCount = 2;
   1229   const GLsizei kSize1 =
   1230       arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
   1231   const GLsizei kSize2 =
   1232       arraysize(verts) * kNumComponents2 * sizeof(verts[0][0]);
   1233   const GLsizei kEmuOffset1 = 0;
   1234   const GLsizei kEmuOffset2 = kSize1;
   1235   const GLsizei kTotalSize = kSize1 + kSize2;
   1236 
   1237   ExpectedMemoryInfo mem1 = GetExpectedMemory(kIndexSize);
   1238   ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize1);
   1239   ExpectedMemoryInfo mem3 = GetExpectedMemory(kSize2);
   1240 
   1241   Cmds expected;
   1242   expected.enable1.Init(kAttribIndex1);
   1243   expected.enable2.Init(kAttribIndex2);
   1244   expected.bind_to_index_emu.Init(GL_ELEMENT_ARRAY_BUFFER, kEmuIndexBufferId);
   1245   expected.set_index_size.Init(
   1246       GL_ELEMENT_ARRAY_BUFFER, kIndexSize, 0, 0, GL_DYNAMIC_DRAW);
   1247   expected.copy_data0.Init(
   1248       GL_ELEMENT_ARRAY_BUFFER, 0, kIndexSize, mem1.id, mem1.offset);
   1249   expected.set_token0.Init(GetNextToken());
   1250   expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
   1251   expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
   1252   expected.copy_data1.Init(
   1253       GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem2.id, mem2.offset);
   1254   expected.set_token1.Init(GetNextToken());
   1255   expected.set_pointer1.Init(
   1256       kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
   1257   expected.copy_data2.Init(
   1258       GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem3.id, mem3.offset);
   1259   expected.set_token2.Init(GetNextToken());
   1260   expected.set_pointer2.Init(kAttribIndex2, kNumComponents2,
   1261                              GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
   1262   expected.draw.Init(GL_POINTS, kCount, GL_UNSIGNED_INT, 0);
   1263   expected.restore.Init(GL_ARRAY_BUFFER, 0);
   1264   expected.restore_element.Init(GL_ELEMENT_ARRAY_BUFFER, 0);
   1265   gl_->EnableVertexAttribArray(kAttribIndex1);
   1266   gl_->EnableVertexAttribArray(kAttribIndex2);
   1267   gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
   1268                            GL_FLOAT, GL_FALSE, kClientStride, verts);
   1269   gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
   1270                            GL_FLOAT, GL_FALSE, kClientStride, verts);
   1271   gl_->DrawElements(GL_POINTS, kCount, GL_UNSIGNED_INT, indices);
   1272   EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
   1273 }
   1274 
   1275 TEST_F(GLES2ImplementationTest, DrawElementsClientSideBuffersInvalidIndexUint) {
   1276   static const float verts[][4] = {
   1277     { 12.0f, 23.0f, 34.0f, 45.0f, },
   1278     { 56.0f, 67.0f, 78.0f, 89.0f, },
   1279     { 13.0f, 24.0f, 35.0f, 46.0f, },
   1280   };
   1281   static const uint32 indices[] = {
   1282     1, 0x90000000
   1283   };
   1284 
   1285   const GLuint kAttribIndex1 = 1;
   1286   const GLuint kAttribIndex2 = 3;
   1287   const GLint kNumComponents1 = 3;
   1288   const GLint kNumComponents2 = 2;
   1289   const GLsizei kClientStride = sizeof(verts[0]);
   1290   const GLsizei kCount = 2;
   1291 
   1292   EXPECT_CALL(*command_buffer(), OnFlush())
   1293       .Times(1)
   1294       .RetiresOnSaturation();
   1295 
   1296   gl_->EnableVertexAttribArray(kAttribIndex1);
   1297   gl_->EnableVertexAttribArray(kAttribIndex2);
   1298   gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
   1299                            GL_FLOAT, GL_FALSE, kClientStride, verts);
   1300   gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
   1301                            GL_FLOAT, GL_FALSE, kClientStride, verts);
   1302   gl_->DrawElements(GL_POINTS, kCount, GL_UNSIGNED_INT, indices);
   1303 
   1304   EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), gl_->GetError());
   1305 }
   1306 
   1307 TEST_F(GLES2ImplementationTest,
   1308        DrawElementsClientSideBuffersServiceSideIndices) {
   1309   static const float verts[][4] = {
   1310     { 12.0f, 23.0f, 34.0f, 45.0f, },
   1311     { 56.0f, 67.0f, 78.0f, 89.0f, },
   1312     { 13.0f, 24.0f, 35.0f, 46.0f, },
   1313   };
   1314   struct Cmds {
   1315     cmds::EnableVertexAttribArray enable1;
   1316     cmds::EnableVertexAttribArray enable2;
   1317     cmds::BindBuffer bind_to_index;
   1318     cmds::GetMaxValueInBufferCHROMIUM get_max;
   1319     cmds::BindBuffer bind_to_emu;
   1320     cmds::BufferData set_size;
   1321     cmds::BufferSubData copy_data1;
   1322     cmd::SetToken set_token1;
   1323     cmds::VertexAttribPointer set_pointer1;
   1324     cmds::BufferSubData copy_data2;
   1325     cmd::SetToken set_token2;
   1326     cmds::VertexAttribPointer set_pointer2;
   1327     cmds::DrawElements draw;
   1328     cmds::BindBuffer restore;
   1329   };
   1330   const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
   1331   const GLuint kClientIndexBufferId = 0x789;
   1332   const GLuint kIndexOffset = 0x40;
   1333   const GLuint kMaxIndex = 2;
   1334   const GLuint kAttribIndex1 = 1;
   1335   const GLuint kAttribIndex2 = 3;
   1336   const GLint kNumComponents1 = 3;
   1337   const GLint kNumComponents2 = 2;
   1338   const GLsizei kClientStride = sizeof(verts[0]);
   1339   const GLsizei kCount = 2;
   1340   const GLsizei kSize1 =
   1341       arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
   1342   const GLsizei kSize2 =
   1343       arraysize(verts) * kNumComponents2 * sizeof(verts[0][0]);
   1344   const GLsizei kEmuOffset1 = 0;
   1345   const GLsizei kEmuOffset2 = kSize1;
   1346   const GLsizei kTotalSize = kSize1 + kSize2;
   1347 
   1348   ExpectedMemoryInfo mem1 = GetExpectedResultMemory(sizeof(uint32));
   1349   ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize1);
   1350   ExpectedMemoryInfo mem3 = GetExpectedMemory(kSize2);
   1351 
   1352 
   1353   Cmds expected;
   1354   expected.enable1.Init(kAttribIndex1);
   1355   expected.enable2.Init(kAttribIndex2);
   1356   expected.bind_to_index.Init(GL_ELEMENT_ARRAY_BUFFER, kClientIndexBufferId);
   1357   expected.get_max.Init(kClientIndexBufferId, kCount, GL_UNSIGNED_SHORT,
   1358                         kIndexOffset, mem1.id, mem1.offset);
   1359   expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
   1360   expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
   1361   expected.copy_data1.Init(
   1362       GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem2.id, mem2.offset);
   1363   expected.set_token1.Init(GetNextToken());
   1364   expected.set_pointer1.Init(kAttribIndex1, kNumComponents1,
   1365                              GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
   1366   expected.copy_data2.Init(
   1367       GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem3.id, mem3.offset);
   1368   expected.set_token2.Init(GetNextToken());
   1369   expected.set_pointer2.Init(kAttribIndex2, kNumComponents2,
   1370                              GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
   1371   expected.draw.Init(GL_POINTS, kCount, GL_UNSIGNED_SHORT, kIndexOffset);
   1372   expected.restore.Init(GL_ARRAY_BUFFER, 0);
   1373 
   1374   EXPECT_CALL(*command_buffer(), OnFlush())
   1375       .WillOnce(SetMemory(mem1.ptr,kMaxIndex))
   1376       .RetiresOnSaturation();
   1377 
   1378   gl_->EnableVertexAttribArray(kAttribIndex1);
   1379   gl_->EnableVertexAttribArray(kAttribIndex2);
   1380   gl_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, kClientIndexBufferId);
   1381   gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
   1382                            GL_FLOAT, GL_FALSE, kClientStride, verts);
   1383   gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
   1384                            GL_FLOAT, GL_FALSE, kClientStride, verts);
   1385   gl_->DrawElements(GL_POINTS, kCount, GL_UNSIGNED_SHORT,
   1386                     reinterpret_cast<const void*>(kIndexOffset));
   1387   EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
   1388 }
   1389 
   1390 TEST_F(GLES2ImplementationTest, DrawElementsInstancedANGLEClientSideBuffers) {
   1391   static const float verts[][4] = {
   1392     { 12.0f, 23.0f, 34.0f, 45.0f, },
   1393     { 56.0f, 67.0f, 78.0f, 89.0f, },
   1394     { 13.0f, 24.0f, 35.0f, 46.0f, },
   1395   };
   1396   static const uint16 indices[] = {
   1397     1, 2,
   1398   };
   1399   struct Cmds {
   1400     cmds::EnableVertexAttribArray enable1;
   1401     cmds::EnableVertexAttribArray enable2;
   1402     cmds::VertexAttribDivisorANGLE divisor;
   1403     cmds::BindBuffer bind_to_index_emu;
   1404     cmds::BufferData set_index_size;
   1405     cmds::BufferSubData copy_data0;
   1406     cmd::SetToken set_token0;
   1407     cmds::BindBuffer bind_to_emu;
   1408     cmds::BufferData set_size;
   1409     cmds::BufferSubData copy_data1;
   1410     cmd::SetToken set_token1;
   1411     cmds::VertexAttribPointer set_pointer1;
   1412     cmds::BufferSubData copy_data2;
   1413     cmd::SetToken set_token2;
   1414     cmds::VertexAttribPointer set_pointer2;
   1415     cmds::DrawElementsInstancedANGLE draw;
   1416     cmds::BindBuffer restore;
   1417     cmds::BindBuffer restore_element;
   1418   };
   1419   const GLsizei kIndexSize = sizeof(indices);
   1420   const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
   1421   const GLuint kEmuIndexBufferId =
   1422       GLES2Implementation::kClientSideElementArrayId;
   1423   const GLuint kAttribIndex1 = 1;
   1424   const GLuint kAttribIndex2 = 3;
   1425   const GLint kNumComponents1 = 3;
   1426   const GLint kNumComponents2 = 2;
   1427   const GLsizei kClientStride = sizeof(verts[0]);
   1428   const GLsizei kCount = 2;
   1429   const GLsizei kSize1 =
   1430       arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
   1431   const GLsizei kSize2 =
   1432       1 * kNumComponents2 * sizeof(verts[0][0]);
   1433   const GLuint kDivisor = 1;
   1434   const GLsizei kEmuOffset1 = 0;
   1435   const GLsizei kEmuOffset2 = kSize1;
   1436   const GLsizei kTotalSize = kSize1 + kSize2;
   1437 
   1438   ExpectedMemoryInfo mem1 = GetExpectedMemory(kIndexSize);
   1439   ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize1);
   1440   ExpectedMemoryInfo mem3 = GetExpectedMemory(kSize2);
   1441 
   1442   Cmds expected;
   1443   expected.enable1.Init(kAttribIndex1);
   1444   expected.enable2.Init(kAttribIndex2);
   1445   expected.divisor.Init(kAttribIndex2, kDivisor);
   1446   expected.bind_to_index_emu.Init(GL_ELEMENT_ARRAY_BUFFER, kEmuIndexBufferId);
   1447   expected.set_index_size.Init(
   1448       GL_ELEMENT_ARRAY_BUFFER, kIndexSize, 0, 0, GL_DYNAMIC_DRAW);
   1449   expected.copy_data0.Init(
   1450       GL_ELEMENT_ARRAY_BUFFER, 0, kIndexSize, mem1.id, mem1.offset);
   1451   expected.set_token0.Init(GetNextToken());
   1452   expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
   1453   expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
   1454   expected.copy_data1.Init(
   1455       GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem2.id, mem2.offset);
   1456   expected.set_token1.Init(GetNextToken());
   1457   expected.set_pointer1.Init(
   1458       kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
   1459   expected.copy_data2.Init(
   1460       GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem3.id, mem3.offset);
   1461   expected.set_token2.Init(GetNextToken());
   1462   expected.set_pointer2.Init(kAttribIndex2, kNumComponents2,
   1463                              GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
   1464   expected.draw.Init(GL_POINTS, kCount, GL_UNSIGNED_SHORT, 0, 1);
   1465   expected.restore.Init(GL_ARRAY_BUFFER, 0);
   1466   expected.restore_element.Init(GL_ELEMENT_ARRAY_BUFFER, 0);
   1467   gl_->EnableVertexAttribArray(kAttribIndex1);
   1468   gl_->EnableVertexAttribArray(kAttribIndex2);
   1469   gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
   1470                            GL_FLOAT, GL_FALSE, kClientStride, verts);
   1471   gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
   1472                            GL_FLOAT, GL_FALSE, kClientStride, verts);
   1473   gl_->VertexAttribDivisorANGLE(kAttribIndex2, kDivisor);
   1474   gl_->DrawElementsInstancedANGLE(
   1475       GL_POINTS, kCount, GL_UNSIGNED_SHORT, indices, 1);
   1476   EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
   1477 }
   1478 
   1479 TEST_F(GLES2ImplementationTest, GetVertexBufferPointerv) {
   1480   static const float verts[1] = { 0.0f, };
   1481   const GLuint kAttribIndex1 = 1;
   1482   const GLuint kAttribIndex2 = 3;
   1483   const GLint kNumComponents1 = 3;
   1484   const GLint kNumComponents2 = 2;
   1485   const GLsizei kStride1 = 12;
   1486   const GLsizei kStride2 = 0;
   1487   const GLuint kBufferId = 0x123;
   1488   const GLint kOffset2 = 0x456;
   1489 
   1490   // It's all cached on the client side so no get commands are issued.
   1491   struct Cmds {
   1492     cmds::BindBuffer bind;
   1493     cmds::VertexAttribPointer set_pointer;
   1494   };
   1495 
   1496   Cmds expected;
   1497   expected.bind.Init(GL_ARRAY_BUFFER, kBufferId);
   1498   expected.set_pointer.Init(kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE,
   1499                             kStride2, kOffset2);
   1500 
   1501   // Set one client side buffer.
   1502   gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
   1503                            GL_FLOAT, GL_FALSE, kStride1, verts);
   1504   // Set one VBO
   1505   gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);
   1506   gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
   1507                            GL_FLOAT, GL_FALSE, kStride2,
   1508                            reinterpret_cast<const void*>(kOffset2));
   1509   // now get them both.
   1510   void* ptr1 = NULL;
   1511   void* ptr2 = NULL;
   1512 
   1513   gl_->GetVertexAttribPointerv(
   1514       kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_POINTER, &ptr1);
   1515   gl_->GetVertexAttribPointerv(
   1516       kAttribIndex2, GL_VERTEX_ATTRIB_ARRAY_POINTER, &ptr2);
   1517 
   1518   EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
   1519   EXPECT_TRUE(static_cast<const void*>(&verts) == ptr1);
   1520   EXPECT_TRUE(ptr2 == reinterpret_cast<void*>(kOffset2));
   1521 }
   1522 
   1523 TEST_F(GLES2ImplementationTest, GetVertexAttrib) {
   1524   static const float verts[1] = { 0.0f, };
   1525   const GLuint kAttribIndex1 = 1;
   1526   const GLuint kAttribIndex2 = 3;
   1527   const GLint kNumComponents1 = 3;
   1528   const GLint kNumComponents2 = 2;
   1529   const GLsizei kStride1 = 12;
   1530   const GLsizei kStride2 = 0;
   1531   const GLuint kBufferId = 0x123;
   1532   const GLint kOffset2 = 0x456;
   1533 
   1534   // Only one set and one get because the client side buffer's info is stored
   1535   // on the client side.
   1536   struct Cmds {
   1537     cmds::EnableVertexAttribArray enable;
   1538     cmds::BindBuffer bind;
   1539     cmds::VertexAttribPointer set_pointer;
   1540     cmds::GetVertexAttribfv get2;  // for getting the value from attrib1
   1541   };
   1542 
   1543   ExpectedMemoryInfo mem2 = GetExpectedResultMemory(16);
   1544 
   1545   Cmds expected;
   1546   expected.enable.Init(kAttribIndex1);
   1547   expected.bind.Init(GL_ARRAY_BUFFER, kBufferId);
   1548   expected.set_pointer.Init(kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE,
   1549                             kStride2, kOffset2);
   1550   expected.get2.Init(kAttribIndex1,
   1551                      GL_CURRENT_VERTEX_ATTRIB,
   1552                      mem2.id, mem2.offset);
   1553 
   1554   FourFloats current_attrib(1.2f, 3.4f, 5.6f, 7.8f);
   1555 
   1556   // One call to flush to wait for last call to GetVertexAttribiv
   1557   // as others are all cached.
   1558   EXPECT_CALL(*command_buffer(), OnFlush())
   1559       .WillOnce(SetMemory(
   1560           mem2.ptr, SizedResultHelper<FourFloats>(current_attrib)))
   1561       .RetiresOnSaturation();
   1562 
   1563   gl_->EnableVertexAttribArray(kAttribIndex1);
   1564   // Set one client side buffer.
   1565   gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
   1566                            GL_FLOAT, GL_FALSE, kStride1, verts);
   1567   // Set one VBO
   1568   gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);
   1569   gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
   1570                            GL_FLOAT, GL_FALSE, kStride2,
   1571                            reinterpret_cast<const void*>(kOffset2));
   1572   // first get the service side once to see that we make a command
   1573   GLint buffer_id = 0;
   1574   GLint enabled = 0;
   1575   GLint size = 0;
   1576   GLint stride = 0;
   1577   GLint type = 0;
   1578   GLint normalized = 1;
   1579   float current[4] = { 0.0f, };
   1580 
   1581   gl_->GetVertexAttribiv(
   1582       kAttribIndex2, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &buffer_id);
   1583   EXPECT_EQ(kBufferId, static_cast<GLuint>(buffer_id));
   1584   gl_->GetVertexAttribiv(
   1585       kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &buffer_id);
   1586   gl_->GetVertexAttribiv(
   1587       kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &enabled);
   1588   gl_->GetVertexAttribiv(
   1589       kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_SIZE, &size);
   1590   gl_->GetVertexAttribiv(
   1591       kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &stride);
   1592   gl_->GetVertexAttribiv(
   1593       kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_TYPE, &type);
   1594   gl_->GetVertexAttribiv(
   1595       kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &normalized);
   1596   gl_->GetVertexAttribfv(
   1597       kAttribIndex1, GL_CURRENT_VERTEX_ATTRIB, &current[0]);
   1598 
   1599   EXPECT_EQ(0, buffer_id);
   1600   EXPECT_EQ(GL_TRUE, enabled);
   1601   EXPECT_EQ(kNumComponents1, size);
   1602   EXPECT_EQ(kStride1, stride);
   1603   EXPECT_EQ(GL_FLOAT, type);
   1604   EXPECT_EQ(GL_FALSE, normalized);
   1605   EXPECT_EQ(0, memcmp(&current_attrib, &current, sizeof(current_attrib)));
   1606 
   1607   EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
   1608 }
   1609 
   1610 TEST_F(GLES2ImplementationTest, ReservedIds) {
   1611   // Only the get error command should be issued.
   1612   struct Cmds {
   1613     cmds::GetError get;
   1614   };
   1615   Cmds expected;
   1616 
   1617   ExpectedMemoryInfo mem1 = GetExpectedResultMemory(
   1618       sizeof(cmds::GetError::Result));
   1619 
   1620   expected.get.Init(mem1.id, mem1.offset);
   1621 
   1622   // One call to flush to wait for GetError
   1623   EXPECT_CALL(*command_buffer(), OnFlush())
   1624       .WillOnce(SetMemory(mem1.ptr, GLuint(GL_NO_ERROR)))
   1625       .RetiresOnSaturation();
   1626 
   1627   gl_->BindBuffer(
   1628       GL_ARRAY_BUFFER,
   1629       GLES2Implementation::kClientSideArrayId);
   1630   gl_->BindBuffer(
   1631       GL_ARRAY_BUFFER,
   1632       GLES2Implementation::kClientSideElementArrayId);
   1633   GLenum err = gl_->GetError();
   1634   EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), err);
   1635   EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
   1636 }
   1637 
   1638 #endif  // defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
   1639 
   1640 TEST_F(GLES2ImplementationTest, ReadPixels2Reads) {
   1641   struct Cmds {
   1642     cmds::ReadPixels read1;
   1643     cmd::SetToken set_token1;
   1644     cmds::ReadPixels read2;
   1645     cmd::SetToken set_token2;
   1646   };
   1647   const GLint kBytesPerPixel = 4;
   1648   const GLint kWidth =
   1649       (kTransferBufferSize - GLES2Implementation::kStartingOffset) /
   1650       kBytesPerPixel;
   1651   const GLint kHeight = 2;
   1652   const GLenum kFormat = GL_RGBA;
   1653   const GLenum kType = GL_UNSIGNED_BYTE;
   1654 
   1655   ExpectedMemoryInfo mem1 =
   1656       GetExpectedMemory(kWidth * kHeight / 2 * kBytesPerPixel);
   1657   ExpectedMemoryInfo result1 =
   1658       GetExpectedResultMemory(sizeof(cmds::ReadPixels::Result));
   1659   ExpectedMemoryInfo mem2 =
   1660       GetExpectedMemory(kWidth * kHeight / 2 * kBytesPerPixel);
   1661   ExpectedMemoryInfo result2 =
   1662       GetExpectedResultMemory(sizeof(cmds::ReadPixels::Result));
   1663 
   1664   Cmds expected;
   1665   expected.read1.Init(
   1666       0, 0, kWidth, kHeight / 2, kFormat, kType,
   1667       mem1.id, mem1.offset, result1.id, result1.offset,
   1668       false);
   1669   expected.set_token1.Init(GetNextToken());
   1670   expected.read2.Init(
   1671       0, kHeight / 2, kWidth, kHeight / 2, kFormat, kType,
   1672       mem2.id, mem2.offset, result2.id, result2.offset, false);
   1673   expected.set_token2.Init(GetNextToken());
   1674   scoped_ptr<int8[]> buffer(new int8[kWidth * kHeight * kBytesPerPixel]);
   1675 
   1676   EXPECT_CALL(*command_buffer(), OnFlush())
   1677       .WillOnce(SetMemory(result1.ptr, static_cast<uint32>(1)))
   1678       .WillOnce(SetMemory(result2.ptr, static_cast<uint32>(1)))
   1679       .RetiresOnSaturation();
   1680 
   1681   gl_->ReadPixels(0, 0, kWidth, kHeight, kFormat, kType, buffer.get());
   1682   EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
   1683 }
   1684 
   1685 TEST_F(GLES2ImplementationTest, ReadPixelsBadFormatType) {
   1686   struct Cmds {
   1687     cmds::ReadPixels read;
   1688     cmd::SetToken set_token;
   1689   };
   1690   const GLint kBytesPerPixel = 4;
   1691   const GLint kWidth = 2;
   1692   const GLint kHeight = 2;
   1693   const GLenum kFormat = 0;
   1694   const GLenum kType = 0;
   1695 
   1696   ExpectedMemoryInfo mem1 =
   1697       GetExpectedMemory(kWidth * kHeight * kBytesPerPixel);
   1698   ExpectedMemoryInfo result1 =
   1699       GetExpectedResultMemory(sizeof(cmds::ReadPixels::Result));
   1700 
   1701   Cmds expected;
   1702   expected.read.Init(
   1703       0, 0, kWidth, kHeight, kFormat, kType,
   1704       mem1.id, mem1.offset, result1.id, result1.offset, false);
   1705   expected.set_token.Init(GetNextToken());
   1706   scoped_ptr<int8[]> buffer(new int8[kWidth * kHeight * kBytesPerPixel]);
   1707 
   1708   EXPECT_CALL(*command_buffer(), OnFlush())
   1709       .Times(1)
   1710       .RetiresOnSaturation();
   1711 
   1712   gl_->ReadPixels(0, 0, kWidth, kHeight, kFormat, kType, buffer.get());
   1713 }
   1714 
   1715 TEST_F(GLES2ImplementationTest, FreeUnusedSharedMemory) {
   1716   struct Cmds {
   1717     cmds::BufferSubData buf;
   1718     cmd::SetToken set_token;
   1719   };
   1720   const GLenum kTarget = GL_ELEMENT_ARRAY_BUFFER;
   1721   const GLintptr kOffset = 15;
   1722   const GLsizeiptr kSize = 16;
   1723 
   1724   ExpectedMemoryInfo mem1 = GetExpectedMemory(kSize);
   1725 
   1726   Cmds expected;
   1727   expected.buf.Init(
   1728     kTarget, kOffset, kSize, mem1.id, mem1.offset);
   1729   expected.set_token.Init(GetNextToken());
   1730 
   1731   void* mem = gl_->MapBufferSubDataCHROMIUM(
   1732       kTarget, kOffset, kSize, GL_WRITE_ONLY);
   1733   ASSERT_TRUE(mem != NULL);
   1734   gl_->UnmapBufferSubDataCHROMIUM(mem);
   1735   EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
   1736       .Times(1)
   1737       .RetiresOnSaturation();
   1738   gl_->FreeUnusedSharedMemory();
   1739 }
   1740 
   1741 TEST_F(GLES2ImplementationTest, MapUnmapBufferSubDataCHROMIUM) {
   1742   struct Cmds {
   1743     cmds::BufferSubData buf;
   1744     cmd::SetToken set_token;
   1745   };
   1746   const GLenum kTarget = GL_ELEMENT_ARRAY_BUFFER;
   1747   const GLintptr kOffset = 15;
   1748   const GLsizeiptr kSize = 16;
   1749 
   1750   uint32 offset = 0;
   1751   Cmds expected;
   1752   expected.buf.Init(
   1753       kTarget, kOffset, kSize,
   1754       command_buffer()->GetNextFreeTransferBufferId(), offset);
   1755   expected.set_token.Init(GetNextToken());
   1756 
   1757   void* mem = gl_->MapBufferSubDataCHROMIUM(
   1758       kTarget, kOffset, kSize, GL_WRITE_ONLY);
   1759   ASSERT_TRUE(mem != NULL);
   1760   gl_->UnmapBufferSubDataCHROMIUM(mem);
   1761   EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
   1762 }
   1763 
   1764 TEST_F(GLES2ImplementationTest, MapUnmapBufferSubDataCHROMIUMBadArgs) {
   1765   const GLenum kTarget = GL_ELEMENT_ARRAY_BUFFER;
   1766   const GLintptr kOffset = 15;
   1767   const GLsizeiptr kSize = 16;
   1768 
   1769   ExpectedMemoryInfo result1 =
   1770       GetExpectedResultMemory(sizeof(cmds::GetError::Result));
   1771   ExpectedMemoryInfo result2 =
   1772       GetExpectedResultMemory(sizeof(cmds::GetError::Result));
   1773   ExpectedMemoryInfo result3 =
   1774       GetExpectedResultMemory(sizeof(cmds::GetError::Result));
   1775   ExpectedMemoryInfo result4 =
   1776       GetExpectedResultMemory(sizeof(cmds::GetError::Result));
   1777 
   1778   // Calls to flush to wait for GetError
   1779   EXPECT_CALL(*command_buffer(), OnFlush())
   1780       .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
   1781       .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
   1782       .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR)))
   1783       .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR)))
   1784       .RetiresOnSaturation();
   1785 
   1786   void* mem;
   1787   mem = gl_->MapBufferSubDataCHROMIUM(kTarget, -1, kSize, GL_WRITE_ONLY);
   1788   ASSERT_TRUE(mem == NULL);
   1789   EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
   1790   mem = gl_->MapBufferSubDataCHROMIUM(kTarget, kOffset, -1, GL_WRITE_ONLY);
   1791   ASSERT_TRUE(mem == NULL);
   1792   EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
   1793   mem = gl_->MapBufferSubDataCHROMIUM(kTarget, kOffset, kSize, GL_READ_ONLY);
   1794   ASSERT_TRUE(mem == NULL);
   1795   EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), gl_->GetError());
   1796   const char* kPtr = "something";
   1797   gl_->UnmapBufferSubDataCHROMIUM(kPtr);
   1798   EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
   1799 }
   1800 
   1801 TEST_F(GLES2ImplementationTest, MapUnmapTexSubImage2DCHROMIUM) {
   1802   struct Cmds {
   1803     cmds::TexSubImage2D tex;
   1804     cmd::SetToken set_token;
   1805   };
   1806   const GLint kLevel = 1;
   1807   const GLint kXOffset = 2;
   1808   const GLint kYOffset = 3;
   1809   const GLint kWidth = 4;
   1810   const GLint kHeight = 5;
   1811   const GLenum kFormat = GL_RGBA;
   1812   const GLenum kType = GL_UNSIGNED_BYTE;
   1813 
   1814   uint32 offset = 0;
   1815   Cmds expected;
   1816   expected.tex.Init(
   1817       GL_TEXTURE_2D, kLevel, kXOffset, kYOffset, kWidth, kHeight, kFormat,
   1818       kType,
   1819       command_buffer()->GetNextFreeTransferBufferId(), offset, GL_FALSE);
   1820   expected.set_token.Init(GetNextToken());
   1821 
   1822   void* mem = gl_->MapTexSubImage2DCHROMIUM(
   1823       GL_TEXTURE_2D,
   1824       kLevel,
   1825       kXOffset,
   1826       kYOffset,
   1827       kWidth,
   1828       kHeight,
   1829       kFormat,
   1830       kType,
   1831       GL_WRITE_ONLY);
   1832   ASSERT_TRUE(mem != NULL);
   1833   gl_->UnmapTexSubImage2DCHROMIUM(mem);
   1834   EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
   1835 }
   1836 
   1837 TEST_F(GLES2ImplementationTest, MapUnmapTexSubImage2DCHROMIUMBadArgs) {
   1838   const GLint kLevel = 1;
   1839   const GLint kXOffset = 2;
   1840   const GLint kYOffset = 3;
   1841   const GLint kWidth = 4;
   1842   const GLint kHeight = 5;
   1843   const GLenum kFormat = GL_RGBA;
   1844   const GLenum kType = GL_UNSIGNED_BYTE;
   1845 
   1846   ExpectedMemoryInfo result1 =
   1847       GetExpectedResultMemory(sizeof(cmds::GetError::Result));
   1848   ExpectedMemoryInfo result2 =
   1849       GetExpectedResultMemory(sizeof(cmds::GetError::Result));
   1850   ExpectedMemoryInfo result3 =
   1851       GetExpectedResultMemory(sizeof(cmds::GetError::Result));
   1852   ExpectedMemoryInfo result4 =
   1853       GetExpectedResultMemory(sizeof(cmds::GetError::Result));
   1854   ExpectedMemoryInfo result5 =
   1855       GetExpectedResultMemory(sizeof(cmds::GetError::Result));
   1856   ExpectedMemoryInfo result6 =
   1857       GetExpectedResultMemory(sizeof(cmds::GetError::Result));
   1858   ExpectedMemoryInfo result7 =
   1859       GetExpectedResultMemory(sizeof(cmds::GetError::Result));
   1860 
   1861   // Calls to flush to wait for GetError
   1862   EXPECT_CALL(*command_buffer(), OnFlush())
   1863       .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
   1864       .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
   1865       .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR)))
   1866       .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR)))
   1867       .WillOnce(SetMemory(result5.ptr, GLuint(GL_NO_ERROR)))
   1868       .WillOnce(SetMemory(result6.ptr, GLuint(GL_NO_ERROR)))
   1869       .WillOnce(SetMemory(result7.ptr, GLuint(GL_NO_ERROR)))
   1870       .RetiresOnSaturation();
   1871 
   1872   void* mem;
   1873   mem = gl_->MapTexSubImage2DCHROMIUM(
   1874     GL_TEXTURE_2D,
   1875     -1,
   1876     kXOffset,
   1877     kYOffset,
   1878     kWidth,
   1879     kHeight,
   1880     kFormat,
   1881     kType,
   1882     GL_WRITE_ONLY);
   1883   EXPECT_TRUE(mem == NULL);
   1884   EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
   1885   mem = gl_->MapTexSubImage2DCHROMIUM(
   1886     GL_TEXTURE_2D,
   1887     kLevel,
   1888     -1,
   1889     kYOffset,
   1890     kWidth,
   1891     kHeight,
   1892     kFormat,
   1893     kType,
   1894     GL_WRITE_ONLY);
   1895   EXPECT_TRUE(mem == NULL);
   1896   EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
   1897   mem = gl_->MapTexSubImage2DCHROMIUM(
   1898     GL_TEXTURE_2D,
   1899     kLevel,
   1900     kXOffset,
   1901     -1,
   1902     kWidth,
   1903     kHeight,
   1904     kFormat,
   1905     kType,
   1906     GL_WRITE_ONLY);
   1907   EXPECT_TRUE(mem == NULL);
   1908   EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
   1909   mem = gl_->MapTexSubImage2DCHROMIUM(
   1910     GL_TEXTURE_2D,
   1911     kLevel,
   1912     kXOffset,
   1913     kYOffset,
   1914     -1,
   1915     kHeight,
   1916     kFormat,
   1917     kType,
   1918     GL_WRITE_ONLY);
   1919   EXPECT_TRUE(mem == NULL);
   1920   EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
   1921   mem = gl_->MapTexSubImage2DCHROMIUM(
   1922     GL_TEXTURE_2D,
   1923     kLevel,
   1924     kXOffset,
   1925     kYOffset,
   1926     kWidth,
   1927     -1,
   1928     kFormat,
   1929     kType,
   1930     GL_WRITE_ONLY);
   1931   EXPECT_TRUE(mem == NULL);
   1932   EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
   1933   mem = gl_->MapTexSubImage2DCHROMIUM(
   1934     GL_TEXTURE_2D,
   1935     kLevel,
   1936     kXOffset,
   1937     kYOffset,
   1938     kWidth,
   1939     kHeight,
   1940     kFormat,
   1941     kType,
   1942     GL_READ_ONLY);
   1943   EXPECT_TRUE(mem == NULL);
   1944   EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), gl_->GetError());
   1945   const char* kPtr = "something";
   1946   gl_->UnmapTexSubImage2DCHROMIUM(kPtr);
   1947   EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
   1948 }
   1949 
   1950 TEST_F(GLES2ImplementationTest, GetMultipleIntegervCHROMIUMValidArgs) {
   1951   const GLenum pnames[] = {
   1952     GL_DEPTH_WRITEMASK,
   1953     GL_COLOR_WRITEMASK,
   1954     GL_STENCIL_WRITEMASK,
   1955   };
   1956   const GLint num_results = 6;
   1957   GLint results[num_results + 1];
   1958   struct Cmds {
   1959     cmds::GetMultipleIntegervCHROMIUM get_multiple;
   1960     cmd::SetToken set_token;
   1961   };
   1962   const GLsizei kNumPnames = arraysize(pnames);
   1963   const GLsizeiptr kResultsSize = num_results * sizeof(results[0]);
   1964   const size_t kPNamesSize = kNumPnames * sizeof(pnames[0]);
   1965 
   1966   ExpectedMemoryInfo mem1 = GetExpectedMemory(kPNamesSize + kResultsSize);
   1967   ExpectedMemoryInfo result1 = GetExpectedResultMemory(
   1968       sizeof(cmds::GetError::Result));
   1969 
   1970   const uint32 kPnamesOffset = mem1.offset;
   1971   const uint32 kResultsOffset = mem1.offset + kPNamesSize;
   1972   Cmds expected;
   1973   expected.get_multiple.Init(
   1974       mem1.id, kPnamesOffset, kNumPnames,
   1975       mem1.id, kResultsOffset, kResultsSize);
   1976   expected.set_token.Init(GetNextToken());
   1977 
   1978   const GLint kSentinel = 0x12345678;
   1979   memset(results, 0, sizeof(results));
   1980   results[num_results] = kSentinel;
   1981   const GLint returned_results[] = {
   1982     1, 0, 1, 0, 1, -1,
   1983   };
   1984   // One call to flush to wait for results
   1985   EXPECT_CALL(*command_buffer(), OnFlush())
   1986       .WillOnce(SetMemoryFromArray(mem1.ptr + kPNamesSize,
   1987                                    returned_results, sizeof(returned_results)))
   1988       .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
   1989       .RetiresOnSaturation();
   1990 
   1991   gl_->GetMultipleIntegervCHROMIUM(
   1992       &pnames[0], kNumPnames, &results[0], kResultsSize);
   1993   EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
   1994   EXPECT_EQ(0, memcmp(&returned_results, results, sizeof(returned_results)));
   1995   EXPECT_EQ(kSentinel, results[num_results]);
   1996   EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError());
   1997 }
   1998 
   1999 TEST_F(GLES2ImplementationTest, GetMultipleIntegervCHROMIUMBadArgs) {
   2000   GLenum pnames[] = {
   2001     GL_DEPTH_WRITEMASK,
   2002     GL_COLOR_WRITEMASK,
   2003     GL_STENCIL_WRITEMASK,
   2004   };
   2005   const GLint num_results = 6;
   2006   GLint results[num_results + 1];
   2007   const GLsizei kNumPnames = arraysize(pnames);
   2008   const GLsizeiptr kResultsSize = num_results * sizeof(results[0]);
   2009 
   2010   ExpectedMemoryInfo result1 =
   2011       GetExpectedResultMemory(sizeof(cmds::GetError::Result));
   2012   ExpectedMemoryInfo result2 =
   2013       GetExpectedResultMemory(sizeof(cmds::GetError::Result));
   2014   ExpectedMemoryInfo result3 =
   2015       GetExpectedResultMemory(sizeof(cmds::GetError::Result));
   2016   ExpectedMemoryInfo result4 =
   2017       GetExpectedResultMemory(sizeof(cmds::GetError::Result));
   2018 
   2019   // Calls to flush to wait for GetError
   2020   EXPECT_CALL(*command_buffer(), OnFlush())
   2021       .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
   2022       .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
   2023       .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR)))
   2024       .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR)))
   2025       .RetiresOnSaturation();
   2026 
   2027   const GLint kSentinel = 0x12345678;
   2028   memset(results, 0, sizeof(results));
   2029   results[num_results] = kSentinel;
   2030   // try bad size.
   2031   gl_->GetMultipleIntegervCHROMIUM(
   2032       &pnames[0], kNumPnames, &results[0], kResultsSize + 1);
   2033   EXPECT_TRUE(NoCommandsWritten());
   2034   EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
   2035   EXPECT_EQ(0, results[0]);
   2036   EXPECT_EQ(kSentinel, results[num_results]);
   2037   // try bad size.
   2038   ClearCommands();
   2039   gl_->GetMultipleIntegervCHROMIUM(
   2040       &pnames[0], kNumPnames, &results[0], kResultsSize - 1);
   2041   EXPECT_TRUE(NoCommandsWritten());
   2042   EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
   2043   EXPECT_EQ(0, results[0]);
   2044   EXPECT_EQ(kSentinel, results[num_results]);
   2045   // try uncleared results.
   2046   ClearCommands();
   2047   results[2] = 1;
   2048   gl_->GetMultipleIntegervCHROMIUM(
   2049       &pnames[0], kNumPnames, &results[0], kResultsSize);
   2050   EXPECT_TRUE(NoCommandsWritten());
   2051   EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
   2052   EXPECT_EQ(0, results[0]);
   2053   EXPECT_EQ(kSentinel, results[num_results]);
   2054   // try bad enum results.
   2055   ClearCommands();
   2056   results[2] = 0;
   2057   pnames[1] = GL_TRUE;
   2058   gl_->GetMultipleIntegervCHROMIUM(
   2059       &pnames[0], kNumPnames, &results[0], kResultsSize);
   2060   EXPECT_TRUE(NoCommandsWritten());
   2061   EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), gl_->GetError());
   2062   EXPECT_EQ(0, results[0]);
   2063   EXPECT_EQ(kSentinel, results[num_results]);
   2064 }
   2065 
   2066 TEST_F(GLES2ImplementationTest, GetProgramInfoCHROMIUMGoodArgs) {
   2067   const uint32 kBucketId = GLES2Implementation::kResultBucketId;
   2068   const GLuint kProgramId = 123;
   2069   const char kBad = 0x12;
   2070   GLsizei size = 0;
   2071   const Str7 kString = {"foobar"};
   2072   char buf[20];
   2073 
   2074   ExpectedMemoryInfo mem1 =
   2075       GetExpectedMemory(MaxTransferBufferSize());
   2076   ExpectedMemoryInfo result1 =
   2077       GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result));
   2078   ExpectedMemoryInfo result2 =
   2079       GetExpectedResultMemory(sizeof(cmds::GetError::Result));
   2080 
   2081   memset(buf, kBad, sizeof(buf));
   2082   EXPECT_CALL(*command_buffer(), OnFlush())
   2083       .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))),
   2084                       SetMemory(mem1.ptr, kString)))
   2085       .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
   2086       .RetiresOnSaturation();
   2087 
   2088   struct Cmds {
   2089     cmd::SetBucketSize set_bucket_size1;
   2090     cmds::GetProgramInfoCHROMIUM get_program_info;
   2091     cmd::GetBucketStart get_bucket_start;
   2092     cmd::SetToken set_token1;
   2093     cmd::SetBucketSize set_bucket_size2;
   2094   };
   2095   Cmds expected;
   2096   expected.set_bucket_size1.Init(kBucketId, 0);
   2097   expected.get_program_info.Init(kProgramId, kBucketId);
   2098   expected.get_bucket_start.Init(
   2099       kBucketId, result1.id, result1.offset,
   2100       MaxTransferBufferSize(), mem1.id, mem1.offset);
   2101   expected.set_token1.Init(GetNextToken());
   2102   expected.set_bucket_size2.Init(kBucketId, 0);
   2103   gl_->GetProgramInfoCHROMIUM(kProgramId, sizeof(buf), &size, &buf);
   2104   EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
   2105   EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError());
   2106   EXPECT_EQ(sizeof(kString), static_cast<size_t>(size));
   2107   EXPECT_STREQ(kString.str, buf);
   2108   EXPECT_EQ(buf[sizeof(kString)], kBad);
   2109 }
   2110 
   2111 TEST_F(GLES2ImplementationTest, GetProgramInfoCHROMIUMBadArgs) {
   2112   const uint32 kBucketId = GLES2Implementation::kResultBucketId;
   2113   const GLuint kProgramId = 123;
   2114   GLsizei size = 0;
   2115   const Str7 kString = {"foobar"};
   2116   char buf[20];
   2117 
   2118   ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
   2119   ExpectedMemoryInfo result1 =
   2120       GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result));
   2121   ExpectedMemoryInfo result2 =
   2122       GetExpectedResultMemory(sizeof(cmds::GetError::Result));
   2123   ExpectedMemoryInfo result3 =
   2124       GetExpectedResultMemory(sizeof(cmds::GetError::Result));
   2125   ExpectedMemoryInfo result4 =
   2126       GetExpectedResultMemory(sizeof(cmds::GetError::Result));
   2127 
   2128   EXPECT_CALL(*command_buffer(), OnFlush())
   2129       .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))),
   2130                       SetMemory(mem1.ptr,  kString)))
   2131       .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
   2132       .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR)))
   2133       .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR)))
   2134       .RetiresOnSaturation();
   2135 
   2136   // try bufsize not big enough.
   2137   struct Cmds {
   2138     cmd::SetBucketSize set_bucket_size1;
   2139     cmds::GetProgramInfoCHROMIUM get_program_info;
   2140     cmd::GetBucketStart get_bucket_start;
   2141     cmd::SetToken set_token1;
   2142     cmd::SetBucketSize set_bucket_size2;
   2143   };
   2144   Cmds expected;
   2145   expected.set_bucket_size1.Init(kBucketId, 0);
   2146   expected.get_program_info.Init(kProgramId, kBucketId);
   2147   expected.get_bucket_start.Init(
   2148       kBucketId, result1.id, result1.offset,
   2149       MaxTransferBufferSize(), mem1.id, mem1.offset);
   2150   expected.set_token1.Init(GetNextToken());
   2151   expected.set_bucket_size2.Init(kBucketId, 0);
   2152   gl_->GetProgramInfoCHROMIUM(kProgramId, 6, &size, &buf);
   2153   EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
   2154   EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), gl_->GetError());
   2155   ClearCommands();
   2156 
   2157   // try bad bufsize
   2158   gl_->GetProgramInfoCHROMIUM(kProgramId, -1, &size, &buf);
   2159   EXPECT_TRUE(NoCommandsWritten());
   2160   EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
   2161   ClearCommands();
   2162   // try no size ptr.
   2163   gl_->GetProgramInfoCHROMIUM(kProgramId, sizeof(buf), NULL, &buf);
   2164   EXPECT_TRUE(NoCommandsWritten());
   2165   EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
   2166 }
   2167 
   2168 // Test that things are cached
   2169 TEST_F(GLES2ImplementationTest, GetIntegerCacheRead) {
   2170   struct PNameValue {
   2171     GLenum pname;
   2172     GLint expected;
   2173   };
   2174   const PNameValue pairs[] = {
   2175       {GL_ACTIVE_TEXTURE, GL_TEXTURE0, },
   2176       {GL_TEXTURE_BINDING_2D, 0, },
   2177       {GL_TEXTURE_BINDING_CUBE_MAP, 0, },
   2178       {GL_TEXTURE_BINDING_EXTERNAL_OES, 0, },
   2179       {GL_FRAMEBUFFER_BINDING, 0, },
   2180       {GL_RENDERBUFFER_BINDING, 0, },
   2181       {GL_ARRAY_BUFFER_BINDING, 0, },
   2182       {GL_ELEMENT_ARRAY_BUFFER_BINDING, 0, },
   2183       {GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, kMaxCombinedTextureImageUnits, },
   2184       {GL_MAX_CUBE_MAP_TEXTURE_SIZE, kMaxCubeMapTextureSize, },
   2185       {GL_MAX_FRAGMENT_UNIFORM_VECTORS, kMaxFragmentUniformVectors, },
   2186       {GL_MAX_RENDERBUFFER_SIZE, kMaxRenderbufferSize, },
   2187       {GL_MAX_TEXTURE_IMAGE_UNITS, kMaxTextureImageUnits, },
   2188       {GL_MAX_TEXTURE_SIZE, kMaxTextureSize, },
   2189       {GL_MAX_VARYING_VECTORS, kMaxVaryingVectors, },
   2190       {GL_MAX_VERTEX_ATTRIBS, kMaxVertexAttribs, },
   2191       {GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, kMaxVertexTextureImageUnits, },
   2192       {GL_MAX_VERTEX_UNIFORM_VECTORS, kMaxVertexUniformVectors, },
   2193       {GL_NUM_COMPRESSED_TEXTURE_FORMATS, kNumCompressedTextureFormats, },
   2194       {GL_NUM_SHADER_BINARY_FORMATS, kNumShaderBinaryFormats, }, };
   2195   size_t num_pairs = sizeof(pairs) / sizeof(pairs[0]);
   2196   for (size_t ii = 0; ii < num_pairs; ++ii) {
   2197     const PNameValue& pv = pairs[ii];
   2198     GLint v = -1;
   2199     gl_->GetIntegerv(pv.pname, &v);
   2200     EXPECT_TRUE(NoCommandsWritten());
   2201     EXPECT_EQ(pv.expected, v);
   2202   }
   2203 
   2204   ExpectedMemoryInfo result1 =
   2205       GetExpectedResultMemory(sizeof(cmds::GetError::Result));
   2206 
   2207   EXPECT_CALL(*command_buffer(), OnFlush())
   2208       .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
   2209       .RetiresOnSaturation();
   2210   EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError());
   2211 }
   2212 
   2213 TEST_F(GLES2ImplementationTest, GetIntegerCacheWrite) {
   2214   struct PNameValue {
   2215     GLenum pname;
   2216     GLint expected;
   2217   };
   2218   gl_->ActiveTexture(GL_TEXTURE4);
   2219   gl_->BindBuffer(GL_ARRAY_BUFFER, 2);
   2220   gl_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 3);
   2221   gl_->BindFramebuffer(GL_FRAMEBUFFER, 4);
   2222   gl_->BindRenderbuffer(GL_RENDERBUFFER, 5);
   2223   gl_->BindTexture(GL_TEXTURE_2D, 6);
   2224   gl_->BindTexture(GL_TEXTURE_CUBE_MAP, 7);
   2225   gl_->BindTexture(GL_TEXTURE_EXTERNAL_OES, 8);
   2226 
   2227   const PNameValue pairs[] = {{GL_ACTIVE_TEXTURE, GL_TEXTURE4, },
   2228                               {GL_ARRAY_BUFFER_BINDING, 2, },
   2229                               {GL_ELEMENT_ARRAY_BUFFER_BINDING, 3, },
   2230                               {GL_FRAMEBUFFER_BINDING, 4, },
   2231                               {GL_RENDERBUFFER_BINDING, 5, },
   2232                               {GL_TEXTURE_BINDING_2D, 6, },
   2233                               {GL_TEXTURE_BINDING_CUBE_MAP, 7, },
   2234                               {GL_TEXTURE_BINDING_EXTERNAL_OES, 8, }, };
   2235   size_t num_pairs = sizeof(pairs) / sizeof(pairs[0]);
   2236   for (size_t ii = 0; ii < num_pairs; ++ii) {
   2237     const PNameValue& pv = pairs[ii];
   2238     GLint v = -1;
   2239     gl_->GetIntegerv(pv.pname, &v);
   2240     EXPECT_EQ(pv.expected, v);
   2241   }
   2242 
   2243   ExpectedMemoryInfo result1 =
   2244       GetExpectedResultMemory(sizeof(cmds::GetError::Result));
   2245 
   2246   EXPECT_CALL(*command_buffer(), OnFlush())
   2247       .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
   2248       .RetiresOnSaturation();
   2249   EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError());
   2250 }
   2251 
   2252 static bool CheckRect(
   2253     int width, int height, GLenum format, GLenum type, int alignment,
   2254     bool flip_y, const uint8* r1, const uint8* r2) {
   2255   uint32 size = 0;
   2256   uint32 unpadded_row_size = 0;
   2257   uint32 padded_row_size = 0;
   2258   if (!GLES2Util::ComputeImageDataSizes(
   2259       width, height, format, type, alignment, &size, &unpadded_row_size,
   2260       &padded_row_size)) {
   2261     return false;
   2262   }
   2263 
   2264   int r2_stride = flip_y ?
   2265       -static_cast<int>(padded_row_size) :
   2266       static_cast<int>(padded_row_size);
   2267   r2 = flip_y ? (r2 + (height - 1) * padded_row_size) : r2;
   2268 
   2269   for (int y = 0; y < height; ++y) {
   2270     if (memcmp(r1, r2, unpadded_row_size) != 0) {
   2271       return false;
   2272     }
   2273     r1 += padded_row_size;
   2274     r2 += r2_stride;
   2275   }
   2276   return true;
   2277 }
   2278 
   2279 ACTION_P8(CheckRectAction, width, height, format, type, alignment, flip_y,
   2280           r1, r2) {
   2281   EXPECT_TRUE(CheckRect(
   2282       width, height, format, type, alignment, flip_y, r1, r2));
   2283 }
   2284 
   2285 // Test TexImage2D with and without flip_y
   2286 TEST_F(GLES2ImplementationTest, TexImage2D) {
   2287   struct Cmds {
   2288     cmds::TexImage2D tex_image_2d;
   2289     cmd::SetToken set_token;
   2290   };
   2291   struct Cmds2 {
   2292     cmds::TexImage2D tex_image_2d;
   2293     cmd::SetToken set_token;
   2294   };
   2295   const GLenum kTarget = GL_TEXTURE_2D;
   2296   const GLint kLevel = 0;
   2297   const GLenum kFormat = GL_RGB;
   2298   const GLsizei kWidth = 3;
   2299   const GLsizei kHeight = 4;
   2300   const GLint kBorder = 0;
   2301   const GLenum kType = GL_UNSIGNED_BYTE;
   2302   const GLint kPixelStoreUnpackAlignment = 4;
   2303   static uint8 pixels[] = {
   2304     11, 12, 13, 13, 14, 15, 15, 16, 17, 101, 102, 103,
   2305     21, 22, 23, 23, 24, 25, 25, 26, 27, 201, 202, 203,
   2306     31, 32, 33, 33, 34, 35, 35, 36, 37, 123, 124, 125,
   2307     41, 42, 43, 43, 44, 45, 45, 46, 47,
   2308   };
   2309 
   2310   ExpectedMemoryInfo mem1 = GetExpectedMemory(sizeof(pixels));
   2311 
   2312   Cmds expected;
   2313   expected.tex_image_2d.Init(
   2314       kTarget, kLevel, kFormat, kWidth, kHeight, kFormat, kType,
   2315       mem1.id, mem1.offset);
   2316   expected.set_token.Init(GetNextToken());
   2317   gl_->TexImage2D(
   2318       kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
   2319       pixels);
   2320   EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
   2321   EXPECT_TRUE(CheckRect(
   2322       kWidth, kHeight, kFormat, kType, kPixelStoreUnpackAlignment, false,
   2323       pixels, mem1.ptr));
   2324 
   2325   ClearCommands();
   2326   gl_->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE);
   2327 
   2328   ExpectedMemoryInfo mem2 = GetExpectedMemory(sizeof(pixels));
   2329   Cmds2 expected2;
   2330   expected2.tex_image_2d.Init(
   2331       kTarget, kLevel, kFormat, kWidth, kHeight, kFormat, kType,
   2332       mem2.id, mem2.offset);
   2333   expected2.set_token.Init(GetNextToken());
   2334   const void* commands2 = GetPut();
   2335   gl_->TexImage2D(
   2336       kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
   2337       pixels);
   2338   EXPECT_EQ(0, memcmp(&expected2, commands2, sizeof(expected2)));
   2339   EXPECT_TRUE(CheckRect(
   2340       kWidth, kHeight, kFormat, kType, kPixelStoreUnpackAlignment, true,
   2341       pixels, mem2.ptr));
   2342 }
   2343 
   2344 // Test TexImage2D with 2 writes
   2345 TEST_F(GLES2ImplementationTest, TexImage2D2Writes) {
   2346   struct Cmds {
   2347     cmds::TexImage2D tex_image_2d;
   2348     cmds::TexSubImage2D tex_sub_image_2d1;
   2349     cmd::SetToken set_token1;
   2350     cmds::TexSubImage2D tex_sub_image_2d2;
   2351     cmd::SetToken set_token2;
   2352   };
   2353   const GLenum kTarget = GL_TEXTURE_2D;
   2354   const GLint kLevel = 0;
   2355   const GLenum kFormat = GL_RGB;
   2356   const GLint kBorder = 0;
   2357   const GLenum kType = GL_UNSIGNED_BYTE;
   2358   const GLint kPixelStoreUnpackAlignment = 4;
   2359   const GLsizei kWidth = 3;
   2360 
   2361   uint32 size = 0;
   2362   uint32 unpadded_row_size = 0;
   2363   uint32 padded_row_size = 0;
   2364   ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
   2365       kWidth, 2, kFormat, kType, kPixelStoreUnpackAlignment,
   2366       &size, &unpadded_row_size, &padded_row_size));
   2367   const GLsizei kHeight = (MaxTransferBufferSize() / padded_row_size) * 2;
   2368   ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
   2369       kWidth, kHeight, kFormat, kType, kPixelStoreUnpackAlignment,
   2370       &size, NULL, NULL));
   2371   uint32 half_size = 0;
   2372   ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
   2373       kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment,
   2374       &half_size, NULL, NULL));
   2375 
   2376   scoped_ptr<uint8[]> pixels(new uint8[size]);
   2377   for (uint32 ii = 0; ii < size; ++ii) {
   2378     pixels[ii] = static_cast<uint8>(ii);
   2379   }
   2380 
   2381   ExpectedMemoryInfo mem1 = GetExpectedMemory(half_size);
   2382   ExpectedMemoryInfo mem2 = GetExpectedMemory(half_size);
   2383 
   2384   Cmds expected;
   2385   expected.tex_image_2d.Init(
   2386       kTarget, kLevel, kFormat, kWidth, kHeight, kFormat, kType,
   2387       0, 0);
   2388   expected.tex_sub_image_2d1.Init(
   2389       kTarget, kLevel, 0, 0, kWidth, kHeight / 2, kFormat, kType,
   2390       mem1.id, mem1.offset, true);
   2391   expected.set_token1.Init(GetNextToken());
   2392   expected.tex_sub_image_2d2.Init(
   2393       kTarget, kLevel, 0, kHeight / 2, kWidth, kHeight / 2, kFormat, kType,
   2394       mem2.id, mem2.offset, true);
   2395   expected.set_token2.Init(GetNextToken());
   2396 
   2397   // TODO(gman): Make it possible to run this test
   2398   // EXPECT_CALL(*command_buffer(), OnFlush())
   2399   //     .WillOnce(CheckRectAction(
   2400   //         kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment,
   2401   //         false, pixels.get(),
   2402   //         GetExpectedTransferAddressFromOffsetAs<uint8>(offset1, half_size)))
   2403   //     .RetiresOnSaturation();
   2404 
   2405   gl_->TexImage2D(
   2406       kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
   2407       pixels.get());
   2408   EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
   2409   EXPECT_TRUE(CheckRect(
   2410       kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment, false,
   2411       pixels.get() + kHeight / 2 * padded_row_size, mem2.ptr));
   2412 
   2413   ClearCommands();
   2414   gl_->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE);
   2415   const void* commands2 = GetPut();
   2416   ExpectedMemoryInfo mem3 = GetExpectedMemory(half_size);
   2417   ExpectedMemoryInfo mem4 = GetExpectedMemory(half_size);
   2418   expected.tex_image_2d.Init(
   2419       kTarget, kLevel, kFormat, kWidth, kHeight, kFormat, kType,
   2420       0, 0);
   2421   expected.tex_sub_image_2d1.Init(
   2422       kTarget, kLevel, 0, kHeight / 2, kWidth, kHeight / 2, kFormat, kType,
   2423       mem3.id, mem3.offset, true);
   2424   expected.set_token1.Init(GetNextToken());
   2425   expected.tex_sub_image_2d2.Init(
   2426       kTarget, kLevel, 0, 0, kWidth, kHeight / 2, kFormat, kType,
   2427       mem4.id, mem4.offset, true);
   2428   expected.set_token2.Init(GetNextToken());
   2429 
   2430   // TODO(gman): Make it possible to run this test
   2431   // EXPECT_CALL(*command_buffer(), OnFlush())
   2432   //     .WillOnce(CheckRectAction(
   2433   //         kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment,
   2434   //         true, pixels.get(),
   2435   //         GetExpectedTransferAddressFromOffsetAs<uint8>(offset3, half_size)))
   2436   //     .RetiresOnSaturation();
   2437 
   2438   gl_->TexImage2D(
   2439       kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
   2440       pixels.get());
   2441   EXPECT_EQ(0, memcmp(&expected, commands2, sizeof(expected)));
   2442   EXPECT_TRUE(CheckRect(
   2443       kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment, true,
   2444       pixels.get() + kHeight / 2 * padded_row_size, mem4.ptr));
   2445 }
   2446 
   2447 // Test TexSubImage2D with GL_PACK_FLIP_Y set and partial multirow transfers
   2448 TEST_F(GLES2ImplementationTest, TexSubImage2DFlipY) {
   2449   const GLsizei kTextureWidth = MaxTransferBufferSize() / 4;
   2450   const GLsizei kTextureHeight = 7;
   2451   const GLsizei kSubImageWidth = MaxTransferBufferSize() / 8;
   2452   const GLsizei kSubImageHeight = 4;
   2453   const GLint kSubImageXOffset = 1;
   2454   const GLint kSubImageYOffset = 2;
   2455   const GLenum kFormat = GL_RGBA;
   2456   const GLenum kType = GL_UNSIGNED_BYTE;
   2457   const GLenum kTarget = GL_TEXTURE_2D;
   2458   const GLint kLevel = 0;
   2459   const GLint kBorder = 0;
   2460   const GLint kPixelStoreUnpackAlignment = 4;
   2461 
   2462   struct Cmds {
   2463     cmds::PixelStorei pixel_store_i1;
   2464     cmds::TexImage2D tex_image_2d;
   2465     cmds::PixelStorei pixel_store_i2;
   2466     cmds::TexSubImage2D tex_sub_image_2d1;
   2467     cmd::SetToken set_token1;
   2468     cmds::TexSubImage2D tex_sub_image_2d2;
   2469     cmd::SetToken set_token2;
   2470   };
   2471 
   2472   uint32 sub_2_high_size = 0;
   2473   ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
   2474       kSubImageWidth, 2, kFormat, kType, kPixelStoreUnpackAlignment,
   2475       &sub_2_high_size, NULL, NULL));
   2476 
   2477   ExpectedMemoryInfo mem1 = GetExpectedMemory(sub_2_high_size);
   2478   ExpectedMemoryInfo mem2 = GetExpectedMemory(sub_2_high_size);
   2479 
   2480   Cmds expected;
   2481   expected.pixel_store_i1.Init(GL_UNPACK_ALIGNMENT, kPixelStoreUnpackAlignment);
   2482   expected.tex_image_2d.Init(
   2483       kTarget, kLevel, kFormat, kTextureWidth, kTextureHeight, kFormat,
   2484       kType, 0, 0);
   2485   expected.pixel_store_i2.Init(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE);
   2486   expected.tex_sub_image_2d1.Init(kTarget, kLevel, kSubImageXOffset,
   2487       kSubImageYOffset + 2, kSubImageWidth, 2, kFormat, kType,
   2488       mem1.id, mem1.offset, false);
   2489   expected.set_token1.Init(GetNextToken());
   2490   expected.tex_sub_image_2d2.Init(kTarget, kLevel, kSubImageXOffset,
   2491       kSubImageYOffset, kSubImageWidth , 2, kFormat, kType,
   2492       mem2.id, mem2.offset, false);
   2493   expected.set_token2.Init(GetNextToken());
   2494 
   2495   gl_->PixelStorei(GL_UNPACK_ALIGNMENT, kPixelStoreUnpackAlignment);
   2496   gl_->TexImage2D(
   2497       kTarget, kLevel, kFormat, kTextureWidth, kTextureHeight, kBorder, kFormat,
   2498       kType, NULL);
   2499   gl_->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE);
   2500   scoped_ptr<uint32[]> pixels(new uint32[kSubImageWidth * kSubImageHeight]);
   2501   for (int y = 0; y < kSubImageHeight; ++y) {
   2502     for (int x = 0; x < kSubImageWidth; ++x) {
   2503       pixels.get()[kSubImageWidth * y + x] = x | (y << 16);
   2504     }
   2505   }
   2506   gl_->TexSubImage2D(
   2507       GL_TEXTURE_2D, 0, kSubImageXOffset, kSubImageYOffset, kSubImageWidth,
   2508       kSubImageHeight, GL_RGBA, GL_UNSIGNED_BYTE, pixels.get());
   2509 
   2510   EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
   2511   EXPECT_TRUE(CheckRect(
   2512       kSubImageWidth, 2, kFormat, kType, kPixelStoreUnpackAlignment, true,
   2513       reinterpret_cast<uint8*>(pixels.get() + 2 * kSubImageWidth),
   2514       mem2.ptr));
   2515 }
   2516 
   2517 TEST_F(GLES2ImplementationTest, SubImageUnpack) {
   2518   static const GLint unpack_alignments[] = { 1, 2, 4, 8 };
   2519 
   2520   static const GLenum kFormat = GL_RGB;
   2521   static const GLenum kType = GL_UNSIGNED_BYTE;
   2522   static const GLint kLevel = 0;
   2523   static const GLint kBorder = 0;
   2524   // We're testing using the unpack params to pull a subimage out of a larger
   2525   // source of pixels. Here we specify the subimage by its border rows /
   2526   // columns.
   2527   static const GLint kSrcWidth = 33;
   2528   static const GLint kSrcSubImageX0 = 11;
   2529   static const GLint kSrcSubImageX1 = 20;
   2530   static const GLint kSrcSubImageY0 = 18;
   2531   static const GLint kSrcSubImageY1 = 23;
   2532   static const GLint kSrcSubImageWidth = kSrcSubImageX1 - kSrcSubImageX0;
   2533   static const GLint kSrcSubImageHeight = kSrcSubImageY1 - kSrcSubImageY0;
   2534 
   2535   // these are only used in the texsubimage tests
   2536   static const GLint kTexWidth = 1023;
   2537   static const GLint kTexHeight = 511;
   2538   static const GLint kTexSubXOffset = 419;
   2539   static const GLint kTexSubYOffset = 103;
   2540 
   2541   struct {
   2542     cmds::PixelStorei pixel_store_i;
   2543     cmds::PixelStorei pixel_store_i2;
   2544     cmds::TexImage2D tex_image_2d;
   2545   } texImageExpected;
   2546 
   2547   struct  {
   2548     cmds::PixelStorei pixel_store_i;
   2549     cmds::PixelStorei pixel_store_i2;
   2550     cmds::TexImage2D tex_image_2d;
   2551     cmds::TexSubImage2D tex_sub_image_2d;
   2552   } texSubImageExpected;
   2553 
   2554   uint32 src_size;
   2555   ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
   2556       kSrcWidth, kSrcSubImageY1, kFormat, kType, 8, &src_size, NULL, NULL));
   2557   scoped_ptr<uint8[]> src_pixels;
   2558   src_pixels.reset(new uint8[src_size]);
   2559   for (size_t i = 0; i < src_size; ++i) {
   2560     src_pixels[i] = static_cast<int8>(i);
   2561   }
   2562 
   2563   for (int sub = 0; sub < 2; ++sub) {
   2564     for (int flip_y = 0; flip_y < 2; ++flip_y) {
   2565       for (size_t a = 0; a < arraysize(unpack_alignments); ++a) {
   2566         GLint alignment = unpack_alignments[a];
   2567         uint32 size;
   2568         uint32 unpadded_row_size;
   2569         uint32 padded_row_size;
   2570         ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
   2571             kSrcSubImageWidth, kSrcSubImageHeight, kFormat, kType, alignment,
   2572             &size, &unpadded_row_size, &padded_row_size));
   2573         ASSERT_TRUE(size <= MaxTransferBufferSize());
   2574         ExpectedMemoryInfo mem = GetExpectedMemory(size);
   2575 
   2576         const void* commands = GetPut();
   2577         gl_->PixelStorei(GL_UNPACK_ALIGNMENT, alignment);
   2578         gl_->PixelStorei(GL_UNPACK_ROW_LENGTH_EXT, kSrcWidth);
   2579         gl_->PixelStorei(GL_UNPACK_SKIP_PIXELS_EXT, kSrcSubImageX0);
   2580         gl_->PixelStorei(GL_UNPACK_SKIP_ROWS_EXT, kSrcSubImageY0);
   2581         gl_->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, flip_y);
   2582         if (sub) {
   2583           gl_->TexImage2D(
   2584               GL_TEXTURE_2D, kLevel, kFormat, kTexWidth, kTexHeight, kBorder,
   2585               kFormat, kType, NULL);
   2586           gl_->TexSubImage2D(
   2587               GL_TEXTURE_2D, kLevel, kTexSubXOffset, kTexSubYOffset,
   2588               kSrcSubImageWidth, kSrcSubImageHeight, kFormat, kType,
   2589               src_pixels.get());
   2590           texSubImageExpected.pixel_store_i.Init(
   2591               GL_UNPACK_ALIGNMENT, alignment);
   2592           texSubImageExpected.pixel_store_i2.Init(
   2593               GL_UNPACK_FLIP_Y_CHROMIUM, flip_y);
   2594           texSubImageExpected.tex_image_2d.Init(
   2595               GL_TEXTURE_2D, kLevel, kFormat, kTexWidth, kTexHeight,
   2596               kFormat, kType, 0, 0);
   2597           texSubImageExpected.tex_sub_image_2d.Init(
   2598               GL_TEXTURE_2D, kLevel, kTexSubXOffset, kTexSubYOffset,
   2599               kSrcSubImageWidth, kSrcSubImageHeight, kFormat, kType, mem.id,
   2600               mem.offset, GL_FALSE);
   2601           EXPECT_EQ(0, memcmp(
   2602               &texSubImageExpected, commands, sizeof(texSubImageExpected)));
   2603         } else {
   2604           gl_->TexImage2D(
   2605               GL_TEXTURE_2D, kLevel, kFormat,
   2606               kSrcSubImageWidth, kSrcSubImageHeight, kBorder, kFormat, kType,
   2607               src_pixels.get());
   2608           texImageExpected.pixel_store_i.Init(GL_UNPACK_ALIGNMENT, alignment);
   2609           texImageExpected.pixel_store_i2.Init(
   2610               GL_UNPACK_FLIP_Y_CHROMIUM, flip_y);
   2611           texImageExpected.tex_image_2d.Init(
   2612               GL_TEXTURE_2D, kLevel, kFormat, kSrcSubImageWidth,
   2613               kSrcSubImageHeight, kFormat, kType, mem.id, mem.offset);
   2614           EXPECT_EQ(0, memcmp(
   2615               &texImageExpected, commands, sizeof(texImageExpected)));
   2616         }
   2617         uint32 src_padded_row_size;
   2618         ASSERT_TRUE(GLES2Util::ComputeImagePaddedRowSize(
   2619             kSrcWidth, kFormat, kType, alignment, &src_padded_row_size));
   2620         uint32 bytes_per_group = GLES2Util::ComputeImageGroupSize(
   2621             kFormat, kType);
   2622         for (int y = 0; y < kSrcSubImageHeight; ++y) {
   2623           GLint src_sub_y = flip_y ? kSrcSubImageHeight - y - 1 : y;
   2624           const uint8* src_row = src_pixels.get() +
   2625               (kSrcSubImageY0 + src_sub_y) * src_padded_row_size +
   2626               bytes_per_group * kSrcSubImageX0;
   2627           const uint8* dst_row = mem.ptr + y * padded_row_size;
   2628           EXPECT_EQ(0, memcmp(src_row, dst_row, unpadded_row_size));
   2629         }
   2630         ClearCommands();
   2631       }
   2632     }
   2633   }
   2634 }
   2635 
   2636 // Test texture related calls with invalid arguments.
   2637 TEST_F(GLES2ImplementationTest, TextureInvalidArguments) {
   2638   struct Cmds {
   2639     cmds::TexImage2D tex_image_2d;
   2640     cmd::SetToken set_token;
   2641   };
   2642   const GLenum kTarget = GL_TEXTURE_2D;
   2643   const GLint kLevel = 0;
   2644   const GLenum kFormat = GL_RGB;
   2645   const GLsizei kWidth = 3;
   2646   const GLsizei kHeight = 4;
   2647   const GLint kBorder = 0;
   2648   const GLint kInvalidBorder = 1;
   2649   const GLenum kType = GL_UNSIGNED_BYTE;
   2650   const GLint kPixelStoreUnpackAlignment = 4;
   2651   static uint8 pixels[] = {
   2652     11, 12, 13, 13, 14, 15, 15, 16, 17, 101, 102, 103,
   2653     21, 22, 23, 23, 24, 25, 25, 26, 27, 201, 202, 203,
   2654     31, 32, 33, 33, 34, 35, 35, 36, 37, 123, 124, 125,
   2655     41, 42, 43, 43, 44, 45, 45, 46, 47,
   2656   };
   2657 
   2658   // Verify that something works.
   2659 
   2660   ExpectedMemoryInfo mem1 = GetExpectedMemory(sizeof(pixels));
   2661 
   2662   Cmds expected;
   2663   expected.tex_image_2d.Init(
   2664       kTarget, kLevel, kFormat, kWidth, kHeight, kFormat, kType,
   2665       mem1.id, mem1.offset);
   2666   expected.set_token.Init(GetNextToken());
   2667   gl_->TexImage2D(
   2668       kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
   2669       pixels);
   2670   EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
   2671   EXPECT_TRUE(CheckRect(
   2672       kWidth, kHeight, kFormat, kType, kPixelStoreUnpackAlignment, false,
   2673       pixels, mem1.ptr));
   2674 
   2675   ClearCommands();
   2676 
   2677   // Use invalid border.
   2678   gl_->TexImage2D(
   2679       kTarget, kLevel, kFormat, kWidth, kHeight, kInvalidBorder, kFormat, kType,
   2680       pixels);
   2681 
   2682   EXPECT_TRUE(NoCommandsWritten());
   2683   EXPECT_EQ(GL_INVALID_VALUE, CheckError());
   2684 
   2685   ClearCommands();
   2686 
   2687   gl_->AsyncTexImage2DCHROMIUM(
   2688       kTarget, kLevel, kFormat, kWidth, kHeight, kInvalidBorder, kFormat, kType,
   2689       NULL);
   2690 
   2691   EXPECT_TRUE(NoCommandsWritten());
   2692   EXPECT_EQ(GL_INVALID_VALUE, CheckError());
   2693 
   2694   ClearCommands();
   2695 
   2696   // Checking for CompressedTexImage2D argument validation is a bit tricky due
   2697   // to (runtime-detected) compression formats. Try to infer the error with an
   2698   // aux check.
   2699   const GLenum kCompressedFormat = GL_ETC1_RGB8_OES;
   2700   gl_->CompressedTexImage2D(
   2701       kTarget, kLevel, kCompressedFormat, kWidth, kHeight, kBorder,
   2702       arraysize(pixels), pixels);
   2703 
   2704   // In the above, kCompressedFormat and arraysize(pixels) are possibly wrong
   2705   // values. First ensure that these do not cause failures at the client. If
   2706   // this check ever fails, it probably means that client checks more than at
   2707   // the time of writing of this test. In this case, more code needs to be
   2708   // written for this test.
   2709   EXPECT_FALSE(NoCommandsWritten());
   2710 
   2711   ClearCommands();
   2712 
   2713   // Changing border to invalid border should make the call fail at the client
   2714   // checks.
   2715   gl_->CompressedTexImage2D(
   2716       kTarget, kLevel, kCompressedFormat, kWidth, kHeight, kInvalidBorder,
   2717       arraysize(pixels), pixels);
   2718   EXPECT_TRUE(NoCommandsWritten());
   2719   EXPECT_EQ(GL_INVALID_VALUE, CheckError());
   2720 }
   2721 
   2722 
   2723 // Binds can not be cached with bind_generates_resource = false because
   2724 // our id might not be valid. More specifically if you bind on contextA then
   2725 // delete on contextB the resource is still bound on contextA but GetInterger
   2726 // won't return an id.
   2727 TEST_F(GLES2ImplementationStrictSharedTest, BindsNotCached) {
   2728   struct PNameValue {
   2729     GLenum pname;
   2730     GLint expected;
   2731   };
   2732   const PNameValue pairs[] = {{GL_TEXTURE_BINDING_2D, 1, },
   2733                               {GL_TEXTURE_BINDING_CUBE_MAP, 2, },
   2734                               {GL_TEXTURE_BINDING_EXTERNAL_OES, 3, },
   2735                               {GL_FRAMEBUFFER_BINDING, 4, },
   2736                               {GL_RENDERBUFFER_BINDING, 5, },
   2737                               {GL_ARRAY_BUFFER_BINDING, 6, },
   2738                               {GL_ELEMENT_ARRAY_BUFFER_BINDING, 7, }, };
   2739   size_t num_pairs = sizeof(pairs) / sizeof(pairs[0]);
   2740   for (size_t ii = 0; ii < num_pairs; ++ii) {
   2741     const PNameValue& pv = pairs[ii];
   2742     GLint v = -1;
   2743     ExpectedMemoryInfo result1 =
   2744         GetExpectedResultMemory(sizeof(cmds::GetIntegerv::Result));
   2745     EXPECT_CALL(*command_buffer(), OnFlush())
   2746         .WillOnce(SetMemory(result1.ptr,
   2747                             SizedResultHelper<GLuint>(pv.expected)))
   2748         .RetiresOnSaturation();
   2749     gl_->GetIntegerv(pv.pname, &v);
   2750     EXPECT_EQ(pv.expected, v);
   2751   }
   2752 }
   2753 
   2754 // glGen* Ids must not be reused until glDelete* commands have been
   2755 // flushed by glFlush.
   2756 TEST_F(GLES2ImplementationStrictSharedTest, FlushGenerationTestBuffers) {
   2757   FlushGenerationTest<GenBuffersAPI>();
   2758 }
   2759 TEST_F(GLES2ImplementationStrictSharedTest, FlushGenerationTestFramebuffers) {
   2760   FlushGenerationTest<GenFramebuffersAPI>();
   2761 }
   2762 TEST_F(GLES2ImplementationStrictSharedTest, FlushGenerationTestRenderbuffers) {
   2763   FlushGenerationTest<GenRenderbuffersAPI>();
   2764 }
   2765 TEST_F(GLES2ImplementationStrictSharedTest, FlushGenerationTestTextures) {
   2766   FlushGenerationTest<GenTexturesAPI>();
   2767 }
   2768 
   2769 // glGen* Ids must not be reused cross-context until glDelete* commands are
   2770 // flushed by glFlush, and the Ids are lazily freed after.
   2771 TEST_F(GLES2ImplementationStrictSharedTest, CrossContextGenerationTestBuffers) {
   2772   CrossContextGenerationTest<GenBuffersAPI>();
   2773 }
   2774 TEST_F(GLES2ImplementationStrictSharedTest,
   2775        CrossContextGenerationTestFramebuffers) {
   2776   CrossContextGenerationTest<GenFramebuffersAPI>();
   2777 }
   2778 TEST_F(GLES2ImplementationStrictSharedTest,
   2779        CrossContextGenerationTestRenderbuffers) {
   2780   CrossContextGenerationTest<GenRenderbuffersAPI>();
   2781 }
   2782 TEST_F(GLES2ImplementationStrictSharedTest,
   2783        CrossContextGenerationTestTextures) {
   2784   CrossContextGenerationTest<GenTexturesAPI>();
   2785 }
   2786 
   2787 // Test Delete which causes auto flush.  Tests a regression case that occurred
   2788 // in testing.
   2789 TEST_F(GLES2ImplementationStrictSharedTest,
   2790        CrossContextGenerationAutoFlushTestBuffers) {
   2791   CrossContextGenerationAutoFlushTest<GenBuffersAPI>();
   2792 }
   2793 TEST_F(GLES2ImplementationStrictSharedTest,
   2794        CrossContextGenerationAutoFlushTestFramebuffers) {
   2795   CrossContextGenerationAutoFlushTest<GenFramebuffersAPI>();
   2796 }
   2797 TEST_F(GLES2ImplementationStrictSharedTest,
   2798        CrossContextGenerationAutoFlushTestRenderbuffers) {
   2799   CrossContextGenerationAutoFlushTest<GenRenderbuffersAPI>();
   2800 }
   2801 TEST_F(GLES2ImplementationStrictSharedTest,
   2802        CrossContextGenerationAutoFlushTestTextures) {
   2803   CrossContextGenerationAutoFlushTest<GenTexturesAPI>();
   2804 }
   2805 
   2806 TEST_F(GLES2ImplementationTest, GetString) {
   2807   const uint32 kBucketId = GLES2Implementation::kResultBucketId;
   2808   const Str7 kString = {"foobar"};
   2809   // GL_CHROMIUM_map_sub GL_CHROMIUM_flipy are hard coded into
   2810   // GLES2Implementation.
   2811   const char* expected_str =
   2812       "foobar "
   2813       "GL_CHROMIUM_flipy "
   2814       "GL_EXT_unpack_subimage "
   2815       "GL_CHROMIUM_map_sub";
   2816   const char kBad = 0x12;
   2817   struct Cmds {
   2818     cmd::SetBucketSize set_bucket_size1;
   2819     cmds::GetString get_string;
   2820     cmd::GetBucketStart get_bucket_start;
   2821     cmd::SetToken set_token1;
   2822     cmd::SetBucketSize set_bucket_size2;
   2823   };
   2824   ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
   2825   ExpectedMemoryInfo result1 =
   2826       GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result));
   2827   Cmds expected;
   2828   expected.set_bucket_size1.Init(kBucketId, 0);
   2829   expected.get_string.Init(GL_EXTENSIONS, kBucketId);
   2830   expected.get_bucket_start.Init(
   2831       kBucketId, result1.id, result1.offset,
   2832       MaxTransferBufferSize(), mem1.id, mem1.offset);
   2833   expected.set_token1.Init(GetNextToken());
   2834   expected.set_bucket_size2.Init(kBucketId, 0);
   2835   char buf[sizeof(kString) + 1];
   2836   memset(buf, kBad, sizeof(buf));
   2837 
   2838   EXPECT_CALL(*command_buffer(), OnFlush())
   2839       .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))),
   2840                       SetMemory(mem1.ptr, kString)))
   2841       .RetiresOnSaturation();
   2842 
   2843   const GLubyte* result = gl_->GetString(GL_EXTENSIONS);
   2844   EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
   2845   EXPECT_STREQ(expected_str, reinterpret_cast<const char*>(result));
   2846 }
   2847 
   2848 TEST_F(GLES2ImplementationTest, PixelStoreiGLPackReverseRowOrderANGLE) {
   2849   const uint32 kBucketId = GLES2Implementation::kResultBucketId;
   2850   const Str7 kString = {"foobar"};
   2851   struct Cmds {
   2852     cmd::SetBucketSize set_bucket_size1;
   2853     cmds::GetString get_string;
   2854     cmd::GetBucketStart get_bucket_start;
   2855     cmd::SetToken set_token1;
   2856     cmd::SetBucketSize set_bucket_size2;
   2857     cmds::PixelStorei pixel_store;
   2858   };
   2859 
   2860   ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
   2861   ExpectedMemoryInfo result1 =
   2862       GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result));
   2863 
   2864   Cmds expected;
   2865   expected.set_bucket_size1.Init(kBucketId, 0);
   2866   expected.get_string.Init(GL_EXTENSIONS, kBucketId);
   2867   expected.get_bucket_start.Init(
   2868       kBucketId, result1.id, result1.offset,
   2869       MaxTransferBufferSize(), mem1.id, mem1.offset);
   2870   expected.set_token1.Init(GetNextToken());
   2871   expected.set_bucket_size2.Init(kBucketId, 0);
   2872   expected.pixel_store.Init(GL_PACK_REVERSE_ROW_ORDER_ANGLE, 1);
   2873 
   2874   EXPECT_CALL(*command_buffer(), OnFlush())
   2875       .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))),
   2876                       SetMemory(mem1.ptr, kString)))
   2877       .RetiresOnSaturation();
   2878 
   2879   gl_->PixelStorei(GL_PACK_REVERSE_ROW_ORDER_ANGLE, 1);
   2880   EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
   2881 }
   2882 
   2883 TEST_F(GLES2ImplementationTest, CreateProgram) {
   2884   struct Cmds {
   2885     cmds::CreateProgram cmd;
   2886   };
   2887 
   2888   Cmds expected;
   2889   expected.cmd.Init(kProgramsAndShadersStartId);
   2890   GLuint id = gl_->CreateProgram();
   2891   EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
   2892   EXPECT_EQ(kProgramsAndShadersStartId, id);
   2893 }
   2894 
   2895 TEST_F(GLES2ImplementationTest, BufferDataLargerThanTransferBuffer) {
   2896   struct Cmds {
   2897     cmds::BufferData set_size;
   2898     cmds::BufferSubData copy_data1;
   2899     cmd::SetToken set_token1;
   2900     cmds::BufferSubData copy_data2;
   2901     cmd::SetToken set_token2;
   2902   };
   2903   const unsigned kUsableSize =
   2904       kTransferBufferSize - GLES2Implementation::kStartingOffset;
   2905   uint8 buf[kUsableSize * 2] = { 0, };
   2906 
   2907   ExpectedMemoryInfo mem1 = GetExpectedMemory(kUsableSize);
   2908   ExpectedMemoryInfo mem2 = GetExpectedMemory(kUsableSize);
   2909 
   2910   Cmds expected;
   2911   expected.set_size.Init(
   2912       GL_ARRAY_BUFFER, arraysize(buf), 0, 0, GL_DYNAMIC_DRAW);
   2913   expected.copy_data1.Init(
   2914       GL_ARRAY_BUFFER, 0, kUsableSize, mem1.id, mem1.offset);
   2915   expected.set_token1.Init(GetNextToken());
   2916   expected.copy_data2.Init(
   2917       GL_ARRAY_BUFFER, kUsableSize, kUsableSize, mem2.id, mem2.offset);
   2918   expected.set_token2.Init(GetNextToken());
   2919   gl_->BufferData(GL_ARRAY_BUFFER, arraysize(buf), buf, GL_DYNAMIC_DRAW);
   2920   EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
   2921 }
   2922 
   2923 TEST_F(GLES2ImplementationTest, CapabilitiesAreCached) {
   2924   static const GLenum kStates[] = {
   2925     GL_DITHER,
   2926     GL_BLEND,
   2927     GL_CULL_FACE,
   2928     GL_DEPTH_TEST,
   2929     GL_POLYGON_OFFSET_FILL,
   2930     GL_SAMPLE_ALPHA_TO_COVERAGE,
   2931     GL_SAMPLE_COVERAGE,
   2932     GL_SCISSOR_TEST,
   2933     GL_STENCIL_TEST,
   2934   };
   2935   struct Cmds {
   2936     cmds::Enable enable_cmd;
   2937   };
   2938   Cmds expected;
   2939 
   2940   for (size_t ii = 0; ii < arraysize(kStates); ++ii) {
   2941     GLenum state = kStates[ii];
   2942     expected.enable_cmd.Init(state);
   2943     GLboolean result = gl_->IsEnabled(state);
   2944     EXPECT_EQ(static_cast<GLboolean>(ii == 0), result);
   2945     EXPECT_TRUE(NoCommandsWritten());
   2946     const void* commands = GetPut();
   2947     if (!result) {
   2948       gl_->Enable(state);
   2949       EXPECT_EQ(0, memcmp(&expected, commands, sizeof(expected)));
   2950     }
   2951     ClearCommands();
   2952     result = gl_->IsEnabled(state);
   2953     EXPECT_TRUE(result);
   2954     EXPECT_TRUE(NoCommandsWritten());
   2955   }
   2956 }
   2957 
   2958 TEST_F(GLES2ImplementationTest, BindVertexArrayOES) {
   2959   GLuint id = 0;
   2960   gl_->GenVertexArraysOES(1, &id);
   2961   ClearCommands();
   2962 
   2963   struct Cmds {
   2964     cmds::BindVertexArrayOES cmd;
   2965   };
   2966   Cmds expected;
   2967   expected.cmd.Init(id);
   2968 
   2969   const void* commands = GetPut();
   2970   gl_->BindVertexArrayOES(id);
   2971   EXPECT_EQ(0, memcmp(&expected, commands, sizeof(expected)));
   2972   ClearCommands();
   2973   gl_->BindVertexArrayOES(id);
   2974   EXPECT_TRUE(NoCommandsWritten());
   2975 }
   2976 
   2977 TEST_F(GLES2ImplementationTest, BeginEndQueryEXT) {
   2978   // Test GetQueryivEXT returns 0 if no current query.
   2979   GLint param = -1;
   2980   gl_->GetQueryivEXT(GL_ANY_SAMPLES_PASSED_EXT, GL_CURRENT_QUERY_EXT, &param);
   2981   EXPECT_EQ(0, param);
   2982 
   2983   GLuint expected_ids[2] = { 1, 2 }; // These must match what's actually genned.
   2984   struct GenCmds {
   2985     cmds::GenQueriesEXTImmediate gen;
   2986     GLuint data[2];
   2987   };
   2988   GenCmds expected_gen_cmds;
   2989   expected_gen_cmds.gen.Init(arraysize(expected_ids), &expected_ids[0]);
   2990   GLuint ids[arraysize(expected_ids)] = { 0, };
   2991   gl_->GenQueriesEXT(arraysize(expected_ids), &ids[0]);
   2992   EXPECT_EQ(0, memcmp(
   2993       &expected_gen_cmds, commands_, sizeof(expected_gen_cmds)));
   2994   GLuint id1 = ids[0];
   2995   GLuint id2 = ids[1];
   2996   ClearCommands();
   2997 
   2998   // Test BeginQueryEXT fails if id = 0.
   2999   gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, 0);
   3000   EXPECT_TRUE(NoCommandsWritten());
   3001   EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
   3002 
   3003   // Test BeginQueryEXT inserts command.
   3004   struct BeginCmds {
   3005     cmds::BeginQueryEXT begin_query;
   3006   };
   3007   BeginCmds expected_begin_cmds;
   3008   const void* commands = GetPut();
   3009   gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, id1);
   3010   QueryTracker::Query* query = GetQuery(id1);
   3011   ASSERT_TRUE(query != NULL);
   3012   expected_begin_cmds.begin_query.Init(
   3013       GL_ANY_SAMPLES_PASSED_EXT, id1, query->shm_id(), query->shm_offset());
   3014   EXPECT_EQ(0, memcmp(
   3015       &expected_begin_cmds, commands, sizeof(expected_begin_cmds)));
   3016   ClearCommands();
   3017 
   3018   // Test GetQueryivEXT returns id.
   3019   param = -1;
   3020   gl_->GetQueryivEXT(GL_ANY_SAMPLES_PASSED_EXT, GL_CURRENT_QUERY_EXT, &param);
   3021   EXPECT_EQ(id1, static_cast<GLuint>(param));
   3022   gl_->GetQueryivEXT(
   3023       GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, GL_CURRENT_QUERY_EXT, &param);
   3024   EXPECT_EQ(0, param);
   3025 
   3026   // Test BeginQueryEXT fails if between Begin/End.
   3027   gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, id2);
   3028   EXPECT_TRUE(NoCommandsWritten());
   3029   EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
   3030 
   3031   // Test EndQueryEXT fails if target not same as current query.
   3032   ClearCommands();
   3033   gl_->EndQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT);
   3034   EXPECT_TRUE(NoCommandsWritten());
   3035   EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
   3036 
   3037   // Test EndQueryEXT sends command
   3038   struct EndCmds {
   3039     cmds::EndQueryEXT end_query;
   3040   };
   3041   EndCmds expected_end_cmds;
   3042   expected_end_cmds.end_query.Init(
   3043       GL_ANY_SAMPLES_PASSED_EXT, query->submit_count());
   3044   commands = GetPut();
   3045   gl_->EndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
   3046   EXPECT_EQ(0, memcmp(
   3047       &expected_end_cmds, commands, sizeof(expected_end_cmds)));
   3048 
   3049   // Test EndQueryEXT fails if no current query.
   3050   ClearCommands();
   3051   gl_->EndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
   3052   EXPECT_TRUE(NoCommandsWritten());
   3053   EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
   3054 
   3055   // Test 2nd Begin/End increments count.
   3056   base::subtle::Atomic32 old_submit_count = query->submit_count();
   3057   gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, id1);
   3058   EXPECT_NE(old_submit_count, query->submit_count());
   3059   expected_end_cmds.end_query.Init(
   3060       GL_ANY_SAMPLES_PASSED_EXT, query->submit_count());
   3061   commands = GetPut();
   3062   gl_->EndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
   3063   EXPECT_EQ(0, memcmp(
   3064       &expected_end_cmds, commands, sizeof(expected_end_cmds)));
   3065 
   3066   // Test BeginQueryEXT fails if target changed.
   3067   ClearCommands();
   3068   gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, id1);
   3069   EXPECT_TRUE(NoCommandsWritten());
   3070   EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
   3071 
   3072   // Test GetQueryObjectuivEXT fails if unused id
   3073   GLuint available = 0xBDu;
   3074   ClearCommands();
   3075   gl_->GetQueryObjectuivEXT(id2, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
   3076   EXPECT_TRUE(NoCommandsWritten());
   3077   EXPECT_EQ(0xBDu, available);
   3078   EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
   3079 
   3080   // Test GetQueryObjectuivEXT fails if bad id
   3081   ClearCommands();
   3082   gl_->GetQueryObjectuivEXT(4567, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
   3083   EXPECT_TRUE(NoCommandsWritten());
   3084   EXPECT_EQ(0xBDu, available);
   3085   EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
   3086 
   3087   // Test GetQueryObjectuivEXT CheckResultsAvailable
   3088   ClearCommands();
   3089   gl_->GetQueryObjectuivEXT(id1, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
   3090   EXPECT_EQ(0u, available);
   3091 }
   3092 
   3093 TEST_F(GLES2ImplementationTest, ErrorQuery) {
   3094   GLuint id = 0;
   3095   gl_->GenQueriesEXT(1, &id);
   3096   ClearCommands();
   3097 
   3098   // Test BeginQueryEXT does NOT insert commands.
   3099   gl_->BeginQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM, id);
   3100   EXPECT_TRUE(NoCommandsWritten());
   3101   QueryTracker::Query* query = GetQuery(id);
   3102   ASSERT_TRUE(query != NULL);
   3103 
   3104   // Test EndQueryEXT sends both begin and end command
   3105   struct EndCmds {
   3106     cmds::BeginQueryEXT begin_query;
   3107     cmds::EndQueryEXT end_query;
   3108   };
   3109   EndCmds expected_end_cmds;
   3110   expected_end_cmds.begin_query.Init(
   3111       GL_GET_ERROR_QUERY_CHROMIUM, id, query->shm_id(), query->shm_offset());
   3112   expected_end_cmds.end_query.Init(
   3113       GL_GET_ERROR_QUERY_CHROMIUM, query->submit_count());
   3114   const void* commands = GetPut();
   3115   gl_->EndQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM);
   3116   EXPECT_EQ(0, memcmp(
   3117       &expected_end_cmds, commands, sizeof(expected_end_cmds)));
   3118   ClearCommands();
   3119 
   3120   // Check result is not yet available.
   3121   GLuint available = 0xBDu;
   3122   gl_->GetQueryObjectuivEXT(id, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
   3123   EXPECT_TRUE(NoCommandsWritten());
   3124   EXPECT_EQ(0u, available);
   3125 
   3126   // Test no commands are sent if there is a client side error.
   3127 
   3128   // Generate a client side error
   3129   gl_->ActiveTexture(GL_TEXTURE0 - 1);
   3130 
   3131   gl_->BeginQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM, id);
   3132   gl_->EndQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM);
   3133   EXPECT_TRUE(NoCommandsWritten());
   3134 
   3135   // Check result is available.
   3136   gl_->GetQueryObjectuivEXT(id, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
   3137   EXPECT_TRUE(NoCommandsWritten());
   3138   EXPECT_NE(0u, available);
   3139 
   3140   // Check result.
   3141   GLuint result = 0xBDu;
   3142   gl_->GetQueryObjectuivEXT(id, GL_QUERY_RESULT_EXT, &result);
   3143   EXPECT_TRUE(NoCommandsWritten());
   3144   EXPECT_EQ(static_cast<GLuint>(GL_INVALID_ENUM), result);
   3145 }
   3146 
   3147 #if !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
   3148 TEST_F(GLES2ImplementationTest, VertexArrays) {
   3149   const GLuint kAttribIndex1 = 1;
   3150   const GLint kNumComponents1 = 3;
   3151   const GLsizei kClientStride = 12;
   3152 
   3153   GLuint id = 0;
   3154   gl_->GenVertexArraysOES(1, &id);
   3155   ClearCommands();
   3156 
   3157   gl_->BindVertexArrayOES(id);
   3158 
   3159   // Test that VertexAttribPointer cannot be called with a bound buffer of 0
   3160   // unless the offset is NULL
   3161   gl_->BindBuffer(GL_ARRAY_BUFFER, 0);
   3162 
   3163   gl_->VertexAttribPointer(
   3164       kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, kClientStride,
   3165       reinterpret_cast<const void*>(4));
   3166   EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
   3167 
   3168   gl_->VertexAttribPointer(
   3169       kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, kClientStride, NULL);
   3170   EXPECT_EQ(GL_NO_ERROR, CheckError());
   3171 }
   3172 #endif
   3173 
   3174 TEST_F(GLES2ImplementationTest, Disable) {
   3175   struct Cmds {
   3176     cmds::Disable cmd;
   3177   };
   3178   Cmds expected;
   3179   expected.cmd.Init(GL_DITHER);  // Note: DITHER defaults to enabled.
   3180 
   3181   gl_->Disable(GL_DITHER);
   3182   EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
   3183   // Check it's cached and not called again.
   3184   ClearCommands();
   3185   gl_->Disable(GL_DITHER);
   3186   EXPECT_TRUE(NoCommandsWritten());
   3187 }
   3188 
   3189 TEST_F(GLES2ImplementationTest, Enable) {
   3190   struct Cmds {
   3191     cmds::Enable cmd;
   3192   };
   3193   Cmds expected;
   3194   expected.cmd.Init(GL_BLEND);  // Note: BLEND defaults to disabled.
   3195 
   3196   gl_->Enable(GL_BLEND);
   3197   EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
   3198   // Check it's cached and not called again.
   3199   ClearCommands();
   3200   gl_->Enable(GL_BLEND);
   3201   EXPECT_TRUE(NoCommandsWritten());
   3202 }
   3203 
   3204 TEST_F(GLES2ImplementationTest, ConsumeTextureCHROMIUM) {
   3205   struct Cmds {
   3206     cmds::ConsumeTextureCHROMIUMImmediate cmd;
   3207     GLbyte data[64];
   3208   };
   3209 
   3210   Mailbox mailbox = Mailbox::Generate();
   3211   Cmds expected;
   3212   expected.cmd.Init(GL_TEXTURE_2D, mailbox.name);
   3213   gl_->ConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
   3214   EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
   3215 }
   3216 
   3217 TEST_F(GLES2ImplementationTest, CreateAndConsumeTextureCHROMIUM) {
   3218   struct Cmds {
   3219     cmds::CreateAndConsumeTextureCHROMIUMImmediate cmd;
   3220     GLbyte data[64];
   3221   };
   3222 
   3223   Mailbox mailbox = Mailbox::Generate();
   3224   Cmds expected;
   3225   expected.cmd.Init(GL_TEXTURE_2D, kTexturesStartId, mailbox.name);
   3226   GLuint id = gl_->CreateAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
   3227   EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
   3228   EXPECT_EQ(kTexturesStartId, id);
   3229 }
   3230 
   3231 TEST_F(GLES2ImplementationTest, ProduceTextureCHROMIUM) {
   3232   struct Cmds {
   3233     cmds::ProduceTextureCHROMIUMImmediate cmd;
   3234     GLbyte data[64];
   3235   };
   3236 
   3237   Mailbox mailbox = Mailbox::Generate();
   3238   Cmds expected;
   3239   expected.cmd.Init(GL_TEXTURE_2D, mailbox.name);
   3240   gl_->ProduceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
   3241   EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
   3242 }
   3243 
   3244 TEST_F(GLES2ImplementationTest, ProduceTextureDirectCHROMIUM) {
   3245   struct Cmds {
   3246     cmds::ProduceTextureDirectCHROMIUMImmediate cmd;
   3247     GLbyte data[64];
   3248   };
   3249 
   3250   Mailbox mailbox = Mailbox::Generate();
   3251   Cmds expected;
   3252   expected.cmd.Init(kTexturesStartId, GL_TEXTURE_2D, mailbox.name);
   3253   gl_->ProduceTextureDirectCHROMIUM(
   3254       kTexturesStartId, GL_TEXTURE_2D, mailbox.name);
   3255   EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
   3256 }
   3257 
   3258 TEST_F(GLES2ImplementationTest, LimitSizeAndOffsetTo32Bit) {
   3259   GLsizeiptr size;
   3260   GLintptr offset;
   3261   if (sizeof(size) <= 4 || sizeof(offset) <= 4)
   3262     return;
   3263   // The below two casts should be no-op, as we return early if
   3264   // it's 32-bit system.
   3265   int64 value64 = 0x100000000;
   3266   size = static_cast<GLsizeiptr>(value64);
   3267   offset = static_cast<GLintptr>(value64);
   3268 
   3269   const char kSizeOverflowMessage[] = "size more than 32-bit";
   3270   const char kOffsetOverflowMessage[] = "offset more than 32-bit";
   3271 
   3272   const GLfloat buf[] = { 1.0, 1.0, 1.0, 1.0 };
   3273   const GLubyte indices[] = { 0 };
   3274 
   3275   const GLuint kClientArrayBufferId = 0x789;
   3276   const GLuint kClientElementArrayBufferId = 0x790;
   3277   gl_->BindBuffer(GL_ARRAY_BUFFER, kClientArrayBufferId);
   3278   gl_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, kClientElementArrayBufferId);
   3279   EXPECT_EQ(GL_NO_ERROR, CheckError());
   3280 
   3281   // Call BufferData() should succeed with legal paramaters.
   3282   gl_->BufferData(GL_ARRAY_BUFFER, sizeof(buf), buf, GL_DYNAMIC_DRAW);
   3283   gl_->BufferData(
   3284       GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_DYNAMIC_DRAW);
   3285   EXPECT_EQ(GL_NO_ERROR, CheckError());
   3286 
   3287   // BufferData: size
   3288   gl_->BufferData(GL_ARRAY_BUFFER, size, buf, GL_DYNAMIC_DRAW);
   3289   EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
   3290   EXPECT_STREQ(kSizeOverflowMessage, GetLastError().c_str());
   3291 
   3292   // Call BufferSubData() should succeed with legal paramaters.
   3293   gl_->BufferSubData(GL_ARRAY_BUFFER, 0, sizeof(buf[0]), buf);
   3294   EXPECT_EQ(GL_NO_ERROR, CheckError());
   3295 
   3296   // BufferSubData: offset
   3297   gl_->BufferSubData(GL_ARRAY_BUFFER, offset, 1, buf);
   3298   EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
   3299   EXPECT_STREQ(kOffsetOverflowMessage, GetLastError().c_str());
   3300 
   3301   // BufferSubData: size
   3302   EXPECT_EQ(GL_NO_ERROR, CheckError());
   3303   gl_->BufferSubData(GL_ARRAY_BUFFER, 0, size, buf);
   3304   EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
   3305   EXPECT_STREQ(kSizeOverflowMessage, GetLastError().c_str());
   3306 
   3307   // Call MapBufferSubDataCHROMIUM() should succeed with legal paramaters.
   3308   void* mem =
   3309       gl_->MapBufferSubDataCHROMIUM(GL_ARRAY_BUFFER, 0, 1, GL_WRITE_ONLY);
   3310   EXPECT_TRUE(NULL != mem);
   3311   EXPECT_EQ(GL_NO_ERROR, CheckError());
   3312   gl_->UnmapBufferSubDataCHROMIUM(mem);
   3313 
   3314   // MapBufferSubDataCHROMIUM: offset
   3315   EXPECT_TRUE(NULL == gl_->MapBufferSubDataCHROMIUM(
   3316       GL_ARRAY_BUFFER, offset, 1, GL_WRITE_ONLY));
   3317   EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
   3318   EXPECT_STREQ(kOffsetOverflowMessage, GetLastError().c_str());
   3319 
   3320   // MapBufferSubDataCHROMIUM: size
   3321   EXPECT_EQ(GL_NO_ERROR, CheckError());
   3322   EXPECT_TRUE(NULL == gl_->MapBufferSubDataCHROMIUM(
   3323       GL_ARRAY_BUFFER, 0, size, GL_WRITE_ONLY));
   3324   EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
   3325   EXPECT_STREQ(kSizeOverflowMessage, GetLastError().c_str());
   3326 
   3327   // Call DrawElements() should succeed with legal paramaters.
   3328   gl_->DrawElements(GL_POINTS, 1, GL_UNSIGNED_BYTE, NULL);
   3329   EXPECT_EQ(GL_NO_ERROR, CheckError());
   3330 
   3331   // DrawElements: offset
   3332   gl_->DrawElements(
   3333       GL_POINTS, 1, GL_UNSIGNED_BYTE, reinterpret_cast<void*>(offset));
   3334   EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
   3335   EXPECT_STREQ(kOffsetOverflowMessage, GetLastError().c_str());
   3336 
   3337   // Call DrawElementsInstancedANGLE() should succeed with legal paramaters.
   3338   gl_->DrawElementsInstancedANGLE(GL_POINTS, 1, GL_UNSIGNED_BYTE, NULL, 1);
   3339   EXPECT_EQ(GL_NO_ERROR, CheckError());
   3340 
   3341   // DrawElementsInstancedANGLE: offset
   3342   gl_->DrawElementsInstancedANGLE(
   3343       GL_POINTS, 1, GL_UNSIGNED_BYTE, reinterpret_cast<void*>(offset), 1);
   3344   EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
   3345   EXPECT_STREQ(kOffsetOverflowMessage, GetLastError().c_str());
   3346 
   3347   // Call VertexAttribPointer() should succeed with legal paramaters.
   3348   const GLuint kAttribIndex = 1;
   3349   const GLsizei kStride = 4;
   3350   gl_->VertexAttribPointer(
   3351       kAttribIndex, 1, GL_FLOAT, GL_FALSE, kStride, NULL);
   3352   EXPECT_EQ(GL_NO_ERROR, CheckError());
   3353 
   3354   // VertexAttribPointer: offset
   3355   gl_->VertexAttribPointer(
   3356       kAttribIndex, 1, GL_FLOAT, GL_FALSE, kStride,
   3357       reinterpret_cast<void*>(offset));
   3358   EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
   3359   EXPECT_STREQ(kOffsetOverflowMessage, GetLastError().c_str());
   3360 }
   3361 
   3362 TEST_F(GLES2ImplementationManualInitTest, LoseContextOnOOM) {
   3363   ContextInitOptions init_options;
   3364   init_options.lose_context_when_out_of_memory = true;
   3365   ASSERT_TRUE(Initialize(init_options));
   3366 
   3367   struct Cmds {
   3368     cmds::LoseContextCHROMIUM cmd;
   3369   };
   3370 
   3371   GLsizei max = std::numeric_limits<GLsizei>::max();
   3372   EXPECT_CALL(*gpu_control_, CreateGpuMemoryBuffer(max, max, _, _, _))
   3373       .WillOnce(Return(static_cast<gfx::GpuMemoryBuffer*>(NULL)));
   3374   gl_->CreateImageCHROMIUM(max, max, 0, GL_IMAGE_MAP_CHROMIUM);
   3375   // The context should be lost.
   3376   Cmds expected;
   3377   expected.cmd.Init(GL_GUILTY_CONTEXT_RESET_ARB, GL_UNKNOWN_CONTEXT_RESET_ARB);
   3378   EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
   3379 }
   3380 
   3381 TEST_F(GLES2ImplementationManualInitTest, NoLoseContextOnOOM) {
   3382   ContextInitOptions init_options;
   3383   ASSERT_TRUE(Initialize(init_options));
   3384 
   3385   struct Cmds {
   3386     cmds::LoseContextCHROMIUM cmd;
   3387   };
   3388 
   3389   GLsizei max = std::numeric_limits<GLsizei>::max();
   3390   EXPECT_CALL(*gpu_control_, CreateGpuMemoryBuffer(max, max, _, _, _))
   3391       .WillOnce(Return(static_cast<gfx::GpuMemoryBuffer*>(NULL)));
   3392   gl_->CreateImageCHROMIUM(max, max, 0, GL_IMAGE_MAP_CHROMIUM);
   3393   // The context should not be lost.
   3394   EXPECT_TRUE(NoCommandsWritten());
   3395 }
   3396 
   3397 TEST_F(GLES2ImplementationManualInitTest, FailInitOnBGRMismatch1) {
   3398   ContextInitOptions init_options;
   3399   init_options.bind_generates_resource_client = false;
   3400   init_options.bind_generates_resource_service = true;
   3401   EXPECT_FALSE(Initialize(init_options));
   3402 }
   3403 
   3404 TEST_F(GLES2ImplementationManualInitTest, FailInitOnBGRMismatch2) {
   3405   ContextInitOptions init_options;
   3406   init_options.bind_generates_resource_client = true;
   3407   init_options.bind_generates_resource_service = false;
   3408   EXPECT_FALSE(Initialize(init_options));
   3409 }
   3410 
   3411 #include "gpu/command_buffer/client/gles2_implementation_unittest_autogen.h"
   3412 
   3413 }  // namespace gles2
   3414 }  // namespace gpu
   3415