Chromium Code Reviews| 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 | 8 |
| 9 #include "base/auto_reset.h" | 9 #include "base/auto_reset.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 122 | 122 |
| 123 base::TimeTicks Scheduler::Now() const { | 123 base::TimeTicks Scheduler::Now() const { |
| 124 base::TimeTicks now = gfx::FrameTime::Now(); | 124 base::TimeTicks now = gfx::FrameTime::Now(); |
| 125 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.now"), | 125 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.now"), |
| 126 "Scheduler::Now", | 126 "Scheduler::Now", |
| 127 "now", | 127 "now", |
| 128 now); | 128 now); |
| 129 return now; | 129 return now; |
| 130 } | 130 } |
| 131 | 131 |
| 132 void Scheduler::SetAuthoritativeVSyncInterval(const base::TimeDelta& interval) { | |
|
mithro-old
2015/05/27 04:40:14
Moving this SetAuthoritativeVSyncInterval seems un
| |
| 133 authoritative_vsync_interval_ = interval; | |
|
mithro-old
2015/05/27 04:40:14
Would it be useful to do a TRACE_EVENT here too?
| |
| 134 if (vsync_observer_) | |
| 135 vsync_observer_->OnUpdateVSyncParameters(last_vsync_timebase_, interval); | |
| 136 } | |
| 137 | |
| 132 void Scheduler::CommitVSyncParameters(base::TimeTicks timebase, | 138 void Scheduler::CommitVSyncParameters(base::TimeTicks timebase, |
| 133 base::TimeDelta interval) { | 139 base::TimeDelta interval) { |
| 140 TRACE_EVENT2("cc", "Scheduler::CommitVSyncParameters", "timebase", | |
| 141 (timebase - base::TimeTicks()).InSecondsF(), "interval", | |
|
mithro-old
2015/05/27 04:40:14
TRACE_EVENT should have native support for base::T
| |
| 142 interval.InSecondsF()); | |
| 143 | |
| 134 if (authoritative_vsync_interval_ != base::TimeDelta()) { | 144 if (authoritative_vsync_interval_ != base::TimeDelta()) { |
| 135 interval = authoritative_vsync_interval_; | 145 interval = authoritative_vsync_interval_; |
| 136 } else if (interval == base::TimeDelta()) { | 146 } else if (interval == base::TimeDelta()) { |
| 137 // TODO(brianderson): We should not be receiving 0 intervals. | 147 // TODO(brianderson): We should not be receiving 0 intervals. |
| 138 interval = BeginFrameArgs::DefaultInterval(); | 148 interval = BeginFrameArgs::DefaultInterval(); |
| 139 } | 149 } |
| 140 | 150 |
| 141 last_vsync_timebase_ = timebase; | 151 last_vsync_timebase_ = timebase; |
| 142 | 152 |
| 143 if (vsync_observer_) | 153 if (vsync_observer_) |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 380 BeginImplFrameWithDeadline(adjusted_args); | 390 BeginImplFrameWithDeadline(adjusted_args); |
| 381 } | 391 } |
| 382 return true; | 392 return true; |
| 383 } | 393 } |
| 384 | 394 |
| 385 void Scheduler::SetChildrenNeedBeginFrames(bool children_need_begin_frames) { | 395 void Scheduler::SetChildrenNeedBeginFrames(bool children_need_begin_frames) { |
| 386 state_machine_.SetChildrenNeedBeginFrames(children_need_begin_frames); | 396 state_machine_.SetChildrenNeedBeginFrames(children_need_begin_frames); |
| 387 ProcessScheduledActions(); | 397 ProcessScheduledActions(); |
| 388 } | 398 } |
| 389 | 399 |
| 390 void Scheduler::SetAuthoritativeVSyncInterval(const base::TimeDelta& interval) { | |
| 391 authoritative_vsync_interval_ = interval; | |
| 392 if (vsync_observer_) | |
| 393 vsync_observer_->OnUpdateVSyncParameters(last_vsync_timebase_, interval); | |
| 394 } | |
| 395 | |
| 396 void Scheduler::SetVideoNeedsBeginFrames(bool video_needs_begin_frames) { | 400 void Scheduler::SetVideoNeedsBeginFrames(bool video_needs_begin_frames) { |
| 397 state_machine_.SetVideoNeedsBeginFrames(video_needs_begin_frames); | 401 state_machine_.SetVideoNeedsBeginFrames(video_needs_begin_frames); |
| 398 ProcessScheduledActions(); | 402 ProcessScheduledActions(); |
| 399 } | 403 } |
| 400 | 404 |
| 401 void Scheduler::OnDrawForOutputSurface() { | 405 void Scheduler::OnDrawForOutputSurface() { |
| 402 DCHECK(settings_.using_synchronous_renderer_compositor); | 406 DCHECK(settings_.using_synchronous_renderer_compositor); |
| 403 DCHECK_EQ(state_machine_.begin_impl_frame_state(), | 407 DCHECK_EQ(state_machine_.begin_impl_frame_state(), |
| 404 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); | 408 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); |
| 405 DCHECK(!BeginImplFrameDeadlinePending()); | 409 DCHECK(!BeginImplFrameDeadlinePending()); |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 491 args.AsValue(), "main_thread_is_high_latency", | 495 args.AsValue(), "main_thread_is_high_latency", |
| 492 main_thread_is_in_high_latency_mode); | 496 main_thread_is_in_high_latency_mode); |
| 493 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), | 497 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), |
| 494 "MainThreadLatency", main_thread_is_in_high_latency_mode); | 498 "MainThreadLatency", main_thread_is_in_high_latency_mode); |
| 495 | 499 |
| 496 advance_commit_state_task_.Cancel(); | 500 advance_commit_state_task_.Cancel(); |
| 497 | 501 |
| 498 begin_impl_frame_args_ = args; | 502 begin_impl_frame_args_ = args; |
| 499 begin_impl_frame_args_.deadline -= client_->DrawDurationEstimate(); | 503 begin_impl_frame_args_.deadline -= client_->DrawDurationEstimate(); |
| 500 | 504 |
| 501 if (!state_machine_.impl_latency_takes_priority() && | 505 if (ShouldRecoverMainLatency()) { |
| 502 main_thread_is_in_high_latency_mode && | 506 TRACE_EVENT_INSTANT0("cc", "SkipBeginMainFrameToReduceLatency", |
| 503 CanCommitAndActivateBeforeDeadline()) { | 507 TRACE_EVENT_SCOPE_THREAD); |
| 504 state_machine_.SetSkipNextBeginMainFrameToReduceLatency(); | 508 state_machine_.SetSkipNextBeginMainFrameToReduceLatency(); |
| 509 } else if (ShouldRecoverImplLatency()) { | |
| 510 TRACE_EVENT_INSTANT0("cc", "SkipBeginImplFrameToReduceLatency", | |
|
mithro-old
2015/05/27 04:40:14
Should this be Scheduler::SkipBeginImplFrameToRedu
| |
| 511 TRACE_EVENT_SCOPE_THREAD); | |
| 512 frame_source_->DidFinishFrame(begin_retro_frame_args_.size()); | |
| 513 return; | |
| 505 } | 514 } |
| 506 | 515 |
| 507 BeginImplFrame(); | 516 BeginImplFrame(); |
| 508 | 517 |
| 509 // The deadline will be scheduled in ProcessScheduledActions. | 518 // The deadline will be scheduled in ProcessScheduledActions. |
| 510 state_machine_.OnBeginImplFrameDeadlinePending(); | 519 state_machine_.OnBeginImplFrameDeadlinePending(); |
| 511 ProcessScheduledActions(); | 520 ProcessScheduledActions(); |
| 512 } | 521 } |
| 513 | 522 |
| 514 void Scheduler::BeginImplFrameSynchronous(const BeginFrameArgs& args) { | 523 void Scheduler::BeginImplFrameSynchronous(const BeginFrameArgs& args) { |
| 515 TRACE_EVENT1("cc,benchmark", "Scheduler::BeginImplFrame", "args", | 524 TRACE_EVENT1("cc,benchmark", "Scheduler::BeginImplFrame", "args", |
| 516 args.AsValue()); | 525 args.AsValue()); |
| 517 begin_impl_frame_args_ = args; | 526 begin_impl_frame_args_ = args; |
| 518 BeginImplFrame(); | 527 BeginImplFrame(); |
| 528 | |
|
mithro-old
2015/05/27 04:40:14
nit: Extra newline?
| |
| 519 FinishImplFrame(); | 529 FinishImplFrame(); |
| 520 } | 530 } |
| 521 | 531 |
| 522 void Scheduler::FinishImplFrame() { | 532 void Scheduler::FinishImplFrame() { |
| 523 state_machine_.OnBeginImplFrameIdle(); | 533 state_machine_.OnBeginImplFrameIdle(); |
| 524 ProcessScheduledActions(); | 534 ProcessScheduledActions(); |
| 525 | 535 |
| 526 client_->DidFinishImplFrame(); | 536 client_->DidFinishImplFrame(); |
| 527 frame_source_->DidFinishFrame(begin_retro_frame_args_.size()); | 537 frame_source_->DidFinishFrame(begin_retro_frame_args_.size()); |
| 528 } | 538 } |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 545 } | 555 } |
| 546 | 556 |
| 547 void Scheduler::ScheduleBeginImplFrameDeadline() { | 557 void Scheduler::ScheduleBeginImplFrameDeadline() { |
| 548 // The synchronous compositor does not post a deadline task. | 558 // The synchronous compositor does not post a deadline task. |
| 549 DCHECK(!settings_.using_synchronous_renderer_compositor); | 559 DCHECK(!settings_.using_synchronous_renderer_compositor); |
| 550 | 560 |
| 551 begin_impl_frame_deadline_task_.Cancel(); | 561 begin_impl_frame_deadline_task_.Cancel(); |
| 552 begin_impl_frame_deadline_task_.Reset(begin_impl_frame_deadline_closure_); | 562 begin_impl_frame_deadline_task_.Reset(begin_impl_frame_deadline_closure_); |
| 553 | 563 |
| 554 begin_impl_frame_deadline_mode_ = | 564 begin_impl_frame_deadline_mode_ = |
| 555 state_machine_.CurrentBeginImplFrameDeadlineMode(); | 565 state_machine_.CurrentBeginImplFrameDeadlineMode(); |
|
mithro-old
2015/05/27 04:40:14
nit: Random new line removal?
| |
| 556 | |
| 557 base::TimeTicks deadline; | 566 base::TimeTicks deadline; |
| 558 switch (begin_impl_frame_deadline_mode_) { | 567 switch (begin_impl_frame_deadline_mode_) { |
| 559 case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_NONE: | 568 case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_NONE: |
| 560 // No deadline. | 569 // No deadline. |
| 561 return; | 570 return; |
| 562 case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_IMMEDIATE: | 571 case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_IMMEDIATE: |
| 563 // We are ready to draw a new active tree immediately. | 572 // We are ready to draw a new active tree immediately. |
| 564 // We don't use Now() here because it's somewhat expensive to call. | 573 // We don't use Now() here because it's somewhat expensive to call. |
| 565 deadline = base::TimeTicks(); | 574 deadline = base::TimeTicks(); |
| 566 break; | 575 break; |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 764 state->SetInteger("begin_retro_frame_args_", begin_retro_frame_args_.size()); | 773 state->SetInteger("begin_retro_frame_args_", begin_retro_frame_args_.size()); |
| 765 state->SetBoolean("begin_retro_frame_task_", | 774 state->SetBoolean("begin_retro_frame_task_", |
| 766 !begin_retro_frame_task_.IsCancelled()); | 775 !begin_retro_frame_task_.IsCancelled()); |
| 767 state->SetBoolean("begin_impl_frame_deadline_task_", | 776 state->SetBoolean("begin_impl_frame_deadline_task_", |
| 768 !begin_impl_frame_deadline_task_.IsCancelled()); | 777 !begin_impl_frame_deadline_task_.IsCancelled()); |
| 769 state->SetBoolean("advance_commit_state_task_", | 778 state->SetBoolean("advance_commit_state_task_", |
| 770 !advance_commit_state_task_.IsCancelled()); | 779 !advance_commit_state_task_.IsCancelled()); |
| 771 state->BeginDictionary("begin_impl_frame_args"); | 780 state->BeginDictionary("begin_impl_frame_args"); |
| 772 begin_impl_frame_args_.AsValueInto(state); | 781 begin_impl_frame_args_.AsValueInto(state); |
| 773 state->EndDictionary(); | 782 state->EndDictionary(); |
| 783 state->SetString("begin_impl_frame_deadline_mode_", | |
| 784 SchedulerStateMachine::BeginImplFrameDeadlineModeToString( | |
| 785 begin_impl_frame_deadline_mode_)); | |
| 774 | 786 |
| 775 base::TimeTicks now = Now(); | 787 base::TimeTicks now = Now(); |
| 776 base::TimeTicks frame_time = begin_impl_frame_args_.frame_time; | 788 base::TimeTicks frame_time = begin_impl_frame_args_.frame_time; |
| 777 base::TimeTicks deadline = begin_impl_frame_args_.deadline; | 789 base::TimeTicks deadline = begin_impl_frame_args_.deadline; |
| 778 base::TimeDelta interval = begin_impl_frame_args_.interval; | 790 base::TimeDelta interval = begin_impl_frame_args_.interval; |
| 779 state->BeginDictionary("major_timestamps_in_ms"); | 791 state->BeginDictionary("major_timestamps_in_ms"); |
| 780 state->SetDouble("0_interval", interval.InMillisecondsF()); | 792 state->SetDouble("0_interval", interval.InMillisecondsF()); |
| 781 state->SetDouble("1_now_to_deadline", (deadline - now).InMillisecondsF()); | 793 state->SetDouble("1_now_to_deadline", (deadline - now).InMillisecondsF()); |
| 782 state->SetDouble("2_frame_time_to_now", (now - frame_time).InMillisecondsF()); | 794 state->SetDouble("2_frame_time_to_now", (now - frame_time).InMillisecondsF()); |
| 783 state->SetDouble("3_frame_time_to_deadline", | 795 state->SetDouble("3_frame_time_to_deadline", |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 796 client_->DrawDurationEstimate().InMillisecondsF()); | 808 client_->DrawDurationEstimate().InMillisecondsF()); |
| 797 state->SetDouble( | 809 state->SetDouble( |
| 798 "begin_main_frame_to_commit_duration_estimate_ms", | 810 "begin_main_frame_to_commit_duration_estimate_ms", |
| 799 client_->BeginMainFrameToCommitDurationEstimate().InMillisecondsF()); | 811 client_->BeginMainFrameToCommitDurationEstimate().InMillisecondsF()); |
| 800 state->SetDouble( | 812 state->SetDouble( |
| 801 "commit_to_activate_duration_estimate_ms", | 813 "commit_to_activate_duration_estimate_ms", |
| 802 client_->CommitToActivateDurationEstimate().InMillisecondsF()); | 814 client_->CommitToActivateDurationEstimate().InMillisecondsF()); |
| 803 state->EndDictionary(); | 815 state->EndDictionary(); |
| 804 } | 816 } |
| 805 | 817 |
| 818 bool Scheduler::ShouldRecoverMainLatency() const { | |
| 819 if (!state_machine_.MainThreadIsInHighLatencyMode()) | |
| 820 return false; | |
| 821 | |
| 822 if (state_machine_.impl_latency_takes_priority()) | |
| 823 return false; | |
| 824 | |
| 825 return CanCommitAndActivateBeforeDeadline(); | |
| 826 } | |
| 827 | |
| 828 bool Scheduler::ShouldRecoverImplLatency() const { | |
| 829 if (!state_machine_.SwapThrottled()) | |
| 830 return false; | |
| 831 | |
| 832 bool frame_time_is_before_deadline = | |
| 833 begin_impl_frame_args_.frame_time < begin_impl_frame_args_.deadline; | |
|
mithro-old
2015/05/27 04:40:14
When is this ever not true? Is it because begin_im
brianderson
2015/05/27 23:22:31
Yes, if the estimated draw time is 20ms, for examp
| |
| 834 | |
| 835 SchedulerStateMachine::BeginImplFrameDeadlineMode | |
| 836 next_begin_impl_frame_deadline_mode = | |
| 837 state_machine_.CurrentBeginImplFrameDeadlineMode(); | |
| 838 switch (next_begin_impl_frame_deadline_mode) { | |
| 839 case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_NONE: | |
| 840 return false; | |
| 841 case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_IMMEDIATE: | |
| 842 return frame_time_is_before_deadline; | |
|
mithro-old
2015/05/27 04:40:14
I can't remember, are we allow to use fall through
brianderson
2015/05/27 23:22:32
Looks like it is allowed.
| |
| 843 case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_REGULAR: | |
| 844 return frame_time_is_before_deadline; | |
| 845 case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_LATE: | |
| 846 return CanCommitAndActivateBeforeDeadline(); | |
| 847 case SchedulerStateMachine:: | |
| 848 BEGIN_IMPL_FRAME_DEADLINE_MODE_BLOCKED_ON_READY_TO_DRAW: | |
| 849 return false; | |
| 850 } | |
| 851 NOTREACHED(); | |
| 852 return false; | |
| 853 } | |
| 854 | |
| 806 bool Scheduler::CanCommitAndActivateBeforeDeadline() const { | 855 bool Scheduler::CanCommitAndActivateBeforeDeadline() const { |
| 807 // Check if the main thread computation and commit can be finished before the | 856 // Check if the main thread computation and commit can be finished before the |
| 808 // impl thread's deadline. | 857 // impl thread's deadline. |
| 809 base::TimeTicks estimated_draw_time = | 858 base::TimeTicks estimated_draw_time = |
| 810 begin_impl_frame_args_.frame_time + | 859 begin_impl_frame_args_.frame_time + |
| 811 client_->BeginMainFrameToCommitDurationEstimate() + | 860 client_->BeginMainFrameToCommitDurationEstimate() + |
| 812 client_->CommitToActivateDurationEstimate(); | 861 client_->CommitToActivateDurationEstimate(); |
| 813 | 862 |
|
mithro-old
2015/05/27 04:40:14
nit: Unrelated removal?
brianderson
2015/06/30 22:03:53
I added a trace event on line 506 above and remove
| |
| 814 TRACE_EVENT2( | |
| 815 TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), | |
| 816 "CanCommitAndActivateBeforeDeadline", | |
| 817 "time_left_after_drawing_ms", | |
| 818 (begin_impl_frame_args_.deadline - estimated_draw_time).InMillisecondsF(), | |
| 819 "state", | |
| 820 AsValue()); | |
| 821 | |
| 822 return estimated_draw_time < begin_impl_frame_args_.deadline; | 863 return estimated_draw_time < begin_impl_frame_args_.deadline; |
| 823 } | 864 } |
| 824 | 865 |
| 825 bool Scheduler::IsBeginMainFrameSentOrStarted() const { | 866 bool Scheduler::IsBeginMainFrameSentOrStarted() const { |
| 826 return (state_machine_.commit_state() == | 867 return (state_machine_.commit_state() == |
| 827 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT || | 868 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT || |
| 828 state_machine_.commit_state() == | 869 state_machine_.commit_state() == |
| 829 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED); | 870 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED); |
| 830 } | 871 } |
| 831 | 872 |
| 832 } // namespace cc | 873 } // namespace cc |
| OLD | NEW |