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