Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(415)

Side by Side Diff: cc/scheduler/scheduler.cc

Issue 1425973003: cc: Don't attempt main thread synchronization if it is slow. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698