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