• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
SetUpBase(MemoryTracker * memory_tracker,FeatureInfo * feature_info,const char * extensions)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 
TearDown()36   virtual void TearDown() {
37     manager_->Destroy(false);
38     manager_.reset();
39     error_state_.reset();
40     GpuServiceTest::TearDown();
41   }
42 
GetTarget(const Buffer * buffer) const43   GLenum GetTarget(const Buffer* buffer) const {
44     return buffer->target();
45   }
46 
DoBufferData(Buffer * buffer,GLsizeiptr size,GLenum usage,const GLvoid * data,GLenum error)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 
DoBufferSubData(Buffer * buffer,GLintptr offset,GLsizeiptr size,const GLvoid * data)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:
SetUp()81   virtual void SetUp() {
82     SetUpBase(NULL, NULL, "");
83   }
84 };
85 
86 class BufferManagerMemoryTrackerTest : public BufferManagerTestBase {
87  protected:
SetUp()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:
SetUp()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 
TEST_F(BufferManagerTest,Basic)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 
TEST_F(BufferManagerMemoryTrackerTest,Basic)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 
TEST_F(BufferManagerTest,Destroy)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 
TEST_F(BufferManagerTest,DoBufferSubData)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 
TEST_F(BufferManagerTest,GetRange)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 
TEST_F(BufferManagerTest,GetMaxValueForRangeUint8)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 
TEST_F(BufferManagerTest,GetMaxValueForRangeUint16)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 
TEST_F(BufferManagerTest,GetMaxValueForRangeUint32)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 
TEST_F(BufferManagerTest,UseDeletedBuffer)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.
TEST_F(BufferManagerClientSideArraysTest,StreamBuffersAreShadowed)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 
TEST_F(BufferManagerTest,MaxValueCacheClearedCorrectly)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