Index: content/common/gpu/gpu_memory_manager_unittest.cc |
diff --git a/content/common/gpu/gpu_memory_manager_unittest.cc b/content/common/gpu/gpu_memory_manager_unittest.cc |
index 06c785c87d167ed301b53186541c528306eb24cb..b9c3727f39eaa5489359e3ab4170bfc7e351c22a 100644 |
--- a/content/common/gpu/gpu_memory_manager_unittest.cc |
+++ b/content/common/gpu/gpu_memory_manager_unittest.cc |
@@ -164,6 +164,7 @@ class GpuMemoryManagerTest : public testing::Test { |
GpuMemoryManagerTest() |
: memmgr_(0, kFrontbufferLimitForTest) { |
memmgr_.TestingDisableScheduleManage(); |
+ memmgr_.TestingSetUseNonuniformMemoryPolicy(false); |
} |
virtual void SetUp() { |
@@ -250,6 +251,17 @@ class GpuMemoryManagerTest : public testing::Test { |
GpuMemoryManager memmgr_; |
}; |
+class GpuMemoryManagerTestNonuniform : public GpuMemoryManagerTest { |
+ protected: |
+ void SetClientStats( |
+ FakeClient* client, |
+ uint64 required, |
+ uint64 nicetohave) { |
+ client->SetManagedMemoryStats( |
+ GpuManagedMemoryStats(required, nicetohave, 0, false)); |
+ } |
+}; |
+ |
// Test GpuMemoryManager::Manage basic functionality. |
// Expect memory allocation to set suggest_have_frontbuffer/backbuffer |
// according to visibility and last used time for stubs with surface. |
@@ -873,4 +885,168 @@ TEST_F(GpuMemoryManagerTest, TestUnmanagedTracking) { |
gpu::gles2::MemoryTracker::kUnmanaged); |
} |
+// Test nonvisible MRU behavior (the most recently used nonvisible clients |
+// keep their contents). |
+TEST_F(GpuMemoryManagerTestNonuniform, BackgroundMru) { |
+ // Set memory manager constants for this test |
+ memmgr_.TestingSetUseNonuniformMemoryPolicy(true); |
+ memmgr_.TestingSetAvailableGpuMemory(64); |
+ memmgr_.TestingSetNonvisibleAvailableGpuMemory(16); |
+ memmgr_.TestingSetMinimumClientAllocation(8); |
+ |
+ FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true); |
+ FakeClient stub2(&memmgr_, GenerateUniqueSurfaceId(), true); |
+ FakeClient stub3(&memmgr_, GenerateUniqueSurfaceId(), true); |
+ |
+ // When all are visible, they should all be allowed to have memory |
+ // should they become nonvisible. |
+ SetClientStats(&stub1, 6, 23); |
+ SetClientStats(&stub2, 6, 23); |
+ SetClientStats(&stub3, 6, 23); |
+ Manage(); |
+ EXPECT_GE(stub1.BytesWhenVisible(), 20u); |
+ EXPECT_GE(stub2.BytesWhenVisible(), 20u); |
+ EXPECT_GE(stub3.BytesWhenVisible(), 20u); |
+ EXPECT_LT(stub1.BytesWhenVisible(), 22u); |
+ EXPECT_LT(stub2.BytesWhenVisible(), 22u); |
+ EXPECT_LT(stub3.BytesWhenVisible(), 22u); |
+ EXPECT_GE(stub1.BytesWhenNotVisible(), 6u); |
+ EXPECT_GE(stub2.BytesWhenNotVisible(), 6u); |
+ EXPECT_GE(stub3.BytesWhenNotVisible(), 6u); |
+ |
+ // Background stubs 1 and 2, and they should fit. All stubs should |
+ // have their full nicetohave budget should they become visible. |
+ stub2.SetVisible(false); |
+ stub1.SetVisible(false); |
+ Manage(); |
+ EXPECT_GE(stub1.BytesWhenVisible(), 23u); |
+ EXPECT_GE(stub2.BytesWhenVisible(), 23u); |
+ EXPECT_GE(stub3.BytesWhenVisible(), 23u); |
+ EXPECT_LT(stub1.BytesWhenVisible(), 32u); |
+ EXPECT_LT(stub2.BytesWhenVisible(), 32u); |
+ EXPECT_LT(stub3.BytesWhenVisible(), 32u); |
+ EXPECT_GE(stub1.BytesWhenNotVisible(), 6u); |
+ EXPECT_GE(stub2.BytesWhenNotVisible(), 6u); |
+ EXPECT_GE(stub3.BytesWhenNotVisible(), 6u); |
+ |
+ // Now background stub 3, and it should cause stub 2 to be |
+ // evicted because it was set non-visible first |
+ stub3.SetVisible(false); |
+ Manage(); |
+ EXPECT_GE(stub1.BytesWhenNotVisible(), 6u); |
+ EXPECT_EQ(stub2.BytesWhenNotVisible(), 0u); |
+ EXPECT_GE(stub3.BytesWhenNotVisible(), 6u); |
+} |
+ |
+// Test that once a backgrounded client has dropped its resources, it |
+// doesn't get them back until it becomes visible again. |
+TEST_F(GpuMemoryManagerTestNonuniform, BackgroundDiscardPersistent) { |
+ // Set memory manager constants for this test |
+ memmgr_.TestingSetUseNonuniformMemoryPolicy(true); |
+ memmgr_.TestingSetAvailableGpuMemory(64); |
+ memmgr_.TestingSetNonvisibleAvailableGpuMemory(16); |
+ memmgr_.TestingSetMinimumClientAllocation(8); |
+ |
+ FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true); |
+ FakeClient stub2(&memmgr_, GenerateUniqueSurfaceId(), true); |
+ |
+ // Both clients should be able to keep their contents should one of |
+ // them become nonvisible. |
+ SetClientStats(&stub1, 10, 20); |
+ SetClientStats(&stub2, 10, 20); |
+ Manage(); |
+ EXPECT_GE(stub1.BytesWhenNotVisible(), 10u); |
+ EXPECT_GE(stub2.BytesWhenNotVisible(), 10u); |
+ |
+ // If they both go nonvisible, then only the most recently used client |
+ // should keep its contents. |
+ stub1.SetVisible(false); |
+ stub2.SetVisible(false); |
+ Manage(); |
+ EXPECT_EQ(stub1.BytesWhenNotVisible(), 0u); |
+ EXPECT_GE(stub2.BytesWhenNotVisible(), 10u); |
+ |
+ // When becoming visible, stub 2 should get its contents back, and |
+ // retain them next time it is made nonvisible. |
+ stub2.SetVisible(true); |
+ Manage(); |
+ EXPECT_GE(stub2.BytesWhenNotVisible(), 10u); |
+ stub2.SetVisible(false); |
+ Manage(); |
+ EXPECT_GE(stub2.BytesWhenNotVisible(), 10u); |
+} |
+ |
+// Test tracking of unmanaged (e.g, WebGL) memory. |
+TEST_F(GpuMemoryManagerTestNonuniform, UnmanagedTracking) { |
+ // Set memory manager constants for this test |
+ memmgr_.TestingSetUseNonuniformMemoryPolicy(true); |
+ memmgr_.TestingSetAvailableGpuMemory(64); |
+ memmgr_.TestingSetNonvisibleAvailableGpuMemory(16); |
+ memmgr_.TestingSetMinimumClientAllocation(8); |
+ memmgr_.TestingSetUnmanagedLimitStep(16); |
+ |
+ FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true); |
+ |
+ // Expect that the one stub get its nicetohave level. |
+ SetClientStats(&stub1, 16, 32); |
+ Manage(); |
+ EXPECT_GE(stub1.BytesWhenVisible(), 32u); |
+ |
+ // Now allocate some unmanaged memory and make sure the amount |
+ // goes down. |
+ memmgr_.TrackMemoryAllocatedChange( |
+ stub1.tracking_group_.get(), |
+ 0, |
+ 48, |
+ gpu::gles2::MemoryTracker::kUnmanaged); |
+ Manage(); |
+ EXPECT_LT(stub1.BytesWhenVisible(), 24u); |
+ |
+ // Now allocate the entire FB worth of unmanaged memory, and |
+ // make sure that we stay stuck at the minimum tab allocation. |
+ memmgr_.TrackMemoryAllocatedChange( |
+ stub1.tracking_group_.get(), |
+ 48, |
+ 64, |
+ gpu::gles2::MemoryTracker::kUnmanaged); |
+ Manage(); |
+ EXPECT_EQ(stub1.BytesWhenVisible(), 8u); |
+ |
+ // Far-oversubscribe the entire FB, and make sure we stay at |
+ // the minimum allocation, and don't blow up. |
+ memmgr_.TrackMemoryAllocatedChange( |
+ stub1.tracking_group_.get(), |
+ 64, |
+ 999, |
+ gpu::gles2::MemoryTracker::kUnmanaged); |
+ Manage(); |
+ EXPECT_EQ(stub1.BytesWhenVisible(), 8u); |
+ |
+ // Delete all tracked memory so we don't hit leak checks. |
+ memmgr_.TrackMemoryAllocatedChange( |
+ stub1.tracking_group_.get(), |
+ 999, |
+ 0, |
+ gpu::gles2::MemoryTracker::kUnmanaged); |
+} |
+ |
+// Test the default allocation levels are used. |
+TEST_F(GpuMemoryManagerTestNonuniform, DefaultAllocation) { |
+ // Set memory manager constants for this test |
+ memmgr_.TestingSetUseNonuniformMemoryPolicy(true); |
+ memmgr_.TestingSetAvailableGpuMemory(64); |
+ memmgr_.TestingSetNonvisibleAvailableGpuMemory(16); |
+ memmgr_.TestingSetMinimumClientAllocation(8); |
+ memmgr_.TestingSetDefaultClientAllocation(16); |
+ |
+ FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true); |
+ |
+ // Expect that a client which has not sent stats receive the |
+ // default allocation. |
+ Manage(); |
+ EXPECT_EQ(stub1.BytesWhenVisible(), |
+ memmgr_.GetDefaultClientAllocation()); |
+ EXPECT_EQ(stub1.BytesWhenNotVisible(), 0u); |
+} |
+ |
} // namespace content |