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 |