Index: cc/scheduler/begin_frame_source.cc |
diff --git a/cc/scheduler/begin_frame_source.cc b/cc/scheduler/begin_frame_source.cc |
index 5c20a86caf2c4b11fd1fd54d48b74ca78a893cc7..3421ce978d4811b225c053f93039a8c9cd6b3d5e 100644 |
--- a/cc/scheduler/begin_frame_source.cc |
+++ b/cc/scheduler/begin_frame_source.cc |
@@ -9,6 +9,7 @@ |
#include "base/auto_reset.h" |
#include "base/location.h" |
#include "base/logging.h" |
+#include "base/memory/ptr_util.h" |
#include "base/strings/string_number_conversions.h" |
#include "base/strings/stringprintf.h" |
#include "base/trace_event/trace_event.h" |
@@ -33,11 +34,6 @@ const BeginFrameArgs& BeginFrameObserverBase::LastUsedBeginFrameArgs() const { |
return last_begin_frame_args_; |
} |
void BeginFrameObserverBase::OnBeginFrame(const BeginFrameArgs& args) { |
- DEBUG_FRAMES("BeginFrameObserverBase::OnBeginFrame", |
- "last args", |
- last_begin_frame_args_.AsValue(), |
- "new args", |
- args.AsValue()); |
DCHECK(args.IsValid()); |
DCHECK(args.frame_time >= last_begin_frame_args_.frame_time); |
bool used = OnBeginFrameDerivedImpl(args); |
@@ -48,150 +44,93 @@ void BeginFrameObserverBase::OnBeginFrame(const BeginFrameArgs& args) { |
} |
} |
-// BeginFrameSourceBase ------------------------------------------------------ |
-BeginFrameSourceBase::BeginFrameSourceBase() : paused_(false) {} |
- |
-BeginFrameSourceBase::~BeginFrameSourceBase() {} |
- |
-void BeginFrameSourceBase::AddObserver(BeginFrameObserver* obs) { |
- DEBUG_FRAMES("BeginFrameSourceBase::AddObserver", "num observers", |
- observers_.size(), "to add observer", obs); |
- DCHECK(obs); |
- DCHECK(observers_.find(obs) == observers_.end()) |
- << "AddObserver cannot be called with an observer that was already added"; |
- bool observers_was_empty = observers_.empty(); |
- observers_.insert(obs); |
- if (observers_was_empty) |
- OnNeedsBeginFramesChanged(true); |
- obs->OnBeginFrameSourcePausedChanged(paused_); |
-} |
- |
-void BeginFrameSourceBase::RemoveObserver(BeginFrameObserver* obs) { |
- DEBUG_FRAMES("BeginFrameSourceBase::RemoveObserver", "num observers", |
- observers_.size(), "removed observer", obs); |
- DCHECK(obs); |
- DCHECK(observers_.find(obs) != observers_.end()) |
- << "RemoveObserver cannot be called with an observer that wasn't added"; |
- observers_.erase(obs); |
- if (observers_.empty()) |
- OnNeedsBeginFramesChanged(false); |
-} |
- |
-void BeginFrameSourceBase::CallOnBeginFrame(const BeginFrameArgs& args) { |
- DEBUG_FRAMES("BeginFrameSourceBase::CallOnBeginFrame", "num observers", |
- observers_.size(), "args", args.AsValue()); |
- std::set<BeginFrameObserver*> observers(observers_); |
- for (BeginFrameObserver* obs : observers) |
- obs->OnBeginFrame(args); |
-} |
- |
-void BeginFrameSourceBase::SetBeginFrameSourcePaused(bool paused) { |
- if (paused_ == paused) |
- return; |
- paused_ = paused; |
- std::set<BeginFrameObserver*> observers(observers_); |
- for (BeginFrameObserver* obs : observers) |
- obs->OnBeginFrameSourcePausedChanged(paused_); |
-} |
+// SyntheticBeginFrameSource --------------------------------------------- |
+SyntheticBeginFrameSource::~SyntheticBeginFrameSource() = default; |
// BackToBackBeginFrameSource -------------------------------------------- |
BackToBackBeginFrameSource::BackToBackBeginFrameSource( |
- base::SingleThreadTaskRunner* task_runner) |
- : BeginFrameSourceBase(), task_runner_(task_runner), weak_factory_(this) { |
- DCHECK(task_runner); |
-} |
- |
-BackToBackBeginFrameSource::~BackToBackBeginFrameSource() { |
+ std::unique_ptr<DelayBasedTimeSource> time_source) |
+ : time_source_(std::move(time_source)), weak_factory_(this) { |
+ time_source_->SetClient(this); |
+ // The time_source_ ticks immediately, so we SetActive(true) for a single |
+ // tick when we need it, and keep it as SetActive(false) otherwise. |
+ time_source_->SetTimebaseAndInterval(base::TimeTicks(), base::TimeDelta()); |
} |
-base::TimeTicks BackToBackBeginFrameSource::Now() { |
- return base::TimeTicks::Now(); |
-} |
+BackToBackBeginFrameSource::~BackToBackBeginFrameSource() = default; |
-// BeginFrameSourceBase support |
void BackToBackBeginFrameSource::AddObserver(BeginFrameObserver* obs) { |
- BeginFrameSourceBase::AddObserver(obs); |
+ DCHECK(obs); |
+ DCHECK(observers_.find(obs) == observers_.end()); |
+ observers_.insert(obs); |
pending_begin_frame_observers_.insert(obs); |
- PostPendingBeginFramesTask(); |
+ obs->OnBeginFrameSourcePausedChanged(false); |
+ time_source_->SetActive(true); |
} |
void BackToBackBeginFrameSource::RemoveObserver(BeginFrameObserver* obs) { |
- BeginFrameSourceBase::RemoveObserver(obs); |
+ DCHECK(obs); |
+ DCHECK(observers_.find(obs) != observers_.end()); |
+ observers_.erase(obs); |
pending_begin_frame_observers_.erase(obs); |
- if (pending_begin_frame_observers_.empty()) |
- begin_frame_task_.Cancel(); |
+ if (observers_.empty()) |
+ time_source_->SetActive(false); |
} |
void BackToBackBeginFrameSource::DidFinishFrame(BeginFrameObserver* obs, |
size_t remaining_frames) { |
- BeginFrameSourceBase::DidFinishFrame(obs, remaining_frames); |
if (remaining_frames == 0 && observers_.find(obs) != observers_.end()) { |
pending_begin_frame_observers_.insert(obs); |
- PostPendingBeginFramesTask(); |
+ time_source_->SetActive(true); |
} |
} |
-void BackToBackBeginFrameSource::PostPendingBeginFramesTask() { |
- DCHECK(needs_begin_frames()); |
- DCHECK(!pending_begin_frame_observers_.empty()); |
- if (begin_frame_task_.IsCancelled()) { |
- begin_frame_task_.Reset( |
- base::Bind(&BackToBackBeginFrameSource::SendPendingBeginFrames, |
- weak_factory_.GetWeakPtr())); |
- task_runner_->PostTask(FROM_HERE, begin_frame_task_.callback()); |
- } |
-} |
- |
-void BackToBackBeginFrameSource::SendPendingBeginFrames() { |
- DCHECK(needs_begin_frames()); |
- DCHECK(!begin_frame_task_.IsCancelled()); |
- begin_frame_task_.Cancel(); |
- |
- base::TimeTicks now = Now(); |
+void BackToBackBeginFrameSource::OnTimerTick() { |
+ base::TimeTicks frame_time = time_source_->LastTickTime(); |
+ base::TimeDelta default_interval = BeginFrameArgs::DefaultInterval(); |
BeginFrameArgs args = BeginFrameArgs::Create( |
- BEGINFRAME_FROM_HERE, now, now + BeginFrameArgs::DefaultInterval(), |
- BeginFrameArgs::DefaultInterval(), BeginFrameArgs::NORMAL); |
+ BEGINFRAME_FROM_HERE, frame_time, frame_time + default_interval, |
+ default_interval, BeginFrameArgs::NORMAL); |
+ |
+ // This must happen after getting the LastTickTime() from the time source. |
+ time_source_->SetActive(false); |
- std::set<BeginFrameObserver*> pending_observers; |
+ std::unordered_set<BeginFrameObserver*> pending_observers; |
pending_observers.swap(pending_begin_frame_observers_); |
for (BeginFrameObserver* obs : pending_observers) |
obs->OnBeginFrame(args); |
} |
-// SyntheticBeginFrameSource --------------------------------------------- |
-SyntheticBeginFrameSource::SyntheticBeginFrameSource( |
- base::SingleThreadTaskRunner* task_runner, |
- base::TimeDelta initial_vsync_interval) |
- : time_source_( |
- DelayBasedTimeSource::Create(initial_vsync_interval, task_runner)) { |
- time_source_->SetClient(this); |
-} |
- |
-SyntheticBeginFrameSource::SyntheticBeginFrameSource( |
+// DelayBasedBeginFrameSource --------------------------------------------- |
+DelayBasedBeginFrameSource::DelayBasedBeginFrameSource( |
std::unique_ptr<DelayBasedTimeSource> time_source) |
: time_source_(std::move(time_source)) { |
time_source_->SetClient(this); |
} |
-SyntheticBeginFrameSource::~SyntheticBeginFrameSource() {} |
+DelayBasedBeginFrameSource::~DelayBasedBeginFrameSource() = default; |
-void SyntheticBeginFrameSource::OnUpdateVSyncParameters( |
+void DelayBasedBeginFrameSource::OnUpdateVSyncParameters( |
base::TimeTicks timebase, |
base::TimeDelta interval) { |
- if (!authoritative_interval_.is_zero()) |
+ if (!authoritative_interval_.is_zero()) { |
interval = authoritative_interval_; |
+ } else if (interval.is_zero()) { |
+ // TODO(brianderson): We should not be receiving 0 intervals. |
+ interval = BeginFrameArgs::DefaultInterval(); |
+ } |
last_timebase_ = timebase; |
time_source_->SetTimebaseAndInterval(timebase, interval); |
} |
-void SyntheticBeginFrameSource::SetAuthoritativeVSyncInterval( |
+void DelayBasedBeginFrameSource::SetAuthoritativeVSyncInterval( |
base::TimeDelta interval) { |
authoritative_interval_ = interval; |
OnUpdateVSyncParameters(last_timebase_, interval); |
} |
-BeginFrameArgs SyntheticBeginFrameSource::CreateBeginFrameArgs( |
+BeginFrameArgs DelayBasedBeginFrameSource::CreateBeginFrameArgs( |
base::TimeTicks frame_time, |
BeginFrameArgs::BeginFrameArgsType type) { |
return BeginFrameArgs::Create(BEGINFRAME_FROM_HERE, frame_time, |
@@ -199,9 +138,13 @@ BeginFrameArgs SyntheticBeginFrameSource::CreateBeginFrameArgs( |
time_source_->Interval(), type); |
} |
-// BeginFrameSource support |
-void SyntheticBeginFrameSource::AddObserver(BeginFrameObserver* obs) { |
- BeginFrameSourceBase::AddObserver(obs); |
+void DelayBasedBeginFrameSource::AddObserver(BeginFrameObserver* obs) { |
+ DCHECK(obs); |
+ DCHECK(observers_.find(obs) == observers_.end()); |
+ |
+ observers_.insert(obs); |
+ obs->OnBeginFrameSourcePausedChanged(false); |
+ time_source_->SetActive(true); |
BeginFrameArgs args = CreateBeginFrameArgs( |
time_source_->NextTickTime() - time_source_->Interval(), |
BeginFrameArgs::MISSED); |
@@ -213,23 +156,25 @@ void SyntheticBeginFrameSource::AddObserver(BeginFrameObserver* obs) { |
} |
} |
-void SyntheticBeginFrameSource::OnNeedsBeginFramesChanged( |
- bool needs_begin_frames) { |
- time_source_->SetActive(needs_begin_frames); |
+void DelayBasedBeginFrameSource::RemoveObserver(BeginFrameObserver* obs) { |
+ DCHECK(obs); |
+ DCHECK(observers_.find(obs) != observers_.end()); |
+ |
+ observers_.erase(obs); |
+ if (observers_.empty()) |
+ time_source_->SetActive(false); |
} |
-// DelayBasedTimeSourceClient support |
-void SyntheticBeginFrameSource::OnTimerTick() { |
+void DelayBasedBeginFrameSource::OnTimerTick() { |
BeginFrameArgs args = CreateBeginFrameArgs(time_source_->LastTickTime(), |
BeginFrameArgs::NORMAL); |
- std::set<BeginFrameObserver*> observers(observers_); |
- for (auto& it : observers) { |
- BeginFrameArgs last_args = it->LastUsedBeginFrameArgs(); |
+ std::unordered_set<BeginFrameObserver*> observers(observers_); |
+ for (auto& obs : observers) { |
+ BeginFrameArgs last_args = obs->LastUsedBeginFrameArgs(); |
if (!last_args.IsValid() || |
(args.frame_time > |
- last_args.frame_time + args.interval / kDoubleTickDivisor)) { |
- it->OnBeginFrame(args); |
- } |
+ last_args.frame_time + args.interval / kDoubleTickDivisor)) |
+ obs->OnBeginFrame(args); |
} |
} |