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