OLD | NEW |
1 // Copyright 2011 The Chromium Authors. All rights reserved. | 1 // Copyright 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "cc/scheduler/delay_based_time_source.h" | 5 #include "cc/scheduler/delay_based_time_source.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <cmath> | 8 #include <cmath> |
9 | 9 |
10 #include "base/debug/trace_event.h" | 10 #include "base/debug/trace_event.h" |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "base/message_loop.h" | 12 #include "base/single_thread_task_runner.h" |
13 #include "cc/base/thread.h" | |
14 | 13 |
15 namespace cc { | 14 namespace cc { |
16 | 15 |
17 namespace { | 16 namespace { |
18 | 17 |
19 // kDoubleTickThreshold prevents ticks from running within the specified | 18 // kDoubleTickThreshold prevents ticks from running within the specified |
20 // fraction of an interval. This helps account for jitter in the timebase as | 19 // fraction of an interval. This helps account for jitter in the timebase as |
21 // well as quick timer reactivation. | 20 // well as quick timer reactivation. |
22 static const double kDoubleTickThreshold = 0.25; | 21 static const double kDoubleTickThreshold = 0.25; |
23 | 22 |
24 // kIntervalChangeThreshold is the fraction of the interval that will trigger an | 23 // kIntervalChangeThreshold is the fraction of the interval that will trigger an |
25 // immediate interval change. kPhaseChangeThreshold is the fraction of the | 24 // immediate interval change. kPhaseChangeThreshold is the fraction of the |
26 // interval that will trigger an immediate phase change. If the changes are | 25 // interval that will trigger an immediate phase change. If the changes are |
27 // within the thresholds, the change will take place on the next tick. If | 26 // within the thresholds, the change will take place on the next tick. If |
28 // either change is outside the thresholds, the next tick will be canceled and | 27 // either change is outside the thresholds, the next tick will be canceled and |
29 // reissued immediately. | 28 // reissued immediately. |
30 static const double kIntervalChangeThreshold = 0.25; | 29 static const double kIntervalChangeThreshold = 0.25; |
31 static const double kPhaseChangeThreshold = 0.25; | 30 static const double kPhaseChangeThreshold = 0.25; |
32 | 31 |
33 } // namespace | 32 } // namespace |
34 | 33 |
35 scoped_refptr<DelayBasedTimeSource> DelayBasedTimeSource::Create( | 34 scoped_refptr<DelayBasedTimeSource> DelayBasedTimeSource::Create( |
36 base::TimeDelta interval, | 35 base::TimeDelta interval, |
37 Thread* thread) { | 36 base::SingleThreadTaskRunner* task_runner) { |
38 return make_scoped_refptr(new DelayBasedTimeSource(interval, thread)); | 37 return make_scoped_refptr(new DelayBasedTimeSource(interval, task_runner)); |
39 } | 38 } |
40 | 39 |
41 DelayBasedTimeSource::DelayBasedTimeSource(base::TimeDelta interval, | 40 DelayBasedTimeSource::DelayBasedTimeSource( |
42 Thread* thread) | 41 base::TimeDelta interval, base::SingleThreadTaskRunner* task_runner) |
43 : client_(NULL), | 42 : client_(NULL), |
44 has_tick_target_(false), | 43 has_tick_target_(false), |
45 current_parameters_(interval, base::TimeTicks()), | 44 current_parameters_(interval, base::TimeTicks()), |
46 next_parameters_(interval, base::TimeTicks()), | 45 next_parameters_(interval, base::TimeTicks()), |
47 state_(STATE_INACTIVE), | 46 state_(STATE_INACTIVE), |
48 thread_(thread), | 47 task_runner_(task_runner), |
49 weak_factory_(this) {} | 48 weak_factory_(this) {} |
50 | 49 |
51 DelayBasedTimeSource::~DelayBasedTimeSource() {} | 50 DelayBasedTimeSource::~DelayBasedTimeSource() {} |
52 | 51 |
53 void DelayBasedTimeSource::SetActive(bool active) { | 52 void DelayBasedTimeSource::SetActive(bool active) { |
54 TRACE_EVENT1("cc", "DelayBasedTimeSource::SetActive", "active", active); | 53 TRACE_EVENT1("cc", "DelayBasedTimeSource::SetActive", "active", active); |
55 if (!active) { | 54 if (!active) { |
56 state_ = STATE_INACTIVE; | 55 state_ = STATE_INACTIVE; |
57 weak_factory_.InvalidateWeakPtrs(); | 56 weak_factory_.InvalidateWeakPtrs(); |
58 return; | 57 return; |
59 } | 58 } |
60 | 59 |
61 if (state_ == STATE_STARTING || state_ == STATE_ACTIVE) | 60 if (state_ == STATE_STARTING || state_ == STATE_ACTIVE) |
62 return; | 61 return; |
63 | 62 |
64 if (!has_tick_target_) { | 63 if (!has_tick_target_) { |
65 // Becoming active the first time is deferred: we post a 0-delay task. | 64 // Becoming active the first time is deferred: we post a 0-delay task. |
66 // When it runs, we use that to establish the timebase, become truly | 65 // When it runs, we use that to establish the timebase, become truly |
67 // active, and fire the first tick. | 66 // active, and fire the first tick. |
68 state_ = STATE_STARTING; | 67 state_ = STATE_STARTING; |
69 thread_->PostTask(base::Bind(&DelayBasedTimeSource::OnTimerFired, | 68 task_runner_->PostTask(FROM_HERE, |
70 weak_factory_.GetWeakPtr())); | 69 base::Bind(&DelayBasedTimeSource::OnTimerFired, |
| 70 weak_factory_.GetWeakPtr())); |
71 return; | 71 return; |
72 } | 72 } |
73 | 73 |
74 state_ = STATE_ACTIVE; | 74 state_ = STATE_ACTIVE; |
75 | 75 |
76 PostNextTickTask(Now()); | 76 PostNextTickTask(Now()); |
77 } | 77 } |
78 | 78 |
79 bool DelayBasedTimeSource::Active() const { return state_ != STATE_INACTIVE; } | 79 bool DelayBasedTimeSource::Active() const { return state_ != STATE_INACTIVE; } |
80 | 80 |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
231 } | 231 } |
232 | 232 |
233 void DelayBasedTimeSource::PostNextTickTask(base::TimeTicks now) { | 233 void DelayBasedTimeSource::PostNextTickTask(base::TimeTicks now) { |
234 base::TimeTicks new_tick_target = NextTickTarget(now); | 234 base::TimeTicks new_tick_target = NextTickTarget(now); |
235 | 235 |
236 // Post another task *before* the tick and update state | 236 // Post another task *before* the tick and update state |
237 base::TimeDelta delay = new_tick_target - now; | 237 base::TimeDelta delay = new_tick_target - now; |
238 DCHECK(delay.InMillisecondsF() <= | 238 DCHECK(delay.InMillisecondsF() <= |
239 next_parameters_.interval.InMillisecondsF() * | 239 next_parameters_.interval.InMillisecondsF() * |
240 (1.0 + kDoubleTickThreshold)); | 240 (1.0 + kDoubleTickThreshold)); |
241 thread_->PostDelayedTask(base::Bind(&DelayBasedTimeSource::OnTimerFired, | 241 task_runner_->PostDelayedTask(FROM_HERE, |
242 weak_factory_.GetWeakPtr()), | 242 base::Bind(&DelayBasedTimeSource::OnTimerFired, |
243 delay); | 243 weak_factory_.GetWeakPtr()), |
| 244 delay); |
244 | 245 |
245 next_parameters_.tick_target = new_tick_target; | 246 next_parameters_.tick_target = new_tick_target; |
246 current_parameters_ = next_parameters_; | 247 current_parameters_ = next_parameters_; |
247 } | 248 } |
248 | 249 |
249 } // namespace cc | 250 } // namespace cc |
OLD | NEW |