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