OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "gpu/command_buffer/client/mapped_memory.h" | 5 #include "gpu/command_buffer/client/mapped_memory.h" |
6 | 6 |
| 7 #include <list> |
7 #include "base/bind.h" | 8 #include "base/bind.h" |
8 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
9 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
10 #include "gpu/command_buffer/client/cmd_buffer_helper.h" | 11 #include "gpu/command_buffer/client/cmd_buffer_helper.h" |
11 #include "gpu/command_buffer/service/command_buffer_service.h" | 12 #include "gpu/command_buffer/service/command_buffer_service.h" |
12 #include "gpu/command_buffer/service/gpu_scheduler.h" | 13 #include "gpu/command_buffer/service/gpu_scheduler.h" |
13 #include "gpu/command_buffer/service/mocks.h" | 14 #include "gpu/command_buffer/service/mocks.h" |
14 #include "gpu/command_buffer/service/transfer_buffer_manager.h" | 15 #include "gpu/command_buffer/service/transfer_buffer_manager.h" |
15 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
16 | 17 |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
78 scoped_ptr<TransferBufferManagerInterface> transfer_buffer_manager_; | 79 scoped_ptr<TransferBufferManagerInterface> transfer_buffer_manager_; |
79 scoped_ptr<CommandBufferService> command_buffer_; | 80 scoped_ptr<CommandBufferService> command_buffer_; |
80 scoped_ptr<GpuScheduler> gpu_scheduler_; | 81 scoped_ptr<GpuScheduler> gpu_scheduler_; |
81 scoped_ptr<CommandBufferHelper> helper_; | 82 scoped_ptr<CommandBufferHelper> helper_; |
82 }; | 83 }; |
83 | 84 |
84 #ifndef _MSC_VER | 85 #ifndef _MSC_VER |
85 const unsigned int MappedMemoryTestBase::kBufferSize; | 86 const unsigned int MappedMemoryTestBase::kBufferSize; |
86 #endif | 87 #endif |
87 | 88 |
| 89 namespace { |
| 90 void EmptyPoll() { |
| 91 } |
| 92 } |
| 93 |
88 // Test fixture for MemoryChunk test - Creates a MemoryChunk, using a | 94 // Test fixture for MemoryChunk test - Creates a MemoryChunk, using a |
89 // CommandBufferHelper with a mock AsyncAPIInterface for its interface (calling | 95 // CommandBufferHelper with a mock AsyncAPIInterface for its interface (calling |
90 // it directly, not through the RPC mechanism), making sure Noops are ignored | 96 // it directly, not through the RPC mechanism), making sure Noops are ignored |
91 // and SetToken are properly forwarded to the engine. | 97 // and SetToken are properly forwarded to the engine. |
92 class MemoryChunkTest : public MappedMemoryTestBase { | 98 class MemoryChunkTest : public MappedMemoryTestBase { |
93 protected: | 99 protected: |
94 static const int32 kShmId = 123; | 100 static const int32 kShmId = 123; |
95 virtual void SetUp() { | 101 virtual void SetUp() { |
96 MappedMemoryTestBase::SetUp(); | 102 MappedMemoryTestBase::SetUp(); |
97 scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory()); | 103 scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory()); |
98 shared_memory->CreateAndMapAnonymous(kBufferSize); | 104 shared_memory->CreateAndMapAnonymous(kBufferSize); |
99 buffer_ = new gpu::Buffer(shared_memory.Pass(), kBufferSize); | 105 buffer_ = new gpu::Buffer(shared_memory.Pass(), kBufferSize); |
100 chunk_.reset(new MemoryChunk(kShmId, buffer_, helper_.get())); | 106 chunk_.reset(new MemoryChunk(kShmId, |
| 107 buffer_, |
| 108 helper_.get(), |
| 109 base::Bind(&EmptyPoll))); |
101 } | 110 } |
102 | 111 |
103 virtual void TearDown() { | 112 virtual void TearDown() { |
104 // If the GpuScheduler posts any tasks, this forces them to run. | 113 // If the GpuScheduler posts any tasks, this forces them to run. |
105 base::MessageLoop::current()->RunUntilIdle(); | 114 base::MessageLoop::current()->RunUntilIdle(); |
106 | 115 |
107 MappedMemoryTestBase::TearDown(); | 116 MappedMemoryTestBase::TearDown(); |
108 } | 117 } |
109 | 118 |
110 uint8* buffer_memory() { return static_cast<uint8*>(buffer_->memory()); } | 119 uint8* buffer_memory() { return static_cast<uint8*>(buffer_->memory()); } |
(...skipping 30 matching lines...) Expand all Loading... |
141 EXPECT_LE(buffer_memory(), pointer_char); | 150 EXPECT_LE(buffer_memory(), pointer_char); |
142 EXPECT_GE(buffer_memory() + kBufferSize, pointer_char + kSize); | 151 EXPECT_GE(buffer_memory() + kBufferSize, pointer_char + kSize); |
143 EXPECT_EQ(kBufferSize - kSize, chunk_->GetLargestFreeSizeWithoutWaiting()); | 152 EXPECT_EQ(kBufferSize - kSize, chunk_->GetLargestFreeSizeWithoutWaiting()); |
144 EXPECT_EQ(kBufferSize - kSize, chunk_->GetLargestFreeSizeWithWaiting()); | 153 EXPECT_EQ(kBufferSize - kSize, chunk_->GetLargestFreeSizeWithWaiting()); |
145 chunk_->Free(pointer_char); | 154 chunk_->Free(pointer_char); |
146 EXPECT_EQ(kBufferSize, chunk_->GetLargestFreeSizeWithoutWaiting()); | 155 EXPECT_EQ(kBufferSize, chunk_->GetLargestFreeSizeWithoutWaiting()); |
147 EXPECT_EQ(kBufferSize, chunk_->GetLargestFreeSizeWithWaiting()); | 156 EXPECT_EQ(kBufferSize, chunk_->GetLargestFreeSizeWithWaiting()); |
148 } | 157 } |
149 | 158 |
150 class MappedMemoryManagerTest : public MappedMemoryTestBase { | 159 class MappedMemoryManagerTest : public MappedMemoryTestBase { |
| 160 public: |
| 161 MappedMemoryManager* manager() const { |
| 162 return manager_.get(); |
| 163 } |
| 164 |
151 protected: | 165 protected: |
152 virtual void SetUp() { | 166 virtual void SetUp() { |
153 MappedMemoryTestBase::SetUp(); | 167 MappedMemoryTestBase::SetUp(); |
154 manager_.reset(new MappedMemoryManager( | 168 manager_.reset(new MappedMemoryManager( |
155 helper_.get(), MappedMemoryManager::kNoLimit)); | 169 helper_.get(), base::Bind(&EmptyPoll), MappedMemoryManager::kNoLimit)); |
156 } | 170 } |
157 | 171 |
158 virtual void TearDown() { | 172 virtual void TearDown() { |
159 // If the GpuScheduler posts any tasks, this forces them to run. | 173 // If the GpuScheduler posts any tasks, this forces them to run. |
160 base::MessageLoop::current()->RunUntilIdle(); | 174 base::MessageLoop::current()->RunUntilIdle(); |
161 manager_.reset(); | 175 manager_.reset(); |
162 MappedMemoryTestBase::TearDown(); | 176 MappedMemoryTestBase::TearDown(); |
163 } | 177 } |
164 | 178 |
165 scoped_ptr<MappedMemoryManager> manager_; | 179 scoped_ptr<MappedMemoryManager> manager_; |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
305 EXPECT_EQ(id1, id2); | 319 EXPECT_EQ(id1, id2); |
306 EXPECT_NE(id2, id3); | 320 EXPECT_NE(id2, id3); |
307 EXPECT_EQ(0u, offset1); | 321 EXPECT_EQ(0u, offset1); |
308 EXPECT_EQ(kSize, offset2); | 322 EXPECT_EQ(kSize, offset2); |
309 EXPECT_EQ(0u, offset3); | 323 EXPECT_EQ(0u, offset3); |
310 } | 324 } |
311 | 325 |
312 TEST_F(MappedMemoryManagerTest, UnusedMemoryLimit) { | 326 TEST_F(MappedMemoryManagerTest, UnusedMemoryLimit) { |
313 const unsigned int kChunkSize = 2048; | 327 const unsigned int kChunkSize = 2048; |
314 // Reset the manager with a memory limit. | 328 // Reset the manager with a memory limit. |
315 manager_.reset(new MappedMemoryManager(helper_.get(), kChunkSize)); | 329 manager_.reset(new MappedMemoryManager( |
| 330 helper_.get(), base::Bind(&EmptyPoll), kChunkSize)); |
316 manager_->set_chunk_size_multiple(kChunkSize); | 331 manager_->set_chunk_size_multiple(kChunkSize); |
317 | 332 |
318 // Allocate one chunk worth of memory. | 333 // Allocate one chunk worth of memory. |
319 int32 id1 = -1; | 334 int32 id1 = -1; |
320 unsigned int offset1 = 0xFFFFFFFFU; | 335 unsigned int offset1 = 0xFFFFFFFFU; |
321 void* mem1 = manager_->Alloc(kChunkSize, &id1, &offset1); | 336 void* mem1 = manager_->Alloc(kChunkSize, &id1, &offset1); |
322 ASSERT_TRUE(mem1); | 337 ASSERT_TRUE(mem1); |
323 EXPECT_NE(-1, id1); | 338 EXPECT_NE(-1, id1); |
324 EXPECT_EQ(0u, offset1); | 339 EXPECT_EQ(0u, offset1); |
325 | 340 |
326 // Allocate half a chunk worth of memory again. | 341 // Allocate half a chunk worth of memory again. |
327 // The same chunk will be used. | 342 // The same chunk will be used. |
328 int32 id2 = -1; | 343 int32 id2 = -1; |
329 unsigned int offset2 = 0xFFFFFFFFU; | 344 unsigned int offset2 = 0xFFFFFFFFU; |
330 void* mem2 = manager_->Alloc(kChunkSize, &id2, &offset2); | 345 void* mem2 = manager_->Alloc(kChunkSize, &id2, &offset2); |
331 ASSERT_TRUE(mem2); | 346 ASSERT_TRUE(mem2); |
332 EXPECT_NE(-1, id2); | 347 EXPECT_NE(-1, id2); |
333 EXPECT_EQ(0u, offset2); | 348 EXPECT_EQ(0u, offset2); |
334 | 349 |
335 // Expect two chunks to be allocated, exceeding the limit, | 350 // Expect two chunks to be allocated, exceeding the limit, |
336 // since all memory is in use. | 351 // since all memory is in use. |
337 EXPECT_EQ(2 * kChunkSize, manager_->allocated_memory()); | 352 EXPECT_EQ(2 * kChunkSize, manager_->allocated_memory()); |
338 } | 353 } |
339 | 354 |
340 TEST_F(MappedMemoryManagerTest, MemoryLimitWithReuse) { | 355 TEST_F(MappedMemoryManagerTest, MemoryLimitWithReuse) { |
341 const unsigned int kSize = 1024; | 356 const unsigned int kSize = 1024; |
342 // Reset the manager with a memory limit. | 357 // Reset the manager with a memory limit. |
343 manager_.reset(new MappedMemoryManager(helper_.get(), kSize)); | 358 manager_.reset(new MappedMemoryManager( |
| 359 helper_.get(), base::Bind(&EmptyPoll), kSize)); |
344 const unsigned int kChunkSize = 2 * 1024; | 360 const unsigned int kChunkSize = 2 * 1024; |
345 manager_->set_chunk_size_multiple(kChunkSize); | 361 manager_->set_chunk_size_multiple(kChunkSize); |
346 | 362 |
347 // Allocate half a chunk worth of memory. | 363 // Allocate half a chunk worth of memory. |
348 int32 id1 = -1; | 364 int32 id1 = -1; |
349 unsigned int offset1 = 0xFFFFFFFFU; | 365 unsigned int offset1 = 0xFFFFFFFFU; |
350 void* mem1 = manager_->Alloc(kSize, &id1, &offset1); | 366 void* mem1 = manager_->Alloc(kSize, &id1, &offset1); |
351 ASSERT_TRUE(mem1); | 367 ASSERT_TRUE(mem1); |
352 EXPECT_NE(-1, id1); | 368 EXPECT_NE(-1, id1); |
353 EXPECT_EQ(0u, offset1); | 369 EXPECT_EQ(0u, offset1); |
(...skipping 25 matching lines...) Expand all Loading... |
379 void* mem3 = manager_->Alloc(kSize, &id3, &offset3); | 395 void* mem3 = manager_->Alloc(kSize, &id3, &offset3); |
380 ASSERT_TRUE(mem3); | 396 ASSERT_TRUE(mem3); |
381 EXPECT_NE(-1, id3); | 397 EXPECT_NE(-1, id3); |
382 // It will reuse the space from the second allocation just freed. | 398 // It will reuse the space from the second allocation just freed. |
383 EXPECT_EQ(kSize, offset3); | 399 EXPECT_EQ(kSize, offset3); |
384 | 400 |
385 // Expect one chunk to be allocated | 401 // Expect one chunk to be allocated |
386 EXPECT_EQ(1 * kChunkSize, manager_->allocated_memory()); | 402 EXPECT_EQ(1 * kChunkSize, manager_->allocated_memory()); |
387 } | 403 } |
388 | 404 |
| 405 namespace { |
| 406 void Poll(MappedMemoryManagerTest *test, std::list<void*>* list) { |
| 407 std::list<void*>::iterator it = list->begin(); |
| 408 while (it != list->end()) { |
| 409 void* address = *it; |
| 410 test->manager()->Free(address); |
| 411 it = list->erase(it); |
| 412 } |
| 413 } |
| 414 } |
| 415 |
| 416 TEST_F(MappedMemoryManagerTest, Poll) { |
| 417 std::list<void*> unmanaged_memory_list; |
| 418 |
| 419 const unsigned int kSize = 1024; |
| 420 // Reset the manager with a memory limit. |
| 421 manager_.reset(new MappedMemoryManager( |
| 422 helper_.get(), |
| 423 base::Bind(&Poll, this, &unmanaged_memory_list), |
| 424 kSize)); |
| 425 |
| 426 // Allocate kSize bytes. Don't add the address to |
| 427 // the unmanaged memory list, so that it won't be free:ed just yet. |
| 428 int32 id1; |
| 429 unsigned int offset1; |
| 430 void* mem1 = manager_->Alloc(kSize, &id1, &offset1); |
| 431 EXPECT_EQ(manager_->bytes_in_use(), kSize); |
| 432 |
| 433 // Allocate kSize more bytes, and make sure we grew. |
| 434 int32 id2; |
| 435 unsigned int offset2; |
| 436 void* mem2 = manager_->Alloc(kSize, &id2, &offset2); |
| 437 EXPECT_EQ(manager_->bytes_in_use(), kSize * 2); |
| 438 |
| 439 // Make the unmanaged buffer be released next time FreeUnused() is called |
| 440 // in MappedMemoryManager/FencedAllocator. This happens for example when |
| 441 // allocating new memory. |
| 442 unmanaged_memory_list.push_back(mem1); |
| 443 |
| 444 // Allocate kSize more bytes. This should poll unmanaged memory, which now |
| 445 // should free the previously allocated unmanaged memory. |
| 446 int32 id3; |
| 447 unsigned int offset3; |
| 448 void* mem3 = manager_->Alloc(kSize, &id3, &offset3); |
| 449 EXPECT_EQ(manager_->bytes_in_use(), kSize * 2); |
| 450 |
| 451 manager_->Free(mem2); |
| 452 manager_->Free(mem3); |
| 453 EXPECT_EQ(manager_->bytes_in_use(), static_cast<size_t>(0)); |
| 454 } |
| 455 |
389 } // namespace gpu | 456 } // namespace gpu |
OLD | NEW |