| 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/scheduler.h" | 5 #include "cc/scheduler/scheduler.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include "base/auto_reset.h" | 8 #include "base/auto_reset.h" |
| 9 #include "base/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/single_thread_task_runner.h" | 11 #include "base/single_thread_task_runner.h" |
| 12 #include "cc/debug/devtools_instrumentation.h" | 12 #include "cc/debug/devtools_instrumentation.h" |
| 13 #include "cc/debug/traced_value.h" | 13 #include "cc/debug/traced_value.h" |
| 14 #include "cc/scheduler/delay_based_time_source.h" | 14 #include "cc/scheduler/delay_based_time_source.h" |
| 15 #include "ui/gfx/frame_time.h" | |
| 16 | 15 |
| 17 namespace cc { | 16 namespace cc { |
| 18 | 17 |
| 19 Scheduler::SyntheticBeginFrameSource::SyntheticBeginFrameSource( | 18 Scheduler::SyntheticBeginFrameSource::SyntheticBeginFrameSource( |
| 20 Scheduler* scheduler, | 19 Scheduler* scheduler, |
| 21 base::SingleThreadTaskRunner* task_runner) | 20 base::SingleThreadTaskRunner* task_runner) |
| 22 : scheduler_(scheduler) { | 21 : scheduler_(scheduler) { |
| 23 if (gfx::FrameTime::TimestampsAreHighRes()) { | 22 if (gfx::FrameTime::TimestampsAreHighRes()) { |
| 24 time_source_ = DelayBasedTimeSourceHighRes::Create( | 23 time_source_ = DelayBasedTimeSourceHighRes::Create( |
| 25 scheduler_->VSyncInterval(), task_runner); | 24 scheduler_->VSyncInterval(), task_runner); |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 122 &begin_retro_frame_args_); | 121 &begin_retro_frame_args_); |
| 123 } | 122 } |
| 124 } | 123 } |
| 125 | 124 |
| 126 void Scheduler::SetupSyntheticBeginFrames() { | 125 void Scheduler::SetupSyntheticBeginFrames() { |
| 127 DCHECK(!synthetic_begin_frame_source_); | 126 DCHECK(!synthetic_begin_frame_source_); |
| 128 synthetic_begin_frame_source_.reset( | 127 synthetic_begin_frame_source_.reset( |
| 129 new SyntheticBeginFrameSource(this, impl_task_runner_.get())); | 128 new SyntheticBeginFrameSource(this, impl_task_runner_.get())); |
| 130 } | 129 } |
| 131 | 130 |
| 131 base::TimeTicks Scheduler::Now() const { |
| 132 return gfx::FrameTime::Now(); |
| 133 } |
| 134 |
| 132 void Scheduler::CommitVSyncParameters(base::TimeTicks timebase, | 135 void Scheduler::CommitVSyncParameters(base::TimeTicks timebase, |
| 133 base::TimeDelta interval) { | 136 base::TimeDelta interval) { |
| 134 // TODO(brianderson): We should not be receiving 0 intervals. | 137 // TODO(brianderson): We should not be receiving 0 intervals. |
| 135 if (interval == base::TimeDelta()) | 138 if (interval == base::TimeDelta()) |
| 136 interval = BeginFrameArgs::DefaultInterval(); | 139 interval = BeginFrameArgs::DefaultInterval(); |
| 137 vsync_interval_ = interval; | 140 vsync_interval_ = interval; |
| 138 if (!settings_.begin_frame_scheduling_enabled) | 141 if (!settings_.begin_frame_scheduling_enabled) |
| 139 synthetic_begin_frame_source_->CommitVSyncParameters(timebase, interval); | 142 synthetic_begin_frame_source_->CommitVSyncParameters(timebase, interval); |
| 140 } | 143 } |
| 141 | 144 |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 253 void Scheduler::NotifyBeginMainFrameStarted() { | 256 void Scheduler::NotifyBeginMainFrameStarted() { |
| 254 TRACE_EVENT0("cc", "Scheduler::NotifyBeginMainFrameStarted"); | 257 TRACE_EVENT0("cc", "Scheduler::NotifyBeginMainFrameStarted"); |
| 255 state_machine_.NotifyBeginMainFrameStarted(); | 258 state_machine_.NotifyBeginMainFrameStarted(); |
| 256 } | 259 } |
| 257 | 260 |
| 258 base::TimeTicks Scheduler::AnticipatedDrawTime() const { | 261 base::TimeTicks Scheduler::AnticipatedDrawTime() const { |
| 259 if (!last_set_needs_begin_frame_ || | 262 if (!last_set_needs_begin_frame_ || |
| 260 begin_impl_frame_args_.interval <= base::TimeDelta()) | 263 begin_impl_frame_args_.interval <= base::TimeDelta()) |
| 261 return base::TimeTicks(); | 264 return base::TimeTicks(); |
| 262 | 265 |
| 263 base::TimeTicks now = gfx::FrameTime::Now(); | 266 base::TimeTicks now = Now(); |
| 264 base::TimeTicks timebase = std::max(begin_impl_frame_args_.frame_time, | 267 base::TimeTicks timebase = std::max(begin_impl_frame_args_.frame_time, |
| 265 begin_impl_frame_args_.deadline); | 268 begin_impl_frame_args_.deadline); |
| 266 int64 intervals = 1 + ((now - timebase) / begin_impl_frame_args_.interval); | 269 int64 intervals = 1 + ((now - timebase) / begin_impl_frame_args_.interval); |
| 267 return timebase + (begin_impl_frame_args_.interval * intervals); | 270 return timebase + (begin_impl_frame_args_.interval * intervals); |
| 268 } | 271 } |
| 269 | 272 |
| 270 base::TimeTicks Scheduler::LastBeginImplFrameTime() { | 273 base::TimeTicks Scheduler::LastBeginImplFrameTime() { |
| 271 return begin_impl_frame_args_.frame_time; | 274 return begin_impl_frame_args_.frame_time; |
| 272 } | 275 } |
| 273 | 276 |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 328 begin_unthrottled_frame_posted_ = true; | 331 begin_unthrottled_frame_posted_ = true; |
| 329 impl_task_runner_->PostTask(FROM_HERE, begin_unthrottled_frame_closure_); | 332 impl_task_runner_->PostTask(FROM_HERE, begin_unthrottled_frame_closure_); |
| 330 } | 333 } |
| 331 | 334 |
| 332 // BeginUnthrottledFrame is used when we aren't throttling frame production. | 335 // BeginUnthrottledFrame is used when we aren't throttling frame production. |
| 333 // This will usually be because VSync is disabled. | 336 // This will usually be because VSync is disabled. |
| 334 void Scheduler::BeginUnthrottledFrame() { | 337 void Scheduler::BeginUnthrottledFrame() { |
| 335 DCHECK(!settings_.throttle_frame_production); | 338 DCHECK(!settings_.throttle_frame_production); |
| 336 DCHECK(begin_retro_frame_args_.empty()); | 339 DCHECK(begin_retro_frame_args_.empty()); |
| 337 | 340 |
| 338 base::TimeTicks now = gfx::FrameTime::Now(); | 341 base::TimeTicks now = Now(); |
| 339 base::TimeTicks deadline = now + vsync_interval_; | 342 base::TimeTicks deadline = now + vsync_interval_; |
| 340 | 343 |
| 341 BeginFrameArgs begin_frame_args = | 344 BeginFrameArgs begin_frame_args = |
| 342 BeginFrameArgs::Create(now, deadline, vsync_interval_); | 345 BeginFrameArgs::Create(now, deadline, vsync_interval_); |
| 343 BeginImplFrame(begin_frame_args); | 346 BeginImplFrame(begin_frame_args); |
| 344 | 347 |
| 345 begin_unthrottled_frame_posted_ = false; | 348 begin_unthrottled_frame_posted_ = false; |
| 346 } | 349 } |
| 347 | 350 |
| 348 // We may need to poll when we can't rely on BeginFrame to advance certain | 351 // We may need to poll when we can't rely on BeginFrame to advance certain |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 439 if (begin_retro_frame_args_.empty()) | 442 if (begin_retro_frame_args_.empty()) |
| 440 return; | 443 return; |
| 441 | 444 |
| 442 // Discard expired BeginRetroFrames | 445 // Discard expired BeginRetroFrames |
| 443 // Today, we should always end up with at most one un-expired BeginRetroFrame | 446 // Today, we should always end up with at most one un-expired BeginRetroFrame |
| 444 // because deadlines will not be greater than the next frame time. We don't | 447 // because deadlines will not be greater than the next frame time. We don't |
| 445 // DCHECK though because some systems don't always have monotonic timestamps. | 448 // DCHECK though because some systems don't always have monotonic timestamps. |
| 446 // TODO(brianderson): In the future, long deadlines could result in us not | 449 // TODO(brianderson): In the future, long deadlines could result in us not |
| 447 // draining the queue if we don't catch up. If we consistently can't catch | 450 // draining the queue if we don't catch up. If we consistently can't catch |
| 448 // up, our fallback should be to lower our frame rate. | 451 // up, our fallback should be to lower our frame rate. |
| 449 base::TimeTicks now = gfx::FrameTime::Now(); | 452 base::TimeTicks now = Now(); |
| 450 base::TimeDelta draw_duration_estimate = client_->DrawDurationEstimate(); | 453 base::TimeDelta draw_duration_estimate = client_->DrawDurationEstimate(); |
| 451 while (!begin_retro_frame_args_.empty() && | 454 while (!begin_retro_frame_args_.empty() && |
| 452 now > AdjustedBeginImplFrameDeadline(begin_retro_frame_args_.front(), | 455 now > AdjustedBeginImplFrameDeadline(begin_retro_frame_args_.front(), |
| 453 draw_duration_estimate)) { | 456 draw_duration_estimate)) { |
| 454 TRACE_EVENT1("cc", | 457 TRACE_EVENT1("cc", |
| 455 "Scheduler::BeginRetroFrame discarding", | 458 "Scheduler::BeginRetroFrame discarding", |
| 456 "frame_time", | 459 "frame_time", |
| 457 begin_retro_frame_args_.front().frame_time); | 460 begin_retro_frame_args_.front().frame_time); |
| 458 begin_retro_frame_args_.pop_front(); | 461 begin_retro_frame_args_.pop_front(); |
| 459 } | 462 } |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 555 // within this call. | 558 // within this call. |
| 556 // TODO(brianderson): Have the OutputSurface initiate the deadline tasks | 559 // TODO(brianderson): Have the OutputSurface initiate the deadline tasks |
| 557 // so the sychronous renderer compositor can take advantage of splitting | 560 // so the sychronous renderer compositor can take advantage of splitting |
| 558 // up the BeginImplFrame and deadline as well. | 561 // up the BeginImplFrame and deadline as well. |
| 559 OnBeginImplFrameDeadline(); | 562 OnBeginImplFrameDeadline(); |
| 560 return; | 563 return; |
| 561 } | 564 } |
| 562 begin_impl_frame_deadline_task_.Cancel(); | 565 begin_impl_frame_deadline_task_.Cancel(); |
| 563 begin_impl_frame_deadline_task_.Reset(begin_impl_frame_deadline_closure_); | 566 begin_impl_frame_deadline_task_.Reset(begin_impl_frame_deadline_closure_); |
| 564 | 567 |
| 565 base::TimeDelta delta = deadline - gfx::FrameTime::Now(); | 568 base::TimeDelta delta = deadline - Now(); |
| 566 if (delta <= base::TimeDelta()) | 569 if (delta <= base::TimeDelta()) |
| 567 delta = base::TimeDelta(); | 570 delta = base::TimeDelta(); |
| 568 impl_task_runner_->PostDelayedTask( | 571 impl_task_runner_->PostDelayedTask( |
| 569 FROM_HERE, begin_impl_frame_deadline_task_.callback(), delta); | 572 FROM_HERE, begin_impl_frame_deadline_task_.callback(), delta); |
| 570 } | 573 } |
| 571 | 574 |
| 572 void Scheduler::OnBeginImplFrameDeadline() { | 575 void Scheduler::OnBeginImplFrameDeadline() { |
| 573 TRACE_EVENT0("cc", "Scheduler::OnBeginImplFrameDeadline"); | 576 TRACE_EVENT0("cc", "Scheduler::OnBeginImplFrameDeadline"); |
| 574 begin_impl_frame_deadline_task_.Cancel(); | 577 begin_impl_frame_deadline_task_.Cancel(); |
| 575 | 578 |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 747 } | 750 } |
| 748 | 751 |
| 749 bool Scheduler::IsBeginMainFrameSentOrStarted() const { | 752 bool Scheduler::IsBeginMainFrameSentOrStarted() const { |
| 750 return (state_machine_.commit_state() == | 753 return (state_machine_.commit_state() == |
| 751 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT || | 754 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT || |
| 752 state_machine_.commit_state() == | 755 state_machine_.commit_state() == |
| 753 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED); | 756 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED); |
| 754 } | 757 } |
| 755 | 758 |
| 756 } // namespace cc | 759 } // namespace cc |
| OLD | NEW |