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> | |
8 #include "base/bind.h" | 7 #include "base/bind.h" |
9 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
10 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
11 #include "gpu/command_buffer/client/cmd_buffer_helper.h" | 10 #include "gpu/command_buffer/client/cmd_buffer_helper.h" |
12 #include "gpu/command_buffer/service/command_buffer_service.h" | 11 #include "gpu/command_buffer/service/command_buffer_service.h" |
13 #include "gpu/command_buffer/service/gpu_scheduler.h" | 12 #include "gpu/command_buffer/service/gpu_scheduler.h" |
14 #include "gpu/command_buffer/service/mocks.h" | 13 #include "gpu/command_buffer/service/mocks.h" |
15 #include "gpu/command_buffer/service/transfer_buffer_manager.h" | 14 #include "gpu/command_buffer/service/transfer_buffer_manager.h" |
16 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
17 | 16 |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 scoped_ptr<TransferBufferManagerInterface> transfer_buffer_manager_; | 78 scoped_ptr<TransferBufferManagerInterface> transfer_buffer_manager_; |
80 scoped_ptr<CommandBufferService> command_buffer_; | 79 scoped_ptr<CommandBufferService> command_buffer_; |
81 scoped_ptr<GpuScheduler> gpu_scheduler_; | 80 scoped_ptr<GpuScheduler> gpu_scheduler_; |
82 scoped_ptr<CommandBufferHelper> helper_; | 81 scoped_ptr<CommandBufferHelper> helper_; |
83 }; | 82 }; |
84 | 83 |
85 #ifndef _MSC_VER | 84 #ifndef _MSC_VER |
86 const unsigned int MappedMemoryTestBase::kBufferSize; | 85 const unsigned int MappedMemoryTestBase::kBufferSize; |
87 #endif | 86 #endif |
88 | 87 |
89 namespace { | |
90 void EmptyPoll() { | |
91 } | |
92 } | |
93 | |
94 // Test fixture for MemoryChunk test - Creates a MemoryChunk, using a | 88 // Test fixture for MemoryChunk test - Creates a MemoryChunk, using a |
95 // CommandBufferHelper with a mock AsyncAPIInterface for its interface (calling | 89 // CommandBufferHelper with a mock AsyncAPIInterface for its interface (calling |
96 // it directly, not through the RPC mechanism), making sure Noops are ignored | 90 // it directly, not through the RPC mechanism), making sure Noops are ignored |
97 // and SetToken are properly forwarded to the engine. | 91 // and SetToken are properly forwarded to the engine. |
98 class MemoryChunkTest : public MappedMemoryTestBase { | 92 class MemoryChunkTest : public MappedMemoryTestBase { |
99 protected: | 93 protected: |
100 static const int32 kShmId = 123; | 94 static const int32 kShmId = 123; |
101 virtual void SetUp() { | 95 virtual void SetUp() { |
102 MappedMemoryTestBase::SetUp(); | 96 MappedMemoryTestBase::SetUp(); |
103 scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory()); | 97 scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory()); |
104 shared_memory->CreateAndMapAnonymous(kBufferSize); | 98 shared_memory->CreateAndMapAnonymous(kBufferSize); |
105 buffer_ = new gpu::Buffer(shared_memory.Pass(), kBufferSize); | 99 buffer_ = new gpu::Buffer(shared_memory.Pass(), kBufferSize); |
106 chunk_.reset(new MemoryChunk(kShmId, | 100 chunk_.reset(new MemoryChunk(kShmId, buffer_, helper_.get())); |
107 buffer_, | |
108 helper_.get(), | |
109 base::Bind(&EmptyPoll))); | |
110 } | 101 } |
111 | 102 |
112 virtual void TearDown() { | 103 virtual void TearDown() { |
113 // If the GpuScheduler posts any tasks, this forces them to run. | 104 // If the GpuScheduler posts any tasks, this forces them to run. |
114 base::MessageLoop::current()->RunUntilIdle(); | 105 base::MessageLoop::current()->RunUntilIdle(); |
115 | 106 |
116 MappedMemoryTestBase::TearDown(); | 107 MappedMemoryTestBase::TearDown(); |
117 } | 108 } |
118 | 109 |
119 uint8* buffer_memory() { return static_cast<uint8*>(buffer_->memory()); } | 110 uint8* buffer_memory() { return static_cast<uint8*>(buffer_->memory()); } |
(...skipping 30 matching lines...) Expand all Loading... |
150 EXPECT_LE(buffer_memory(), pointer_char); | 141 EXPECT_LE(buffer_memory(), pointer_char); |
151 EXPECT_GE(buffer_memory() + kBufferSize, pointer_char + kSize); | 142 EXPECT_GE(buffer_memory() + kBufferSize, pointer_char + kSize); |
152 EXPECT_EQ(kBufferSize - kSize, chunk_->GetLargestFreeSizeWithoutWaiting()); | 143 EXPECT_EQ(kBufferSize - kSize, chunk_->GetLargestFreeSizeWithoutWaiting()); |
153 EXPECT_EQ(kBufferSize - kSize, chunk_->GetLargestFreeSizeWithWaiting()); | 144 EXPECT_EQ(kBufferSize - kSize, chunk_->GetLargestFreeSizeWithWaiting()); |
154 chunk_->Free(pointer_char); | 145 chunk_->Free(pointer_char); |
155 EXPECT_EQ(kBufferSize, chunk_->GetLargestFreeSizeWithoutWaiting()); | 146 EXPECT_EQ(kBufferSize, chunk_->GetLargestFreeSizeWithoutWaiting()); |
156 EXPECT_EQ(kBufferSize, chunk_->GetLargestFreeSizeWithWaiting()); | 147 EXPECT_EQ(kBufferSize, chunk_->GetLargestFreeSizeWithWaiting()); |
157 } | 148 } |
158 | 149 |
159 class MappedMemoryManagerTest : public MappedMemoryTestBase { | 150 class MappedMemoryManagerTest : public MappedMemoryTestBase { |
160 public: | |
161 MappedMemoryManager* manager() const { | |
162 return manager_.get(); | |
163 } | |
164 | |
165 protected: | 151 protected: |
166 virtual void SetUp() { | 152 virtual void SetUp() { |
167 MappedMemoryTestBase::SetUp(); | 153 MappedMemoryTestBase::SetUp(); |
168 manager_.reset(new MappedMemoryManager( | 154 manager_.reset(new MappedMemoryManager( |
169 helper_.get(), base::Bind(&EmptyPoll), MappedMemoryManager::kNoLimit)); | 155 helper_.get(), MappedMemoryManager::kNoLimit)); |
170 } | 156 } |
171 | 157 |
172 virtual void TearDown() { | 158 virtual void TearDown() { |
173 // If the GpuScheduler posts any tasks, this forces them to run. | 159 // If the GpuScheduler posts any tasks, this forces them to run. |
174 base::MessageLoop::current()->RunUntilIdle(); | 160 base::MessageLoop::current()->RunUntilIdle(); |
175 manager_.reset(); | 161 manager_.reset(); |
176 MappedMemoryTestBase::TearDown(); | 162 MappedMemoryTestBase::TearDown(); |
177 } | 163 } |
178 | 164 |
179 scoped_ptr<MappedMemoryManager> manager_; | 165 scoped_ptr<MappedMemoryManager> manager_; |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
319 EXPECT_EQ(id1, id2); | 305 EXPECT_EQ(id1, id2); |
320 EXPECT_NE(id2, id3); | 306 EXPECT_NE(id2, id3); |
321 EXPECT_EQ(0u, offset1); | 307 EXPECT_EQ(0u, offset1); |
322 EXPECT_EQ(kSize, offset2); | 308 EXPECT_EQ(kSize, offset2); |
323 EXPECT_EQ(0u, offset3); | 309 EXPECT_EQ(0u, offset3); |
324 } | 310 } |
325 | 311 |
326 TEST_F(MappedMemoryManagerTest, UnusedMemoryLimit) { | 312 TEST_F(MappedMemoryManagerTest, UnusedMemoryLimit) { |
327 const unsigned int kChunkSize = 2048; | 313 const unsigned int kChunkSize = 2048; |
328 // Reset the manager with a memory limit. | 314 // Reset the manager with a memory limit. |
329 manager_.reset(new MappedMemoryManager( | 315 manager_.reset(new MappedMemoryManager(helper_.get(), kChunkSize)); |
330 helper_.get(), base::Bind(&EmptyPoll), kChunkSize)); | |
331 manager_->set_chunk_size_multiple(kChunkSize); | 316 manager_->set_chunk_size_multiple(kChunkSize); |
332 | 317 |
333 // Allocate one chunk worth of memory. | 318 // Allocate one chunk worth of memory. |
334 int32 id1 = -1; | 319 int32 id1 = -1; |
335 unsigned int offset1 = 0xFFFFFFFFU; | 320 unsigned int offset1 = 0xFFFFFFFFU; |
336 void* mem1 = manager_->Alloc(kChunkSize, &id1, &offset1); | 321 void* mem1 = manager_->Alloc(kChunkSize, &id1, &offset1); |
337 ASSERT_TRUE(mem1); | 322 ASSERT_TRUE(mem1); |
338 EXPECT_NE(-1, id1); | 323 EXPECT_NE(-1, id1); |
339 EXPECT_EQ(0u, offset1); | 324 EXPECT_EQ(0u, offset1); |
340 | 325 |
341 // Allocate half a chunk worth of memory again. | 326 // Allocate half a chunk worth of memory again. |
342 // The same chunk will be used. | 327 // The same chunk will be used. |
343 int32 id2 = -1; | 328 int32 id2 = -1; |
344 unsigned int offset2 = 0xFFFFFFFFU; | 329 unsigned int offset2 = 0xFFFFFFFFU; |
345 void* mem2 = manager_->Alloc(kChunkSize, &id2, &offset2); | 330 void* mem2 = manager_->Alloc(kChunkSize, &id2, &offset2); |
346 ASSERT_TRUE(mem2); | 331 ASSERT_TRUE(mem2); |
347 EXPECT_NE(-1, id2); | 332 EXPECT_NE(-1, id2); |
348 EXPECT_EQ(0u, offset2); | 333 EXPECT_EQ(0u, offset2); |
349 | 334 |
350 // Expect two chunks to be allocated, exceeding the limit, | 335 // Expect two chunks to be allocated, exceeding the limit, |
351 // since all memory is in use. | 336 // since all memory is in use. |
352 EXPECT_EQ(2 * kChunkSize, manager_->allocated_memory()); | 337 EXPECT_EQ(2 * kChunkSize, manager_->allocated_memory()); |
353 } | 338 } |
354 | 339 |
355 TEST_F(MappedMemoryManagerTest, MemoryLimitWithReuse) { | 340 TEST_F(MappedMemoryManagerTest, MemoryLimitWithReuse) { |
356 const unsigned int kSize = 1024; | 341 const unsigned int kSize = 1024; |
357 // Reset the manager with a memory limit. | 342 // Reset the manager with a memory limit. |
358 manager_.reset(new MappedMemoryManager( | 343 manager_.reset(new MappedMemoryManager(helper_.get(), kSize)); |
359 helper_.get(), base::Bind(&EmptyPoll), kSize)); | |
360 const unsigned int kChunkSize = 2 * 1024; | 344 const unsigned int kChunkSize = 2 * 1024; |
361 manager_->set_chunk_size_multiple(kChunkSize); | 345 manager_->set_chunk_size_multiple(kChunkSize); |
362 | 346 |
363 // Allocate half a chunk worth of memory. | 347 // Allocate half a chunk worth of memory. |
364 int32 id1 = -1; | 348 int32 id1 = -1; |
365 unsigned int offset1 = 0xFFFFFFFFU; | 349 unsigned int offset1 = 0xFFFFFFFFU; |
366 void* mem1 = manager_->Alloc(kSize, &id1, &offset1); | 350 void* mem1 = manager_->Alloc(kSize, &id1, &offset1); |
367 ASSERT_TRUE(mem1); | 351 ASSERT_TRUE(mem1); |
368 EXPECT_NE(-1, id1); | 352 EXPECT_NE(-1, id1); |
369 EXPECT_EQ(0u, offset1); | 353 EXPECT_EQ(0u, offset1); |
(...skipping 25 matching lines...) Expand all Loading... |
395 void* mem3 = manager_->Alloc(kSize, &id3, &offset3); | 379 void* mem3 = manager_->Alloc(kSize, &id3, &offset3); |
396 ASSERT_TRUE(mem3); | 380 ASSERT_TRUE(mem3); |
397 EXPECT_NE(-1, id3); | 381 EXPECT_NE(-1, id3); |
398 // It will reuse the space from the second allocation just freed. | 382 // It will reuse the space from the second allocation just freed. |
399 EXPECT_EQ(kSize, offset3); | 383 EXPECT_EQ(kSize, offset3); |
400 | 384 |
401 // Expect one chunk to be allocated | 385 // Expect one chunk to be allocated |
402 EXPECT_EQ(1 * kChunkSize, manager_->allocated_memory()); | 386 EXPECT_EQ(1 * kChunkSize, manager_->allocated_memory()); |
403 } | 387 } |
404 | 388 |
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 | |
456 } // namespace gpu | 389 } // namespace gpu |
OLD | NEW |