| 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 |