Home | History | Annotate | Download | only in service
      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 #include "gpu/command_buffer/service/buffer_manager.h"
      6 #include "gpu/command_buffer/service/error_state_mock.h"
      7 #include "gpu/command_buffer/service/feature_info.h"
      8 #include "gpu/command_buffer/service/gpu_service_test.h"
      9 #include "gpu/command_buffer/service/mocks.h"
     10 #include "gpu/command_buffer/service/test_helper.h"
     11 #include "testing/gtest/include/gtest/gtest.h"
     12 #include "ui/gl/gl_mock.h"
     13 
     14 using ::testing::_;
     15 using ::testing::Return;
     16 using ::testing::StrictMock;
     17 
     18 namespace gpu {
     19 namespace gles2 {
     20 
     21 class BufferManagerTestBase : public GpuServiceTest {
     22  protected:
     23   void SetUpBase(
     24       MemoryTracker* memory_tracker,
     25       FeatureInfo* feature_info,
     26       const char* extensions) {
     27     GpuServiceTest::SetUp();
     28     if (feature_info) {
     29       TestHelper::SetupFeatureInfoInitExpectations(gl_.get(), extensions);
     30       feature_info->Initialize();
     31     }
     32     error_state_.reset(new MockErrorState());
     33     manager_.reset(new BufferManager(memory_tracker, feature_info));
     34   }
     35 
     36   virtual void TearDown() {
     37     manager_->Destroy(false);
     38     manager_.reset();
     39     error_state_.reset();
     40     GpuServiceTest::TearDown();
     41   }
     42 
     43   GLenum GetTarget(const Buffer* buffer) const {
     44     return buffer->target();
     45   }
     46 
     47   void DoBufferData(
     48       Buffer* buffer, GLsizeiptr size, GLenum usage, const GLvoid* data,
     49       GLenum error) {
     50     TestHelper::DoBufferData(
     51         gl_.get(), error_state_.get(), manager_.get(),
     52         buffer, size, usage, data, error);
     53   }
     54 
     55   bool DoBufferSubData(
     56       Buffer* buffer, GLintptr offset, GLsizeiptr size,
     57       const GLvoid* data) {
     58     bool success = true;
     59     if (!buffer->CheckRange(offset, size)) {
     60       EXPECT_CALL(*error_state_, SetGLError(_, _, GL_INVALID_VALUE, _, _))
     61          .Times(1)
     62          .RetiresOnSaturation();
     63       success = false;
     64     } else if (!buffer->IsClientSideArray()) {
     65       EXPECT_CALL(*gl_, BufferSubData(
     66           buffer->target(), offset, size, _))
     67           .Times(1)
     68           .RetiresOnSaturation();
     69     }
     70     manager_->DoBufferSubData(
     71         error_state_.get(), buffer, offset, size, data);
     72     return success;
     73   }
     74 
     75   scoped_ptr<BufferManager> manager_;
     76   scoped_ptr<MockErrorState> error_state_;
     77 };
     78 
     79 class BufferManagerTest : public BufferManagerTestBase {
     80  protected:
     81   virtual void SetUp() {
     82     SetUpBase(NULL, NULL, "");
     83   }
     84 };
     85 
     86 class BufferManagerMemoryTrackerTest : public BufferManagerTestBase {
     87  protected:
     88   virtual void SetUp() {
     89     mock_memory_tracker_ = new StrictMock<MockMemoryTracker>();
     90     SetUpBase(mock_memory_tracker_.get(), NULL, "");
     91   }
     92 
     93   scoped_refptr<MockMemoryTracker> mock_memory_tracker_;
     94 };
     95 
     96 class BufferManagerClientSideArraysTest : public BufferManagerTestBase {
     97  protected:
     98   virtual void SetUp() {
     99     feature_info_ = new FeatureInfo();
    100     feature_info_->workarounds_.use_client_side_arrays_for_stream_buffers =
    101       true;
    102     SetUpBase(NULL, feature_info_.get(), "");
    103   }
    104 
    105   scoped_refptr<FeatureInfo> feature_info_;
    106 };
    107 
    108 #define EXPECT_MEMORY_ALLOCATION_CHANGE(old_size, new_size, pool)   \
    109   EXPECT_CALL(*mock_memory_tracker_.get(),                          \
    110               TrackMemoryAllocatedChange(old_size, new_size, pool)) \
    111       .Times(1).RetiresOnSaturation()
    112 
    113 TEST_F(BufferManagerTest, Basic) {
    114   const GLuint kClientBuffer1Id = 1;
    115   const GLuint kServiceBuffer1Id = 11;
    116   const GLsizeiptr kBuffer1Size = 123;
    117   const GLuint kClientBuffer2Id = 2;
    118   // Check we can create buffer.
    119   manager_->CreateBuffer(kClientBuffer1Id, kServiceBuffer1Id);
    120   // Check buffer got created.
    121   Buffer* buffer1 = manager_->GetBuffer(kClientBuffer1Id);
    122   ASSERT_TRUE(buffer1 != NULL);
    123   EXPECT_EQ(0u, GetTarget(buffer1));
    124   EXPECT_EQ(0, buffer1->size());
    125   EXPECT_EQ(static_cast<GLenum>(GL_STATIC_DRAW), buffer1->usage());
    126   EXPECT_FALSE(buffer1->IsDeleted());
    127   EXPECT_FALSE(buffer1->IsClientSideArray());
    128   EXPECT_EQ(kServiceBuffer1Id, buffer1->service_id());
    129   GLuint client_id = 0;
    130   EXPECT_TRUE(manager_->GetClientId(buffer1->service_id(), &client_id));
    131   EXPECT_EQ(kClientBuffer1Id, client_id);
    132   manager_->SetTarget(buffer1, GL_ELEMENT_ARRAY_BUFFER);
    133   EXPECT_EQ(static_cast<GLenum>(GL_ELEMENT_ARRAY_BUFFER), GetTarget(buffer1));
    134   // Check we and set its size.
    135   DoBufferData(buffer1, kBuffer1Size, GL_DYNAMIC_DRAW, NULL, GL_NO_ERROR);
    136   EXPECT_EQ(kBuffer1Size, buffer1->size());
    137   EXPECT_EQ(static_cast<GLenum>(GL_DYNAMIC_DRAW), buffer1->usage());
    138   // Check we get nothing for a non-existent buffer.
    139   EXPECT_TRUE(manager_->GetBuffer(kClientBuffer2Id) == NULL);
    140   // Check trying to a remove non-existent buffers does not crash.
    141   manager_->RemoveBuffer(kClientBuffer2Id);
    142   // Check that it gets deleted when the last reference is released.
    143   EXPECT_CALL(*gl_, DeleteBuffersARB(1, ::testing::Pointee(kServiceBuffer1Id)))
    144       .Times(1)
    145       .RetiresOnSaturation();
    146   // Check we can't get the buffer after we remove it.
    147   manager_->RemoveBuffer(kClientBuffer1Id);
    148   EXPECT_TRUE(manager_->GetBuffer(kClientBuffer1Id) == NULL);
    149 }
    150 
    151 TEST_F(BufferManagerMemoryTrackerTest, Basic) {
    152   const GLuint kClientBuffer1Id = 1;
    153   const GLuint kServiceBuffer1Id = 11;
    154   const GLsizeiptr kBuffer1Size1 = 123;
    155   const GLsizeiptr kBuffer1Size2 = 456;
    156   // Check we can create buffer.
    157   EXPECT_MEMORY_ALLOCATION_CHANGE(0, 0, MemoryTracker::kManaged);
    158   manager_->CreateBuffer(kClientBuffer1Id, kServiceBuffer1Id);
    159   // Check buffer got created.
    160   Buffer* buffer1 = manager_->GetBuffer(kClientBuffer1Id);
    161   ASSERT_TRUE(buffer1 != NULL);
    162   manager_->SetTarget(buffer1, GL_ELEMENT_ARRAY_BUFFER);
    163   // Check we and set its size.
    164   EXPECT_MEMORY_ALLOCATION_CHANGE(0, kBuffer1Size1, MemoryTracker::kManaged);
    165   DoBufferData(buffer1, kBuffer1Size1, GL_DYNAMIC_DRAW, NULL, GL_NO_ERROR);
    166   EXPECT_MEMORY_ALLOCATION_CHANGE(kBuffer1Size1, 0, MemoryTracker::kManaged);
    167   EXPECT_MEMORY_ALLOCATION_CHANGE(0, kBuffer1Size2, MemoryTracker::kManaged);
    168   DoBufferData(buffer1, kBuffer1Size2, GL_DYNAMIC_DRAW, NULL, GL_NO_ERROR);
    169   // On delete it will get freed.
    170   EXPECT_MEMORY_ALLOCATION_CHANGE(kBuffer1Size2, 0, MemoryTracker::kManaged);
    171 }
    172 
    173 TEST_F(BufferManagerTest, Destroy) {
    174   const GLuint kClient1Id = 1;
    175   const GLuint kService1Id = 11;
    176   // Check we can create buffer.
    177   manager_->CreateBuffer(kClient1Id, kService1Id);
    178   // Check buffer got created.
    179   Buffer* buffer1 = manager_->GetBuffer(kClient1Id);
    180   ASSERT_TRUE(buffer1 != NULL);
    181   EXPECT_CALL(*gl_, DeleteBuffersARB(1, ::testing::Pointee(kService1Id)))
    182       .Times(1)
    183       .RetiresOnSaturation();
    184   manager_->Destroy(true);
    185   // Check the resources were released.
    186   buffer1 = manager_->GetBuffer(kClient1Id);
    187   ASSERT_TRUE(buffer1 == NULL);
    188 }
    189 
    190 TEST_F(BufferManagerTest, DoBufferSubData) {
    191   const GLuint kClientBufferId = 1;
    192   const GLuint kServiceBufferId = 11;
    193   const uint8 data[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
    194   manager_->CreateBuffer(kClientBufferId, kServiceBufferId);
    195   Buffer* buffer = manager_->GetBuffer(kClientBufferId);
    196   ASSERT_TRUE(buffer != NULL);
    197   manager_->SetTarget(buffer, GL_ELEMENT_ARRAY_BUFFER);
    198   DoBufferData(buffer, sizeof(data), GL_STATIC_DRAW, NULL, GL_NO_ERROR);
    199   EXPECT_TRUE(DoBufferSubData(buffer, 0, sizeof(data), data));
    200   EXPECT_TRUE(DoBufferSubData(buffer, sizeof(data), 0, data));
    201   EXPECT_FALSE(DoBufferSubData(buffer, sizeof(data), 1, data));
    202   EXPECT_FALSE(DoBufferSubData(buffer, 0, sizeof(data) + 1, data));
    203   EXPECT_FALSE(DoBufferSubData(buffer, -1, sizeof(data), data));
    204   EXPECT_FALSE(DoBufferSubData(buffer, 0, -1, data));
    205   DoBufferData(buffer, 1, GL_STATIC_DRAW, NULL, GL_NO_ERROR);
    206   const int size = 0x20000;
    207   scoped_ptr<uint8[]> temp(new uint8[size]);
    208   EXPECT_FALSE(DoBufferSubData(buffer, 0 - size, size, temp.get()));
    209   EXPECT_FALSE(DoBufferSubData(buffer, 1, size / 2, temp.get()));
    210 }
    211 
    212 TEST_F(BufferManagerTest, GetRange) {
    213   const GLuint kClientBufferId = 1;
    214   const GLuint kServiceBufferId = 11;
    215   const uint8 data[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
    216   manager_->CreateBuffer(kClientBufferId, kServiceBufferId);
    217   Buffer* buffer = manager_->GetBuffer(kClientBufferId);
    218   ASSERT_TRUE(buffer != NULL);
    219   manager_->SetTarget(buffer, GL_ELEMENT_ARRAY_BUFFER);
    220   DoBufferData(buffer, sizeof(data), GL_STATIC_DRAW, NULL, GL_NO_ERROR);
    221   const char* buf =
    222       static_cast<const char*>(buffer->GetRange(0, sizeof(data)));
    223   ASSERT_TRUE(buf != NULL);
    224   const char* buf1 =
    225       static_cast<const char*>(buffer->GetRange(1, sizeof(data) - 1));
    226   EXPECT_EQ(buf + 1, buf1);
    227   EXPECT_TRUE(buffer->GetRange(sizeof(data), 1) == NULL);
    228   EXPECT_TRUE(buffer->GetRange(0, sizeof(data) + 1) == NULL);
    229   EXPECT_TRUE(buffer->GetRange(-1, sizeof(data)) == NULL);
    230   EXPECT_TRUE(buffer->GetRange(-0, -1) == NULL);
    231   const int size = 0x20000;
    232   DoBufferData(buffer, size / 2, GL_STATIC_DRAW, NULL, GL_NO_ERROR);
    233   EXPECT_TRUE(buffer->GetRange(0 - size, size) == NULL);
    234   EXPECT_TRUE(buffer->GetRange(1, size / 2) == NULL);
    235 }
    236 
    237 TEST_F(BufferManagerTest, GetMaxValueForRangeUint8) {
    238   const GLuint kClientBufferId = 1;
    239   const GLuint kServiceBufferId = 11;
    240   const uint8 data[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
    241   const uint8 new_data[] = {100, 120, 110};
    242   manager_->CreateBuffer(kClientBufferId, kServiceBufferId);
    243   Buffer* buffer = manager_->GetBuffer(kClientBufferId);
    244   ASSERT_TRUE(buffer != NULL);
    245   manager_->SetTarget(buffer, GL_ELEMENT_ARRAY_BUFFER);
    246   DoBufferData(buffer, sizeof(data), GL_STATIC_DRAW, NULL, GL_NO_ERROR);
    247   EXPECT_TRUE(DoBufferSubData(buffer, 0, sizeof(data), data));
    248   GLuint max_value;
    249   // Check entire range succeeds.
    250   EXPECT_TRUE(buffer->GetMaxValueForRange(
    251       0, 10, GL_UNSIGNED_BYTE, &max_value));
    252   EXPECT_EQ(10u, max_value);
    253   // Check sub range succeeds.
    254   EXPECT_TRUE(buffer->GetMaxValueForRange(
    255       4, 3, GL_UNSIGNED_BYTE, &max_value));
    256   EXPECT_EQ(6u, max_value);
    257   // Check changing sub range succeeds.
    258   EXPECT_TRUE(DoBufferSubData(buffer, 4, sizeof(new_data), new_data));
    259   EXPECT_TRUE(buffer->GetMaxValueForRange(
    260       4, 3, GL_UNSIGNED_BYTE, &max_value));
    261   EXPECT_EQ(120u, max_value);
    262   max_value = 0;
    263   EXPECT_TRUE(buffer->GetMaxValueForRange(
    264       0, 10, GL_UNSIGNED_BYTE, &max_value));
    265   EXPECT_EQ(120u, max_value);
    266   // Check out of range fails.
    267   EXPECT_FALSE(buffer->GetMaxValueForRange(
    268       0, 11, GL_UNSIGNED_BYTE, &max_value));
    269   EXPECT_FALSE(buffer->GetMaxValueForRange(
    270       10, 1, GL_UNSIGNED_BYTE, &max_value));
    271 }
    272 
    273 TEST_F(BufferManagerTest, GetMaxValueForRangeUint16) {
    274   const GLuint kClientBufferId = 1;
    275   const GLuint kServiceBufferId = 11;
    276   const uint16 data[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
    277   const uint16 new_data[] = {100, 120, 110};
    278   manager_->CreateBuffer(kClientBufferId, kServiceBufferId);
    279   Buffer* buffer = manager_->GetBuffer(kClientBufferId);
    280   ASSERT_TRUE(buffer != NULL);
    281   manager_->SetTarget(buffer, GL_ELEMENT_ARRAY_BUFFER);
    282   DoBufferData(buffer, sizeof(data), GL_STATIC_DRAW, NULL, GL_NO_ERROR);
    283   EXPECT_TRUE(DoBufferSubData(buffer, 0, sizeof(data), data));
    284   GLuint max_value;
    285   // Check entire range succeeds.
    286   EXPECT_TRUE(buffer->GetMaxValueForRange(
    287       0, 10, GL_UNSIGNED_SHORT, &max_value));
    288   EXPECT_EQ(10u, max_value);
    289   // Check odd offset fails for GL_UNSIGNED_SHORT.
    290   EXPECT_FALSE(buffer->GetMaxValueForRange(
    291       1, 10, GL_UNSIGNED_SHORT, &max_value));
    292   // Check sub range succeeds.
    293   EXPECT_TRUE(buffer->GetMaxValueForRange(
    294       8, 3, GL_UNSIGNED_SHORT, &max_value));
    295   EXPECT_EQ(6u, max_value);
    296   // Check changing sub range succeeds.
    297   EXPECT_TRUE(DoBufferSubData(buffer, 8, sizeof(new_data), new_data));
    298   EXPECT_TRUE(buffer->GetMaxValueForRange(
    299       8, 3, GL_UNSIGNED_SHORT, &max_value));
    300   EXPECT_EQ(120u, max_value);
    301   max_value = 0;
    302   EXPECT_TRUE(buffer->GetMaxValueForRange(
    303       0, 10, GL_UNSIGNED_SHORT, &max_value));
    304   EXPECT_EQ(120u, max_value);
    305   // Check out of range fails.
    306   EXPECT_FALSE(buffer->GetMaxValueForRange(
    307       0, 11, GL_UNSIGNED_SHORT, &max_value));
    308   EXPECT_FALSE(buffer->GetMaxValueForRange(
    309       20, 1, GL_UNSIGNED_SHORT, &max_value));
    310 }
    311 
    312 TEST_F(BufferManagerTest, GetMaxValueForRangeUint32) {
    313   const GLuint kClientBufferId = 1;
    314   const GLuint kServiceBufferId = 11;
    315   const uint32 data[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
    316   const uint32 new_data[] = {100, 120, 110};
    317   manager_->CreateBuffer(kClientBufferId, kServiceBufferId);
    318   Buffer* buffer = manager_->GetBuffer(kClientBufferId);
    319   ASSERT_TRUE(buffer != NULL);
    320   manager_->SetTarget(buffer, GL_ELEMENT_ARRAY_BUFFER);
    321   DoBufferData(buffer, sizeof(data), GL_STATIC_DRAW, NULL, GL_NO_ERROR);
    322   EXPECT_TRUE(DoBufferSubData(buffer, 0, sizeof(data), data));
    323   GLuint max_value;
    324   // Check entire range succeeds.
    325   EXPECT_TRUE(
    326       buffer->GetMaxValueForRange(0, 10, GL_UNSIGNED_INT, &max_value));
    327   EXPECT_EQ(10u, max_value);
    328   // Check non aligned offsets fails for GL_UNSIGNED_INT.
    329   EXPECT_FALSE(
    330       buffer->GetMaxValueForRange(1, 10, GL_UNSIGNED_INT, &max_value));
    331   EXPECT_FALSE(
    332       buffer->GetMaxValueForRange(2, 10, GL_UNSIGNED_INT, &max_value));
    333   EXPECT_FALSE(
    334       buffer->GetMaxValueForRange(3, 10, GL_UNSIGNED_INT, &max_value));
    335   // Check sub range succeeds.
    336   EXPECT_TRUE(buffer->GetMaxValueForRange(16, 3, GL_UNSIGNED_INT, &max_value));
    337   EXPECT_EQ(6u, max_value);
    338   // Check changing sub range succeeds.
    339   EXPECT_TRUE(DoBufferSubData(buffer, 16, sizeof(new_data), new_data));
    340   EXPECT_TRUE(buffer->GetMaxValueForRange(16, 3, GL_UNSIGNED_INT, &max_value));
    341   EXPECT_EQ(120u, max_value);
    342   max_value = 0;
    343   EXPECT_TRUE(buffer->GetMaxValueForRange(0, 10, GL_UNSIGNED_INT, &max_value));
    344   EXPECT_EQ(120u, max_value);
    345   // Check out of range fails.
    346   EXPECT_FALSE(
    347       buffer->GetMaxValueForRange(0, 11, GL_UNSIGNED_INT, &max_value));
    348   EXPECT_FALSE(
    349       buffer->GetMaxValueForRange(40, 1, GL_UNSIGNED_INT, &max_value));
    350 }
    351 
    352 TEST_F(BufferManagerTest, UseDeletedBuffer) {
    353   const GLuint kClientBufferId = 1;
    354   const GLuint kServiceBufferId = 11;
    355   const uint32 data[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
    356   manager_->CreateBuffer(kClientBufferId, kServiceBufferId);
    357   scoped_refptr<Buffer> buffer = manager_->GetBuffer(kClientBufferId);
    358   ASSERT_TRUE(buffer.get() != NULL);
    359   manager_->SetTarget(buffer.get(), GL_ARRAY_BUFFER);
    360   // Remove buffer
    361   manager_->RemoveBuffer(kClientBufferId);
    362   // Use it after removing
    363   DoBufferData(buffer.get(), sizeof(data), GL_STATIC_DRAW, NULL, GL_NO_ERROR);
    364   // Check that it gets deleted when the last reference is released.
    365   EXPECT_CALL(*gl_, DeleteBuffersARB(1, ::testing::Pointee(kServiceBufferId)))
    366       .Times(1)
    367       .RetiresOnSaturation();
    368   buffer = NULL;
    369 }
    370 
    371 // Test buffers get shadowed when they are supposed to be.
    372 TEST_F(BufferManagerClientSideArraysTest, StreamBuffersAreShadowed) {
    373   const GLuint kClientBufferId = 1;
    374   const GLuint kServiceBufferId = 11;
    375   static const uint32 data[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
    376   manager_->CreateBuffer(kClientBufferId, kServiceBufferId);
    377   Buffer* buffer = manager_->GetBuffer(kClientBufferId);
    378   ASSERT_TRUE(buffer != NULL);
    379   manager_->SetTarget(buffer, GL_ARRAY_BUFFER);
    380   DoBufferData(buffer, sizeof(data), GL_STREAM_DRAW, data, GL_NO_ERROR);
    381   EXPECT_TRUE(buffer->IsClientSideArray());
    382   EXPECT_EQ(0, memcmp(data, buffer->GetRange(0, sizeof(data)), sizeof(data)));
    383   DoBufferData(buffer, sizeof(data), GL_DYNAMIC_DRAW, data, GL_NO_ERROR);
    384   EXPECT_FALSE(buffer->IsClientSideArray());
    385 }
    386 
    387 TEST_F(BufferManagerTest, MaxValueCacheClearedCorrectly) {
    388   const GLuint kClientBufferId = 1;
    389   const GLuint kServiceBufferId = 11;
    390   const uint32 data1[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
    391   const uint32 data2[] = {11, 12, 13, 14, 15, 16, 17, 18, 19, 20};
    392   const uint32 data3[] = {30, 29, 28};
    393   manager_->CreateBuffer(kClientBufferId, kServiceBufferId);
    394   Buffer* buffer = manager_->GetBuffer(kClientBufferId);
    395   ASSERT_TRUE(buffer != NULL);
    396   manager_->SetTarget(buffer, GL_ELEMENT_ARRAY_BUFFER);
    397   GLuint max_value;
    398   // Load the buffer with some initial data, and then get the maximum value for
    399   // a range, which has the side effect of caching it.
    400   DoBufferData(buffer, sizeof(data1), GL_STATIC_DRAW, data1, GL_NO_ERROR);
    401   EXPECT_TRUE(
    402       buffer->GetMaxValueForRange(0, 10, GL_UNSIGNED_INT, &max_value));
    403   EXPECT_EQ(10u, max_value);
    404   // Check that any cached values are invalidated if the buffer is reloaded
    405   // with the same amount of data (but different content)
    406   ASSERT_EQ(sizeof(data2), sizeof(data1));
    407   DoBufferData(buffer, sizeof(data2), GL_STATIC_DRAW, data2, GL_NO_ERROR);
    408   EXPECT_TRUE(
    409       buffer->GetMaxValueForRange(0, 10, GL_UNSIGNED_INT, &max_value));
    410   EXPECT_EQ(20u, max_value);
    411   // Check that any cached values are invalidated if the buffer is reloaded
    412   // with entirely different content.
    413   ASSERT_NE(sizeof(data3), sizeof(data1));
    414   DoBufferData(buffer, sizeof(data3), GL_STATIC_DRAW, data3, GL_NO_ERROR);
    415   EXPECT_TRUE(
    416       buffer->GetMaxValueForRange(0, 3, GL_UNSIGNED_INT, &max_value));
    417   EXPECT_EQ(30u, max_value);
    418 }
    419 
    420 }  // namespace gles2
    421 }  // namespace gpu
    422 
    423 
    424