Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(383)

Unified Diff: cc/scheduler/delay_based_time_source.cc

Issue 25819002: Revert 210101 "cc: Fix and simplify DelayBasedTimeSource" (Closed) Base URL: svn://svn.chromium.org/chrome/branches/1599_59/src/
Patch Set: Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « cc/scheduler/delay_based_time_source.h ('k') | cc/scheduler/delay_based_time_source_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: cc/scheduler/delay_based_time_source.cc
===================================================================
--- cc/scheduler/delay_based_time_source.cc (revision 226616)
+++ cc/scheduler/delay_based_time_source.cc (working copy)
@@ -17,10 +17,10 @@
namespace {
-// kDoubleTickDivisor prevents ticks from running within the specified
+// kDoubleTickThreshold prevents ticks from running within the specified
// fraction of an interval. This helps account for jitter in the timebase as
// well as quick timer reactivation.
-static const int kDoubleTickDivisor = 4;
+static const double kDoubleTickThreshold = 0.25;
// kIntervalChangeThreshold is the fraction of the interval that will trigger an
// immediate interval change. kPhaseChangeThreshold is the fraction of the
@@ -42,10 +42,10 @@
DelayBasedTimeSource::DelayBasedTimeSource(
base::TimeDelta interval, base::SingleThreadTaskRunner* task_runner)
: client_(NULL),
- last_tick_time_(base::TimeTicks() - interval),
+ has_tick_target_(false),
current_parameters_(interval, base::TimeTicks()),
next_parameters_(interval, base::TimeTicks()),
- active_(false),
+ state_(STATE_INACTIVE),
task_runner_(task_runner),
weak_factory_(this) {}
@@ -53,19 +53,32 @@
void DelayBasedTimeSource::SetActive(bool active) {
TRACE_EVENT1("cc", "DelayBasedTimeSource::SetActive", "active", active);
- if (active == active_)
+ if (!active) {
+ state_ = STATE_INACTIVE;
+ weak_factory_.InvalidateWeakPtrs();
return;
- active_ = active;
+ }
- if (!active_) {
- weak_factory_.InvalidateWeakPtrs();
+ if (state_ == STATE_STARTING || state_ == STATE_ACTIVE)
return;
+
+ if (!has_tick_target_) {
+ // Becoming active the first time is deferred: we post a 0-delay task.
+ // When it runs, we use that to establish the timebase, become truly
+ // active, and fire the first tick.
+ state_ = STATE_STARTING;
+ task_runner_->PostTask(FROM_HERE,
+ base::Bind(&DelayBasedTimeSource::OnTimerFired,
+ weak_factory_.GetWeakPtr()));
+ return;
}
+ state_ = STATE_ACTIVE;
+
PostNextTickTask(Now());
}
-bool DelayBasedTimeSource::Active() const { return active_; }
+bool DelayBasedTimeSource::Active() const { return state_ != STATE_INACTIVE; }
base::TimeTicks DelayBasedTimeSource::LastTickTime() { return last_tick_time_; }
@@ -74,12 +87,18 @@
}
void DelayBasedTimeSource::OnTimerFired() {
- DCHECK(active_);
+ DCHECK(state_ != STATE_INACTIVE);
- last_tick_time_ = current_parameters_.tick_target;
+ base::TimeTicks now = this->Now();
+ last_tick_time_ = now;
- PostNextTickTask(Now());
+ if (state_ == STATE_STARTING) {
+ SetTimebaseAndInterval(now, current_parameters_.interval);
+ state_ = STATE_ACTIVE;
+ }
+ PostNextTickTask(now);
+
// Fire the tick.
if (client_)
client_->OnTimerTick();
@@ -93,8 +112,9 @@
base::TimeDelta interval) {
next_parameters_.interval = interval;
next_parameters_.tick_target = timebase;
+ has_tick_target_ = true;
- if (!active_) {
+ if (state_ != STATE_ACTIVE) {
// If we aren't active, there's no need to reset the timer.
return;
}
@@ -105,8 +125,6 @@
std::abs((interval - current_parameters_.interval).InSecondsF());
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);
return;
@@ -124,8 +142,6 @@
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);
return;
@@ -191,24 +207,26 @@
// 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) {
- const base::TimeDelta epsilon(base::TimeDelta::FromMicroseconds(1));
base::TimeDelta new_interval = next_parameters_.interval;
int intervals_elapsed =
- (now - next_parameters_.tick_target + new_interval - epsilon) /
- new_interval;
- base::TimeTicks new_tick_target =
+ static_cast<int>(floor((now - next_parameters_.tick_target).InSecondsF() /
+ new_interval.InSecondsF()));
+ base::TimeTicks last_effective_tick =
next_parameters_.tick_target + new_interval * intervals_elapsed;
- DCHECK(now <= new_tick_target)
+ base::TimeTicks new_tick_target = last_effective_tick + new_interval;
+ DCHECK(now < new_tick_target)
<< "now = " << now.ToInternalValue()
<< "; new_tick_target = " << new_tick_target.ToInternalValue()
<< "; new_interval = " << new_interval.InMicroseconds()
<< "; tick_target = " << next_parameters_.tick_target.ToInternalValue()
- << "; intervals_elapsed = " << intervals_elapsed;
+ << "; intervals_elapsed = " << intervals_elapsed
+ << "; last_effective_tick = " << last_effective_tick.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_ <= new_interval / kDoubleTickDivisor)
+ if (new_tick_target - last_tick_time_ <=
+ new_interval / static_cast<int>(1.0 / kDoubleTickThreshold))
new_tick_target += new_interval;
return new_tick_target;
@@ -218,9 +236,10 @@
base::TimeTicks new_tick_target = NextTickTarget(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 = new_tick_target - now;
+ DCHECK(delay.InMillisecondsF() <=
+ next_parameters_.interval.InMillisecondsF() *
+ (1.0 + kDoubleTickThreshold));
task_runner_->PostDelayedTask(FROM_HERE,
base::Bind(&DelayBasedTimeSource::OnTimerFired,
weak_factory_.GetWeakPtr()),
« no previous file with comments | « cc/scheduler/delay_based_time_source.h ('k') | cc/scheduler/delay_based_time_source_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698