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 #include <string> | 9 #include <string> |
10 | 10 |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
227 // now=18 tick_target=16.667 new_target=33.333 --> | 227 // now=18 tick_target=16.667 new_target=33.333 --> |
228 // tick(), PostDelayedTask(floor(33.333-18)) --> PostDelayedTask(15) | 228 // tick(), PostDelayedTask(floor(33.333-18)) --> PostDelayedTask(15) |
229 // This brings us back to 18+15 = 33, which was where we would have been if the | 229 // This brings us back to 18+15 = 33, which was where we would have been if the |
230 // task hadn't been late. | 230 // task hadn't been late. |
231 // | 231 // |
232 // For the really late delay, we we move to the next logical tick. The timebase | 232 // For the really late delay, we we move to the next logical tick. The timebase |
233 // is not reset. | 233 // is not reset. |
234 // now=37 tick_target=16.667 new_target=50.000 --> | 234 // now=37 tick_target=16.667 new_target=50.000 --> |
235 // tick(), PostDelayedTask(floor(50.000-37)) --> PostDelayedTask(13) | 235 // tick(), PostDelayedTask(floor(50.000-37)) --> PostDelayedTask(13) |
236 base::TimeTicks DelayBasedTimeSource::NextTickTarget(base::TimeTicks now) { | 236 base::TimeTicks DelayBasedTimeSource::NextTickTarget(base::TimeTicks now) { |
237 base::TimeDelta new_interval = next_parameters_.interval; | 237 base::TimeTicks new_tick_target = now.SnappedToNextTick( |
238 | 238 next_parameters_.tick_target, next_parameters_.interval); |
239 // |interval_offset| is the offset from |now| to the next multiple of | |
240 // |interval| after |tick_target|, possibly negative if in the past. | |
241 base::TimeDelta interval_offset = base::TimeDelta::FromInternalValue( | |
242 (next_parameters_.tick_target - now).ToInternalValue() % | |
243 new_interval.ToInternalValue()); | |
244 // If |now| is exactly on the interval (i.e. offset==0), don't adjust. | |
245 // Otherwise, if |tick_target| was in the past, adjust forward to the next | |
246 // tick after |now|. | |
247 if (interval_offset.ToInternalValue() != 0 && | |
248 next_parameters_.tick_target < now) { | |
249 interval_offset += new_interval; | |
250 } | |
251 | |
252 base::TimeTicks new_tick_target = now + interval_offset; | |
253 DCHECK(now <= new_tick_target) | 239 DCHECK(now <= new_tick_target) |
254 << "now = " << now.ToInternalValue() | 240 << "now = " << now.ToInternalValue() |
255 << "; new_tick_target = " << new_tick_target.ToInternalValue() | 241 << "; new_tick_target = " << new_tick_target.ToInternalValue() |
256 << "; new_interval = " << new_interval.InMicroseconds() | 242 << "; new_interval = " << next_parameters_.interval.InMicroseconds() |
257 << "; tick_target = " << next_parameters_.tick_target.ToInternalValue() | 243 << "; tick_target = " << next_parameters_.tick_target.ToInternalValue(); |
258 << "; interval_offset = " << interval_offset.ToInternalValue(); | |
259 | 244 |
260 // Avoid double ticks when: | 245 // Avoid double ticks when: |
261 // 1) Turning off the timer and turning it right back on. | 246 // 1) Turning off the timer and turning it right back on. |
262 // 2) Jittery data is passed to SetTimebaseAndInterval(). | 247 // 2) Jittery data is passed to SetTimebaseAndInterval(). |
263 if (new_tick_target - last_tick_time_ <= new_interval / kDoubleTickDivisor) | 248 if (new_tick_target - last_tick_time_ <= |
264 new_tick_target += new_interval; | 249 next_parameters_.interval / kDoubleTickDivisor) |
| 250 new_tick_target += next_parameters_.interval; |
265 | 251 |
266 return new_tick_target; | 252 return new_tick_target; |
267 } | 253 } |
268 | 254 |
269 void DelayBasedTimeSource::PostNextTickTask(base::TimeTicks now) { | 255 void DelayBasedTimeSource::PostNextTickTask(base::TimeTicks now) { |
270 base::TimeTicks new_tick_target = NextTickTarget(now); | 256 base::TimeTicks new_tick_target = NextTickTarget(now); |
271 | 257 |
272 // Post another task *before* the tick and update state | 258 // Post another task *before* the tick and update state |
273 base::TimeDelta delay; | 259 base::TimeDelta delay; |
274 if (now <= new_tick_target) | 260 if (now <= new_tick_target) |
275 delay = new_tick_target - now; | 261 delay = new_tick_target - now; |
276 task_runner_->PostDelayedTask(FROM_HERE, | 262 task_runner_->PostDelayedTask(FROM_HERE, |
277 base::Bind(&DelayBasedTimeSource::OnTimerFired, | 263 base::Bind(&DelayBasedTimeSource::OnTimerFired, |
278 weak_factory_.GetWeakPtr()), | 264 weak_factory_.GetWeakPtr()), |
279 delay); | 265 delay); |
280 | 266 |
281 next_parameters_.tick_target = new_tick_target; | 267 next_parameters_.tick_target = new_tick_target; |
282 current_parameters_ = next_parameters_; | 268 current_parameters_ = next_parameters_; |
283 } | 269 } |
284 | 270 |
285 std::string DelayBasedTimeSource::TypeString() const { | 271 std::string DelayBasedTimeSource::TypeString() const { |
286 return "DelayBasedTimeSource"; | 272 return "DelayBasedTimeSource"; |
287 } | 273 } |
288 | 274 |
289 std::string DelayBasedTimeSourceHighRes::TypeString() const { | 275 std::string DelayBasedTimeSourceHighRes::TypeString() const { |
290 return "DelayBasedTimeSourceHighRes"; | 276 return "DelayBasedTimeSourceHighRes"; |
291 } | 277 } |
292 | 278 |
293 void DelayBasedTimeSource::AsValueInto(base::debug::TracedValue* state) const { | 279 void DelayBasedTimeSource::AsValueInto( |
| 280 base::trace_event::TracedValue* state) const { |
294 state->SetString("type", TypeString()); | 281 state->SetString("type", TypeString()); |
295 state->SetDouble("last_tick_time_us", LastTickTime().ToInternalValue()); | 282 state->SetDouble("last_tick_time_us", LastTickTime().ToInternalValue()); |
296 state->SetDouble("next_tick_time_us", NextTickTime().ToInternalValue()); | 283 state->SetDouble("next_tick_time_us", NextTickTime().ToInternalValue()); |
297 | 284 |
298 state->BeginDictionary("current_parameters"); | 285 state->BeginDictionary("current_parameters"); |
299 state->SetDouble("interval_us", | 286 state->SetDouble("interval_us", |
300 current_parameters_.interval.InMicroseconds()); | 287 current_parameters_.interval.InMicroseconds()); |
301 state->SetDouble("tick_target_us", | 288 state->SetDouble("tick_target_us", |
302 current_parameters_.tick_target.ToInternalValue()); | 289 current_parameters_.tick_target.ToInternalValue()); |
303 state->EndDictionary(); | 290 state->EndDictionary(); |
304 | 291 |
305 state->BeginDictionary("next_parameters"); | 292 state->BeginDictionary("next_parameters"); |
306 state->SetDouble("interval_us", next_parameters_.interval.InMicroseconds()); | 293 state->SetDouble("interval_us", next_parameters_.interval.InMicroseconds()); |
307 state->SetDouble("tick_target_us", | 294 state->SetDouble("tick_target_us", |
308 next_parameters_.tick_target.ToInternalValue()); | 295 next_parameters_.tick_target.ToInternalValue()); |
309 state->EndDictionary(); | 296 state->EndDictionary(); |
310 | 297 |
311 state->SetBoolean("active", active_); | 298 state->SetBoolean("active", active_); |
312 } | 299 } |
313 | 300 |
314 } // namespace cc | 301 } // namespace cc |
OLD | NEW |