summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbajones <bajones@chromium.org>2015-01-06 12:53:59 -0800
committerCommit bot <commit-bot@chromium.org>2015-01-06 20:55:41 +0000
commit274110611d66427435521032dcbaceca8a502455 (patch)
treed9f61a62f7d8de721bc5ad298e4d81d4954ac9d4
parentd2352889de5bb734efdad0855d39734036cd49ae (diff)
downloadchromium_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.cc49
-rw-r--r--cc/scheduler/scheduler.h7
-rw-r--r--cc/scheduler/scheduler_state_machine.h1
-rw-r--r--cc/scheduler/scheduler_unittest.cc144
-rw-r--r--cc/test/fake_proxy.h1
-rw-r--r--cc/test/layer_tree_test.cc6
-rw-r--r--cc/test/scheduler_test_common.cc25
-rw-r--r--cc/test/scheduler_test_common.h3
-rw-r--r--cc/trees/layer_tree_host.cc4
-rw-r--r--cc/trees/layer_tree_host.h2
-rw-r--r--cc/trees/proxy.h2
-rw-r--r--cc/trees/single_thread_proxy.cc8
-rw-r--r--cc/trees/single_thread_proxy.h1
-rw-r--r--cc/trees/thread_proxy.cc15
-rw-r--r--cc/trees/thread_proxy.h2
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);