Chromium Code Reviews| 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 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 150 client_state_->SetVisible(visible); | 150 client_state_->SetVisible(visible); |
| 151 } | 151 } |
| 152 | 152 |
| 153 void SetManagedMemoryStats(const ManagedMemoryStats& stats) { | 153 void SetManagedMemoryStats(const ManagedMemoryStats& stats) { |
| 154 client_state_->SetManagedMemoryStats(stats); | 154 client_state_->SetManagedMemoryStats(stats); |
| 155 } | 155 } |
| 156 | 156 |
| 157 uint64 BytesWhenVisible() const { | 157 uint64 BytesWhenVisible() const { |
| 158 return allocation_.bytes_limit_when_visible; | 158 return allocation_.bytes_limit_when_visible; |
| 159 } | 159 } |
| 160 | |
| 161 uint64 BytesWhenNotVisible() const { | |
| 162 return allocation_.bytes_limit_when_not_visible; | |
| 163 } | |
| 164 }; | 160 }; |
| 165 | 161 |
| 166 class GpuMemoryManagerTest : public testing::Test { | 162 class GpuMemoryManagerTest : public testing::Test { |
| 167 protected: | 163 protected: |
| 168 static const uint64 kFrontbufferLimitForTest = 3; | 164 static const uint64 kFrontbufferLimitForTest = 3; |
| 169 | 165 |
| 170 GpuMemoryManagerTest() | 166 GpuMemoryManagerTest() |
| 171 : memmgr_(0, kFrontbufferLimitForTest) { | 167 : memmgr_(0, kFrontbufferLimitForTest) { |
| 172 memmgr_.TestingDisableScheduleManage(); | 168 memmgr_.TestingDisableScheduleManage(); |
| 173 memmgr_.allow_nonvisible_memory_ = true; | |
| 174 } | 169 } |
| 175 | 170 |
| 176 virtual void SetUp() { | 171 virtual void SetUp() { |
| 177 } | 172 } |
| 178 | 173 |
| 179 static int32 GenerateUniqueSurfaceId() { | 174 static int32 GenerateUniqueSurfaceId() { |
| 180 static int32 surface_id_ = 1; | 175 static int32 surface_id_ = 1; |
| 181 return surface_id_++; | 176 return surface_id_++; |
| 182 } | 177 } |
| 183 | 178 |
| 184 bool IsAllocationForegroundForSurfaceYes( | 179 bool IsAllocationForegroundForSurfaceYes( |
|
ccameron
2013/10/31 03:30:13
The tests that use these functions are getting to
| |
| 185 const MemoryAllocation& alloc) { | 180 const MemoryAllocation& alloc) { |
| 186 return !alloc.have_backbuffer_when_not_visible; | 181 return true; |
| 187 } | 182 } |
| 188 bool IsAllocationBackgroundForSurfaceYes( | 183 bool IsAllocationBackgroundForSurfaceYes( |
| 189 const MemoryAllocation& alloc) { | 184 const MemoryAllocation& alloc) { |
| 190 return !alloc.have_backbuffer_when_not_visible; | 185 return true; |
| 191 } | 186 } |
| 192 bool IsAllocationHibernatedForSurfaceYes( | 187 bool IsAllocationHibernatedForSurfaceYes( |
| 193 const MemoryAllocation& alloc) { | 188 const MemoryAllocation& alloc) { |
| 194 return !alloc.have_backbuffer_when_not_visible; | 189 return true; |
| 195 } | 190 } |
| 196 bool IsAllocationForegroundForSurfaceNo( | 191 bool IsAllocationForegroundForSurfaceNo( |
| 197 const MemoryAllocation& alloc) { | 192 const MemoryAllocation& alloc) { |
| 198 return !alloc.have_backbuffer_when_not_visible && | 193 return alloc.bytes_limit_when_visible == |
| 199 alloc.bytes_limit_when_visible == | |
| 200 GetMinimumClientAllocation(); | 194 GetMinimumClientAllocation(); |
| 201 } | 195 } |
| 202 bool IsAllocationBackgroundForSurfaceNo( | 196 bool IsAllocationBackgroundForSurfaceNo( |
| 203 const MemoryAllocation& alloc) { | 197 const MemoryAllocation& alloc) { |
| 204 return !alloc.have_backbuffer_when_not_visible && | 198 return alloc.bytes_limit_when_visible == |
| 205 alloc.bytes_limit_when_visible == | |
| 206 GetMinimumClientAllocation(); | 199 GetMinimumClientAllocation(); |
| 207 } | 200 } |
| 208 bool IsAllocationHibernatedForSurfaceNo( | 201 bool IsAllocationHibernatedForSurfaceNo( |
| 209 const MemoryAllocation& alloc) { | 202 const MemoryAllocation& alloc) { |
| 210 return !alloc.have_backbuffer_when_not_visible && | 203 return alloc.bytes_limit_when_visible == 0; |
| 211 alloc.bytes_limit_when_visible == 0; | |
| 212 } | 204 } |
| 213 | 205 |
| 214 void Manage() { | 206 void Manage() { |
| 215 ClientAssignmentCollector::ClearAllStats(); | 207 ClientAssignmentCollector::ClearAllStats(); |
| 216 memmgr_.Manage(); | 208 memmgr_.Manage(); |
| 217 } | 209 } |
| 218 | 210 |
| 219 uint64 CalcAvailableFromGpuTotal(uint64 bytes) { | 211 uint64 CalcAvailableFromGpuTotal(uint64 bytes) { |
| 220 return GpuMemoryManager::CalcAvailableFromGpuTotal(bytes); | 212 return GpuMemoryManager::CalcAvailableFromGpuTotal(bytes); |
| 221 } | 213 } |
| (...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 542 stats[&stub3].allocation.bytes_limit_when_visible; | 534 stats[&stub3].allocation.bytes_limit_when_visible; |
| 543 | 535 |
| 544 EXPECT_EQ(stats.size(), 3ul); | 536 EXPECT_EQ(stats.size(), 3ul); |
| 545 EXPECT_GT(stub1allocation4, 0ul); | 537 EXPECT_GT(stub1allocation4, 0ul); |
| 546 EXPECT_GE(stub2allocation4, 0ul); | 538 EXPECT_GE(stub2allocation4, 0ul); |
| 547 EXPECT_GT(stub3allocation4, 0ul); | 539 EXPECT_GT(stub3allocation4, 0ul); |
| 548 if (stub3allocation3 != GetMaximumClientAllocation()) | 540 if (stub3allocation3 != GetMaximumClientAllocation()) |
| 549 EXPECT_GT(stub3allocation4, stub3allocation3); | 541 EXPECT_GT(stub3allocation4, stub3allocation3); |
| 550 } | 542 } |
| 551 | 543 |
| 552 // Test GpuMemoryManager's managed memory tracking | |
| 553 TEST_F(GpuMemoryManagerTest, TestManagedUsageTracking) { | |
| 554 FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true), | |
| 555 stub2(&memmgr_, GenerateUniqueSurfaceId(), false); | |
| 556 EXPECT_EQ(0ul, memmgr_.bytes_allocated_managed_visible_); | |
| 557 EXPECT_EQ(0ul, memmgr_.bytes_allocated_managed_nonvisible_); | |
| 558 | |
| 559 // Set memory allocations and verify the results are reflected. | |
| 560 stub1.SetManagedMemoryStats(ManagedMemoryStats(0, 0, 5, false)); | |
| 561 stub2.SetManagedMemoryStats(ManagedMemoryStats(0, 0, 7, false)); | |
| 562 EXPECT_EQ(5ul, memmgr_.bytes_allocated_managed_visible_); | |
| 563 EXPECT_EQ(7ul, memmgr_.bytes_allocated_managed_nonvisible_); | |
| 564 | |
| 565 // Remove a visible client | |
| 566 stub1.client_state_.reset(); | |
| 567 EXPECT_EQ(0ul, memmgr_.bytes_allocated_managed_visible_); | |
| 568 EXPECT_EQ(7ul, memmgr_.bytes_allocated_managed_nonvisible_); | |
| 569 EXPECT_EQ(0ul, memmgr_.bytes_allocated_managed_visible_); | |
| 570 EXPECT_EQ(7ul, memmgr_.bytes_allocated_managed_nonvisible_); | |
| 571 stub1.client_state_.reset(memmgr_.CreateClientState(&stub1, true, true)); | |
| 572 EXPECT_EQ(0ul, memmgr_.bytes_allocated_managed_visible_); | |
| 573 EXPECT_EQ(7ul, memmgr_.bytes_allocated_managed_nonvisible_); | |
| 574 stub1.SetManagedMemoryStats(ManagedMemoryStats(0, 0, 5, false)); | |
| 575 EXPECT_EQ(5ul, memmgr_.bytes_allocated_managed_visible_); | |
| 576 EXPECT_EQ(7ul, memmgr_.bytes_allocated_managed_nonvisible_); | |
| 577 | |
| 578 // Remove a nonvisible client | |
| 579 stub2.client_state_.reset(); | |
| 580 EXPECT_EQ(5ul, memmgr_.bytes_allocated_managed_visible_); | |
| 581 EXPECT_EQ(0ul, memmgr_.bytes_allocated_managed_nonvisible_); | |
| 582 EXPECT_EQ(5ul, memmgr_.bytes_allocated_managed_visible_); | |
| 583 EXPECT_EQ(0ul, memmgr_.bytes_allocated_managed_nonvisible_); | |
| 584 stub2.client_state_.reset(memmgr_.CreateClientState(&stub2, true, false)); | |
| 585 EXPECT_EQ(5ul, memmgr_.bytes_allocated_managed_visible_); | |
| 586 EXPECT_EQ(0ul, memmgr_.bytes_allocated_managed_nonvisible_); | |
| 587 stub2.SetManagedMemoryStats(ManagedMemoryStats(0, 0, 7, false)); | |
| 588 EXPECT_EQ(5ul, memmgr_.bytes_allocated_managed_visible_); | |
| 589 EXPECT_EQ(7ul, memmgr_.bytes_allocated_managed_nonvisible_); | |
| 590 | |
| 591 // Create and then destroy some stubs, and verify their allocations go away. | |
| 592 { | |
| 593 FakeClient stub3(&memmgr_, GenerateUniqueSurfaceId(), true), | |
| 594 stub4(&memmgr_, GenerateUniqueSurfaceId(), false); | |
| 595 stub3.SetManagedMemoryStats(ManagedMemoryStats(0, 0, 1, false)); | |
| 596 stub4.SetManagedMemoryStats(ManagedMemoryStats(0, 0, 2, false)); | |
| 597 EXPECT_EQ(6ul, memmgr_.bytes_allocated_managed_visible_); | |
| 598 EXPECT_EQ(9ul, memmgr_.bytes_allocated_managed_nonvisible_); | |
| 599 } | |
| 600 EXPECT_EQ(5ul, memmgr_.bytes_allocated_managed_visible_); | |
| 601 EXPECT_EQ(7ul, memmgr_.bytes_allocated_managed_nonvisible_); | |
| 602 | |
| 603 // Do no-op changes to stubs' visibility and make sure nothing chnages. | |
| 604 stub1.SetVisible(true); | |
| 605 stub2.SetVisible(false); | |
| 606 EXPECT_EQ(5ul, memmgr_.bytes_allocated_managed_visible_); | |
| 607 EXPECT_EQ(7ul, memmgr_.bytes_allocated_managed_nonvisible_); | |
| 608 | |
| 609 // Change visbility state. | |
| 610 stub1.SetVisible(false); | |
| 611 stub2.SetVisible(true); | |
| 612 EXPECT_EQ(7ul, memmgr_.bytes_allocated_managed_visible_); | |
| 613 EXPECT_EQ(5ul, memmgr_.bytes_allocated_managed_nonvisible_); | |
| 614 | |
| 615 // Increase allocation amounts. | |
| 616 stub1.SetManagedMemoryStats(ManagedMemoryStats(0, 0, 6, false)); | |
| 617 stub2.SetManagedMemoryStats(ManagedMemoryStats(0, 0, 8, false)); | |
| 618 EXPECT_EQ(8ul, memmgr_.bytes_allocated_managed_visible_); | |
| 619 EXPECT_EQ(6ul, memmgr_.bytes_allocated_managed_nonvisible_); | |
| 620 | |
| 621 // Decrease allocation amounts. | |
| 622 stub1.SetManagedMemoryStats(ManagedMemoryStats(0, 0, 4, false)); | |
| 623 stub2.SetManagedMemoryStats(ManagedMemoryStats(0, 0, 6, false)); | |
| 624 EXPECT_EQ(6ul, memmgr_.bytes_allocated_managed_visible_); | |
| 625 EXPECT_EQ(4ul, memmgr_.bytes_allocated_managed_nonvisible_); | |
| 626 } | |
| 627 | |
| 628 // Test nonvisible MRU behavior (the most recently used nonvisible clients | |
| 629 // keep their contents). | |
| 630 TEST_F(GpuMemoryManagerTest, BackgroundMru) { | |
| 631 // Set memory manager constants for this test. Note that the budget | |
| 632 // for backgrounded content will be 64/4 = 16. | |
| 633 memmgr_.TestingSetAvailableGpuMemory(64); | |
| 634 memmgr_.TestingSetMinimumClientAllocation(8); | |
| 635 | |
| 636 uint64 bytes_when_not_visible_expected = 6u; | |
| 637 | |
| 638 FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true); | |
| 639 FakeClient stub2(&memmgr_, GenerateUniqueSurfaceId(), true); | |
| 640 FakeClient stub3(&memmgr_, GenerateUniqueSurfaceId(), true); | |
| 641 | |
| 642 // When all are visible, they should all be allowed to have memory | |
| 643 // should they become nonvisible. | |
| 644 SetClientStats(&stub1, 6, 23); | |
| 645 SetClientStats(&stub2, 6, 23); | |
| 646 SetClientStats(&stub3, 6, 23); | |
| 647 Manage(); | |
| 648 EXPECT_GE(stub1.BytesWhenVisible(), 20u); | |
| 649 EXPECT_GE(stub2.BytesWhenVisible(), 20u); | |
| 650 EXPECT_GE(stub3.BytesWhenVisible(), 20u); | |
| 651 EXPECT_LT(stub1.BytesWhenVisible(), 22u); | |
| 652 EXPECT_LT(stub2.BytesWhenVisible(), 22u); | |
| 653 EXPECT_LT(stub3.BytesWhenVisible(), 22u); | |
| 654 EXPECT_GE(stub1.BytesWhenNotVisible(), bytes_when_not_visible_expected); | |
| 655 EXPECT_GE(stub2.BytesWhenNotVisible(), bytes_when_not_visible_expected); | |
| 656 EXPECT_GE(stub3.BytesWhenNotVisible(), bytes_when_not_visible_expected); | |
| 657 | |
| 658 // Background stubs 1 and 2, and they should fit. All stubs should | |
| 659 // have their full nicetohave budget should they become visible. | |
| 660 stub2.SetVisible(false); | |
| 661 stub1.SetVisible(false); | |
| 662 Manage(); | |
| 663 EXPECT_GE(stub1.BytesWhenVisible(), 23u); | |
| 664 EXPECT_GE(stub2.BytesWhenVisible(), 23u); | |
| 665 EXPECT_GE(stub3.BytesWhenVisible(), 23u); | |
| 666 EXPECT_LT(stub1.BytesWhenVisible(), 32u); | |
| 667 EXPECT_LT(stub2.BytesWhenVisible(), 32u); | |
| 668 EXPECT_GE(stub1.BytesWhenNotVisible(), bytes_when_not_visible_expected); | |
| 669 EXPECT_GE(stub2.BytesWhenNotVisible(), bytes_when_not_visible_expected); | |
| 670 EXPECT_GE(stub3.BytesWhenNotVisible(), bytes_when_not_visible_expected); | |
| 671 | |
| 672 // Now background stub 3, and it should cause stub 2 to be | |
| 673 // evicted because it was set non-visible first | |
| 674 stub3.SetVisible(false); | |
| 675 Manage(); | |
| 676 EXPECT_GE(stub1.BytesWhenNotVisible(), bytes_when_not_visible_expected); | |
| 677 EXPECT_EQ(stub2.BytesWhenNotVisible(), 0u); | |
| 678 EXPECT_GE(stub3.BytesWhenNotVisible(), bytes_when_not_visible_expected); | |
| 679 } | |
| 680 | |
| 681 TEST_F(GpuMemoryManagerTest, AllowNonvisibleMemory) { | |
| 682 memmgr_.TestingSetAvailableGpuMemory(512); | |
| 683 memmgr_.TestingSetMinimumClientAllocation(16); | |
| 684 | |
| 685 FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true); | |
| 686 FakeClient stub2(&memmgr_, GenerateUniqueSurfaceId(), true); | |
| 687 FakeClient stub3(&memmgr_, GenerateUniqueSurfaceId(), true); | |
| 688 | |
| 689 memmgr_.allow_nonvisible_memory_ = true; | |
| 690 stub1.SetVisible(true); | |
| 691 SetClientStats(&stub1, 20, 80); | |
| 692 SetClientStats(&stub2, 20, 80); | |
| 693 SetClientStats(&stub3, 20, 80); | |
| 694 Manage(); | |
| 695 EXPECT_GT(stub1.BytesWhenNotVisible(), 0u); | |
| 696 EXPECT_GT(stub2.BytesWhenNotVisible(), 0u); | |
| 697 EXPECT_GT(stub3.BytesWhenNotVisible(), 0u); | |
| 698 | |
| 699 memmgr_.allow_nonvisible_memory_ = false; | |
| 700 Manage(); | |
| 701 EXPECT_EQ(stub1.BytesWhenNotVisible(), 0u); | |
| 702 EXPECT_EQ(stub2.BytesWhenNotVisible(), 0u); | |
| 703 EXPECT_EQ(stub3.BytesWhenNotVisible(), 0u); | |
| 704 } | |
| 705 | |
| 706 // Test that once a backgrounded client has dropped its resources, it | |
| 707 // doesn't get them back until it becomes visible again. | |
| 708 TEST_F(GpuMemoryManagerTest, BackgroundDiscardPersistent) { | |
| 709 // Set memory manager constants for this test. Note that the budget | |
| 710 // for backgrounded content will be 64/4 = 16. | |
| 711 memmgr_.TestingSetAvailableGpuMemory(64); | |
| 712 memmgr_.TestingSetMinimumClientAllocation(8); | |
| 713 | |
| 714 uint64 bytes_when_not_visible_expected = 10ul; | |
| 715 if (!memmgr_.allow_nonvisible_memory_) | |
| 716 bytes_when_not_visible_expected = 0; | |
| 717 | |
| 718 FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true); | |
| 719 FakeClient stub2(&memmgr_, GenerateUniqueSurfaceId(), true); | |
| 720 | |
| 721 // Both clients should be able to keep their contents should one of | |
| 722 // them become nonvisible. | |
| 723 SetClientStats(&stub1, 10, 20); | |
| 724 SetClientStats(&stub2, 10, 20); | |
| 725 Manage(); | |
| 726 EXPECT_GE(stub1.BytesWhenNotVisible(), bytes_when_not_visible_expected); | |
| 727 EXPECT_GE(stub2.BytesWhenNotVisible(), bytes_when_not_visible_expected); | |
| 728 | |
| 729 // If they both go nonvisible, then only the most recently used client | |
| 730 // should keep its contents. | |
| 731 stub1.SetVisible(false); | |
| 732 stub2.SetVisible(false); | |
| 733 Manage(); | |
| 734 EXPECT_EQ(stub1.BytesWhenNotVisible(), 0u); | |
| 735 EXPECT_GE(stub2.BytesWhenNotVisible(), bytes_when_not_visible_expected); | |
| 736 | |
| 737 // When becoming visible, stub 2 should get its contents back, and | |
| 738 // retain them next time it is made nonvisible. | |
| 739 stub2.SetVisible(true); | |
| 740 Manage(); | |
| 741 EXPECT_GE(stub2.BytesWhenNotVisible(), bytes_when_not_visible_expected); | |
| 742 stub2.SetVisible(false); | |
| 743 Manage(); | |
| 744 EXPECT_GE(stub2.BytesWhenNotVisible(), bytes_when_not_visible_expected); | |
| 745 } | |
| 746 | |
| 747 // Test tracking of unmanaged (e.g, WebGL) memory. | 544 // Test tracking of unmanaged (e.g, WebGL) memory. |
| 748 TEST_F(GpuMemoryManagerTest, UnmanagedTracking) { | 545 TEST_F(GpuMemoryManagerTest, UnmanagedTracking) { |
| 749 // Set memory manager constants for this test | 546 // Set memory manager constants for this test |
| 750 memmgr_.TestingSetAvailableGpuMemory(64); | 547 memmgr_.TestingSetAvailableGpuMemory(64); |
| 751 memmgr_.TestingSetMinimumClientAllocation(8); | 548 memmgr_.TestingSetMinimumClientAllocation(8); |
| 752 memmgr_.TestingSetUnmanagedLimitStep(16); | 549 memmgr_.TestingSetUnmanagedLimitStep(16); |
| 753 | 550 |
| 754 FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true); | 551 FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true); |
| 755 | 552 |
| 756 // Expect that the one stub get its nicetohave level. | 553 // Expect that the one stub get its nicetohave level. |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 803 memmgr_.TestingSetMinimumClientAllocation(8); | 600 memmgr_.TestingSetMinimumClientAllocation(8); |
| 804 memmgr_.TestingSetDefaultClientAllocation(16); | 601 memmgr_.TestingSetDefaultClientAllocation(16); |
| 805 | 602 |
| 806 FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true); | 603 FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true); |
| 807 | 604 |
| 808 // Expect that a client which has not sent stats receive at | 605 // Expect that a client which has not sent stats receive at |
| 809 // least the default allocation. | 606 // least the default allocation. |
| 810 Manage(); | 607 Manage(); |
| 811 EXPECT_GE(stub1.BytesWhenVisible(), | 608 EXPECT_GE(stub1.BytesWhenVisible(), |
| 812 memmgr_.GetDefaultClientAllocation()); | 609 memmgr_.GetDefaultClientAllocation()); |
| 813 EXPECT_EQ(stub1.BytesWhenNotVisible(), 0u); | |
| 814 } | 610 } |
| 815 | 611 |
| 816 } // namespace content | 612 } // namespace content |
| OLD | NEW |