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( |
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 |