diff options
author | rmcilroy <rmcilroy@chromium.org> | 2015-02-18 04:34:25 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-02-18 12:35:06 +0000 |
commit | 0a19362adbaa53af4fb7ccb5819f482b30ca75af (patch) | |
tree | 64ca517e1b0129984eff6d8042ba551a312db8de /cc | |
parent | 042ba9e6f314f96f237da815ae204c7f1be787c9 (diff) | |
download | chromium_src-0a19362adbaa53af4fb7ccb5819f482b30ca75af.zip chromium_src-0a19362adbaa53af4fb7ccb5819f482b30ca75af.tar.gz chromium_src-0a19362adbaa53af4fb7ccb5819f482b30ca75af.tar.bz2 |
[cc]: Add a BeginMainFrameNotExpectedSoon signal and route it to the RendererScheduler.
In order to implement long idle times, the RendererScheduler needs to
know when the compositor has stoped drawing frames. To enable this, add
a BeginMainFrameNotExpectedSoon signal which is sent when the cc
scheduler stops requesting BeginFrames from the Browser.
Design Doc: https://docs.google.com/a/chromium.org/document/d/1yBlUdYW8VTIfB-DqhvQqUeP0kf-Ap1W4cao2yQq58Do/edit
BUG=455713
TBR=danakj@chromium.org, torne@chromium.org, aa@chromium.org
Review URL: https://codereview.chromium.org/904633004
Cr-Commit-Position: refs/heads/master@{#316804}
Diffstat (limited to 'cc')
-rw-r--r-- | cc/scheduler/scheduler.cc | 3 | ||||
-rw-r--r-- | cc/scheduler/scheduler.h | 1 | ||||
-rw-r--r-- | cc/scheduler/scheduler_unittest.cc | 77 | ||||
-rw-r--r-- | cc/test/fake_layer_tree_host_client.h | 1 | ||||
-rw-r--r-- | cc/test/layer_tree_test.cc | 1 | ||||
-rw-r--r-- | cc/trees/layer_tree_host.cc | 4 | ||||
-rw-r--r-- | cc/trees/layer_tree_host.h | 1 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_client.h | 1 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_unittest_no_message_loop.cc | 1 | ||||
-rw-r--r-- | cc/trees/single_thread_proxy.cc | 4 | ||||
-rw-r--r-- | cc/trees/single_thread_proxy.h | 1 | ||||
-rw-r--r-- | cc/trees/thread_proxy.cc | 12 | ||||
-rw-r--r-- | cc/trees/thread_proxy.h | 2 |
13 files changed, 95 insertions, 14 deletions
diff --git a/cc/scheduler/scheduler.cc b/cc/scheduler/scheduler.cc index ed8c0a2..904a057 100644 --- a/cc/scheduler/scheduler.cc +++ b/cc/scheduler/scheduler.cc @@ -335,6 +335,9 @@ void Scheduler::SetupNextBeginFrameIfNeeded() { if (state_machine_.ShouldSetNeedsBeginFrames( frame_source_->NeedsBeginFrames())) { frame_source_->SetNeedsBeginFrames(state_machine_.BeginFrameNeeded()); + if (!frame_source_->NeedsBeginFrames()) { + client_->SendBeginMainFrameNotExpectedSoon(); + } } if (state_machine_.begin_impl_frame_state() == diff --git a/cc/scheduler/scheduler.h b/cc/scheduler/scheduler.h index 82f305a..370ac25 100644 --- a/cc/scheduler/scheduler.h +++ b/cc/scheduler/scheduler.h @@ -49,6 +49,7 @@ class SchedulerClient { virtual base::TimeDelta CommitToActivateDurationEstimate() = 0; virtual void DidBeginImplFrameDeadline() = 0; virtual void SendBeginFramesToChildren(const BeginFrameArgs& args) = 0; + virtual void SendBeginMainFrameNotExpectedSoon() = 0; protected: virtual ~SchedulerClient() {} diff --git a/cc/scheduler/scheduler_unittest.cc b/cc/scheduler/scheduler_unittest.cc index ac52271..50cc846 100644 --- a/cc/scheduler/scheduler_unittest.cc +++ b/cc/scheduler/scheduler_unittest.cc @@ -161,6 +161,10 @@ class FakeSchedulerClient : public SchedulerClient { begin_frame_is_sent_to_children_ = true; } + void SendBeginMainFrameNotExpectedSoon() override { + PushAction("SendBeginMainFrameNotExpectedSoon"); + } + base::Callback<bool(void)> ImplFrameDeadlinePending(bool state) { return base::Bind(&FakeSchedulerClient::ImplFrameDeadlinePendingCallback, base::Unretained(this), @@ -517,7 +521,8 @@ TEST_F(SchedulerTest, RequestCommit) { client_->Reset(); task_runner().RunPendingTasks(); // Run posted deadline. - EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(false)", client_); + EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 0, 2); + EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 1, 2); client_->Reset(); } @@ -1001,7 +1006,8 @@ TEST_F(SchedulerTest, PrepareTiles) { EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); client->Reset(); task_runner().RunPendingTasks(); // Run posted deadline. - EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(false)", client); + EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 0, 2); + EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 1, 2); EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending()); EXPECT_EQ(0, client->num_draws()); @@ -1376,7 +1382,8 @@ TEST_F(SchedulerTest, BeginRetroFrame) { client_->Reset(); task_runner().RunPendingTasks(); // Run posted deadline. - EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(false)", client_); + EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 0, 2); + EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 1, 2); client_->Reset(); } @@ -1627,7 +1634,7 @@ void SchedulerTest::BeginFramesNotFromClient( // Make sure SetNeedsBeginFrame isn't called on the client // when the BeginFrame is no longer needed. task_runner().RunPendingTasks(); // Run posted deadline. - EXPECT_NO_ACTION(client_); + EXPECT_SINGLE_ACTION("SendBeginMainFrameNotExpectedSoon", client_); client_->Reset(); } @@ -1783,7 +1790,8 @@ TEST_F(SchedulerTest, DidLoseOutputSurfaceAfterBeginFrameStarted) { client_->Reset(); scheduler_->DidLoseOutputSurface(); // Do nothing when impl frame is in deadine pending state. - EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(false)", client_); + EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 0, 2); + EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 1, 2); client_->Reset(); scheduler_->NotifyBeginMainFrameStarted(); @@ -1814,7 +1822,8 @@ void SchedulerTest::DidLoseOutputSurfaceAfterBeginFrameStartedWithHighLatency( client_->Reset(); scheduler_->DidLoseOutputSurface(); // Do nothing when impl frame is in deadine pending state. - EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(false)", client_); + EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 0, 2); + EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 1, 2); client_->Reset(); // Run posted deadline. @@ -1881,10 +1890,12 @@ void SchedulerTest::DidLoseOutputSurfaceAfterReadyToCommit( scheduler_->DidLoseOutputSurface(); if (impl_side_painting) { // Sync tree should be forced to activate. - EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 0, 2); - EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 1, 2); + EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 0, 3); + EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 1, 3); + EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3); } else { - EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(false)", client_); + EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 0, 2); + EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 1, 2); } client_->Reset(); @@ -1916,7 +1927,8 @@ TEST_F(SchedulerTest, DidLoseOutputSurfaceAfterSetNeedsPrepareTiles) { client_->Reset(); scheduler_->DidLoseOutputSurface(); - EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(false)", client_); + EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 0, 2); + EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 1, 2); client_->Reset(); task_runner().RunPendingTasks(); // Run posted deadline. @@ -1967,8 +1979,9 @@ TEST_F(SchedulerTest, DidLoseOutputSurfaceAfterBeginRetroFramePosted) { client_->Reset(); EXPECT_FALSE(scheduler_->IsBeginRetroFrameArgsEmpty()); scheduler_->DidLoseOutputSurface(); - EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_, 0, 2); - EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 1, 2); + EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_, 0, 3); + EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 1, 3); + EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3); EXPECT_TRUE(scheduler_->IsBeginRetroFrameArgsEmpty()); // Posted BeginRetroFrame is aborted. @@ -2028,7 +2041,8 @@ TEST_F(SchedulerTest, DidLoseOutputSurfaceDuringBeginRetroFrameRunning) { client_->Reset(); EXPECT_FALSE(scheduler_->IsBeginRetroFrameArgsEmpty()); scheduler_->DidLoseOutputSurface(); - EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(false)", client_); + EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 0, 2); + EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 1, 2); EXPECT_TRUE(scheduler_->IsBeginRetroFrameArgsEmpty()); // BeginImplFrame deadline should abort drawing. @@ -2069,7 +2083,7 @@ TEST_F(SchedulerTest, client_->Reset(); scheduler_->DidLoseOutputSurface(); - EXPECT_NO_ACTION(client_); + EXPECT_SINGLE_ACTION("SendBeginMainFrameNotExpectedSoon", client_); EXPECT_FALSE(scheduler_->frame_source().NeedsBeginFrames()); client_->Reset(); @@ -2347,5 +2361,40 @@ TEST_F(SchedulerTest, SwitchFrameSourceToThrottled) { EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 1); } +// Tests to ensure that we send a BeginMainFrameNotExpectedSoon when expected. +TEST_F(SchedulerTest, SendBeginMainFrameNotExpectedSoon) { + scheduler_settings_.use_external_begin_frame_source = true; + SetUpScheduler(true); + + // SetNeedsCommit should begin the frame on the next BeginImplFrame. + scheduler_->SetNeedsCommit(); + EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_); + client_->Reset(); + + // Trigger a frame draw. + EXPECT_SCOPED(AdvanceFrame()); + scheduler_->NotifyBeginMainFrameStarted(); + scheduler_->NotifyReadyToCommit(); + task_runner().RunPendingTasks(); + EXPECT_ACTION("WillBeginImplFrame", client_, 0, 5); + EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 5); + EXPECT_ACTION("ScheduledActionCommit", client_, 2, 5); + EXPECT_ACTION("ScheduledActionAnimate", client_, 3, 5); + EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 4, 5); + client_->Reset(); + + // The following BeginImplFrame deadline should SetNeedsBeginFrame(false) + // and send a SendBeginMainFrameNotExpectedSoon. + EXPECT_SCOPED(AdvanceFrame()); + EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_); + EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); + client_->Reset(); + + task_runner().RunPendingTasks(); // Run posted deadline. + EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 0, 2); + EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 1, 2); + client_->Reset(); +} + } // namespace } // namespace cc diff --git a/cc/test/fake_layer_tree_host_client.h b/cc/test/fake_layer_tree_host_client.h index f5f3504..b5093ad 100644 --- a/cc/test/fake_layer_tree_host_client.h +++ b/cc/test/fake_layer_tree_host_client.h @@ -33,6 +33,7 @@ class FakeLayerTreeHostClient : public LayerTreeHostClient, void WillBeginMainFrame() override {} void DidBeginMainFrame() override {} void BeginMainFrame(const BeginFrameArgs& args) override {} + void BeginMainFrameNotExpectedSoon() override {} void Layout() override {} void ApplyViewportDeltas(const gfx::Vector2dF& inner_delta, const gfx::Vector2dF& outer_delta, diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc index ce69079..129a27d 100644 --- a/cc/test/layer_tree_test.cc +++ b/cc/test/layer_tree_test.cc @@ -441,6 +441,7 @@ class LayerTreeHostClientForTesting : public LayerTreeHostClient, void DidAbortSwapBuffers() override {} void ScheduleComposite() override { test_hooks_->ScheduleComposite(); } void DidCompletePageScaleAnimation() override {} + void BeginMainFrameNotExpectedSoon() override {} private: explicit LayerTreeHostClientForTesting(TestHooks* test_hooks) diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc index f478078..56bca4f 100644 --- a/cc/trees/layer_tree_host.cc +++ b/cc/trees/layer_tree_host.cc @@ -233,6 +233,10 @@ void LayerTreeHost::DidBeginMainFrame() { client_->DidBeginMainFrame(); } +void LayerTreeHost::BeginMainFrameNotExpectedSoon() { + client_->BeginMainFrameNotExpectedSoon(); +} + void LayerTreeHost::BeginMainFrame(const BeginFrameArgs& args) { inside_begin_main_frame_ = true; client_->BeginMainFrame(args); diff --git a/cc/trees/layer_tree_host.h b/cc/trees/layer_tree_host.h index b17b5a4..2c9cdaf 100644 --- a/cc/trees/layer_tree_host.h +++ b/cc/trees/layer_tree_host.h @@ -113,6 +113,7 @@ class CC_EXPORT LayerTreeHost { void WillBeginMainFrame(); void DidBeginMainFrame(); void BeginMainFrame(const BeginFrameArgs& args); + void BeginMainFrameNotExpectedSoon(); void AnimateLayers(base::TimeTicks monotonic_frame_begin_time); void DidStopFlinging(); void Layout(); diff --git a/cc/trees/layer_tree_host_client.h b/cc/trees/layer_tree_host_client.h index 574325b..6b30532 100644 --- a/cc/trees/layer_tree_host_client.h +++ b/cc/trees/layer_tree_host_client.h @@ -26,6 +26,7 @@ class LayerTreeHostClient { // Marks finishing compositing-related tasks on the main thread. In threaded // mode, this corresponds to DidCommit(). virtual void BeginMainFrame(const BeginFrameArgs& args) = 0; + virtual void BeginMainFrameNotExpectedSoon() = 0; virtual void DidBeginMainFrame() = 0; virtual void Layout() = 0; virtual void ApplyViewportDeltas( diff --git a/cc/trees/layer_tree_host_unittest_no_message_loop.cc b/cc/trees/layer_tree_host_unittest_no_message_loop.cc index d2014ea..06b3674 100644 --- a/cc/trees/layer_tree_host_unittest_no_message_loop.cc +++ b/cc/trees/layer_tree_host_unittest_no_message_loop.cc @@ -56,6 +56,7 @@ class LayerTreeHostNoMessageLoopTest // LayerTreeHostClient overrides. void WillBeginMainFrame() override {} void BeginMainFrame(const BeginFrameArgs& args) override {} + void BeginMainFrameNotExpectedSoon() override {} void DidBeginMainFrame() override {} void Layout() override {} void ApplyViewportDeltas(const gfx::Vector2dF& inner_delta, diff --git a/cc/trees/single_thread_proxy.cc b/cc/trees/single_thread_proxy.cc index 4a079f3..5d447bf 100644 --- a/cc/trees/single_thread_proxy.cc +++ b/cc/trees/single_thread_proxy.cc @@ -685,6 +685,10 @@ void SingleThreadProxy::ScheduledActionSendBeginMainFrame() { weak_factory_.GetWeakPtr())); } +void SingleThreadProxy::SendBeginMainFrameNotExpectedSoon() { + layer_tree_host_->BeginMainFrameNotExpectedSoon(); +} + void SingleThreadProxy::BeginMainFrame() { if (defer_commits_) { TRACE_EVENT_INSTANT0("cc", "EarlyOut_DeferCommit", diff --git a/cc/trees/single_thread_proxy.h b/cc/trees/single_thread_proxy.h index 52dd876..f463db1 100644 --- a/cc/trees/single_thread_proxy.h +++ b/cc/trees/single_thread_proxy.h @@ -79,6 +79,7 @@ class CC_EXPORT SingleThreadProxy : public Proxy, base::TimeDelta CommitToActivateDurationEstimate() override; void DidBeginImplFrameDeadline() override; void SendBeginFramesToChildren(const BeginFrameArgs& args) override; + void SendBeginMainFrameNotExpectedSoon() override; // LayerTreeHostImplClient implementation void UpdateRendererCapabilitiesOnImplThread() override; diff --git a/cc/trees/thread_proxy.cc b/cc/trees/thread_proxy.cc index 167cca9..b72f03c 100644 --- a/cc/trees/thread_proxy.cc +++ b/cc/trees/thread_proxy.cc @@ -701,6 +701,12 @@ void ThreadProxy::ScheduledActionSendBeginMainFrame() { impl().timing_history.DidBeginMainFrame(); } +void ThreadProxy::SendBeginMainFrameNotExpectedSoon() { + Proxy::MainThreadTaskRunner()->PostTask( + FROM_HERE, base::Bind(&ThreadProxy::BeginMainFrameNotExpectedSoon, + main_thread_weak_ptr_)); +} + void ThreadProxy::BeginMainFrame( scoped_ptr<BeginMainFrameAndCommitState> begin_main_frame_state) { benchmark_instrumentation::ScopedBeginFrameTask begin_frame_task( @@ -861,6 +867,12 @@ void ThreadProxy::BeginMainFrame( layer_tree_host()->DidBeginMainFrame(); } +void ThreadProxy::BeginMainFrameNotExpectedSoon() { + TRACE_EVENT0("cc", "ThreadProxy::BeginMainFrameNotExpectedSoon"); + DCHECK(IsMainThread()); + layer_tree_host()->BeginMainFrameNotExpectedSoon(); +} + void ThreadProxy::StartCommitOnImplThread(CompletionEvent* completion, ResourceUpdateQueue* raw_queue) { TRACE_EVENT0("cc", "ThreadProxy::StartCommitOnImplThread"); diff --git a/cc/trees/thread_proxy.h b/cc/trees/thread_proxy.h index 570d240..8b4c302 100644 --- a/cc/trees/thread_proxy.h +++ b/cc/trees/thread_proxy.h @@ -227,6 +227,7 @@ class CC_EXPORT ThreadProxy : public Proxy, base::TimeDelta CommitToActivateDurationEstimate() override; void DidBeginImplFrameDeadline() override; void SendBeginFramesToChildren(const BeginFrameArgs& args) override; + void SendBeginMainFrameNotExpectedSoon() override; // ResourceUpdateControllerClient implementation void ReadyToFinalizeTextureUpdates() override; @@ -244,6 +245,7 @@ class CC_EXPORT ThreadProxy : public Proxy, const RendererCapabilities& capabilities); void BeginMainFrame( scoped_ptr<BeginMainFrameAndCommitState> begin_main_frame_state); + void BeginMainFrameNotExpectedSoon(); void DidCommitAndDrawFrame(); void DidCompleteSwapBuffers(); void SetAnimationEvents(scoped_ptr<AnimationEventsVector> queue); |