Index: cc/scheduler/delay_based_time_source.cc |
diff --git a/cc/scheduler/delay_based_time_source.cc b/cc/scheduler/delay_based_time_source.cc |
index b1f68bd27c94fda46cd5919eed1a76326feeeedb..1f8e92dfefb7f3897114419ab2dd347660420419 100644 |
--- a/cc/scheduler/delay_based_time_source.cc |
+++ b/cc/scheduler/delay_based_time_source.cc |
@@ -42,40 +42,49 @@ DelayBasedTimeSource::DelayBasedTimeSource( |
base::SingleThreadTaskRunner* task_runner) |
: client_(NULL), |
last_tick_time_(base::TimeTicks() - interval), |
- current_parameters_(interval, base::TimeTicks()), |
- next_parameters_(interval, base::TimeTicks()), |
+ next_tick_time_(base::TimeTicks()), |
+ timebase_(base::TimeTicks()), |
+ interval_(interval), |
active_(false), |
task_runner_(task_runner), |
weak_factory_(this) { |
- DCHECK_GT(interval.ToInternalValue(), 0); |
+ DCHECK_GT(interval, base::TimeDelta()); |
} |
DelayBasedTimeSource::~DelayBasedTimeSource() {} |
-base::TimeTicks DelayBasedTimeSource::SetActive(bool active) { |
+void DelayBasedTimeSource::SetActive(bool active) { |
TRACE_EVENT1("cc", "DelayBasedTimeSource::SetActive", "active", active); |
if (active == active_) |
- return base::TimeTicks(); |
+ return; |
active_ = active; |
if (!active_) { |
+ next_tick_time_ = base::TimeTicks(); |
weak_factory_.InvalidateWeakPtrs(); |
mithro-old
2015/06/30 08:11:52
It's really weird that this works by invalidating
|
- return base::TimeTicks(); |
+ return; |
} |
- PostNextTickTask(Now()); |
+ base::TimeTicks now = Now(); |
+ base::TimeTicks next_tick_target = NextTickTarget(now); |
// Determine if there was a tick that was missed while not active. |
base::TimeTicks last_tick_time_if_always_active = |
- current_parameters_.tick_target - current_parameters_.interval; |
- base::TimeTicks new_tick_time_threshold = |
- last_tick_time_ + current_parameters_.interval / kDoubleTickDivisor; |
- if (last_tick_time_if_always_active > new_tick_time_threshold) { |
- last_tick_time_ = last_tick_time_if_always_active; |
- return last_tick_time_; |
+ next_tick_target - interval_; |
+ base::TimeTicks last_tick_time_threshold = |
+ last_tick_time_ + interval_ / kDoubleTickDivisor; |
+ if (last_tick_time_if_always_active > last_tick_time_threshold) { |
+ missed_tick_time_ = last_tick_time_if_always_active; |
+ task_runner_->PostTask(FROM_HERE, |
+ base::Bind(&DelayBasedTimeSource::OnMissedTick, |
brianderson
2015/06/26 19:24:35
Can you bind to a Closure (in the constructor and
|
+ weak_factory_.GetWeakPtr())); |
} |
- return base::TimeTicks(); |
+ PostNextTickTask(now); |
+} |
+ |
+base::TimeDelta DelayBasedTimeSource::Interval() const { |
+ return interval_; |
} |
bool DelayBasedTimeSource::Active() const { return active_; } |
@@ -84,14 +93,27 @@ base::TimeTicks DelayBasedTimeSource::LastTickTime() const { |
return last_tick_time_; |
} |
+base::TimeTicks DelayBasedTimeSource::MissedTickTime() const { |
brianderson
2015/06/26 19:24:34
Is this needed? Looks like Client::OnMissedTick ca
|
+ return missed_tick_time_; |
+} |
+ |
base::TimeTicks DelayBasedTimeSource::NextTickTime() const { |
- return Active() ? current_parameters_.tick_target : base::TimeTicks(); |
+ return next_tick_time_; |
brianderson
2015/06/26 19:24:34
Probably doesn't matter for the current user of th
|
} |
-void DelayBasedTimeSource::OnTimerFired() { |
+void DelayBasedTimeSource::OnMissedTick() { |
brianderson
2015/06/26 19:24:34
Should missed_tick_time_ be reset somewhere in thi
|
DCHECK(active_); |
- last_tick_time_ = current_parameters_.tick_target; |
+ last_tick_time_ = missed_tick_time_; |
+ |
+ if (client_) |
+ client_->OnMissedTick(); |
+} |
+ |
+void DelayBasedTimeSource::OnTimerTick() { |
+ DCHECK(active_); |
+ |
+ last_tick_time_ = next_tick_time_; |
PostNextTickTask(Now()); |
@@ -100,31 +122,31 @@ void DelayBasedTimeSource::OnTimerFired() { |
client_->OnTimerTick(); |
} |
-void DelayBasedTimeSource::SetClient(TimeSourceClient* client) { |
+void DelayBasedTimeSource::SetClient(DelayBasedTimeSourceClient* client) { |
client_ = client; |
} |
void DelayBasedTimeSource::SetTimebaseAndInterval(base::TimeTicks timebase, |
base::TimeDelta interval) { |
- DCHECK_GT(interval.ToInternalValue(), 0); |
- next_parameters_.interval = interval; |
- next_parameters_.tick_target = timebase; |
- |
- if (!active_) { |
- // If we aren't active, there's no need to reset the timer. |
- return; |
- } |
+ DCHECK_GT(interval, base::TimeDelta()); |
// If the change in interval is larger than the change threshold, |
// request an immediate reset. |
- double interval_delta = |
- std::abs((interval - current_parameters_.interval).InSecondsF()); |
+ double interval_delta = std::abs((interval - interval_).InSecondsF()); |
+ double target_delta = std::abs((timebase - timebase_).InSecondsF()); |
+ |
+ interval_ = interval; |
+ timebase_ = timebase; |
+ |
+ // If we aren't active, there's no need to reset the timer. |
+ if (!active_) |
+ return; |
+ |
double interval_change = interval_delta / interval.InSecondsF(); |
if (interval_change > kIntervalChangeThreshold) { |
TRACE_EVENT_INSTANT0("cc", "DelayBasedTimeSource::IntervalChanged", |
TRACE_EVENT_SCOPE_THREAD); |
- SetActive(false); |
- SetActive(true); |
+ ResetTickTask(Now()); |
return; |
} |
@@ -134,16 +156,13 @@ void DelayBasedTimeSource::SetTimebaseAndInterval(base::TimeTicks timebase, |
// fmod just happens to return something near zero. Assuming the timebase |
// is very recent though, which it should be, we'll still be ok because the |
// old clock and new clock just happen to line up. |
- double target_delta = |
- std::abs((timebase - current_parameters_.tick_target).InSecondsF()); |
double phase_change = |
fmod(target_delta, interval.InSecondsF()) / interval.InSecondsF(); |
if (phase_change > kPhaseChangeThreshold && |
phase_change < (1.0 - kPhaseChangeThreshold)) { |
TRACE_EVENT_INSTANT0("cc", "DelayBasedTimeSource::PhaseChanged", |
TRACE_EVENT_SCOPE_THREAD); |
- SetActive(false); |
- SetActive(true); |
+ ResetTickTask(Now()); |
return; |
} |
} |
@@ -206,39 +225,41 @@ base::TimeTicks DelayBasedTimeSource::Now() const { |
// is not reset. |
// now=37 tick_target=16.667 new_target=50.000 --> |
// tick(), PostDelayedTask(floor(50.000-37)) --> PostDelayedTask(13) |
-base::TimeTicks DelayBasedTimeSource::NextTickTarget(base::TimeTicks now) { |
- base::TimeTicks new_tick_target = now.SnappedToNextTick( |
- next_parameters_.tick_target, next_parameters_.interval); |
- DCHECK(now <= new_tick_target) |
+base::TimeTicks DelayBasedTimeSource::NextTickTarget( |
+ base::TimeTicks now) const { |
+ base::TimeTicks next_tick_target = |
+ now.SnappedToNextTick(timebase_, interval_); |
+ DCHECK(now <= next_tick_target) |
<< "now = " << now.ToInternalValue() |
- << "; new_tick_target = " << new_tick_target.ToInternalValue() |
- << "; new_interval = " << next_parameters_.interval.InMicroseconds() |
- << "; tick_target = " << next_parameters_.tick_target.ToInternalValue(); |
+ << "; new_tick_target = " << next_tick_target.ToInternalValue() |
+ << "; new_interval = " << interval_.InMicroseconds() |
+ << "; tick_target = " << timebase_.ToInternalValue(); |
// Avoid double ticks when: |
// 1) Turning off the timer and turning it right back on. |
// 2) Jittery data is passed to SetTimebaseAndInterval(). |
- if (new_tick_target - last_tick_time_ <= |
- next_parameters_.interval / kDoubleTickDivisor) |
- new_tick_target += next_parameters_.interval; |
+ if (next_tick_target - last_tick_time_ <= interval_ / kDoubleTickDivisor) |
+ next_tick_target += interval_; |
- return new_tick_target; |
+ return next_tick_target; |
} |
void DelayBasedTimeSource::PostNextTickTask(base::TimeTicks now) { |
- base::TimeTicks new_tick_target = NextTickTarget(now); |
- |
+ base::TimeTicks next_tick_target = NextTickTarget(now); |
+ DCHECK(next_tick_target >= now); |
// Post another task *before* the tick and update state |
- base::TimeDelta delay; |
- if (now <= new_tick_target) |
- delay = new_tick_target - now; |
+ base::TimeDelta delay = next_tick_target - now; |
task_runner_->PostDelayedTask(FROM_HERE, |
- base::Bind(&DelayBasedTimeSource::OnTimerFired, |
+ base::Bind(&DelayBasedTimeSource::OnTimerTick, |
brianderson
2015/06/26 19:24:35
Ditto regarding dynamic bind.
|
weak_factory_.GetWeakPtr()), |
delay); |
- next_parameters_.tick_target = new_tick_target; |
- current_parameters_ = next_parameters_; |
+ next_tick_time_ = next_tick_target; |
+} |
+ |
+void DelayBasedTimeSource::ResetTickTask(base::TimeTicks now) { |
+ weak_factory_.InvalidateWeakPtrs(); |
+ PostNextTickTask(now); |
} |
std::string DelayBasedTimeSource::TypeString() const { |
@@ -249,21 +270,10 @@ void DelayBasedTimeSource::AsValueInto( |
base::trace_event::TracedValue* state) const { |
state->SetString("type", TypeString()); |
state->SetDouble("last_tick_time_us", LastTickTime().ToInternalValue()); |
+ state->SetDouble("missed_tick_time_us", MissedTickTime().ToInternalValue()); |
state->SetDouble("next_tick_time_us", NextTickTime().ToInternalValue()); |
- |
- state->BeginDictionary("current_parameters"); |
- state->SetDouble("interval_us", |
- current_parameters_.interval.InMicroseconds()); |
- state->SetDouble("tick_target_us", |
- current_parameters_.tick_target.ToInternalValue()); |
- state->EndDictionary(); |
- |
- state->BeginDictionary("next_parameters"); |
- state->SetDouble("interval_us", next_parameters_.interval.InMicroseconds()); |
- state->SetDouble("tick_target_us", |
- next_parameters_.tick_target.ToInternalValue()); |
- state->EndDictionary(); |
- |
+ state->SetDouble("interval_us", interval_.InMicroseconds()); |
+ state->SetDouble("timebase_us", timebase_.ToInternalValue()); |
state->SetBoolean("active", active_); |
} |