Index: cc/scheduler/begin_frame_source.cc |
diff --git a/cc/scheduler/begin_frame_source.cc b/cc/scheduler/begin_frame_source.cc |
index 30916948cec360b751b158e69316c4e6617f8b3b..caf11b3e21e3ed1b14f895ecb930e82f6cb05c58 100644 |
--- a/cc/scheduler/begin_frame_source.cc |
+++ b/cc/scheduler/begin_frame_source.cc |
@@ -6,6 +6,7 @@ |
#include <stddef.h> |
+#include "base/atomic_sequence_num.h" |
#include "base/auto_reset.h" |
#include "base/location.h" |
#include "base/logging.h" |
@@ -25,7 +26,7 @@ namespace { |
static const double kDoubleTickDivisor = 2.0; |
} |
-// BeginFrameObserverBase ----------------------------------------------- |
+// BeginFrameObserverBase ------------------------------------------------- |
Sami
2016/12/15 13:53:00
Very detail-oriented :)
Eric Seckler
2016/12/15 14:59:38
.. and maybe a touch of ocd :)
|
BeginFrameObserverBase::BeginFrameObserverBase() |
: last_begin_frame_args_(), dropped_begin_frame_args_(0) { |
} |
@@ -33,9 +34,12 @@ BeginFrameObserverBase::BeginFrameObserverBase() |
const BeginFrameArgs& BeginFrameObserverBase::LastUsedBeginFrameArgs() const { |
return last_begin_frame_args_; |
} |
+ |
void BeginFrameObserverBase::OnBeginFrame(const BeginFrameArgs& args) { |
DCHECK(args.IsValid()); |
DCHECK(args.frame_time >= last_begin_frame_args_.frame_time); |
+ DCHECK(args.sequence_number > last_begin_frame_args_.sequence_number || |
+ args.source_id != last_begin_frame_args_.source_id); |
bool used = OnBeginFrameDerivedImpl(args); |
if (used) { |
last_begin_frame_args_ = args; |
@@ -44,17 +48,31 @@ void BeginFrameObserverBase::OnBeginFrame(const BeginFrameArgs& args) { |
} |
} |
+// BeginFrameSource ------------------------------------------------------- |
+namespace { |
+static base::StaticAtomicSequenceNumber next_source_id_; |
Sami
2016/12/15 13:53:00
nit: g_next_source_id since this isn't a member.
Eric Seckler
2016/12/15 14:59:38
Done.
|
+} // namespace |
+ |
+BeginFrameSource::BeginFrameSource() : source_id_(next_source_id_.GetNext()) {} |
+ |
+uint32_t BeginFrameSource::source_id() const { |
+ return source_id_; |
+} |
+ |
+// StubBeginFrameSource --------------------------------------------------- |
bool StubBeginFrameSource::IsThrottled() const { |
return true; |
} |
-// SyntheticBeginFrameSource --------------------------------------------- |
+// SyntheticBeginFrameSource ---------------------------------------------- |
SyntheticBeginFrameSource::~SyntheticBeginFrameSource() = default; |
-// BackToBackBeginFrameSource -------------------------------------------- |
+// BackToBackBeginFrameSource --------------------------------------------- |
BackToBackBeginFrameSource::BackToBackBeginFrameSource( |
std::unique_ptr<DelayBasedTimeSource> time_source) |
- : time_source_(std::move(time_source)), weak_factory_(this) { |
+ : time_source_(std::move(time_source)), |
+ next_sequence_number_(BeginFrameArgs::kStartingFrameNumber), |
+ 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. |
@@ -77,7 +95,7 @@ void BackToBackBeginFrameSource::RemoveObserver(BeginFrameObserver* obs) { |
DCHECK(observers_.find(obs) != observers_.end()); |
observers_.erase(obs); |
pending_begin_frame_observers_.erase(obs); |
- if (observers_.empty()) |
+ if (pending_begin_frame_observers_.empty()) |
brianderson
2016/12/15 20:30:36
Is this change related? If it fixes a bug, please
Eric Seckler
2016/12/16 17:25:57
ok, will do.
|
time_source_->SetActive(false); |
} |
@@ -97,8 +115,8 @@ void BackToBackBeginFrameSource::OnTimerTick() { |
base::TimeTicks frame_time = time_source_->LastTickTime(); |
base::TimeDelta default_interval = BeginFrameArgs::DefaultInterval(); |
BeginFrameArgs args = BeginFrameArgs::Create( |
- BEGINFRAME_FROM_HERE, frame_time, frame_time + default_interval, |
- default_interval, BeginFrameArgs::NORMAL); |
+ BEGINFRAME_FROM_HERE, source_id(), next_sequence_number_++, frame_time, |
brianderson
2016/12/15 20:30:35
Please move the next_sequence_number_++ after the
Eric Seckler
2016/12/16 17:25:57
Done.
|
+ frame_time + default_interval, default_interval, BeginFrameArgs::NORMAL); |
// This must happen after getting the LastTickTime() from the time source. |
time_source_->SetActive(false); |
@@ -139,11 +157,12 @@ void DelayBasedBeginFrameSource::SetAuthoritativeVSyncInterval( |
} |
BeginFrameArgs DelayBasedBeginFrameSource::CreateBeginFrameArgs( |
+ uint64_t sequence_number, |
base::TimeTicks frame_time, |
BeginFrameArgs::BeginFrameArgsType type) { |
- return BeginFrameArgs::Create(BEGINFRAME_FROM_HERE, frame_time, |
- time_source_->NextTickTime(), |
- time_source_->Interval(), type); |
+ return BeginFrameArgs::Create( |
+ BEGINFRAME_FROM_HERE, source_id(), sequence_number, frame_time, |
+ time_source_->NextTickTime(), time_source_->Interval(), type); |
} |
void DelayBasedBeginFrameSource::AddObserver(BeginFrameObserver* obs) { |
@@ -153,14 +172,31 @@ void DelayBasedBeginFrameSource::AddObserver(BeginFrameObserver* obs) { |
observers_.insert(obs); |
obs->OnBeginFrameSourcePausedChanged(false); |
time_source_->SetActive(true); |
- BeginFrameArgs args = CreateBeginFrameArgs( |
- time_source_->NextTickTime() - time_source_->Interval(), |
- BeginFrameArgs::MISSED); |
+ |
+ // Check if |current_begin_frame_args_| are still valid. They may not be valid |
brianderson
2016/12/15 20:30:36
"valid" is an overloaded term in this context. Can
Eric Seckler
2016/12/16 17:25:58
Done.
|
+ // if OnTimerTick() has never run yet, the time source was inactive before |
+ // AddObserver() was called, or the interval changed. |
+ base::TimeTicks last_or_missed_tick_time = |
+ time_source_->NextTickTime() - time_source_->Interval(); |
+ if (current_begin_frame_args_.IsValid() && |
+ current_begin_frame_args_.frame_time == last_or_missed_tick_time && |
+ current_begin_frame_args_.interval == time_source_->Interval()) { |
+ // Ensure that the args have the right type. |
+ current_begin_frame_args_.type = BeginFrameArgs::MISSED; |
+ } else { |
+ // The args are invalid and we need to create new ones with the missed |
+ // tick's time and a new sequence number. |
+ current_begin_frame_args_ = |
+ CreateBeginFrameArgs(current_begin_frame_args_.sequence_number + 1, |
brianderson
2016/12/15 20:30:36
"current_begin_frame_args_.sequence_number + 1" re
Eric Seckler
2016/12/16 17:25:57
Done.
|
+ last_or_missed_tick_time, BeginFrameArgs::MISSED); |
+ } |
+ |
BeginFrameArgs last_args = obs->LastUsedBeginFrameArgs(); |
if (!last_args.IsValid() || |
- (args.frame_time > |
- last_args.frame_time + args.interval / kDoubleTickDivisor)) { |
- obs->OnBeginFrame(args); |
+ (current_begin_frame_args_.frame_time > |
+ last_args.frame_time + |
+ current_begin_frame_args_.interval / kDoubleTickDivisor)) { |
+ obs->OnBeginFrame(current_begin_frame_args_); |
} |
} |
@@ -178,18 +214,22 @@ bool DelayBasedBeginFrameSource::IsThrottled() const { |
} |
void DelayBasedBeginFrameSource::OnTimerTick() { |
- BeginFrameArgs args = CreateBeginFrameArgs(time_source_->LastTickTime(), |
- BeginFrameArgs::NORMAL); |
+ current_begin_frame_args_ = CreateBeginFrameArgs( |
+ current_begin_frame_args_.sequence_number + 1, |
+ time_source_->LastTickTime(), BeginFrameArgs::NORMAL); |
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)) |
- obs->OnBeginFrame(args); |
+ (current_begin_frame_args_.frame_time > |
+ last_args.frame_time + |
+ current_begin_frame_args_.interval / kDoubleTickDivisor)) { |
+ obs->OnBeginFrame(current_begin_frame_args_); |
+ } |
} |
} |
+// ExternalBeginFrameSource ----------------------------------------------- |
ExternalBeginFrameSource::ExternalBeginFrameSource( |
ExternalBeginFrameSourceClient* client) |
: client_(client) { |
@@ -212,7 +252,9 @@ void ExternalBeginFrameSource::AddObserver(BeginFrameObserver* obs) { |
if (missed_begin_frame_args_.IsValid()) { |
BeginFrameArgs last_args = obs->LastUsedBeginFrameArgs(); |
if (!last_args.IsValid() || |
- (missed_begin_frame_args_.frame_time > last_args.frame_time)) { |
+ (missed_begin_frame_args_.source_id != last_args.source_id) || |
+ (missed_begin_frame_args_.sequence_number > |
+ last_args.sequence_number)) { |
brianderson
2016/12/15 20:30:36
I think this if statement should stay the way it w
Eric Seckler
2016/12/16 17:25:57
Hm, okay. Will do. I was thinking ahead, consideri
brianderson
2016/12/16 17:53:38
I see. Maybe the animation system is okay with mon
|
obs->OnBeginFrame(missed_begin_frame_args_); |
} |
} |