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