Chromium Code Reviews| Index: cc/trees/layer_tree_host_unittest.cc |
| diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc |
| index 363e8e2e204d22348fbae5554081a2b8ade4d013..dcc2b2b45e87bc3d1428f853b683a84784aa167a 100644 |
| --- a/cc/trees/layer_tree_host_unittest.cc |
| +++ b/cc/trees/layer_tree_host_unittest.cc |
| @@ -431,36 +431,41 @@ class LayerTreeHostTestReadyToDrawVisibility : public LayerTreeHostTest { |
| // single threaded mode. |
| SINGLE_THREAD_TEST_F(LayerTreeHostTestReadyToDrawVisibility); |
| -class LayerTreeHostFreeWorkerContextResourcesTest : public LayerTreeHostTest { |
| +class LayerTreeHostNotifyContextCacheControllerTest : public LayerTreeHostTest { |
| public: |
| std::unique_ptr<TestDelegatingOutputSurface> CreateDelegatingOutputSurface( |
| scoped_refptr<ContextProvider> compositor_context_provider, |
| scoped_refptr<ContextProvider> worker_context_provider) override { |
| - auto mock_worker_context_support_owned = |
| - base::MakeUnique<MockContextSupport>(); |
| - mock_context_support_ptr_ = mock_worker_context_support_owned.get(); |
| - |
| - auto mock_worker_context_provider = make_scoped_refptr( |
| - new MockContextProvider(std::move(mock_worker_context_support_owned))); |
| - mock_context_provider_ptr_ = mock_worker_context_provider.get(); |
| - |
| - // Workers are bound on the main thread. |
| - mock_worker_context_provider->BindToCurrentThread(); |
| - |
| - // Ensure that our mock calls execute in sequence. |
| - ::testing::InSequence s; |
| - |
| - // At init, visibility is set to true and we will call |
| - // SetAggressivelyFreeResources(false). |
| - EXPECT_CALL(*mock_context_support_ptr_, SetClientVisible(0, true)); |
| - EXPECT_CALL(*mock_context_support_ptr_, AnyClientsVisible()) |
| - .WillOnce(::testing::Return(true)); |
| - EXPECT_CALL(*mock_context_support_ptr_, |
| - SetAggressivelyFreeResources(false)); |
| + // Create the main ContextProvider with a MockContextCacheController. |
| + auto main_support = base::MakeUnique<TestContextSupport>(); |
| + auto main_context = TestWebGraphicsContext3D::Create(); |
| + auto main_cache_controller = |
| + base::MakeUnique<::testing::StrictMock<MockContextCacheController>>( |
| + main_support.get()); |
| + mock_main_cache_controller_ = main_cache_controller.get(); |
| + auto test_main_context_provider = TestContextProvider::Create( |
| + std::move(main_context), std::move(main_support), |
| + std::move(main_cache_controller)); |
| + |
| + // Create the worker ContextProvider with a MockContextCacheController. |
| + auto worker_support = base::MakeUnique<TestContextSupport>(); |
| + auto worker_context = TestWebGraphicsContext3D::Create(); |
| + auto worker_cache_controller = |
| + base::MakeUnique<::testing::StrictMock<MockContextCacheController>>( |
| + main_support.get()); |
| + mock_worker_cache_controller_ = worker_cache_controller.get(); |
| + auto test_worker_context_provider = TestContextProvider::Create( |
| + std::move(worker_context), std::move(worker_support), |
| + std::move(worker_cache_controller)); |
| + test_worker_context_provider->BindToCurrentThread(); |
| + |
| + // At init, visibility is set to true. |
| + EXPECT_CALL(*mock_main_cache_controller_, OnClientBecameVisible()); |
| + EXPECT_CALL(*mock_worker_cache_controller_, OnClientBecameVisible()); |
| return LayerTreeHostTest::CreateDelegatingOutputSurface( |
| - std::move(compositor_context_provider), |
| - std::move(mock_worker_context_provider)); |
| + std::move(test_main_context_provider), |
| + std::move(test_worker_context_provider)); |
| } |
| void InitializeSettings(LayerTreeSettings* settings) override { |
| @@ -470,102 +475,157 @@ class LayerTreeHostFreeWorkerContextResourcesTest : public LayerTreeHostTest { |
| void BeginTest() override {} |
| - void BeforeVisibilityChange() { |
| - // Ensure that our initialization expectations have completed. |
| - Mock::VerifyAndClearExpectations(mock_context_support_ptr_); |
| - |
| - // Ensure that our mock calls execute in sequence. |
| - ::testing::InSequence s; |
| - |
| - // While running, visibility is set to false, and we will call |
| - // DeleteCachedResources and SetAggressivelyFreeResources(true). |
| - EXPECT_CALL(*mock_context_support_ptr_, SetClientVisible(0, false)); |
| - EXPECT_CALL(*mock_context_support_ptr_, AnyClientsVisible()) |
| - .WillOnce(::testing::Return(false)); |
| - EXPECT_CALL(*mock_context_provider_ptr_, DeleteCachedResources()); |
| - EXPECT_CALL(*mock_context_support_ptr_, SetAggressivelyFreeResources(true)) |
| - .WillOnce(testing::Invoke([this](bool is_visible) { EndTest(); })); |
| - } |
| - |
| void AfterTest() override { |
| // Ensure all expectations are satisfied. |
|
danakj
2016/08/29 23:56:20
I don't think these are needed.. gmock will do thi
ericrk
2016/08/30 18:18:58
Done.
|
| - Mock::VerifyAndClearExpectations(mock_context_support_ptr_); |
| - Mock::VerifyAndClearExpectations(mock_context_provider_ptr_); |
| + Mock::VerifyAndClearExpectations(mock_main_cache_controller_); |
| + Mock::VerifyAndClearExpectations(mock_worker_cache_controller_); |
| } |
| - private: |
| - class MockContextProvider : public TestContextProvider { |
| + protected: |
| + class MockContextCacheController : public ContextCacheController { |
| public: |
| - explicit MockContextProvider(std::unique_ptr<TestContextSupport> support) |
| - : TestContextProvider(std::move(support), |
| - base::MakeUnique<TestGLES2Interface>(), |
| - TestWebGraphicsContext3D::Create()) {} |
| + explicit MockContextCacheController(gpu::ContextSupport* support) |
| + : ContextCacheController(support) {} |
| + MOCK_METHOD0(OnClientBecameVisible, void()); |
| + MOCK_METHOD0(OnClientBecameNotVisible, void()); |
| - MOCK_METHOD0(DeleteCachedResources, void()); |
| + std::unique_ptr<ScopedVisibility> ClientBecameVisible() { |
| + if (num_visible_clients_ == 0) |
| + OnClientBecameVisible(); |
| + ++num_visible_clients_; |
| + return CreateScopedVisibilityForTesting(); |
| + } |
| - private: |
| - ~MockContextProvider() = default; |
| - }; |
| + void ClientBecameNotVisible( |
| + std::unique_ptr<ScopedVisibility> scoped_visibility) { |
| + --num_visible_clients_; |
| + if (num_visible_clients_ == 0) |
| + OnClientBecameNotVisible(); |
| + ReleaseScopedVisibilityForTesting(std::move(scoped_visibility)); |
| + } |
| - class MockContextSupport : public TestContextSupport { |
| - public: |
| - MockContextSupport() {} |
| - MOCK_METHOD1(SetAggressivelyFreeResources, |
| - void(bool aggressively_free_resources)); |
| - MOCK_METHOD2(SetClientVisible, void(int client_id, bool is_visible)); |
| - MOCK_CONST_METHOD0(AnyClientsVisible, bool()); |
| + private: |
| + int num_visible_clients_ = 0; |
| }; |
| - MockContextSupport* mock_context_support_ptr_; |
| - MockContextProvider* mock_context_provider_ptr_; |
| + MockContextCacheController* mock_main_cache_controller_; |
| + MockContextCacheController* mock_worker_cache_controller_; |
| }; |
| -// Test if the LTH successfully frees resources on the worker context when |
| -// visibility is set to false. |
| -class LayerTreeHostFreeWorkerContextResourcesOnInvisible |
| - : public LayerTreeHostFreeWorkerContextResourcesTest { |
| +// Test if the LTH successfully notifies the main/worker |
| +// ContextCacheControllers when visibility is set to false. |
| +class LayerTreeHostNotifiesCCCOnInvisible |
| + : public LayerTreeHostNotifyContextCacheControllerTest { |
| public: |
| void InitializedRendererOnThread(LayerTreeHostImpl* host_impl, |
| bool success) override { |
| - BeforeVisibilityChange(); |
| + // Ensure that our initialization expectations have completed. |
| + Mock::VerifyAndClearExpectations(mock_main_cache_controller_); |
| + Mock::VerifyAndClearExpectations(mock_worker_cache_controller_); |
| + |
| + // Update visibility and make sure our two CCCs are updated. |
| + EXPECT_CALL(*mock_main_cache_controller_, OnClientBecameNotVisible()); |
| + EXPECT_CALL(*mock_worker_cache_controller_, OnClientBecameNotVisible()) |
| + .WillOnce(testing::Invoke([this]() { EndTest(); })); |
| PostSetVisibleToMainThread(false); |
| } |
| }; |
| -SINGLE_AND_MULTI_THREAD_TEST_F( |
| - LayerTreeHostFreeWorkerContextResourcesOnInvisible); |
| +SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostNotifiesCCCOnInvisible); |
| -// Test if the LTH successfully frees resources on the worker context when |
| -// hard memory limit is set to zero. |
| -class LayerTreeHostFreeWorkerContextResourcesOnZeroMemoryLimit |
| - : public LayerTreeHostFreeWorkerContextResourcesTest { |
| +// Test if the LTH successfully notifies the worker ContextCacheController when |
| +// the hard memory limit is set to zero. |
| +class LayerTreeHostNotifiesCCCOnZeroMemoryLimit |
| + : public LayerTreeHostNotifyContextCacheControllerTest { |
| public: |
| void InitializedRendererOnThread(LayerTreeHostImpl* host_impl, |
| bool success) override { |
| - BeforeVisibilityChange(); |
| + // Ensure that our initialization expectations have completed. |
| + Mock::VerifyAndClearExpectations(mock_worker_cache_controller_); |
| + |
| + // Worker CC should be notified when hard memory limit is zeroed. |
| + EXPECT_CALL(*mock_worker_cache_controller_, OnClientBecameNotVisible()) |
| + .WillOnce(testing::Invoke([this]() { |
| + // Main context is unchanged. It will go invisible on destruction. |
| + EXPECT_CALL(*mock_main_cache_controller_, OnClientBecameNotVisible()); |
| + EndTest(); |
| + })); |
| ManagedMemoryPolicy zero_policy( |
| 0, gpu::MemoryAllocation::CUTOFF_ALLOW_NOTHING, 0); |
| host_impl->SetMemoryPolicy(zero_policy); |
|
danakj
2016/08/29 23:56:20
You could just VerifyAndClear/EXPECT_CALL/EndTest(
ericrk
2016/08/30 18:18:58
Sadly, because we don't want to interrupt in-proce
|
| } |
| }; |
| -SINGLE_AND_MULTI_THREAD_TEST_F( |
| - LayerTreeHostFreeWorkerContextResourcesOnZeroMemoryLimit); |
| +SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostNotifiesCCCOnZeroMemoryLimit); |
| -// Test if the LTH successfully frees resources on the worker context when |
| -// hard memory limit is set to zero while using a synchronous compositor (like |
| -// Android WebView). |
| -class LayerTreeHostFreeWorkerContextResourcesOnZeroMemoryLimitSynchronous |
| - : public LayerTreeHostFreeWorkerContextResourcesOnZeroMemoryLimit { |
| +// Test if the LTH successfully notifies the ContextCacheController of |
| +// visibility changes when hard memory limit is set to zero while using a |
| +// synchronous compositor (like Android WebView). |
| +class LayerTreeHostNotifiesCCCOnZeroMemoryLimitSynchronous |
| + : public LayerTreeHostNotifiesCCCOnZeroMemoryLimit { |
| public: |
| void InitializeSettings(LayerTreeSettings* settings) override { |
| - LayerTreeHostFreeWorkerContextResourcesTest::InitializeSettings(settings); |
| + LayerTreeHostNotifyContextCacheControllerTest::InitializeSettings(settings); |
| settings->using_synchronous_renderer_compositor = true; |
| } |
| }; |
| SINGLE_AND_MULTI_THREAD_TEST_F( |
| - LayerTreeHostFreeWorkerContextResourcesOnZeroMemoryLimitSynchronous); |
| + LayerTreeHostNotifiesCCCOnZeroMemoryLimitSynchronous); |
| + |
| +// Test if the LTH successfully notifies the main and worker |
| +// ContextCacheControllers of visibility changes when the OutputSurface is |
| +// destroyed. |
| +class LayerTreeHostNotifyCCCOnDestroy |
| + : public LayerTreeHostNotifyContextCacheControllerTest { |
| + public: |
| + void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl, |
| + const BeginFrameArgs& args) override { |
| + // Ensure that our initialization expectations have completed. |
| + Mock::VerifyAndClearExpectations(mock_main_cache_controller_); |
| + Mock::VerifyAndClearExpectations(mock_worker_cache_controller_); |
| + |
| + // We leave the LTHI visible, so it will notify CC on destruction. |
| + EXPECT_CALL(*mock_worker_cache_controller_, OnClientBecameNotVisible()); |
| + EXPECT_CALL(*mock_main_cache_controller_, OnClientBecameNotVisible()); |
| + EndTest(); |
| + } |
| +}; |
| + |
| +SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostNotifyCCCOnDestroy); |
| + |
| +// Test if the LTH successfully notifies the main and worker |
| +// ContextCacheControllers of visibility changes when the OutputSurface is |
| +// lost and recreated. |
| +class LayerTreeHostNotifyCCCOnOutputSurfaceRecreated |
| + : public LayerTreeHostNotifyContextCacheControllerTest { |
| + public: |
| + void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl, |
| + const BeginFrameArgs& args) override { |
| + // Ensure that our initialization expectations have completed. |
| + Mock::VerifyAndClearExpectations(mock_main_cache_controller_); |
| + Mock::VerifyAndClearExpectations(mock_worker_cache_controller_); |
| + |
| + if (has_recreated_) { |
| + // Destruction exptectations. |
| + EXPECT_CALL(*mock_worker_cache_controller_, OnClientBecameNotVisible()); |
| + EXPECT_CALL(*mock_main_cache_controller_, OnClientBecameNotVisible()); |
| + EndTest(); |
| + return; |
| + } |
| + has_recreated_ = true; |
| + |
| + // Output surface lost expectations. |
| + EXPECT_CALL(*mock_worker_cache_controller_, OnClientBecameNotVisible()); |
| + EXPECT_CALL(*mock_main_cache_controller_, OnClientBecameNotVisible()); |
| + host_impl->DidLoseOutputSurface(); |
| + } |
| + |
| + private: |
| + bool has_recreated_ = false; |
| +}; |
| + |
| +SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostNotifyCCCOnOutputSurfaceRecreated); |
| // Two setNeedsCommits in a row should lead to at least 1 commit and at least 1 |
| // draw with frame 0. |
| @@ -2207,6 +2267,9 @@ class LayerTreeHostTestSetVisible : public LayerTreeHostTest { |
| void BeginTest() override { |
| PostSetNeedsCommitToMainThread(); |
| + } |
| + |
| + void WillCommit() override { |
| PostSetVisibleToMainThread(false); |
| // This is suppressed while we're invisible. |
| PostSetNeedsRedrawToMainThread(); |