summaryrefslogtreecommitdiffstats
path: root/cc
diff options
context:
space:
mode:
authorenne <enne@chromium.org>2016-03-16 14:51:11 -0700
committerCommit bot <commit-bot@chromium.org>2016-03-16 21:52:59 +0000
commitb9bf377e238af579e4b6dd01cb4007ba712da742 (patch)
tree0bcff2210f32f89249a0255b9d4a04af787d19d2 /cc
parent6b03d171d4137691637129ebad5cab20f4babbbb (diff)
downloadchromium_src-b9bf377e238af579e4b6dd01cb4007ba712da742.zip
chromium_src-b9bf377e238af579e4b6dd01cb4007ba712da742.tar.gz
chromium_src-b9bf377e238af579e4b6dd01cb4007ba712da742.tar.bz2
Hoist begin frame sources out of scheduler
To avoid cc::Scheduler having to sometimes own / sometimes create / switch between sources / manage parameters on sources, hoist all this logic up to the owners of cc::Scheduler. This refactoring makes it possible to eventually allow an OutputSurface to set a BeginFrameSource on its client and then forward that to the scheduler to use. That future is made easier by the scheduler having a single begin frame source managed by its owner. This patch adds a bit of duplicated logic in three places (single thread proxy / threaded proxy / tests) for the creation of the begin frame source. However, the single thread and threaded versions were already doing different things (re: authoritative vsync signals). The hope is that the vsync information and begin frame source creation for the synthetic sources can get further hoisted into OutputSurface itself. Depends on https://codereview.chromium.org/1762823002 CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel Review URL: https://codereview.chromium.org/1765723002 Cr-Commit-Position: refs/heads/master@{#381558}
Diffstat (limited to 'cc')
-rw-r--r--cc/scheduler/begin_frame_source.cc191
-rw-r--r--cc/scheduler/begin_frame_source.h51
-rw-r--r--cc/scheduler/begin_frame_source_unittest.cc337
-rw-r--r--cc/scheduler/scheduler.cc106
-rw-r--r--cc/scheduler/scheduler.h30
-rw-r--r--cc/scheduler/scheduler_unittest.cc27
-rw-r--r--cc/test/layer_tree_test.cc3
-rw-r--r--cc/test/scheduler_test_common.cc30
-rw-r--r--cc/test/scheduler_test_common.h30
-rw-r--r--cc/trees/proxy_impl.cc32
-rw-r--r--cc/trees/proxy_impl.h2
-rw-r--r--cc/trees/single_thread_proxy.cc36
-rw-r--r--cc/trees/single_thread_proxy.h5
13 files changed, 131 insertions, 749 deletions
diff --git a/cc/scheduler/begin_frame_source.cc b/cc/scheduler/begin_frame_source.cc
index 5447086..99bc9c6 100644
--- a/cc/scheduler/begin_frame_source.cc
+++ b/cc/scheduler/begin_frame_source.cc
@@ -270,195 +270,4 @@ void SyntheticBeginFrameSource::AsValueInto(
dict->EndDictionary();
}
-// BeginFrameSourceMultiplexer -------------------------------------------
-scoped_ptr<BeginFrameSourceMultiplexer> BeginFrameSourceMultiplexer::Create() {
- return make_scoped_ptr(new BeginFrameSourceMultiplexer());
-}
-
-BeginFrameSourceMultiplexer::BeginFrameSourceMultiplexer()
- : BeginFrameSourceBase(),
- active_source_(nullptr),
- inside_add_observer_(false) {}
-
-BeginFrameSourceMultiplexer::BeginFrameSourceMultiplexer(
- base::TimeDelta minimum_interval)
- : BeginFrameSourceBase(),
- active_source_(nullptr),
- inside_add_observer_(false) {}
-
-BeginFrameSourceMultiplexer::~BeginFrameSourceMultiplexer() {
- if (active_source_ && needs_begin_frames())
- active_source_->RemoveObserver(this);
-}
-
-void BeginFrameSourceMultiplexer::SetMinimumInterval(
- base::TimeDelta new_minimum_interval) {
- DEBUG_FRAMES("BeginFrameSourceMultiplexer::SetMinimumInterval",
- "current minimum (us)",
- minimum_interval_.InMicroseconds(),
- "new minimum (us)",
- new_minimum_interval.InMicroseconds());
- DCHECK_GE(new_minimum_interval.ToInternalValue(), 0);
- minimum_interval_ = new_minimum_interval;
-}
-
-void BeginFrameSourceMultiplexer::AddSource(BeginFrameSource* new_source) {
- DEBUG_FRAMES("BeginFrameSourceMultiplexer::AddSource", "current active",
- active_source_, "source to be added", new_source);
- DCHECK(new_source);
- DCHECK(!HasSource(new_source));
-
- source_list_.insert(new_source);
-
- // If there is no active source, set the new one as the active one.
- if (!active_source_)
- SetActiveSource(new_source);
-}
-
-void BeginFrameSourceMultiplexer::RemoveSource(
- BeginFrameSource* existing_source) {
- DEBUG_FRAMES("BeginFrameSourceMultiplexer::RemoveSource", "current active",
- active_source_, "source to be removed", existing_source);
- DCHECK(existing_source);
- DCHECK(HasSource(existing_source));
- DCHECK_NE(existing_source, active_source_);
- source_list_.erase(existing_source);
-}
-
-void BeginFrameSourceMultiplexer::SetActiveSource(
- BeginFrameSource* new_source) {
- DEBUG_FRAMES("BeginFrameSourceMultiplexer::SetActiveSource",
- "current active",
- active_source_,
- "to become active",
- new_source);
-
- DCHECK(HasSource(new_source) || new_source == nullptr);
-
- if (active_source_ == new_source)
- return;
-
- if (active_source_ && needs_begin_frames())
- active_source_->RemoveObserver(this);
-
- active_source_ = new_source;
-
- if (active_source_ && needs_begin_frames())
- active_source_->AddObserver(this);
-}
-
-const BeginFrameSource* BeginFrameSourceMultiplexer::ActiveSource() {
- return active_source_;
-}
-
-// BeginFrameObserver support
-void BeginFrameSourceMultiplexer::OnBeginFrame(const BeginFrameArgs& args) {
- if (!IsIncreasing(args)) {
- DEBUG_FRAMES("BeginFrameSourceMultiplexer::OnBeginFrame",
- "action",
- "discarding",
- "new args",
- args.AsValue());
- return;
- }
- DEBUG_FRAMES("BeginFrameSourceMultiplexer::OnBeginFrame",
- "action",
- "using",
- "new args",
- args.AsValue());
- last_begin_frame_args_ = args;
- CallOnBeginFrame(args);
-}
-
-const BeginFrameArgs& BeginFrameSourceMultiplexer::LastUsedBeginFrameArgs()
- const {
- return last_begin_frame_args_;
-}
-
-void BeginFrameSourceMultiplexer::OnBeginFrameSourcePausedChanged(bool paused) {
- if (paused_ == paused)
- return;
- paused_ = paused;
- if (!inside_add_observer_) {
- std::set<BeginFrameObserver*> observers(observers_);
- for (auto& it : observers)
- it->OnBeginFrameSourcePausedChanged(paused);
- }
-}
-
-// BeginFrameSource support
-void BeginFrameSourceMultiplexer::DidFinishFrame(size_t remaining_frames) {
- DEBUG_FRAMES("BeginFrameSourceMultiplexer::DidFinishFrame",
- "active_source",
- active_source_,
- "remaining_frames",
- remaining_frames);
- if (active_source_)
- active_source_->DidFinishFrame(remaining_frames);
-}
-
-void BeginFrameSourceMultiplexer::AddObserver(BeginFrameObserver* obs) {
- base::AutoReset<bool> reset(&inside_add_observer_, true);
- BeginFrameSourceBase::AddObserver(obs);
-}
-
-void BeginFrameSourceMultiplexer::OnNeedsBeginFramesChanged(
- bool needs_begin_frames) {
- if (!active_source_)
- return;
- if (needs_begin_frames) {
- active_source_->AddObserver(this);
- } else {
- active_source_->RemoveObserver(this);
- }
-}
-
-// Tracing support
-void BeginFrameSourceMultiplexer::AsValueInto(
- base::trace_event::TracedValue* dict) const {
- dict->SetString("type", "BeginFrameSourceMultiplexer");
-
- dict->SetInteger("minimum_interval_us", minimum_interval_.InMicroseconds());
-
- dict->BeginDictionary("last_begin_frame_args");
- last_begin_frame_args_.AsValueInto(dict);
- dict->EndDictionary();
-
- if (active_source_) {
- dict->BeginDictionary("active_source");
- active_source_->AsValueInto(dict);
- dict->EndDictionary();
- } else {
- dict->SetString("active_source", "NULL");
- }
-
- dict->BeginArray("sources");
- for (std::set<BeginFrameSource*>::const_iterator it = source_list_.begin();
- it != source_list_.end();
- ++it) {
- dict->BeginDictionary();
- (*it)->AsValueInto(dict);
- dict->EndDictionary();
- }
- dict->EndArray();
-}
-
-// protected methods
-bool BeginFrameSourceMultiplexer::HasSource(BeginFrameSource* source) {
- return (source_list_.find(source) != source_list_.end());
-}
-
-bool BeginFrameSourceMultiplexer::IsIncreasing(const BeginFrameArgs& args) {
- DCHECK(args.IsValid());
-
- // If the last begin frame is invalid, then any new begin frame is valid.
- if (!last_begin_frame_args_.IsValid())
- return true;
-
- // Only allow new args have a *strictly bigger* frame_time value and statisfy
- // minimum interval requirement.
- return (args.frame_time >=
- last_begin_frame_args_.frame_time + minimum_interval_);
-}
-
} // namespace cc
diff --git a/cc/scheduler/begin_frame_source.h b/cc/scheduler/begin_frame_source.h
index 0850884..6815d42 100644
--- a/cc/scheduler/begin_frame_source.h
+++ b/cc/scheduler/begin_frame_source.h
@@ -249,57 +249,6 @@ class CC_EXPORT SyntheticBeginFrameSource : public BeginFrameSourceBase,
DISALLOW_COPY_AND_ASSIGN(SyntheticBeginFrameSource);
};
-// A "virtual" frame source which lets you switch between multiple other frame
-// sources while making sure the BeginFrameArgs stays increasing (possibly
-// enforcing minimum boundry between BeginFrameArgs messages).
-class CC_EXPORT BeginFrameSourceMultiplexer : public BeginFrameSourceBase,
- public BeginFrameObserver {
- public:
- static scoped_ptr<BeginFrameSourceMultiplexer> Create();
- ~BeginFrameSourceMultiplexer() override;
-
- void SetMinimumInterval(base::TimeDelta new_minimum_interval);
-
- void AddSource(BeginFrameSource* new_source);
- void RemoveSource(BeginFrameSource* existing_source);
- void SetActiveSource(BeginFrameSource* new_source);
- const BeginFrameSource* ActiveSource();
-
- // BeginFrameObserver
- // The mux is an BeginFrameObserver as it needs to proxy the OnBeginFrame
- // calls to preserve the monotonicity of the BeginFrameArgs when switching
- // sources.
- void OnBeginFrame(const BeginFrameArgs& args) override;
- const BeginFrameArgs& LastUsedBeginFrameArgs() const override;
- void OnBeginFrameSourcePausedChanged(bool paused) override;
-
- // BeginFrameSourceBase
- void DidFinishFrame(size_t remaining_frames) override;
- void AddObserver(BeginFrameObserver* obs) override;
- void OnNeedsBeginFramesChanged(bool needs_begin_frames) override;
-
- // Tracing
- void AsValueInto(base::trace_event::TracedValue* dict) const override;
-
- protected:
- BeginFrameSourceMultiplexer();
- explicit BeginFrameSourceMultiplexer(base::TimeDelta minimum_interval);
-
- bool HasSource(BeginFrameSource* source);
- bool IsIncreasing(const BeginFrameArgs& args);
-
- base::TimeDelta minimum_interval_;
-
- BeginFrameSource* active_source_;
- std::set<BeginFrameSource*> source_list_;
-
- BeginFrameArgs last_begin_frame_args_;
- bool inside_add_observer_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(BeginFrameSourceMultiplexer);
-};
-
} // namespace cc
#endif // CC_SCHEDULER_BEGIN_FRAME_SOURCE_H_
diff --git a/cc/scheduler/begin_frame_source_unittest.cc b/cc/scheduler/begin_frame_source_unittest.cc
index 6ab9074..418fd32 100644
--- a/cc/scheduler/begin_frame_source_unittest.cc
+++ b/cc/scheduler/begin_frame_source_unittest.cc
@@ -566,342 +566,5 @@ TEST_F(SyntheticBeginFrameSourceTest, DoubleTickMissedFrame) {
source_->RemoveObserver(&obs);
}
-// BeginFrameSourceMultiplexer testing -----------------------------------
-class BeginFrameSourceMultiplexerTest : public ::testing::Test {
- protected:
- void SetUp() override {
- mux_ = BeginFrameSourceMultiplexer::Create();
-
- source1_store_ = make_scoped_ptr(new FakeBeginFrameSource());
- source2_store_ = make_scoped_ptr(new FakeBeginFrameSource());
- source3_store_ = make_scoped_ptr(new FakeBeginFrameSource());
-
- source1_ = source1_store_.get();
- source2_ = source2_store_.get();
- source3_ = source3_store_.get();
- }
-
- void TearDown() override {
- // Make sure the mux is torn down before the sources.
- mux_.reset();
- }
-
- scoped_ptr<BeginFrameSourceMultiplexer> mux_;
- FakeBeginFrameSource* source1_;
- FakeBeginFrameSource* source2_;
- FakeBeginFrameSource* source3_;
-
- private:
- scoped_ptr<FakeBeginFrameSource> source1_store_;
- scoped_ptr<FakeBeginFrameSource> source2_store_;
- scoped_ptr<FakeBeginFrameSource> source3_store_;
-};
-
-TEST_F(BeginFrameSourceMultiplexerTest, SourcesManipulation) {
- EXPECT_EQ(NULL, mux_->ActiveSource());
-
- mux_->AddSource(source1_);
- EXPECT_EQ(source1_, mux_->ActiveSource());
-
- mux_->SetActiveSource(NULL);
- EXPECT_EQ(NULL, mux_->ActiveSource());
-
- mux_->SetActiveSource(source1_);
-
-#ifndef NDEBUG
- // Setting a source which isn't in the mux as active should DCHECK fail.
- EXPECT_DEATH({ mux_->SetActiveSource(source2_); }, "");
-
- // Adding a source which is already added should DCHECK fail.
- EXPECT_DEATH({ mux_->AddSource(source1_); }, "");
-
- // Removing a source which isn't in the mux should DCHECK fail.
- EXPECT_DEATH({ mux_->RemoveSource(source2_); }, "");
-
- // Removing the active source fails
- EXPECT_DEATH({ mux_->RemoveSource(source1_); }, "");
-#endif
-
- // Test manipulation doesn't segfault.
- mux_->AddSource(source2_);
- mux_->RemoveSource(source2_);
-
- mux_->AddSource(source2_);
- mux_->SetActiveSource(source2_);
- EXPECT_EQ(source2_, mux_->ActiveSource());
-
- mux_->RemoveSource(source1_);
-}
-
-TEST_F(BeginFrameSourceMultiplexerTest, SwitchActiveSource) {
- mux_->AddSource(source1_);
- mux_->AddSource(source2_);
-
- EXPECT_FALSE(source1_->has_observers());
- EXPECT_FALSE(source2_->has_observers());
-
- MockBeginFrameObserver obs;
- mux_->AddObserver(&obs);
-
- mux_->SetActiveSource(source1_);
- EXPECT_TRUE(source1_->has_observers());
- EXPECT_FALSE(source2_->has_observers());
-
- mux_->SetActiveSource(source2_);
- EXPECT_FALSE(source1_->has_observers());
- EXPECT_TRUE(source2_->has_observers());
-}
-
-TEST_F(BeginFrameSourceMultiplexerTest, SingleObserver) {
- mux_->AddSource(source1_);
- mux_->AddSource(source2_);
- mux_->SetActiveSource(source1_);
-
- EXPECT_FALSE(source1_->has_observers());
- EXPECT_FALSE(source2_->has_observers());
-
- MockBeginFrameObserver obs;
- EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs, false);
- mux_->AddObserver(&obs);
- EXPECT_TRUE(source1_->has_observers());
- EXPECT_FALSE(source2_->has_observers());
-
- EXPECT_BEGIN_FRAME_USED(obs, 100, 200, 100);
- SEND_BEGIN_FRAME_USED(*source1_, 100, 200, 100);
- SEND_BEGIN_FRAME_DROP(*source2_, 150, 250, 100);
-
- mux_->RemoveObserver(&obs);
- EXPECT_FALSE(source1_->has_observers());
- EXPECT_FALSE(source2_->has_observers());
-}
-
-TEST_F(BeginFrameSourceMultiplexerTest, MultipleObservers) {
- mux_->AddSource(source1_);
- mux_->AddSource(source2_);
- mux_->SetActiveSource(source1_);
-
- EXPECT_FALSE(source1_->has_observers());
- EXPECT_FALSE(source2_->has_observers());
-
- StrictMock<MockBeginFrameObserver> obs1, obs2;
- EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs1, false);
- mux_->AddObserver(&obs1);
- EXPECT_TRUE(source1_->has_observers());
- EXPECT_FALSE(source2_->has_observers());
-
- EXPECT_BEGIN_FRAME_USED(obs1, 100, 200, 100);
- SEND_BEGIN_FRAME_USED(*source1_, 100, 200, 100);
- SEND_BEGIN_FRAME_DROP(*source2_, 200, 300, 100);
-
- EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs2, false);
- mux_->AddObserver(&obs2);
-
- EXPECT_BEGIN_FRAME_USED(obs1, 300, 400, 100);
- EXPECT_BEGIN_FRAME_USED(obs2, 300, 400, 100);
- SEND_BEGIN_FRAME_USED(*source1_, 300, 400, 100);
- SEND_BEGIN_FRAME_DROP(*source2_, 400, 500, 100);
-
- EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs1, true);
- EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs2, true);
- source1_->SetBeginFrameSourcePaused(true);
-
- EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs1, false);
- EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs2, false);
- mux_->SetActiveSource(source2_);
- EXPECT_FALSE(source1_->has_observers());
- EXPECT_TRUE(source2_->has_observers());
-
- EXPECT_BEGIN_FRAME_USED(obs1, 600, 700, 100);
- EXPECT_BEGIN_FRAME_USED(obs2, 600, 700, 100);
- SEND_BEGIN_FRAME_DROP(*source1_, 500, 600, 100);
- SEND_BEGIN_FRAME_USED(*source2_, 600, 700, 100);
-
- mux_->RemoveObserver(&obs1);
- EXPECT_FALSE(source1_->has_observers());
- EXPECT_TRUE(source2_->has_observers());
-
- EXPECT_BEGIN_FRAME_USED(obs2, 800, 900, 100);
- SEND_BEGIN_FRAME_DROP(*source1_, 700, 800, 100);
- SEND_BEGIN_FRAME_USED(*source2_, 800, 900, 100);
-
- mux_->RemoveObserver(&obs2);
- EXPECT_FALSE(source1_->has_observers());
- EXPECT_FALSE(source2_->has_observers());
-}
-
-TEST_F(BeginFrameSourceMultiplexerTest, BeginFramesSimple) {
- mux_->AddSource(source1_);
- mux_->AddSource(source2_);
- mux_->SetActiveSource(source1_);
-
- MockBeginFrameObserver obs;
- EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs, false);
- mux_->AddObserver(&obs);
- EXPECT_BEGIN_FRAME_USED(obs, 100, 200, 300);
- EXPECT_BEGIN_FRAME_USED(obs, 400, 600, 300);
-
- mux_->SetActiveSource(source1_);
-
- SEND_BEGIN_FRAME_USED(*source1_, 100, 200, 300);
- SEND_BEGIN_FRAME_DROP(*source2_, 200, 500, 300);
-
- mux_->SetActiveSource(source2_);
- SEND_BEGIN_FRAME_USED(*source2_, 400, 600, 300);
- SEND_BEGIN_FRAME_DROP(*source1_, 500, 700, 300);
-}
-
-TEST_F(BeginFrameSourceMultiplexerTest, BeginFramesBackwardsProtection) {
- mux_->AddSource(source1_);
- mux_->AddSource(source2_);
-
- MockBeginFrameObserver obs;
- EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs, false);
- mux_->AddObserver(&obs);
- EXPECT_BEGIN_FRAME_USED(obs, 400, 600, 300);
- EXPECT_BEGIN_FRAME_USED(obs, 700, 900, 300);
- EXPECT_BEGIN_FRAME_USED(obs, 1000, 1200, 300);
- EXPECT_BEGIN_FRAME_USED(obs, 1001, 1201, 301);
-
- mux_->SetActiveSource(source1_);
- SEND_BEGIN_FRAME_USED(*source1_, 400, 600, 300);
- SEND_BEGIN_FRAME_USED(*source1_, 700, 900, 300);
-
- mux_->SetActiveSource(source2_);
- SEND_BEGIN_FRAME_DROP(*source2_, 699, 899, 300);
- SEND_BEGIN_FRAME_USED(*source2_, 1000, 1200, 300);
-
- mux_->SetActiveSource(source1_);
- SEND_BEGIN_FRAME_USED(*source1_, 1001, 1201, 301);
-}
-
-TEST_F(BeginFrameSourceMultiplexerTest, MinimumIntervalNegativeFails) {
-#ifndef NDEBUG
- EXPECT_DEATH(
- { mux_->SetMinimumInterval(base::TimeDelta::FromInternalValue(-100)); },
- "");
-#endif
-}
-
-TEST_F(BeginFrameSourceMultiplexerTest, MinimumIntervalZero) {
- mux_->SetMinimumInterval(base::TimeDelta());
- mux_->AddSource(source1_);
-
- MockBeginFrameObserver obs;
- EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs, false);
- mux_->AddObserver(&obs);
- EXPECT_BEGIN_FRAME_USED(obs, 100, 200, 300);
- EXPECT_BEGIN_FRAME_USED(obs, 400, 600, 300);
- EXPECT_BEGIN_FRAME_USED(obs, 700, 900, 300);
-
- SEND_BEGIN_FRAME_USED(*source1_, 100, 200, 300);
- SEND_BEGIN_FRAME_USED(*source1_, 400, 600, 300);
- SEND_BEGIN_FRAME_USED(*source1_, 700, 900, 300);
-}
-
-TEST_F(BeginFrameSourceMultiplexerTest, MinimumIntervalBasic) {
- mux_->SetMinimumInterval(base::TimeDelta::FromInternalValue(600));
- mux_->AddSource(source1_);
-
- MockBeginFrameObserver obs;
- EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs, false);
- mux_->AddObserver(&obs);
- EXPECT_BEGIN_FRAME_USED(obs, 100, 200, 300);
- EXPECT_BEGIN_FRAME_USED(obs, 700, 900, 300);
-
- SEND_BEGIN_FRAME_USED(*source1_, 100, 200, 300);
- SEND_BEGIN_FRAME_DROP(*source1_, 400, 600, 300);
- SEND_BEGIN_FRAME_USED(*source1_, 700, 900, 300);
-}
-
-TEST_F(BeginFrameSourceMultiplexerTest, MinimumIntervalWithMultipleSources) {
- mux_->SetMinimumInterval(base::TimeDelta::FromMicroseconds(150));
- mux_->AddSource(source1_);
- mux_->AddSource(source2_);
-
- MockBeginFrameObserver obs;
- EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs, false);
- mux_->AddObserver(&obs);
- EXPECT_BEGIN_FRAME_USED(obs, 400, 600, 300);
- EXPECT_BEGIN_FRAME_USED(obs, 700, 900, 300);
- EXPECT_BEGIN_FRAME_USED(obs, 1050, 1250, 300);
-
- mux_->SetActiveSource(source1_);
- SEND_BEGIN_FRAME_USED(*source1_, 400, 600, 300);
- SEND_BEGIN_FRAME_USED(*source1_, 700, 900, 300);
-
- mux_->SetActiveSource(source2_);
- SEND_BEGIN_FRAME_DROP(*source2_, 750, 1050, 300);
- SEND_BEGIN_FRAME_USED(*source2_, 1050, 1250, 300);
-
- mux_->SetActiveSource(source1_);
- SEND_BEGIN_FRAME_DROP(*source2_, 1100, 1400, 300);
-}
-
-TEST_F(BeginFrameSourceMultiplexerTest, BeginFrameSourcePaused) {
- mux_->AddSource(source1_);
- mux_->AddSource(source2_);
- mux_->SetActiveSource(source1_);
-
- MockBeginFrameObserver obs;
- EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs, false);
- mux_->AddObserver(&obs);
- Mock::VerifyAndClearExpectations(&obs);
-
- EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs, true);
- source1_->SetBeginFrameSourcePaused(true);
- EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs, false);
- source1_->SetBeginFrameSourcePaused(false);
- Mock::VerifyAndClearExpectations(&obs);
-
- mux_->SetActiveSource(source2_);
- Mock::VerifyAndClearExpectations(&obs);
-
- EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs, true);
- source2_->SetBeginFrameSourcePaused(true);
- EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs, false);
- source2_->SetBeginFrameSourcePaused(false);
-}
-
-TEST_F(BeginFrameSourceMultiplexerTest,
- BeginFrameSourcePausedUpdateOnSourceTransition) {
- mux_->AddSource(source1_);
- mux_->AddSource(source2_);
- source1_->SetBeginFrameSourcePaused(true);
- source2_->SetBeginFrameSourcePaused(false);
- mux_->SetActiveSource(source1_);
-
- MockBeginFrameObserver obs;
- EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs, true);
- mux_->AddObserver(&obs);
- Mock::VerifyAndClearExpectations(&obs);
-
- // Paused to not paused.
- EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs, false);
- mux_->SetActiveSource(source2_);
- Mock::VerifyAndClearExpectations(&obs);
-
- // Not paused to paused.
- EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs, true);
- mux_->SetActiveSource(source1_);
- Mock::VerifyAndClearExpectations(&obs);
-
- EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs, false);
- source1_->SetBeginFrameSourcePaused(false);
- Mock::VerifyAndClearExpectations(&obs);
-
- // Not paused to not paused.
- mux_->SetActiveSource(source2_);
- Mock::VerifyAndClearExpectations(&obs);
-
- EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs, true);
- source2_->SetBeginFrameSourcePaused(true);
- Mock::VerifyAndClearExpectations(&obs);
- source1_->SetBeginFrameSourcePaused(true);
-
- // Paused to paused.
- mux_->SetActiveSource(source1_);
- Mock::VerifyAndClearExpectations(&obs);
-}
-
} // namespace
} // namespace cc
diff --git a/cc/scheduler/scheduler.cc b/cc/scheduler/scheduler.cc
index a84c1ba..ca36c1e 100644
--- a/cc/scheduler/scheduler.cc
+++ b/cc/scheduler/scheduler.cc
@@ -31,19 +31,11 @@ scoped_ptr<Scheduler> Scheduler::Create(
const SchedulerSettings& settings,
int layer_tree_host_id,
base::SingleThreadTaskRunner* task_runner,
- BeginFrameSource* external_frame_source,
+ BeginFrameSource* begin_frame_source,
scoped_ptr<CompositorTimingHistory> compositor_timing_history) {
- scoped_ptr<SyntheticBeginFrameSource> synthetic_frame_source;
- if (!settings.use_external_begin_frame_source) {
- synthetic_frame_source = SyntheticBeginFrameSource::Create(
- task_runner, BeginFrameArgs::DefaultInterval());
- }
- scoped_ptr<BackToBackBeginFrameSource> unthrottled_frame_source =
- BackToBackBeginFrameSource::Create(task_runner);
- return make_scoped_ptr(new Scheduler(
- client, settings, layer_tree_host_id, task_runner, external_frame_source,
- std::move(synthetic_frame_source), std::move(unthrottled_frame_source),
- std::move(compositor_timing_history)));
+ return make_scoped_ptr(new Scheduler(client, settings, layer_tree_host_id,
+ task_runner, begin_frame_source,
+ std::move(compositor_timing_history)));
}
Scheduler::Scheduler(
@@ -51,19 +43,14 @@ Scheduler::Scheduler(
const SchedulerSettings& settings,
int layer_tree_host_id,
base::SingleThreadTaskRunner* task_runner,
- BeginFrameSource* external_frame_source,
- scoped_ptr<SyntheticBeginFrameSource> synthetic_frame_source,
- scoped_ptr<BackToBackBeginFrameSource> unthrottled_frame_source,
+ BeginFrameSource* begin_frame_source,
scoped_ptr<CompositorTimingHistory> compositor_timing_history)
: settings_(settings),
client_(client),
layer_tree_host_id_(layer_tree_host_id),
task_runner_(task_runner),
- external_frame_source_(external_frame_source),
- synthetic_frame_source_(std::move(synthetic_frame_source)),
- unthrottled_frame_source_(std::move(unthrottled_frame_source)),
- frame_source_(BeginFrameSourceMultiplexer::Create()),
- observing_frame_source_(false),
+ begin_frame_source_(begin_frame_source),
+ observing_begin_frame_source_(false),
compositor_timing_history_(std::move(compositor_timing_history)),
begin_impl_frame_deadline_mode_(
SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_NONE),
@@ -75,33 +62,19 @@ Scheduler::Scheduler(
TRACE_EVENT1("cc", "Scheduler::Scheduler", "settings", settings_.AsValue());
DCHECK(client_);
DCHECK(!state_machine_.BeginFrameNeeded());
- DCHECK(!settings_.use_external_begin_frame_source || external_frame_source_);
- DCHECK(settings_.use_external_begin_frame_source || synthetic_frame_source_);
- DCHECK(unthrottled_frame_source_);
begin_retro_frame_closure_ =
base::Bind(&Scheduler::BeginRetroFrame, weak_factory_.GetWeakPtr());
begin_impl_frame_deadline_closure_ = base::Bind(
&Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr());
- frame_source_->AddSource(primary_frame_source());
- primary_frame_source()->SetClientReady();
-
- frame_source_->AddSource(unthrottled_frame_source_.get());
- unthrottled_frame_source_->SetClientReady();
-
- if (settings_.throttle_frame_production) {
- frame_source_->SetActiveSource(primary_frame_source());
- } else {
- frame_source_->SetActiveSource(unthrottled_frame_source_.get());
- }
+ begin_frame_source_->SetClientReady();
ProcessScheduledActions();
}
Scheduler::~Scheduler() {
- if (observing_frame_source_)
- frame_source_->RemoveObserver(this);
- frame_source_->SetActiveSource(nullptr);
+ if (observing_begin_frame_source_)
+ begin_frame_source_->RemoveObserver(this);
}
base::TimeTicks Scheduler::Now() const {
@@ -113,21 +86,6 @@ base::TimeTicks Scheduler::Now() const {
return now;
}
-void Scheduler::CommitVSyncParameters(base::TimeTicks timebase,
- base::TimeDelta interval) {
- if (authoritative_vsync_interval_ != base::TimeDelta()) {
- interval = authoritative_vsync_interval_;
- } else if (interval == base::TimeDelta()) {
- // TODO(brianderson): We should not be receiving 0 intervals.
- interval = BeginFrameArgs::DefaultInterval();
- }
-
- last_vsync_timebase_ = timebase;
-
- if (synthetic_frame_source_)
- synthetic_frame_source_->OnUpdateVSyncParameters(timebase, interval);
-}
-
void Scheduler::SetEstimatedParentDrawTime(base::TimeDelta draw_time) {
DCHECK_GE(draw_time.ToInternalValue(), 0);
estimated_parent_draw_time_ = draw_time;
@@ -241,7 +199,7 @@ void Scheduler::DidLoseOutputSurface() {
void Scheduler::DidCreateAndInitializeOutputSurface() {
TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface");
- DCHECK(!observing_frame_source_);
+ DCHECK(!observing_begin_frame_source_);
DCHECK(begin_impl_frame_deadline_task_.IsCancelled());
state_machine_.DidCreateAndInitializeOutputSurface();
compositor_timing_history_->DidCreateAndInitializeOutputSurface();
@@ -272,18 +230,18 @@ void Scheduler::BeginImplFrameNotExpectedSoon() {
void Scheduler::SetupNextBeginFrameIfNeeded() {
// Never call SetNeedsBeginFrames if the frame source already has the right
// value.
- if (observing_frame_source_ != state_machine_.BeginFrameNeeded()) {
+ if (observing_begin_frame_source_ != state_machine_.BeginFrameNeeded()) {
if (state_machine_.BeginFrameNeeded()) {
// Call AddObserver as soon as possible.
- observing_frame_source_ = true;
- frame_source_->AddObserver(this);
+ observing_begin_frame_source_ = true;
+ begin_frame_source_->AddObserver(this);
devtools_instrumentation::NeedsBeginFrameChanged(layer_tree_host_id_,
true);
} else if (state_machine_.begin_impl_frame_state() ==
SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE) {
// Call RemoveObserver in between frames only.
- observing_frame_source_ = false;
- frame_source_->RemoveObserver(this);
+ observing_begin_frame_source_ = false;
+ begin_frame_source_->RemoveObserver(this);
BeginImplFrameNotExpectedSoon();
devtools_instrumentation::NeedsBeginFrameChanged(layer_tree_host_id_,
false);
@@ -340,7 +298,8 @@ bool Scheduler::OnBeginFrameDerivedImpl(const BeginFrameArgs& args) {
bool should_defer_begin_frame =
!begin_retro_frame_args_.empty() ||
- !begin_retro_frame_task_.IsCancelled() || !observing_frame_source_ ||
+ !begin_retro_frame_task_.IsCancelled() ||
+ !observing_begin_frame_source_ ||
(state_machine_.begin_impl_frame_state() !=
SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
@@ -360,14 +319,6 @@ void Scheduler::SetChildrenNeedBeginFrames(bool children_need_begin_frames) {
ProcessScheduledActions();
}
-void Scheduler::SetAuthoritativeVSyncInterval(const base::TimeDelta& interval) {
- authoritative_vsync_interval_ = interval;
- if (synthetic_frame_source_) {
- synthetic_frame_source_->OnUpdateVSyncParameters(last_vsync_timebase_,
- interval);
- }
-}
-
void Scheduler::SetVideoNeedsBeginFrames(bool video_needs_begin_frames) {
state_machine_.SetVideoNeedsBeginFrames(video_needs_begin_frames);
ProcessScheduledActions();
@@ -419,7 +370,7 @@ void Scheduler::BeginRetroFrame() {
"expiration_time - now", (expiration_time - now).InMillisecondsF(),
"BeginFrameArgs", begin_retro_frame_args_.front().AsValue());
begin_retro_frame_args_.pop_front();
- frame_source_->DidFinishFrame(begin_retro_frame_args_.size());
+ begin_frame_source_->DidFinishFrame(begin_retro_frame_args_.size());
}
if (begin_retro_frame_args_.empty()) {
@@ -442,7 +393,7 @@ void Scheduler::PostBeginRetroFrameIfNeeded() {
"Scheduler::PostBeginRetroFrameIfNeeded",
"state",
AsValue());
- if (!observing_frame_source_)
+ if (!observing_begin_frame_source_)
return;
if (begin_retro_frame_args_.empty() || !begin_retro_frame_task_.IsCancelled())
@@ -512,7 +463,7 @@ void Scheduler::BeginImplFrameWithDeadline(const BeginFrameArgs& args) {
can_activate_before_deadline)) {
TRACE_EVENT_INSTANT0("cc", "SkipBeginImplFrameToReduceLatency",
TRACE_EVENT_SCOPE_THREAD);
- frame_source_->DidFinishFrame(begin_retro_frame_args_.size());
+ begin_frame_source_->DidFinishFrame(begin_retro_frame_args_.size());
return;
}
@@ -544,7 +495,7 @@ void Scheduler::FinishImplFrame() {
ProcessScheduledActions();
client_->DidFinishImplFrame();
- frame_source_->DidFinishFrame(begin_retro_frame_args_.size());
+ begin_frame_source_->DidFinishFrame(begin_retro_frame_args_.size());
begin_impl_frame_tracker_.Finish();
}
@@ -795,23 +746,18 @@ void Scheduler::AsValueInto(base::trace_event::TracedValue* state) const {
TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"),
&frame_tracing_enabled);
if (frame_tracing_enabled) {
- state->BeginDictionary("frame_source_");
- frame_source_->AsValueInto(state);
+ state->BeginDictionary("begin_frame_source_");
+ begin_frame_source_->AsValueInto(state);
state->EndDictionary();
}
state->BeginDictionary("scheduler_state");
- state->SetBoolean("external_frame_source_", !!external_frame_source_);
state->SetBoolean("throttle_frame_production_",
settings_.throttle_frame_production);
- state->SetDouble("authoritative_vsync_interval_ms",
- authoritative_vsync_interval_.InMillisecondsF());
- state->SetDouble(
- "last_vsync_timebase_ms",
- (last_vsync_timebase_ - base::TimeTicks()).InMillisecondsF());
state->SetDouble("estimated_parent_draw_time_ms",
estimated_parent_draw_time_.InMillisecondsF());
- state->SetBoolean("observing_frame_source", observing_frame_source_);
+ state->SetBoolean("observing_begin_frame_source",
+ observing_begin_frame_source_);
state->SetInteger("begin_retro_frame_args",
static_cast<int>(begin_retro_frame_args_.size()));
state->SetBoolean("begin_retro_frame_task",
diff --git a/cc/scheduler/scheduler.h b/cc/scheduler/scheduler.h
index a5a6bd4..4828896 100644
--- a/cc/scheduler/scheduler.h
+++ b/cc/scheduler/scheduler.h
@@ -60,7 +60,7 @@ class CC_EXPORT Scheduler : public BeginFrameObserverBase {
const SchedulerSettings& scheduler_settings,
int layer_tree_host_id,
base::SingleThreadTaskRunner* task_runner,
- BeginFrameSource* external_frame_source,
+ BeginFrameSource* begin_frame_source,
scoped_ptr<CompositorTimingHistory> compositor_timing_history);
~Scheduler() override;
@@ -73,8 +73,6 @@ class CC_EXPORT Scheduler : public BeginFrameObserverBase {
const SchedulerSettings& settings() const { return settings_; }
- void CommitVSyncParameters(base::TimeTicks timebase,
- base::TimeDelta interval);
void SetEstimatedParentDrawTime(base::TimeDelta draw_time);
void SetVisible(bool visible);
@@ -142,34 +140,26 @@ class CC_EXPORT Scheduler : public BeginFrameObserverBase {
void SetChildrenNeedBeginFrames(bool children_need_begin_frames);
void SetVideoNeedsBeginFrames(bool video_needs_begin_frames);
- void SetAuthoritativeVSyncInterval(const base::TimeDelta& interval);
-
protected:
Scheduler(SchedulerClient* client,
const SchedulerSettings& scheduler_settings,
int layer_tree_host_id,
base::SingleThreadTaskRunner* task_runner,
- BeginFrameSource* external_frame_source,
- scoped_ptr<SyntheticBeginFrameSource> synthetic_frame_source,
- scoped_ptr<BackToBackBeginFrameSource> unthrottled_frame_source,
+ BeginFrameSource* begin_frame_source,
scoped_ptr<CompositorTimingHistory> compositor_timing_history);
// Virtual for testing.
virtual base::TimeTicks Now() const;
const SchedulerSettings settings_;
+ // Not owned.
SchedulerClient* client_;
int layer_tree_host_id_;
base::SingleThreadTaskRunner* task_runner_;
- BeginFrameSource* external_frame_source_;
- scoped_ptr<SyntheticBeginFrameSource> synthetic_frame_source_;
- scoped_ptr<BackToBackBeginFrameSource> unthrottled_frame_source_;
-
- scoped_ptr<BeginFrameSourceMultiplexer> frame_source_;
- bool observing_frame_source_;
- base::TimeDelta authoritative_vsync_interval_;
- base::TimeTicks last_vsync_timebase_;
+ // Not owned.
+ BeginFrameSource* begin_frame_source_;
+ bool observing_begin_frame_source_;
scoped_ptr<CompositorTimingHistory> compositor_timing_history_;
base::TimeDelta estimated_parent_draw_time_;
@@ -224,14 +214,6 @@ class CC_EXPORT Scheduler : public BeginFrameObserverBase {
return inside_action_ == action;
}
- BeginFrameSource* primary_frame_source() {
- if (settings_.use_external_begin_frame_source) {
- DCHECK(external_frame_source_);
- return external_frame_source_;
- }
- return synthetic_frame_source_.get();
- }
-
base::WeakPtrFactory<Scheduler> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(Scheduler);
diff --git a/cc/scheduler/scheduler_unittest.cc b/cc/scheduler/scheduler_unittest.cc
index 4ae7749..37ab466 100644
--- a/cc/scheduler/scheduler_unittest.cc
+++ b/cc/scheduler/scheduler_unittest.cc
@@ -256,9 +256,20 @@ class SchedulerTest : public testing::Test {
protected:
TestScheduler* CreateScheduler() {
- if (scheduler_settings_.use_external_begin_frame_source) {
+ BeginFrameSource* frame_source;
+ if (!scheduler_settings_.throttle_frame_production) {
+ unthrottled_frame_source_ = TestBackToBackBeginFrameSource::Create(
+ now_src_.get(), task_runner_.get());
+ frame_source = unthrottled_frame_source_.get();
+ } else if (scheduler_settings_.use_external_begin_frame_source) {
fake_external_begin_frame_source_.reset(
new FakeExternalBeginFrameSource(client_.get()));
+ frame_source = fake_external_begin_frame_source_.get();
+ } else {
+ synthetic_frame_source_ = TestSyntheticBeginFrameSource::Create(
+ now_src_.get(), task_runner_.get(),
+ BeginFrameArgs::DefaultInterval());
+ frame_source = synthetic_frame_source_.get();
}
scoped_ptr<FakeCompositorTimingHistory> fake_compositor_timing_history =
@@ -266,10 +277,10 @@ class SchedulerTest : public testing::Test {
scheduler_settings_.using_synchronous_renderer_compositor);
fake_compositor_timing_history_ = fake_compositor_timing_history.get();
- scheduler_ = TestScheduler::Create(
- now_src_.get(), client_.get(), scheduler_settings_, 0,
- task_runner_.get(), fake_external_begin_frame_source_.get(),
- std::move(fake_compositor_timing_history));
+ scheduler_.reset(
+ new TestScheduler(now_src_.get(), client_.get(), scheduler_settings_, 0,
+ task_runner_.get(), frame_source,
+ std::move(fake_compositor_timing_history)));
DCHECK(scheduler_);
client_->set_scheduler(scheduler_.get());
@@ -429,6 +440,8 @@ class SchedulerTest : public testing::Test {
scoped_ptr<base::SimpleTestTickClock> now_src_;
scoped_refptr<OrderedSimpleTaskRunner> task_runner_;
scoped_ptr<FakeExternalBeginFrameSource> fake_external_begin_frame_source_;
+ scoped_ptr<TestSyntheticBeginFrameSource> synthetic_frame_source_;
+ scoped_ptr<TestBackToBackBeginFrameSource> unthrottled_frame_source_;
SchedulerSettings scheduler_settings_;
scoped_ptr<FakeSchedulerClient> client_;
scoped_ptr<TestScheduler> scheduler_;
@@ -3446,7 +3459,9 @@ TEST_F(SchedulerTest, AuthoritativeVSyncInterval) {
scheduler_->NotifyReadyToActivate();
task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
- scheduler_->SetAuthoritativeVSyncInterval(authoritative_interval);
+ // Test changing the interval on the frame source external to the scheduler.
+ synthetic_frame_source_->OnUpdateVSyncParameters(now_src_->NowTicks(),
+ authoritative_interval);
EXPECT_SCOPED(AdvanceFrame());
diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc
index d85d3f0..6150f5b 100644
--- a/cc/test/layer_tree_test.cc
+++ b/cc/test/layer_tree_test.cc
@@ -911,7 +911,8 @@ scoped_ptr<OutputSurface> LayerTreeTest::CreateOutputSurface() {
output_surface->capabilities().delegated_rendering);
output_surface_ = output_surface.get();
- if (settings_.use_external_begin_frame_source) {
+ if (settings_.use_external_begin_frame_source &&
+ settings_.wait_for_beginframe_interval) {
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 ef760d2..1c4ddc7 100644
--- a/cc/test/scheduler_test_common.cc
+++ b/cc/test/scheduler_test_common.cc
@@ -181,45 +181,19 @@ base::TimeDelta FakeCompositorTimingHistory::DrawDurationEstimate() const {
return draw_duration_;
}
-scoped_ptr<TestScheduler> TestScheduler::Create(
- base::SimpleTestTickClock* now_src,
- SchedulerClient* client,
- const SchedulerSettings& settings,
- int layer_tree_host_id,
- OrderedSimpleTaskRunner* task_runner,
- BeginFrameSource* external_frame_source,
- scoped_ptr<CompositorTimingHistory> compositor_timing_history) {
- scoped_ptr<TestSyntheticBeginFrameSource> synthetic_frame_source;
- if (!settings.use_external_begin_frame_source) {
- synthetic_frame_source = TestSyntheticBeginFrameSource::Create(
- now_src, task_runner, BeginFrameArgs::DefaultInterval());
- }
- scoped_ptr<TestBackToBackBeginFrameSource> unthrottled_frame_source =
- TestBackToBackBeginFrameSource::Create(now_src, task_runner);
- return make_scoped_ptr(new TestScheduler(
- now_src, client, settings, layer_tree_host_id, task_runner,
- external_frame_source, std::move(synthetic_frame_source),
- std::move(unthrottled_frame_source),
- std::move(compositor_timing_history)));
-}
-
TestScheduler::TestScheduler(
base::SimpleTestTickClock* now_src,
SchedulerClient* client,
const SchedulerSettings& scheduler_settings,
int layer_tree_host_id,
OrderedSimpleTaskRunner* task_runner,
- BeginFrameSource* external_frame_source,
- scoped_ptr<TestSyntheticBeginFrameSource> synthetic_frame_source,
- scoped_ptr<TestBackToBackBeginFrameSource> unthrottled_frame_source,
+ BeginFrameSource* begin_frame_source,
scoped_ptr<CompositorTimingHistory> compositor_timing_history)
: Scheduler(client,
scheduler_settings,
layer_tree_host_id,
task_runner,
- external_frame_source,
- std::move(synthetic_frame_source),
- std::move(unthrottled_frame_source),
+ begin_frame_source,
std::move(compositor_timing_history)),
now_src_(now_src) {}
diff --git a/cc/test/scheduler_test_common.h b/cc/test/scheduler_test_common.h
index ccc8c26..259e991 100644
--- a/cc/test/scheduler_test_common.h
+++ b/cc/test/scheduler_test_common.h
@@ -213,14 +213,13 @@ class FakeCompositorTimingHistory : public CompositorTimingHistory {
class TestScheduler : public Scheduler {
public:
- static scoped_ptr<TestScheduler> Create(
- base::SimpleTestTickClock* now_src,
- SchedulerClient* client,
- const SchedulerSettings& scheduler_settings,
- int layer_tree_host_id,
- OrderedSimpleTaskRunner* task_runner,
- BeginFrameSource* external_frame_source,
- scoped_ptr<CompositorTimingHistory> compositor_timing_history);
+ TestScheduler(base::SimpleTestTickClock* now_src,
+ SchedulerClient* client,
+ const SchedulerSettings& scheduler_settings,
+ int layer_tree_host_id,
+ OrderedSimpleTaskRunner* task_runner,
+ BeginFrameSource* begin_frame_source,
+ scoped_ptr<CompositorTimingHistory> compositor_timing_history);
// Extra test helper functionality
bool IsBeginRetroFrameArgsEmpty() const {
@@ -233,7 +232,7 @@ class TestScheduler : public Scheduler {
return state_machine_.needs_begin_main_frame();
}
- BeginFrameSource& frame_source() { return *frame_source_; }
+ BeginFrameSource& frame_source() { return *begin_frame_source_; }
bool FrameProductionThrottled() {
return settings_.throttle_frame_production;
}
@@ -242,7 +241,7 @@ class TestScheduler : public Scheduler {
return state_machine_.main_thread_missed_last_deadline();
}
- bool begin_frames_expected() const { return observing_frame_source_; }
+ bool begin_frames_expected() const { return observing_begin_frame_source_; }
~TestScheduler() override;
@@ -263,17 +262,6 @@ class TestScheduler : public Scheduler {
base::TimeTicks Now() const override;
private:
- TestScheduler(
- base::SimpleTestTickClock* now_src,
- SchedulerClient* client,
- const SchedulerSettings& scheduler_settings,
- int layer_tree_host_id,
- OrderedSimpleTaskRunner* task_runner,
- BeginFrameSource* external_frame_source,
- scoped_ptr<TestSyntheticBeginFrameSource> synthetic_frame_source,
- scoped_ptr<TestBackToBackBeginFrameSource> unthrottled_frame_source,
- scoped_ptr<CompositorTimingHistory> compositor_timing_history);
-
base::SimpleTestTickClock* now_src_;
DISALLOW_COPY_AND_ASSIGN(TestScheduler);
diff --git a/cc/trees/proxy_impl.cc b/cc/trees/proxy_impl.cc
index 3f5a01e..db52685 100644
--- a/cc/trees/proxy_impl.cc
+++ b/cc/trees/proxy_impl.cc
@@ -79,10 +79,23 @@ ProxyImpl::ProxyImpl(ChannelImpl* channel_impl,
CompositorTimingHistory::RENDERER_UMA,
rendering_stats_instrumentation_));
- scheduler_ = Scheduler::Create(this, scheduler_settings, layer_tree_host_id_,
- task_runner_provider_->ImplThreadTaskRunner(),
- external_begin_frame_source_.get(),
- std::move(compositor_timing_history));
+ BeginFrameSource* frame_source = external_begin_frame_source_.get();
+ if (!scheduler_settings.throttle_frame_production) {
+ // Unthrottled source takes precedence over external sources.
+ unthrottled_begin_frame_source_ = BackToBackBeginFrameSource::Create(
+ task_runner_provider_->ImplThreadTaskRunner());
+ frame_source = unthrottled_begin_frame_source_.get();
+ }
+ if (!frame_source) {
+ synthetic_begin_frame_source_ = SyntheticBeginFrameSource::Create(
+ task_runner_provider_->ImplThreadTaskRunner(),
+ BeginFrameArgs::DefaultInterval());
+ frame_source = synthetic_begin_frame_source_.get();
+ }
+ scheduler_ =
+ Scheduler::Create(this, scheduler_settings, layer_tree_host_id_,
+ task_runner_provider_->ImplThreadTaskRunner(),
+ frame_source, std::move(compositor_timing_history));
DCHECK_EQ(scheduler_->visible(), layer_tree_host_impl_->visible());
}
@@ -99,6 +112,8 @@ ProxyImpl::~ProxyImpl() {
scheduler_ = nullptr;
external_begin_frame_source_ = nullptr;
+ unthrottled_begin_frame_source_ = nullptr;
+ synthetic_begin_frame_source_ = nullptr;
layer_tree_host_impl_ = nullptr;
// We need to explicitly shutdown the notifier to destroy any weakptrs it is
// holding while still on the compositor thread. This also ensures any
@@ -276,7 +291,14 @@ void ProxyImpl::DidLoseOutputSurfaceOnImplThread() {
void ProxyImpl::CommitVSyncParameters(base::TimeTicks timebase,
base::TimeDelta interval) {
DCHECK(IsImplThread());
- scheduler_->CommitVSyncParameters(timebase, interval);
+ if (!synthetic_begin_frame_source_)
+ return;
+
+ if (interval == base::TimeDelta()) {
+ // TODO(brianderson): We should not be receiving 0 intervals.
+ interval = BeginFrameArgs::DefaultInterval();
+ }
+ synthetic_begin_frame_source_->OnUpdateVSyncParameters(timebase, interval);
}
void ProxyImpl::SetEstimatedParentDrawTime(base::TimeDelta draw_time) {
diff --git a/cc/trees/proxy_impl.h b/cc/trees/proxy_impl.h
index 0d96643..a335d8a 100644
--- a/cc/trees/proxy_impl.h
+++ b/cc/trees/proxy_impl.h
@@ -152,6 +152,8 @@ class CC_EXPORT ProxyImpl : public NON_EXPORTED_BASE(LayerTreeHostImplClient),
DelayedUniqueNotifier smoothness_priority_expiration_notifier_;
scoped_ptr<BeginFrameSource> external_begin_frame_source_;
+ scoped_ptr<BeginFrameSource> unthrottled_begin_frame_source_;
+ scoped_ptr<SyntheticBeginFrameSource> synthetic_begin_frame_source_;
RenderingStatsInstrumentation* rendering_stats_instrumentation_;
diff --git a/cc/trees/single_thread_proxy.cc b/cc/trees/single_thread_proxy.cc
index 2735029..7c1d821 100644
--- a/cc/trees/single_thread_proxy.cc
+++ b/cc/trees/single_thread_proxy.cc
@@ -71,11 +71,24 @@ void SingleThreadProxy::Start(
CompositorTimingHistory::BROWSER_UMA,
layer_tree_host_->rendering_stats_instrumentation()));
+ BeginFrameSource* frame_source = external_begin_frame_source_.get();
+ if (!scheduler_settings.throttle_frame_production) {
+ // Unthrottled source takes precedence over external sources.
+ unthrottled_begin_frame_source_ = BackToBackBeginFrameSource::Create(
+ task_runner_provider_->MainThreadTaskRunner());
+ frame_source = unthrottled_begin_frame_source_.get();
+ }
+ if (!frame_source) {
+ synthetic_begin_frame_source_ = SyntheticBeginFrameSource::Create(
+ task_runner_provider_->MainThreadTaskRunner(),
+ BeginFrameArgs::DefaultInterval());
+ frame_source = synthetic_begin_frame_source_.get();
+ }
+
scheduler_on_impl_thread_ =
Scheduler::Create(this, scheduler_settings, layer_tree_host_->id(),
task_runner_provider_->MainThreadTaskRunner(),
- external_begin_frame_source_.get(),
- std::move(compositor_timing_history));
+ frame_source, std::move(compositor_timing_history));
}
layer_tree_host_impl_ = layer_tree_host_->CreateLayerTreeHostImpl(this);
@@ -463,8 +476,17 @@ void SingleThreadProxy::DidLoseOutputSurfaceOnImplThread() {
void SingleThreadProxy::CommitVSyncParameters(base::TimeTicks timebase,
base::TimeDelta interval) {
- if (scheduler_on_impl_thread_)
- scheduler_on_impl_thread_->CommitVSyncParameters(timebase, interval);
+ if (authoritative_vsync_interval_ != base::TimeDelta()) {
+ interval = authoritative_vsync_interval_;
+ } else if (interval == base::TimeDelta()) {
+ // TODO(brianderson): We should not be receiving 0 intervals.
+ interval = BeginFrameArgs::DefaultInterval();
+ }
+
+ last_vsync_timebase_ = timebase;
+
+ if (synthetic_begin_frame_source_)
+ synthetic_begin_frame_source_->OnUpdateVSyncParameters(timebase, interval);
}
void SingleThreadProxy::SetEstimatedParentDrawTime(base::TimeDelta draw_time) {
@@ -699,7 +721,11 @@ void SingleThreadProxy::SetChildrenNeedBeginFrames(
void SingleThreadProxy::SetAuthoritativeVSyncInterval(
const base::TimeDelta& interval) {
- scheduler_on_impl_thread_->SetAuthoritativeVSyncInterval(interval);
+ authoritative_vsync_interval_ = interval;
+ if (synthetic_begin_frame_source_) {
+ synthetic_begin_frame_source_->OnUpdateVSyncParameters(last_vsync_timebase_,
+ interval);
+ }
}
void SingleThreadProxy::WillBeginImplFrame(const BeginFrameArgs& args) {
diff --git a/cc/trees/single_thread_proxy.h b/cc/trees/single_thread_proxy.h
index 3b69668..66e0075 100644
--- a/cc/trees/single_thread_proxy.h
+++ b/cc/trees/single_thread_proxy.h
@@ -145,8 +145,13 @@ class CC_EXPORT SingleThreadProxy : public Proxy,
// Accessed from both threads.
scoped_ptr<BeginFrameSource> external_begin_frame_source_;
+ scoped_ptr<BeginFrameSource> unthrottled_begin_frame_source_;
+ scoped_ptr<SyntheticBeginFrameSource> synthetic_begin_frame_source_;
scoped_ptr<Scheduler> scheduler_on_impl_thread_;
+ base::TimeDelta authoritative_vsync_interval_;
+ base::TimeTicks last_vsync_timebase_;
+
scoped_ptr<BlockingTaskRunner::CapturePostTasks> commit_blocking_task_runner_;
bool next_frame_is_newly_committed_frame_;