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 "content/common/gpu/gpu_memory_manager.h" | 5 #include "content/common/gpu/gpu_memory_manager.h" |
6 #include "content/common/gpu/gpu_memory_manager_client.h" | 6 #include "content/common/gpu/gpu_memory_manager_client.h" |
7 #include "content/common/gpu/gpu_memory_tracking.h" | 7 #include "content/common/gpu/gpu_memory_tracking.h" |
8 #include "gpu/command_buffer/common/gpu_memory_allocation.h" | 8 #include "gpu/command_buffer/common/gpu_memory_allocation.h" |
9 #include "ui/gfx/size_conversions.h" | 9 #include "ui/gfx/size_conversions.h" |
10 | 10 |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
183 bool IsAllocationBackgroundForSurfaceYes( | 183 bool IsAllocationBackgroundForSurfaceYes( |
184 const MemoryAllocation& alloc) { | 184 const MemoryAllocation& alloc) { |
185 return true; | 185 return true; |
186 } | 186 } |
187 bool IsAllocationHibernatedForSurfaceYes( | 187 bool IsAllocationHibernatedForSurfaceYes( |
188 const MemoryAllocation& alloc) { | 188 const MemoryAllocation& alloc) { |
189 return true; | 189 return true; |
190 } | 190 } |
191 bool IsAllocationForegroundForSurfaceNo( | 191 bool IsAllocationForegroundForSurfaceNo( |
192 const MemoryAllocation& alloc) { | 192 const MemoryAllocation& alloc) { |
193 return alloc.bytes_limit_when_visible == | 193 return alloc.bytes_limit_when_visible == 1; |
194 GetMinimumClientAllocation(); | |
195 } | 194 } |
196 bool IsAllocationBackgroundForSurfaceNo( | 195 bool IsAllocationBackgroundForSurfaceNo( |
197 const MemoryAllocation& alloc) { | 196 const MemoryAllocation& alloc) { |
198 return alloc.bytes_limit_when_visible == | 197 return alloc.bytes_limit_when_visible == 1; |
199 GetMinimumClientAllocation(); | |
200 } | 198 } |
201 bool IsAllocationHibernatedForSurfaceNo( | 199 bool IsAllocationHibernatedForSurfaceNo( |
202 const MemoryAllocation& alloc) { | 200 const MemoryAllocation& alloc) { |
203 return alloc.bytes_limit_when_visible == 0; | 201 return alloc.bytes_limit_when_visible == 0; |
204 } | 202 } |
205 | 203 |
206 void Manage() { | 204 void Manage() { |
207 ClientAssignmentCollector::ClearAllStats(); | 205 ClientAssignmentCollector::ClearAllStats(); |
208 memmgr_.Manage(); | 206 memmgr_.Manage(); |
209 } | 207 } |
210 | 208 |
211 uint64 CalcAvailableFromGpuTotal(uint64 bytes) { | |
212 return GpuMemoryManager::CalcAvailableFromGpuTotal(bytes); | |
213 } | |
214 | |
215 uint64 CalcAvailableClamped(uint64 bytes) { | |
216 bytes = std::max(bytes, memmgr_.GetDefaultAvailableGpuMemory()); | |
217 bytes = std::min(bytes, memmgr_.GetMaximumTotalGpuMemory()); | |
218 return bytes; | |
219 } | |
220 | |
221 uint64 GetAvailableGpuMemory() { | |
222 return memmgr_.GetAvailableGpuMemory(); | |
223 } | |
224 | |
225 uint64 GetMaximumClientAllocation() { | |
226 return memmgr_.GetMaximumClientAllocation(); | |
227 } | |
228 | |
229 uint64 GetMinimumClientAllocation() { | |
230 return memmgr_.GetMinimumClientAllocation(); | |
231 } | |
232 | |
233 void SetClientStats( | 209 void SetClientStats( |
234 FakeClient* client, | 210 FakeClient* client, |
235 uint64 required, | 211 uint64 required, |
236 uint64 nicetohave) { | 212 uint64 nicetohave) { |
237 client->SetManagedMemoryStats( | 213 client->SetManagedMemoryStats( |
238 ManagedMemoryStats(required, nicetohave, 0, false)); | 214 ManagedMemoryStats(required, nicetohave, 0, false)); |
239 } | 215 } |
240 | 216 |
241 GpuMemoryManager memmgr_; | 217 GpuMemoryManager memmgr_; |
242 }; | 218 }; |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
446 // and more important). | 422 // and more important). |
447 stub_ignore_c.SetVisible(true); | 423 stub_ignore_c.SetVisible(true); |
448 stub_ignore_c.SetVisible(false); | 424 stub_ignore_c.SetVisible(false); |
449 Manage(); | 425 Manage(); |
450 EXPECT_TRUE(IsAllocationHibernatedForSurfaceYes(stub1.allocation_)); | 426 EXPECT_TRUE(IsAllocationHibernatedForSurfaceYes(stub1.allocation_)); |
451 EXPECT_TRUE(IsAllocationHibernatedForSurfaceYes(stub2.allocation_)); | 427 EXPECT_TRUE(IsAllocationHibernatedForSurfaceYes(stub2.allocation_)); |
452 EXPECT_TRUE(IsAllocationHibernatedForSurfaceNo(stub3.allocation_)); | 428 EXPECT_TRUE(IsAllocationHibernatedForSurfaceNo(stub3.allocation_)); |
453 EXPECT_TRUE(IsAllocationHibernatedForSurfaceNo(stub4.allocation_)); | 429 EXPECT_TRUE(IsAllocationHibernatedForSurfaceNo(stub4.allocation_)); |
454 } | 430 } |
455 | 431 |
456 // Test GpuMemoryManager::UpdateAvailableGpuMemory functionality | |
457 TEST_F(GpuMemoryManagerTest, TestUpdateAvailableGpuMemory) { | |
458 FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true), | |
459 stub2(&memmgr_, GenerateUniqueSurfaceId(), false), | |
460 stub3(&memmgr_, GenerateUniqueSurfaceId(), true), | |
461 stub4(&memmgr_, GenerateUniqueSurfaceId(), false); | |
462 // We take the lowest GPU's total memory as the limit | |
463 uint64 expected = 400 * 1024 * 1024; | |
464 stub1.SetTotalGpuMemory(expected); // GPU Memory | |
465 stub2.SetTotalGpuMemory(expected - 1024 * 1024); // Smaller but not visible. | |
466 stub3.SetTotalGpuMemory(expected + 1024 * 1024); // Visible but larger. | |
467 stub4.SetTotalGpuMemory(expected + 1024 * 1024); // Not visible and larger. | |
468 Manage(); | |
469 uint64 bytes_expected = CalcAvailableFromGpuTotal(expected); | |
470 EXPECT_EQ(GetAvailableGpuMemory(), CalcAvailableClamped(bytes_expected)); | |
471 } | |
472 | |
473 // Test GpuMemoryManager Stub Memory Stats functionality: | |
474 // Creates various surface/non-surface stubs and switches stub visibility and | |
475 // tests to see that stats data structure values are correct. | |
476 TEST_F(GpuMemoryManagerTest, StubMemoryStatsForLastManageTests) { | |
477 ClientAssignmentCollector::ClientMemoryStatMap stats; | |
478 | |
479 Manage(); | |
480 stats = ClientAssignmentCollector::GetClientStatsForLastManage(); | |
481 EXPECT_EQ(stats.size(), 0ul); | |
482 | |
483 FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true); | |
484 Manage(); | |
485 stats = ClientAssignmentCollector::GetClientStatsForLastManage(); | |
486 uint64 stub1allocation1 = | |
487 stats[&stub1].allocation.bytes_limit_when_visible; | |
488 | |
489 EXPECT_EQ(stats.size(), 1ul); | |
490 EXPECT_GT(stub1allocation1, 0ul); | |
491 | |
492 FakeClient stub2(&memmgr_, &stub1); | |
493 Manage(); | |
494 stats = ClientAssignmentCollector::GetClientStatsForLastManage(); | |
495 EXPECT_EQ(stats.count(&stub1), 1ul); | |
496 uint64 stub1allocation2 = | |
497 stats[&stub1].allocation.bytes_limit_when_visible; | |
498 EXPECT_EQ(stats.count(&stub2), 1ul); | |
499 uint64 stub2allocation2 = | |
500 stats[&stub2].allocation.bytes_limit_when_visible; | |
501 | |
502 EXPECT_EQ(stats.size(), 2ul); | |
503 EXPECT_GT(stub1allocation2, 0ul); | |
504 EXPECT_GT(stub2allocation2, 0ul); | |
505 if (stub1allocation2 != GetMaximumClientAllocation()) | |
506 EXPECT_LT(stub1allocation2, stub1allocation1); | |
507 | |
508 FakeClient stub3(&memmgr_, GenerateUniqueSurfaceId(), true); | |
509 Manage(); | |
510 stats = ClientAssignmentCollector::GetClientStatsForLastManage(); | |
511 uint64 stub1allocation3 = | |
512 stats[&stub1].allocation.bytes_limit_when_visible; | |
513 uint64 stub2allocation3 = | |
514 stats[&stub2].allocation.bytes_limit_when_visible; | |
515 uint64 stub3allocation3 = | |
516 stats[&stub3].allocation.bytes_limit_when_visible; | |
517 | |
518 EXPECT_EQ(stats.size(), 3ul); | |
519 EXPECT_GT(stub1allocation3, 0ul); | |
520 EXPECT_GT(stub2allocation3, 0ul); | |
521 EXPECT_GT(stub3allocation3, 0ul); | |
522 if (stub1allocation3 != GetMaximumClientAllocation()) | |
523 EXPECT_LT(stub1allocation3, stub1allocation2); | |
524 | |
525 stub1.SetVisible(false); | |
526 | |
527 Manage(); | |
528 stats = ClientAssignmentCollector::GetClientStatsForLastManage(); | |
529 uint64 stub1allocation4 = | |
530 stats[&stub1].allocation.bytes_limit_when_visible; | |
531 uint64 stub2allocation4 = | |
532 stats[&stub2].allocation.bytes_limit_when_visible; | |
533 uint64 stub3allocation4 = | |
534 stats[&stub3].allocation.bytes_limit_when_visible; | |
535 | |
536 EXPECT_EQ(stats.size(), 3ul); | |
537 EXPECT_GT(stub1allocation4, 0ul); | |
538 EXPECT_GE(stub2allocation4, 0ul); | |
539 EXPECT_GT(stub3allocation4, 0ul); | |
540 if (stub3allocation3 != GetMaximumClientAllocation()) | |
541 EXPECT_GT(stub3allocation4, stub3allocation3); | |
542 } | |
543 | |
544 // Test tracking of unmanaged (e.g, WebGL) memory. | |
545 TEST_F(GpuMemoryManagerTest, UnmanagedTracking) { | |
546 // Set memory manager constants for this test | |
547 memmgr_.TestingSetAvailableGpuMemory(64); | |
548 memmgr_.TestingSetMinimumClientAllocation(8); | |
549 memmgr_.TestingSetUnmanagedLimitStep(16); | |
550 | |
551 FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true); | |
552 | |
553 // Expect that the one stub get its nicetohave level. | |
554 SetClientStats(&stub1, 16, 32); | |
555 Manage(); | |
556 EXPECT_GE(stub1.BytesWhenVisible(), 32u); | |
557 | |
558 // Now allocate some unmanaged memory and make sure the amount | |
559 // goes down. | |
560 memmgr_.TrackMemoryAllocatedChange( | |
561 stub1.tracking_group_.get(), | |
562 0, | |
563 48, | |
564 gpu::gles2::MemoryTracker::kUnmanaged); | |
565 Manage(); | |
566 EXPECT_LT(stub1.BytesWhenVisible(), 24u); | |
567 | |
568 // Now allocate the entire FB worth of unmanaged memory, and | |
569 // make sure that we stay stuck at the minimum tab allocation. | |
570 memmgr_.TrackMemoryAllocatedChange( | |
571 stub1.tracking_group_.get(), | |
572 48, | |
573 64, | |
574 gpu::gles2::MemoryTracker::kUnmanaged); | |
575 Manage(); | |
576 EXPECT_EQ(stub1.BytesWhenVisible(), 8u); | |
577 | |
578 // Far-oversubscribe the entire FB, and make sure we stay at | |
579 // the minimum allocation, and don't blow up. | |
580 memmgr_.TrackMemoryAllocatedChange( | |
581 stub1.tracking_group_.get(), | |
582 64, | |
583 999, | |
584 gpu::gles2::MemoryTracker::kUnmanaged); | |
585 Manage(); | |
586 EXPECT_EQ(stub1.BytesWhenVisible(), 8u); | |
587 | |
588 // Delete all tracked memory so we don't hit leak checks. | |
589 memmgr_.TrackMemoryAllocatedChange( | |
590 stub1.tracking_group_.get(), | |
591 999, | |
592 0, | |
593 gpu::gles2::MemoryTracker::kUnmanaged); | |
594 } | |
595 | |
596 // Test the default allocation levels are used. | |
597 TEST_F(GpuMemoryManagerTest, DefaultAllocation) { | |
598 // Set memory manager constants for this test | |
599 memmgr_.TestingSetAvailableGpuMemory(64); | |
600 memmgr_.TestingSetMinimumClientAllocation(8); | |
601 memmgr_.TestingSetDefaultClientAllocation(16); | |
602 | |
603 FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true); | |
604 | |
605 // Expect that a client which has not sent stats receive at | |
606 // least the default allocation. | |
607 Manage(); | |
608 EXPECT_GE(stub1.BytesWhenVisible(), | |
609 memmgr_.GetDefaultClientAllocation()); | |
610 } | |
611 | |
612 } // namespace content | 432 } // namespace content |
OLD | NEW |