diff options
author | bajones <bajones@chromium.org> | 2015-01-06 12:53:59 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-01-06 20:55:41 +0000 |
commit | 274110611d66427435521032dcbaceca8a502455 (patch) | |
tree | d9f61a62f7d8de721bc5ad298e4d81d4954ac9d4 | |
parent | d2352889de5bb734efdad0855d39734036cd49ae (diff) | |
download | chromium_src-274110611d66427435521032dcbaceca8a502455.zip chromium_src-274110611d66427435521032dcbaceca8a502455.tar.gz chromium_src-274110611d66427435521032dcbaceca8a502455.tar.bz2 |
Added ability to dynamically toggle frame throttling in the scheduler.
In order to allow Vsync to be toggled by dev tools we need to both set the swap
interval to 0 on systems that support it and prevent the scheduler from
throttling frames.
BUG=437172
Review URL: https://codereview.chromium.org/811523002
Cr-Commit-Position: refs/heads/master@{#310139}
-rw-r--r-- | cc/scheduler/scheduler.cc | 49 | ||||
-rw-r--r-- | cc/scheduler/scheduler.h | 7 | ||||
-rw-r--r-- | cc/scheduler/scheduler_state_machine.h | 1 | ||||
-rw-r--r-- | cc/scheduler/scheduler_unittest.cc | 144 | ||||
-rw-r--r-- | cc/test/fake_proxy.h | 1 | ||||
-rw-r--r-- | cc/test/layer_tree_test.cc | 6 | ||||
-rw-r--r-- | cc/test/scheduler_test_common.cc | 25 | ||||
-rw-r--r-- | cc/test/scheduler_test_common.h | 3 | ||||
-rw-r--r-- | cc/trees/layer_tree_host.cc | 4 | ||||
-rw-r--r-- | cc/trees/layer_tree_host.h | 2 | ||||
-rw-r--r-- | cc/trees/proxy.h | 2 | ||||
-rw-r--r-- | cc/trees/single_thread_proxy.cc | 8 | ||||
-rw-r--r-- | cc/trees/single_thread_proxy.h | 1 | ||||
-rw-r--r-- | cc/trees/thread_proxy.cc | 15 | ||||
-rw-r--r-- | cc/trees/thread_proxy.h | 2 |
15 files changed, 228 insertions, 42 deletions
diff --git a/cc/scheduler/scheduler.cc b/cc/scheduler/scheduler.cc index 6857127..b24430f 100644 --- a/cc/scheduler/scheduler.cc +++ b/cc/scheduler/scheduler.cc @@ -20,16 +20,7 @@ namespace cc { BeginFrameSource* SchedulerFrameSourcesConstructor::ConstructPrimaryFrameSource( Scheduler* scheduler) { - if (!scheduler->settings_.throttle_frame_production) { - TRACE_EVENT1("cc", - "Scheduler::Scheduler()", - "PrimaryFrameSource", - "BackToBackBeginFrameSource"); - DCHECK(!scheduler->primary_frame_source_internal_); - scheduler->primary_frame_source_internal_ = - BackToBackBeginFrameSource::Create(scheduler->task_runner_.get()); - return scheduler->primary_frame_source_internal_.get(); - } else if (scheduler->settings_.use_external_begin_frame_source) { + if (scheduler->settings_.use_external_begin_frame_source) { TRACE_EVENT1("cc", "Scheduler::Scheduler()", "PrimaryFrameSource", @@ -71,6 +62,17 @@ SchedulerFrameSourcesConstructor::ConstructBackgroundFrameSource( return scheduler->background_frame_source_internal_.get(); } +BeginFrameSource* +SchedulerFrameSourcesConstructor::ConstructUnthrottledFrameSource( + Scheduler* scheduler) { + TRACE_EVENT1("cc", "Scheduler::Scheduler()", "UnthrottledFrameSource", + "BackToBackBeginFrameSource"); + DCHECK(!scheduler->unthrottled_frame_source_internal_); + scheduler->unthrottled_frame_source_internal_ = + BackToBackBeginFrameSource::Create(scheduler->task_runner_.get()); + return scheduler->unthrottled_frame_source_internal_.get(); +} + Scheduler::Scheduler( SchedulerClient* client, const SchedulerSettings& scheduler_settings, @@ -85,6 +87,7 @@ Scheduler::Scheduler( primary_frame_source_internal_(external_begin_frame_source.Pass()), background_frame_source_internal_(), vsync_observer_(NULL), + throttle_frame_production_(scheduler_settings.throttle_frame_production), settings_(scheduler_settings), client_(client), layer_tree_host_id_(layer_tree_host_id), @@ -124,6 +127,11 @@ Scheduler::Scheduler( frame_sources_constructor->ConstructBackgroundFrameSource(this); frame_source_->AddSource(background_frame_source_); + // Unthrottled frame source + unthrottled_frame_source_ = + frame_sources_constructor->ConstructUnthrottledFrameSource(this); + frame_source_->AddSource(unthrottled_frame_source_); + SetupPowerMonitoring(); } @@ -183,16 +191,24 @@ void Scheduler::SetCanStart() { ProcessScheduledActions(); } -void Scheduler::SetVisible(bool visible) { - state_machine_.SetVisible(visible); - if (visible) { - frame_source_->SetActiveSource(primary_frame_source_); +void Scheduler::UpdateActiveFrameSource() { + if (state_machine_.visible()) { + if (throttle_frame_production_) { + frame_source_->SetActiveSource(primary_frame_source_); + } else { + frame_source_->SetActiveSource(unthrottled_frame_source_); + } } else { frame_source_->SetActiveSource(background_frame_source_); } ProcessScheduledActions(); } +void Scheduler::SetVisible(bool visible) { + state_machine_.SetVisible(visible); + UpdateActiveFrameSource(); +} + void Scheduler::SetCanDraw(bool can_draw) { state_machine_.SetCanDraw(can_draw); ProcessScheduledActions(); @@ -208,6 +224,11 @@ void Scheduler::NotifyReadyToDraw() { // crbugs 352894, 383157, 421923. } +void Scheduler::SetThrottleFrameProduction(bool throttle) { + throttle_frame_production_ = throttle; + UpdateActiveFrameSource(); +} + void Scheduler::SetNeedsCommit() { state_machine_.SetNeedsCommit(); ProcessScheduledActions(); diff --git a/cc/scheduler/scheduler.h b/cc/scheduler/scheduler.h index 577c87e..faf4399 100644 --- a/cc/scheduler/scheduler.h +++ b/cc/scheduler/scheduler.h @@ -65,6 +65,8 @@ class CC_EXPORT SchedulerFrameSourcesConstructor { virtual BeginFrameSource* ConstructPrimaryFrameSource(Scheduler* scheduler); virtual BeginFrameSource* ConstructBackgroundFrameSource( Scheduler* scheduler); + virtual BeginFrameSource* ConstructUnthrottledFrameSource( + Scheduler* scheduler); protected: SchedulerFrameSourcesConstructor() {} @@ -112,6 +114,7 @@ class CC_EXPORT Scheduler : public BeginFrameObserverMixIn, void SetCanDraw(bool can_draw); void NotifyReadyToActivate(); void NotifyReadyToDraw(); + void SetThrottleFrameProduction(bool throttle); void SetNeedsCommit(); @@ -184,12 +187,15 @@ class CC_EXPORT Scheduler : public BeginFrameObserverMixIn, scoped_ptr<BeginFrameSourceMultiplexer> frame_source_; BeginFrameSource* primary_frame_source_; BeginFrameSource* background_frame_source_; + BeginFrameSource* unthrottled_frame_source_; // Storage when frame sources are internal scoped_ptr<BeginFrameSource> primary_frame_source_internal_; scoped_ptr<SyntheticBeginFrameSource> background_frame_source_internal_; + scoped_ptr<BeginFrameSource> unthrottled_frame_source_internal_; VSyncParameterObserver* vsync_observer_; + bool throttle_frame_production_; const SchedulerSettings settings_; SchedulerClient* client_; @@ -236,6 +242,7 @@ class CC_EXPORT Scheduler : public BeginFrameObserverMixIn, void PollToAdvanceCommitState(); void SetupPowerMonitoring(); void TeardownPowerMonitoring(); + void UpdateActiveFrameSource(); base::TimeDelta EstimatedParentDrawTime() { return estimated_parent_draw_time_; diff --git a/cc/scheduler/scheduler_state_machine.h b/cc/scheduler/scheduler_state_machine.h index 7509819..9dc7817 100644 --- a/cc/scheduler/scheduler_state_machine.h +++ b/cc/scheduler/scheduler_state_machine.h @@ -161,6 +161,7 @@ class CC_EXPORT SchedulerStateMachine { // Indicates whether the LayerTreeHostImpl is visible. void SetVisible(bool visible); + bool visible() const { return visible_; } // Indicates that a redraw is required, either due to the impl tree changing // or the screen being damaged and simply needing redisplay. diff --git a/cc/scheduler/scheduler_unittest.cc b/cc/scheduler/scheduler_unittest.cc index 138420e..29e4c49 100644 --- a/cc/scheduler/scheduler_unittest.cc +++ b/cc/scheduler/scheduler_unittest.cc @@ -122,8 +122,7 @@ class FakeSchedulerClient : public SchedulerClient { TestScheduler* CreateScheduler(const SchedulerSettings& settings) { scoped_ptr<FakeExternalBeginFrameSource> fake_external_begin_frame_source; - if (settings.use_external_begin_frame_source && - settings.throttle_frame_production) { + if (settings.use_external_begin_frame_source) { fake_external_begin_frame_source.reset( new FakeExternalBeginFrameSource(this)); fake_external_begin_frame_source_ = @@ -156,11 +155,6 @@ class FakeSchedulerClient : public SchedulerClient { return posted_begin_impl_frame_deadline_; } - bool ExternalBeginFrame() { - return scheduler_->settings().use_external_begin_frame_source && - scheduler_->settings().throttle_frame_production; - } - FakeExternalBeginFrameSource* fake_external_begin_frame_source() const { return fake_external_begin_frame_source_; } @@ -245,7 +239,8 @@ class FakeSchedulerClient : public SchedulerClient { // Send the next BeginFrame message if using an external source, otherwise // it will be already in the task queue. - if (ExternalBeginFrame()) { + if (scheduler_->settings().use_external_begin_frame_source && + scheduler_->FrameProductionThrottled()) { SendNextBeginFrame(); EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); } @@ -256,7 +251,7 @@ class FakeSchedulerClient : public SchedulerClient { } void SendNextBeginFrame() { - DCHECK(ExternalBeginFrame()); + DCHECK(scheduler_->settings().use_external_begin_frame_source); // Creep the time forward so that any BeginFrameArgs is not equal to the // last one otherwise we violate the BeginFrameSource contract. now_src_->AdvanceNow(BeginFrameArgs::DefaultInterval()); @@ -1510,8 +1505,6 @@ void BeginFramesNotFromClient(bool use_external_begin_frame_source, CREATE_SCHEDULER_AND_INIT_SURFACE(scheduler_settings); - DCHECK(!client.fake_external_begin_frame_source()); - // SetNeedsCommit should begin the frame on the next BeginImplFrame // without calling SetNeedsBeginFrame. scheduler->SetNeedsCommit(); @@ -1598,8 +1591,6 @@ void BeginFramesNotFromClient_SwapThrottled( CREATE_SCHEDULER_AND_INIT_SURFACE(scheduler_settings); scheduler->SetEstimatedParentDrawTime(base::TimeDelta::FromMicroseconds(1)); - DCHECK(!client.fake_external_begin_frame_source()); - // To test swap ack throttling, this test disables automatic swap acks. scheduler->SetMaxSwapsPending(1); client.SetAutomaticSwapAck(false); @@ -2200,5 +2191,132 @@ TEST(SchedulerTest, EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending()); } +// Tests to ensure frame sources can be successfully changed while drawing. +TEST(SchedulerTest, SwitchFrameSourceToUnthrottled) { + FakeSchedulerClient client; + SchedulerSettings scheduler_settings; + scheduler_settings.use_external_begin_frame_source = true; + + CREATE_SCHEDULER_AND_INIT_SURFACE(scheduler_settings); + + // SetNeedsRedraw should begin the frame on the next BeginImplFrame. + scheduler->SetNeedsRedraw(); + EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client); + client.Reset(); + + EXPECT_SCOPED(client.AdvanceFrame()); + EXPECT_ACTION("WillBeginImplFrame", client, 0, 2); + EXPECT_ACTION("ScheduledActionAnimate", client, 1, 2); + EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending()); + EXPECT_TRUE(client.needs_begin_frames()); + client.Reset(); + client.task_runner().RunPendingTasks(); // Run posted deadline. + EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 1); + scheduler->SetNeedsRedraw(); + + // Switch to an unthrottled frame source. + scheduler->SetThrottleFrameProduction(false); + client.Reset(); + + // Unthrottled frame source will immediately begin a new frame. + client.task_runner().RunPendingTasks(); // Run posted BeginFrame. + EXPECT_ACTION("WillBeginImplFrame", client, 0, 2); + EXPECT_ACTION("ScheduledActionAnimate", client, 1, 2); + EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending()); + client.Reset(); + + // If we don't swap on the deadline, we wait for the next BeginFrame. + client.task_runner().RunPendingTasks(); // Run posted deadline. + EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 1); + EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending()); + client.Reset(); +} + +// Tests to ensure frame sources can be successfully changed while a frame +// deadline is pending. +TEST(SchedulerTest, SwitchFrameSourceToUnthrottledBeforeDeadline) { + FakeSchedulerClient client; + SchedulerSettings scheduler_settings; + scheduler_settings.use_external_begin_frame_source = true; + + CREATE_SCHEDULER_AND_INIT_SURFACE(scheduler_settings); + + // SetNeedsRedraw should begin the frame on the next BeginImplFrame. + scheduler->SetNeedsRedraw(); + EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client); + client.Reset(); + + EXPECT_SCOPED(client.AdvanceFrame()); + EXPECT_ACTION("WillBeginImplFrame", client, 0, 2); + EXPECT_ACTION("ScheduledActionAnimate", client, 1, 2); + + // Switch to an unthrottled frame source before the frame deadline is hit. + scheduler->SetThrottleFrameProduction(false); + client.Reset(); + + EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending()); + EXPECT_TRUE(client.needs_begin_frames()); + client.Reset(); + + client.task_runner() + .RunPendingTasks(); // Run posted deadline and BeginFrame. + EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 2); + // Unthrottled frame source will immediately begin a new frame. + EXPECT_ACTION("WillBeginImplFrame", client, 1, 2); + scheduler->SetNeedsRedraw(); + client.Reset(); + + client.task_runner().RunPendingTasks(); // Run posted deadline. + EXPECT_ACTION("ScheduledActionAnimate", client, 0, 2); + EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 1, 2); + EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending()); + client.Reset(); +} + +// Tests to ensure that the active frame source can successfully be changed from +// unthrottled to throttled. +TEST(SchedulerTest, SwitchFrameSourceToThrottled) { + FakeSchedulerClient client; + SchedulerSettings scheduler_settings; + scheduler_settings.throttle_frame_production = false; + scheduler_settings.use_external_begin_frame_source = true; + + CREATE_SCHEDULER_AND_INIT_SURFACE(scheduler_settings); + + scheduler->SetNeedsRedraw(); + EXPECT_NO_ACTION(client); + client.Reset(); + + client.task_runner().RunPendingTasks(); // Run posted BeginFrame. + EXPECT_ACTION("WillBeginImplFrame", client, 0, 2); + EXPECT_ACTION("ScheduledActionAnimate", client, 1, 2); + EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending()); + client.Reset(); + + client.task_runner().RunPendingTasks(); // Run posted deadline. + EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 1); + EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending()); + client.Reset(); + + // Switch to a throttled frame source. + scheduler->SetThrottleFrameProduction(true); + client.Reset(); + + // SetNeedsRedraw should begin the frame on the next BeginImplFrame. + scheduler->SetNeedsRedraw(); + client.task_runner().RunPendingTasks(); + EXPECT_NO_ACTION(client); + client.Reset(); + + EXPECT_SCOPED(client.AdvanceFrame()); + EXPECT_ACTION("WillBeginImplFrame", client, 0, 2); + EXPECT_ACTION("ScheduledActionAnimate", client, 1, 2); + EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending()); + EXPECT_TRUE(client.needs_begin_frames()); + client.Reset(); + client.task_runner().RunPendingTasks(); // Run posted deadline. + EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 1); +} + } // namespace } // namespace cc diff --git a/cc/test/fake_proxy.h b/cc/test/fake_proxy.h index 5404cb0..e77d4f9 100644 --- a/cc/test/fake_proxy.h +++ b/cc/test/fake_proxy.h @@ -26,6 +26,7 @@ class FakeProxy : public Proxy { void SetOutputSurface(scoped_ptr<OutputSurface>) override {} void SetLayerTreeHostClientReady() override {} void SetVisible(bool visible) override {} + void SetThrottleFrameProduction(bool throttle) override {} const RendererCapabilities& GetRendererCapabilities() const override; void SetNeedsAnimate() override {} void SetNeedsUpdateLayers() override {} diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc index 8bf30ec..9653d8d 100644 --- a/cc/test/layer_tree_test.cc +++ b/cc/test/layer_tree_test.cc @@ -580,8 +580,7 @@ void LayerTreeTest::DoBeginTest() { client_ = LayerTreeHostClientForTesting::Create(this); scoped_ptr<FakeExternalBeginFrameSource> external_begin_frame_source; - if (settings_.use_external_begin_frame_source && - settings_.throttle_frame_production) { + if (settings_.use_external_begin_frame_source) { external_begin_frame_source.reset(new FakeExternalBeginFrameSource( settings_.renderer_settings.refresh_rate)); external_begin_frame_source_ = external_begin_frame_source.get(); @@ -762,8 +761,7 @@ scoped_ptr<OutputSurface> LayerTreeTest::CreateOutputSurface() { output_surface->capabilities().delegated_rendering); output_surface_ = output_surface.get(); - if (settings_.use_external_begin_frame_source && - settings_.throttle_frame_production) { + if (settings_.use_external_begin_frame_source) { DCHECK(external_begin_frame_source_); DCHECK(external_begin_frame_source_->is_ready()); } diff --git a/cc/test/scheduler_test_common.cc b/cc/test/scheduler_test_common.cc index 61ef0cf..03e65ab 100644 --- a/cc/test/scheduler_test_common.cc +++ b/cc/test/scheduler_test_common.cc @@ -74,17 +74,7 @@ TestSchedulerFrameSourcesConstructor::~TestSchedulerFrameSourcesConstructor() { BeginFrameSource* TestSchedulerFrameSourcesConstructor::ConstructPrimaryFrameSource( Scheduler* scheduler) { - if (!scheduler->settings_.throttle_frame_production) { - TRACE_EVENT1( - "cc", - "TestSchedulerFrameSourcesConstructor::ConstructPrimaryFrameSource", - "source", - "TestBackToBackBeginFrameSource"); - DCHECK(!scheduler->primary_frame_source_internal_); - scheduler->primary_frame_source_internal_ = - TestBackToBackBeginFrameSource::Create(now_src_, test_task_runner_); - return scheduler->primary_frame_source_internal_.get(); - } else if (scheduler->settings_.use_external_begin_frame_source) { + if (scheduler->settings_.use_external_begin_frame_source) { return SchedulerFrameSourcesConstructor::ConstructPrimaryFrameSource( scheduler); } else { @@ -121,6 +111,19 @@ TestSchedulerFrameSourcesConstructor::ConstructBackgroundFrameSource( return scheduler->background_frame_source_internal_.get(); } +BeginFrameSource* +TestSchedulerFrameSourcesConstructor::ConstructUnthrottledFrameSource( + Scheduler* scheduler) { + TRACE_EVENT1( + "cc", + "TestSchedulerFrameSourcesConstructor::ConstructUnthrottledFrameSource", + "source", "TestBackToBackBeginFrameSource"); + DCHECK(!scheduler->unthrottled_frame_source_internal_); + scheduler->unthrottled_frame_source_internal_ = + TestBackToBackBeginFrameSource::Create(now_src_, test_task_runner_); + return scheduler->unthrottled_frame_source_internal_.get(); +} + TestScheduler::TestScheduler( scoped_refptr<TestNowSource> now_src, SchedulerClient* client, diff --git a/cc/test/scheduler_test_common.h b/cc/test/scheduler_test_common.h index d1e599d..93cff9b 100644 --- a/cc/test/scheduler_test_common.h +++ b/cc/test/scheduler_test_common.h @@ -143,6 +143,8 @@ class TestSchedulerFrameSourcesConstructor BeginFrameSource* ConstructPrimaryFrameSource(Scheduler* scheduler) override; BeginFrameSource* ConstructBackgroundFrameSource( Scheduler* scheduler) override; + BeginFrameSource* ConstructUnthrottledFrameSource( + Scheduler* scheduler) override; OrderedSimpleTaskRunner* test_task_runner_; TestNowSource* now_src_; @@ -185,6 +187,7 @@ class TestScheduler : public Scheduler { bool CanStart() const { return state_machine_.CanStartForTesting(); } BeginFrameSource& frame_source() { return *frame_source_; } + bool FrameProductionThrottled() { return throttle_frame_production_; } ~TestScheduler() override; diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc index 7c00672..b6e6473 100644 --- a/cc/trees/layer_tree_host.cc +++ b/cc/trees/layer_tree_host.cc @@ -741,6 +741,10 @@ void LayerTreeHost::SetVisible(bool visible) { proxy_->SetVisible(visible); } +void LayerTreeHost::SetThrottleFrameProduction(bool throttle) { + proxy_->SetThrottleFrameProduction(throttle); +} + void LayerTreeHost::StartPageScaleAnimation(const gfx::Vector2d& target_offset, bool use_anchor, float scale, diff --git a/cc/trees/layer_tree_host.h b/cc/trees/layer_tree_host.h index 9ce8707..9069b9d 100644 --- a/cc/trees/layer_tree_host.h +++ b/cc/trees/layer_tree_host.h @@ -241,6 +241,8 @@ class CC_EXPORT LayerTreeHost { void SetVisible(bool visible); bool visible() const { return visible_; } + void SetThrottleFrameProduction(bool throttle); + void StartPageScaleAnimation(const gfx::Vector2d& target_offset, bool use_anchor, float scale, diff --git a/cc/trees/proxy.h b/cc/trees/proxy.h index c6f281b..e07e9a2 100644 --- a/cc/trees/proxy.h +++ b/cc/trees/proxy.h @@ -67,6 +67,8 @@ class CC_EXPORT Proxy { virtual void SetVisible(bool visible) = 0; + virtual void SetThrottleFrameProduction(bool throttle) = 0; + virtual const RendererCapabilities& GetRendererCapabilities() const = 0; virtual void SetNeedsAnimate() = 0; diff --git a/cc/trees/single_thread_proxy.cc b/cc/trees/single_thread_proxy.cc index ff2ea90..7d3383a 100644 --- a/cc/trees/single_thread_proxy.cc +++ b/cc/trees/single_thread_proxy.cc @@ -113,6 +113,14 @@ void SingleThreadProxy::SetVisible(bool visible) { // Changing visibility could change ShouldComposite(). } +void SingleThreadProxy::SetThrottleFrameProduction(bool throttle) { + TRACE_EVENT1("cc", "SingleThreadProxy::SetThrottleFrameProduction", + "throttle", throttle); + DebugScopedSetImplThread impl(this); + if (scheduler_on_impl_thread_) + scheduler_on_impl_thread_->SetThrottleFrameProduction(throttle); +} + void SingleThreadProxy::RequestNewOutputSurface() { DCHECK(Proxy::IsMainThread()); DCHECK(layer_tree_host_->output_surface_lost()); diff --git a/cc/trees/single_thread_proxy.h b/cc/trees/single_thread_proxy.h index 6f6e91f..4c1eac0 100644 --- a/cc/trees/single_thread_proxy.h +++ b/cc/trees/single_thread_proxy.h @@ -41,6 +41,7 @@ class CC_EXPORT SingleThreadProxy : public Proxy, void SetOutputSurface(scoped_ptr<OutputSurface>) override; void SetLayerTreeHostClientReady() override; void SetVisible(bool visible) override; + void SetThrottleFrameProduction(bool throttle) override; const RendererCapabilities& GetRendererCapabilities() const override; void SetNeedsAnimate() override; void SetNeedsUpdateLayers() override; diff --git a/cc/trees/thread_proxy.cc b/cc/trees/thread_proxy.cc index 389f296..243e603 100644 --- a/cc/trees/thread_proxy.cc +++ b/cc/trees/thread_proxy.cc @@ -188,6 +188,21 @@ void ThreadProxy::SetVisibleOnImplThread(CompletionEvent* completion, completion->Signal(); } +void ThreadProxy::SetThrottleFrameProduction(bool throttle) { + TRACE_EVENT1("cc", "ThreadProxy::SetThrottleFrameProduction", "throttle", + throttle); + Proxy::ImplThreadTaskRunner()->PostTask( + FROM_HERE, + base::Bind(&ThreadProxy::SetThrottleFrameProductionOnImplThread, + impl_thread_weak_ptr_, throttle)); +} + +void ThreadProxy::SetThrottleFrameProductionOnImplThread(bool throttle) { + TRACE_EVENT1("cc", "ThreadProxy::SetThrottleFrameProductionOnImplThread", + "throttle", throttle); + impl().scheduler->SetThrottleFrameProduction(throttle); +} + void ThreadProxy::DidLoseOutputSurface() { TRACE_EVENT0("cc", "ThreadProxy::DidLoseOutputSurface"); DCHECK(IsMainThread()); diff --git a/cc/trees/thread_proxy.h b/cc/trees/thread_proxy.h index 6ca21d5..f8808f9 100644 --- a/cc/trees/thread_proxy.h +++ b/cc/trees/thread_proxy.h @@ -157,6 +157,7 @@ class CC_EXPORT ThreadProxy : public Proxy, void SetOutputSurface(scoped_ptr<OutputSurface>) override; void SetLayerTreeHostClientReady() override; void SetVisible(bool visible) override; + void SetThrottleFrameProduction(bool throttle) override; const RendererCapabilities& GetRendererCapabilities() const override; void SetNeedsAnimate() override; void SetNeedsUpdateLayers() override; @@ -261,6 +262,7 @@ class CC_EXPORT ThreadProxy : public Proxy, void InitializeImplOnImplThread(CompletionEvent* completion); void SetLayerTreeHostClientReadyOnImplThread(); void SetVisibleOnImplThread(CompletionEvent* completion, bool visible); + void SetThrottleFrameProductionOnImplThread(bool throttle); void HasInitializedOutputSurfaceOnImplThread( CompletionEvent* completion, bool* has_initialized_output_surface); |