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 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 203 DCHECK_EQ(state_machine_.NextAction(), SchedulerStateMachine::ACTION_NONE); | 203 DCHECK_EQ(state_machine_.NextAction(), SchedulerStateMachine::ACTION_NONE); |
| 204 } | 204 } |
| 205 } | 205 } |
| 206 | 206 |
| 207 void Scheduler::DidSwapBuffersComplete() { | 207 void Scheduler::DidSwapBuffersComplete() { |
| 208 DCHECK_GT(state_machine_.pending_swaps(), 0) << AsValue()->ToString(); | 208 DCHECK_GT(state_machine_.pending_swaps(), 0) << AsValue()->ToString(); |
| 209 state_machine_.DidSwapBuffersComplete(); | 209 state_machine_.DidSwapBuffersComplete(); |
| 210 ProcessScheduledActions(); | 210 ProcessScheduledActions(); |
| 211 } | 211 } |
| 212 | 212 |
| 213 void Scheduler::SetImplLatencyTakesPriority(bool impl_latency_takes_priority) { | 213 void Scheduler::SetSmoothnessMode(bool smoothness_takes_priority, |
| 214 state_machine_.SetImplLatencyTakesPriority(impl_latency_takes_priority); | 214 bool scroll_affects_scroll_handler) { |
| 215 state_machine_.SetSmoothnessMode(smoothness_takes_priority, | |
| 216 scroll_affects_scroll_handler); | |
| 215 ProcessScheduledActions(); | 217 ProcessScheduledActions(); |
| 216 } | 218 } |
| 217 | 219 |
| 218 void Scheduler::NotifyReadyToCommit() { | 220 void Scheduler::NotifyReadyToCommit() { |
| 219 TRACE_EVENT0("cc", "Scheduler::NotifyReadyToCommit"); | 221 TRACE_EVENT0("cc", "Scheduler::NotifyReadyToCommit"); |
| 220 state_machine_.NotifyReadyToCommit(); | 222 state_machine_.NotifyReadyToCommit(); |
| 221 ProcessScheduledActions(); | 223 ProcessScheduledActions(); |
| 222 } | 224 } |
| 223 | 225 |
| 224 void Scheduler::DidCommit() { | 226 void Scheduler::DidCommit() { |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 456 TRACE_EVENT2("cc,benchmark", "Scheduler::BeginImplFrame", "args", | 458 TRACE_EVENT2("cc,benchmark", "Scheduler::BeginImplFrame", "args", |
| 457 args.AsValue(), "main_thread_missed_last_deadline", | 459 args.AsValue(), "main_thread_missed_last_deadline", |
| 458 main_thread_is_in_high_latency_mode); | 460 main_thread_is_in_high_latency_mode); |
| 459 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), | 461 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), |
| 460 "MainThreadLatency", main_thread_is_in_high_latency_mode); | 462 "MainThreadLatency", main_thread_is_in_high_latency_mode); |
| 461 | 463 |
| 462 BeginFrameArgs adjusted_args = args; | 464 BeginFrameArgs adjusted_args = args; |
| 463 adjusted_args.deadline -= compositor_timing_history_->DrawDurationEstimate(); | 465 adjusted_args.deadline -= compositor_timing_history_->DrawDurationEstimate(); |
| 464 adjusted_args.deadline -= kDeadlineFudgeFactor; | 466 adjusted_args.deadline -= kDeadlineFudgeFactor; |
| 465 | 467 |
| 466 if (ShouldRecoverMainLatency(adjusted_args)) { | 468 base::TimeDelta bmf_to_activate_estimate = |
| 469 compositor_timing_history_->BeginMainFrameToCommitDurationEstimate() + | |
| 470 compositor_timing_history_->CommitToReadyToActivateDurationEstimate() + | |
| 471 compositor_timing_history_->ActivateDurationEstimate(); | |
| 472 | |
| 473 state_machine_.SetMainThreadIsFast(bmf_to_activate_estimate < args.interval); | |
|
Sami
2015/10/29 10:53:56
This part I'm a little unsure about. The delay of
brianderson
2015/10/29 17:56:51
What if we:
1) Make adjusted_args.on_critical_path
Sami
2015/10/29 18:37:04
I like both ideas!
| |
| 474 | |
| 475 bool can_activate_before_deadline = CanCommitAndActivateBeforeDeadline( | |
| 476 adjusted_args, bmf_to_activate_estimate); | |
| 477 if (ShouldRecoverMainLatency(adjusted_args, can_activate_before_deadline)) { | |
| 467 TRACE_EVENT_INSTANT0("cc", "SkipBeginMainFrameToReduceLatency", | 478 TRACE_EVENT_INSTANT0("cc", "SkipBeginMainFrameToReduceLatency", |
| 468 TRACE_EVENT_SCOPE_THREAD); | 479 TRACE_EVENT_SCOPE_THREAD); |
| 469 state_machine_.SetSkipNextBeginMainFrameToReduceLatency(); | 480 state_machine_.SetSkipNextBeginMainFrameToReduceLatency(); |
| 470 } else if (ShouldRecoverImplLatency(adjusted_args)) { | 481 } else if (ShouldRecoverImplLatency(adjusted_args, |
| 482 can_activate_before_deadline)) { | |
| 471 TRACE_EVENT_INSTANT0("cc", "SkipBeginImplFrameToReduceLatency", | 483 TRACE_EVENT_INSTANT0("cc", "SkipBeginImplFrameToReduceLatency", |
| 472 TRACE_EVENT_SCOPE_THREAD); | 484 TRACE_EVENT_SCOPE_THREAD); |
| 473 frame_source_->DidFinishFrame(begin_retro_frame_args_.size()); | 485 frame_source_->DidFinishFrame(begin_retro_frame_args_.size()); |
| 474 return; | 486 return; |
| 475 } | 487 } |
| 476 | 488 |
| 477 BeginImplFrame(adjusted_args); | 489 BeginImplFrame(adjusted_args); |
| 478 | 490 |
| 479 // The deadline will be scheduled in ProcessScheduledActions. | 491 // The deadline will be scheduled in ProcessScheduledActions. |
| 480 state_machine_.OnBeginImplFrameDeadlinePending(); | 492 state_machine_.OnBeginImplFrameDeadlinePending(); |
| (...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 769 state->BeginDictionary("compositor_timing_history"); | 781 state->BeginDictionary("compositor_timing_history"); |
| 770 compositor_timing_history_->AsValueInto(state); | 782 compositor_timing_history_->AsValueInto(state); |
| 771 state->EndDictionary(); | 783 state->EndDictionary(); |
| 772 } | 784 } |
| 773 | 785 |
| 774 void Scheduler::UpdateCompositorTimingHistoryRecordingEnabled() { | 786 void Scheduler::UpdateCompositorTimingHistoryRecordingEnabled() { |
| 775 compositor_timing_history_->SetRecordingEnabled( | 787 compositor_timing_history_->SetRecordingEnabled( |
| 776 state_machine_.HasInitializedOutputSurface() && state_machine_.visible()); | 788 state_machine_.HasInitializedOutputSurface() && state_machine_.visible()); |
| 777 } | 789 } |
| 778 | 790 |
| 779 bool Scheduler::ShouldRecoverMainLatency(const BeginFrameArgs& args) const { | 791 bool Scheduler::ShouldRecoverMainLatency( |
| 792 const BeginFrameArgs& args, | |
| 793 bool can_activate_before_deadline) const { | |
| 780 DCHECK(!settings_.using_synchronous_renderer_compositor); | 794 DCHECK(!settings_.using_synchronous_renderer_compositor); |
| 781 | 795 |
| 782 if (!state_machine_.main_thread_missed_last_deadline()) | 796 if (!state_machine_.main_thread_missed_last_deadline()) |
| 783 return false; | 797 return false; |
| 784 | 798 |
| 785 // When prioritizing impl thread latency, we currently put the | 799 // When prioritizing impl thread latency, we currently put the |
| 786 // main thread in a high latency mode. Don't try to fight it. | 800 // main thread in a high latency mode. Don't try to fight it. |
| 787 if (state_machine_.impl_latency_takes_priority()) | 801 if (state_machine_.ImplLatencyTakesPriority()) |
| 788 return false; | 802 return false; |
| 789 | 803 |
| 790 return CanCommitAndActivateBeforeDeadline(args); | 804 return can_activate_before_deadline; |
| 791 } | 805 } |
| 792 | 806 |
| 793 bool Scheduler::ShouldRecoverImplLatency(const BeginFrameArgs& args) const { | 807 bool Scheduler::ShouldRecoverImplLatency( |
| 808 const BeginFrameArgs& args, | |
| 809 bool can_activate_before_deadline) const { | |
| 794 DCHECK(!settings_.using_synchronous_renderer_compositor); | 810 DCHECK(!settings_.using_synchronous_renderer_compositor); |
| 795 | 811 |
| 796 // Disable impl thread latency recovery when using the unthrottled | 812 // Disable impl thread latency recovery when using the unthrottled |
| 797 // begin frame source since we will always get a BeginFrame before | 813 // begin frame source since we will always get a BeginFrame before |
| 798 // the swap ack and our heuristics below will not work. | 814 // the swap ack and our heuristics below will not work. |
| 799 if (!throttle_frame_production_) | 815 if (!throttle_frame_production_) |
| 800 return false; | 816 return false; |
| 801 | 817 |
| 802 // If we are swap throttled at the BeginFrame, that means the impl thread is | 818 // If we are swap throttled at the BeginFrame, that means the impl thread is |
| 803 // very likely in a high latency mode. | 819 // very likely in a high latency mode. |
| 804 bool impl_thread_is_likely_high_latency = state_machine_.SwapThrottled(); | 820 bool impl_thread_is_likely_high_latency = state_machine_.SwapThrottled(); |
| 805 if (!impl_thread_is_likely_high_latency) | 821 if (!impl_thread_is_likely_high_latency) |
| 806 return false; | 822 return false; |
| 807 | 823 |
| 808 // The deadline may be in the past if our draw time is too long. | 824 // The deadline may be in the past if our draw time is too long. |
| 809 bool can_draw_before_deadline = args.frame_time < args.deadline; | 825 bool can_draw_before_deadline = args.frame_time < args.deadline; |
| 810 | 826 |
| 811 // When prioritizing impl thread latency, the deadline doesn't wait | 827 // When prioritizing impl thread latency, the deadline doesn't wait |
| 812 // for the main thread. | 828 // for the main thread. |
| 813 if (state_machine_.impl_latency_takes_priority()) | 829 if (state_machine_.ImplLatencyTakesPriority()) |
| 814 return can_draw_before_deadline; | 830 return can_draw_before_deadline; |
| 815 | 831 |
| 816 // If we only have impl-side updates, the deadline doesn't wait for | 832 // If we only have impl-side updates, the deadline doesn't wait for |
| 817 // the main thread. | 833 // the main thread. |
| 818 if (state_machine_.OnlyImplSideUpdatesExpected()) | 834 if (state_machine_.OnlyImplSideUpdatesExpected()) |
| 819 return can_draw_before_deadline; | 835 return can_draw_before_deadline; |
| 820 | 836 |
| 821 // If we get here, we know the main thread is in a low-latency mode relative | 837 // If we get here, we know the main thread is in a low-latency mode relative |
| 822 // to the impl thread. In this case, only try to also recover impl thread | 838 // to the impl thread. In this case, only try to also recover impl thread |
| 823 // latency if both the main and impl threads can run serially before the | 839 // latency if both the main and impl threads can run serially before the |
| 824 // deadline. | 840 // deadline. |
| 825 return CanCommitAndActivateBeforeDeadline(args); | 841 return can_activate_before_deadline; |
| 826 } | 842 } |
| 827 | 843 |
| 828 bool Scheduler::CanCommitAndActivateBeforeDeadline( | 844 bool Scheduler::CanCommitAndActivateBeforeDeadline( |
| 829 const BeginFrameArgs& args) const { | 845 const BeginFrameArgs& args, |
| 846 base::TimeDelta bmf_to_activate_estimate) const { | |
| 830 // Check if the main thread computation and commit can be finished before the | 847 // Check if the main thread computation and commit can be finished before the |
| 831 // impl thread's deadline. | 848 // impl thread's deadline. |
| 832 base::TimeTicks estimated_draw_time = | 849 base::TimeTicks estimated_draw_time = |
| 833 args.frame_time + | 850 args.frame_time + bmf_to_activate_estimate; |
| 834 compositor_timing_history_->BeginMainFrameToCommitDurationEstimate() + | |
| 835 compositor_timing_history_->CommitToReadyToActivateDurationEstimate() + | |
| 836 compositor_timing_history_->ActivateDurationEstimate(); | |
| 837 | 851 |
| 838 return estimated_draw_time < args.deadline; | 852 return estimated_draw_time < args.deadline; |
| 839 } | 853 } |
| 840 | 854 |
| 841 bool Scheduler::IsBeginMainFrameSentOrStarted() const { | 855 bool Scheduler::IsBeginMainFrameSentOrStarted() const { |
| 842 return (state_machine_.begin_main_frame_state() == | 856 return (state_machine_.begin_main_frame_state() == |
| 843 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT || | 857 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT || |
| 844 state_machine_.begin_main_frame_state() == | 858 state_machine_.begin_main_frame_state() == |
| 845 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_STARTED); | 859 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_STARTED); |
| 846 } | 860 } |
| 847 | 861 |
| 848 } // namespace cc | 862 } // namespace cc |
| OLD | NEW |