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