diff options
author | enne <enne@chromium.org> | 2016-03-16 14:51:11 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-03-16 21:52:59 +0000 |
commit | b9bf377e238af579e4b6dd01cb4007ba712da742 (patch) | |
tree | 0bcff2210f32f89249a0255b9d4a04af787d19d2 /cc | |
parent | 6b03d171d4137691637129ebad5cab20f4babbbb (diff) | |
download | chromium_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.cc | 191 | ||||
-rw-r--r-- | cc/scheduler/begin_frame_source.h | 51 | ||||
-rw-r--r-- | cc/scheduler/begin_frame_source_unittest.cc | 337 | ||||
-rw-r--r-- | cc/scheduler/scheduler.cc | 106 | ||||
-rw-r--r-- | cc/scheduler/scheduler.h | 30 | ||||
-rw-r--r-- | cc/scheduler/scheduler_unittest.cc | 27 | ||||
-rw-r--r-- | cc/test/layer_tree_test.cc | 3 | ||||
-rw-r--r-- | cc/test/scheduler_test_common.cc | 30 | ||||
-rw-r--r-- | cc/test/scheduler_test_common.h | 30 | ||||
-rw-r--r-- | cc/trees/proxy_impl.cc | 32 | ||||
-rw-r--r-- | cc/trees/proxy_impl.h | 2 | ||||
-rw-r--r-- | cc/trees/single_thread_proxy.cc | 36 | ||||
-rw-r--r-- | cc/trees/single_thread_proxy.h | 5 |
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_; |