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

Side by Side Diff: components/scheduler/renderer/renderer_scheduler_impl.cc

Issue 1977863004: scheduler: Add main thread gesture as a detected use case (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix broken test Created 4 years, 7 months 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "components/scheduler/renderer/renderer_scheduler_impl.h" 5 #include "components/scheduler/renderer/renderer_scheduler_impl.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/debug/stack_trace.h" 8 #include "base/debug/stack_trace.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/memory/ptr_util.h" 10 #include "base/memory/ptr_util.h"
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
133 expensive_task_blocking_allowed(true), 133 expensive_task_blocking_allowed(true),
134 in_idle_period_for_testing(false) {} 134 in_idle_period_for_testing(false) {}
135 135
136 RendererSchedulerImpl::MainThreadOnly::~MainThreadOnly() {} 136 RendererSchedulerImpl::MainThreadOnly::~MainThreadOnly() {}
137 137
138 RendererSchedulerImpl::AnyThread::AnyThread() 138 RendererSchedulerImpl::AnyThread::AnyThread()
139 : awaiting_touch_start_response(false), 139 : awaiting_touch_start_response(false),
140 in_idle_period(false), 140 in_idle_period(false),
141 begin_main_frame_on_critical_path(false), 141 begin_main_frame_on_critical_path(false),
142 last_gesture_was_compositor_driven(false), 142 last_gesture_was_compositor_driven(false),
143 default_gesture_prevented(true),
143 have_seen_touchstart(false) {} 144 have_seen_touchstart(false) {}
144 145
145 RendererSchedulerImpl::AnyThread::~AnyThread() {} 146 RendererSchedulerImpl::AnyThread::~AnyThread() {}
146 147
147 RendererSchedulerImpl::CompositorThreadOnly::CompositorThreadOnly() 148 RendererSchedulerImpl::CompositorThreadOnly::CompositorThreadOnly()
148 : last_input_type(blink::WebInputEvent::Undefined) {} 149 : last_input_type(blink::WebInputEvent::Undefined) {}
149 150
150 RendererSchedulerImpl::CompositorThreadOnly::~CompositorThreadOnly() {} 151 RendererSchedulerImpl::CompositorThreadOnly::~CompositorThreadOnly() {}
151 152
152 void RendererSchedulerImpl::Shutdown() { 153 void RendererSchedulerImpl::Shutdown() {
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 487
487 if (type) { 488 if (type) {
488 switch (type) { 489 switch (type) {
489 case blink::WebInputEvent::TouchStart: 490 case blink::WebInputEvent::TouchStart:
490 AnyThread().awaiting_touch_start_response = true; 491 AnyThread().awaiting_touch_start_response = true;
491 // This is just a fail-safe to reset the state of 492 // This is just a fail-safe to reset the state of
492 // |last_gesture_was_compositor_driven| to the default. We don't know 493 // |last_gesture_was_compositor_driven| to the default. We don't know
493 // yet where the gesture will run. 494 // yet where the gesture will run.
494 AnyThread().last_gesture_was_compositor_driven = false; 495 AnyThread().last_gesture_was_compositor_driven = false;
495 AnyThread().have_seen_touchstart = true; 496 AnyThread().have_seen_touchstart = true;
497 // Assume the default gesture is prevented until we see evidence
498 // otherwise.
499 AnyThread().default_gesture_prevented = true;
496 break; 500 break;
497 501
498 case blink::WebInputEvent::TouchMove: 502 case blink::WebInputEvent::TouchMove:
499 // Observation of consecutive touchmoves is a strong signal that the 503 // Observation of consecutive touchmoves is a strong signal that the
500 // page is consuming the touch sequence, in which case touchstart 504 // page is consuming the touch sequence, in which case touchstart
501 // response prioritization is no longer necessary. Otherwise, the 505 // response prioritization is no longer necessary. Otherwise, the
502 // initial touchmove should preserve the touchstart response pending 506 // initial touchmove should preserve the touchstart response pending
503 // state. 507 // state.
504 if (AnyThread().awaiting_touch_start_response && 508 if (AnyThread().awaiting_touch_start_response &&
505 CompositorThreadOnly().last_input_type == 509 CompositorThreadOnly().last_input_type ==
506 blink::WebInputEvent::TouchMove) { 510 blink::WebInputEvent::TouchMove) {
507 AnyThread().awaiting_touch_start_response = false; 511 AnyThread().awaiting_touch_start_response = false;
508 } 512 }
509 break; 513 break;
510 514
511 case blink::WebInputEvent::GesturePinchUpdate: 515 case blink::WebInputEvent::GesturePinchUpdate:
512 case blink::WebInputEvent::GestureScrollUpdate: 516 case blink::WebInputEvent::GestureScrollUpdate:
513 // If we see events for an established gesture, we can lock it to the 517 // If we see events for an established gesture, we can lock it to the
514 // appropriate thread as the gesture can no longer be cancelled. 518 // appropriate thread as the gesture can no longer be cancelled.
515 AnyThread().last_gesture_was_compositor_driven = 519 AnyThread().last_gesture_was_compositor_driven =
516 input_event_state == InputEventState::EVENT_CONSUMED_BY_COMPOSITOR; 520 input_event_state == InputEventState::EVENT_CONSUMED_BY_COMPOSITOR;
517 AnyThread().awaiting_touch_start_response = false; 521 AnyThread().awaiting_touch_start_response = false;
522 AnyThread().default_gesture_prevented = false;
518 break; 523 break;
519 524
520 case blink::WebInputEvent::GestureFlingCancel: 525 case blink::WebInputEvent::GestureFlingCancel:
521 AnyThread().fling_compositor_escalation_deadline = base::TimeTicks(); 526 AnyThread().fling_compositor_escalation_deadline = base::TimeTicks();
522 break; 527 break;
523 528
524 case blink::WebInputEvent::GestureTapDown: 529 case blink::WebInputEvent::GestureTapDown:
525 case blink::WebInputEvent::GestureShowPress: 530 case blink::WebInputEvent::GestureShowPress:
526 case blink::WebInputEvent::GestureScrollEnd: 531 case blink::WebInputEvent::GestureScrollEnd:
527 // With no observable effect, these meta events do not indicate a 532 // With no observable effect, these meta events do not indicate a
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
562 if (helper_.IsShutdown()) 567 if (helper_.IsShutdown())
563 return false; 568 return false;
564 569
565 MaybeUpdatePolicy(); 570 MaybeUpdatePolicy();
566 // The touchstart, synchronized gesture and main-thread gesture use cases 571 // The touchstart, synchronized gesture and main-thread gesture use cases
567 // indicate a strong likelihood of high-priority work in the near future. 572 // indicate a strong likelihood of high-priority work in the near future.
568 UseCase use_case = MainThreadOnly().current_use_case; 573 UseCase use_case = MainThreadOnly().current_use_case;
569 return MainThreadOnly().touchstart_expected_soon || 574 return MainThreadOnly().touchstart_expected_soon ||
570 use_case == UseCase::TOUCHSTART || 575 use_case == UseCase::TOUCHSTART ||
571 use_case == UseCase::MAIN_THREAD_GESTURE || 576 use_case == UseCase::MAIN_THREAD_GESTURE ||
577 use_case == UseCase::MAIN_THREAD_CUSTOM_INPUT_HANDLING ||
572 use_case == UseCase::SYNCHRONIZED_GESTURE; 578 use_case == UseCase::SYNCHRONIZED_GESTURE;
573 } 579 }
574 580
575 bool RendererSchedulerImpl::ShouldYieldForHighPriorityWork() { 581 bool RendererSchedulerImpl::ShouldYieldForHighPriorityWork() {
576 helper_.CheckOnValidThread(); 582 helper_.CheckOnValidThread();
577 if (helper_.IsShutdown()) 583 if (helper_.IsShutdown())
578 return false; 584 return false;
579 585
580 MaybeUpdatePolicy(); 586 MaybeUpdatePolicy();
581 // We only yield if there's a urgent task to be run now, or we are expecting 587 // We only yield if there's a urgent task to be run now, or we are expecting
582 // one soon (touch start). 588 // one soon (touch start).
583 // Note: even though the control queue has the highest priority we don't yield 589 // Note: even though the control queue has the highest priority we don't yield
584 // for it since these tasks are not user-provided work and they are only 590 // for it since these tasks are not user-provided work and they are only
585 // intended to run before the next task, not interrupt the tasks. 591 // intended to run before the next task, not interrupt the tasks.
586 switch (MainThreadOnly().current_use_case) { 592 switch (MainThreadOnly().current_use_case) {
587 case UseCase::COMPOSITOR_GESTURE: 593 case UseCase::COMPOSITOR_GESTURE:
588 case UseCase::NONE: 594 case UseCase::NONE:
589 return MainThreadOnly().touchstart_expected_soon; 595 return MainThreadOnly().touchstart_expected_soon;
590 596
591 case UseCase::MAIN_THREAD_GESTURE: 597 case UseCase::MAIN_THREAD_GESTURE:
598 case UseCase::MAIN_THREAD_CUSTOM_INPUT_HANDLING:
592 case UseCase::SYNCHRONIZED_GESTURE: 599 case UseCase::SYNCHRONIZED_GESTURE:
593 return compositor_task_runner_->HasPendingImmediateWork() || 600 return compositor_task_runner_->HasPendingImmediateWork() ||
594 MainThreadOnly().touchstart_expected_soon; 601 MainThreadOnly().touchstart_expected_soon;
595 602
596 case UseCase::TOUCHSTART: 603 case UseCase::TOUCHSTART:
597 return true; 604 return true;
598 605
599 case UseCase::LOADING: 606 case UseCase::LOADING:
600 return false; 607 return false;
601 608
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
732 new_policy.compositor_queue_policy.priority = 739 new_policy.compositor_queue_policy.priority =
733 main_thread_compositing_is_fast ? TaskQueue::HIGH_PRIORITY 740 main_thread_compositing_is_fast ? TaskQueue::HIGH_PRIORITY
734 : TaskQueue::NORMAL_PRIORITY; 741 : TaskQueue::NORMAL_PRIORITY;
735 if (touchstart_expected_soon) { 742 if (touchstart_expected_soon) {
736 expensive_task_policy = ExpensiveTaskPolicy::BLOCK; 743 expensive_task_policy = ExpensiveTaskPolicy::BLOCK;
737 } else { 744 } else {
738 expensive_task_policy = ExpensiveTaskPolicy::THROTTLE; 745 expensive_task_policy = ExpensiveTaskPolicy::THROTTLE;
739 } 746 }
740 break; 747 break;
741 748
742 case UseCase::MAIN_THREAD_GESTURE: 749 case UseCase::MAIN_THREAD_CUSTOM_INPUT_HANDLING:
743 // In main thread gestures we don't have perfect knowledge about which 750 // In main thread input handling scenarios we don't have perfect knowledge
744 // things we should be prioritizing, so we don't attempt to block 751 // about which things we should be prioritizing, so we don't attempt to
745 // expensive tasks because we don't know whether they were integral to the 752 // block expensive tasks because we don't know whether they were integral
746 // page's functionality or not. 753 // to the page's functionality or not.
747 new_policy.compositor_queue_policy.priority = 754 new_policy.compositor_queue_policy.priority =
748 main_thread_compositing_is_fast ? TaskQueue::HIGH_PRIORITY 755 main_thread_compositing_is_fast ? TaskQueue::HIGH_PRIORITY
749 : TaskQueue::NORMAL_PRIORITY; 756 : TaskQueue::NORMAL_PRIORITY;
750 break; 757 break;
751 758
759 case UseCase::MAIN_THREAD_GESTURE:
760 // A main thread gesture is for example a scroll gesture which is handled
761 // by the main thread. Since we know the established gesture type, we can
762 // be a little more aggressive about prioritizing compositing and input
763 // handling over other tasks.
764 new_policy.compositor_queue_policy.priority = TaskQueue::HIGH_PRIORITY;
765 if (touchstart_expected_soon) {
766 expensive_task_policy = ExpensiveTaskPolicy::BLOCK;
767 } else {
768 expensive_task_policy = ExpensiveTaskPolicy::THROTTLE;
769 }
770 break;
771
752 case UseCase::TOUCHSTART: 772 case UseCase::TOUCHSTART:
753 new_policy.compositor_queue_policy.priority = TaskQueue::HIGH_PRIORITY; 773 new_policy.compositor_queue_policy.priority = TaskQueue::HIGH_PRIORITY;
754 new_policy.loading_queue_policy.is_enabled = false; 774 new_policy.loading_queue_policy.is_enabled = false;
755 new_policy.timer_queue_policy.is_enabled = false; 775 new_policy.timer_queue_policy.is_enabled = false;
756 // NOTE this is a nop due to the above. 776 // NOTE this is a nop due to the above.
757 expensive_task_policy = ExpensiveTaskPolicy::BLOCK; 777 expensive_task_policy = ExpensiveTaskPolicy::BLOCK;
758 break; 778 break;
759 779
760 case UseCase::NONE: 780 case UseCase::NONE:
761 // It's only safe to block tasks that if we are expecting a compositor 781 // It's only safe to block tasks that if we are expecting a compositor
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
904 *expected_use_case_duration = 924 *expected_use_case_duration =
905 AnyThread().user_model.TimeLeftInUserGesture(now); 925 AnyThread().user_model.TimeLeftInUserGesture(now);
906 if (*expected_use_case_duration > base::TimeDelta()) { 926 if (*expected_use_case_duration > base::TimeDelta()) {
907 // Has a gesture been fully established? 927 // Has a gesture been fully established?
908 if (AnyThread().awaiting_touch_start_response) { 928 if (AnyThread().awaiting_touch_start_response) {
909 // No, so arrange for compositor tasks to be run at the highest priority. 929 // No, so arrange for compositor tasks to be run at the highest priority.
910 return UseCase::TOUCHSTART; 930 return UseCase::TOUCHSTART;
911 } 931 }
912 932
913 // Yes a gesture has been established. Based on how the gesture is handled 933 // Yes a gesture has been established. Based on how the gesture is handled
914 // we need to choose between one of three use cases: 934 // we need to choose between one of four use cases:
915 // 1. COMPOSITOR_GESTURE where the gesture is processed only on the 935 // 1. COMPOSITOR_GESTURE where the gesture is processed only on the
916 // compositor thread. 936 // compositor thread.
917 // 2. MAIN_THREAD_GESTURE where the gesture is processed only on the main 937 // 2. MAIN_THREAD_GESTURE where the gesture is processed only on the main
918 // thread. 938 // thread.
919 // 3. SYNCHRONIZED_GESTURE where the gesture is processed on both threads. 939 // 3. MAIN_THREAD_CUSTOM_INPUT_HANDLING where the main thread processes a
940 // stream of input events and has prevented a default gesture from being
941 // started.
942 // 4. SYNCHRONIZED_GESTURE where the gesture is processed on both threads.
920 // TODO(skyostil): Consider removing in_idle_period_ and 943 // TODO(skyostil): Consider removing in_idle_period_ and
921 // HadAnIdlePeriodRecently() unless we need them here. 944 // HadAnIdlePeriodRecently() unless we need them here.
922 if (AnyThread().last_gesture_was_compositor_driven) { 945 if (AnyThread().last_gesture_was_compositor_driven) {
923 if (AnyThread().begin_main_frame_on_critical_path) { 946 if (AnyThread().begin_main_frame_on_critical_path) {
924 return UseCase::SYNCHRONIZED_GESTURE; 947 return UseCase::SYNCHRONIZED_GESTURE;
925 } else { 948 } else {
926 return UseCase::COMPOSITOR_GESTURE; 949 return UseCase::COMPOSITOR_GESTURE;
927 } 950 }
928 } 951 }
929 return UseCase::MAIN_THREAD_GESTURE; 952 if (AnyThread().default_gesture_prevented) {
953 return UseCase::MAIN_THREAD_CUSTOM_INPUT_HANDLING;
954 } else {
955 return UseCase::MAIN_THREAD_GESTURE;
956 }
930 } 957 }
931 958
932 // TODO(alexclarke): return UseCase::LOADING if signals suggest the system is 959 // TODO(alexclarke): return UseCase::LOADING if signals suggest the system is
933 // in the initial 1s of RAIL loading. 960 // in the initial 1s of RAIL loading.
934 return UseCase::NONE; 961 return UseCase::NONE;
935 } 962 }
936 963
937 base::TimeDelta RendererSchedulerImpl::EstimateLongestJankFreeTaskDuration() 964 base::TimeDelta RendererSchedulerImpl::EstimateLongestJankFreeTaskDuration()
938 const { 965 const {
939 switch (MainThreadOnly().current_use_case) { 966 switch (MainThreadOnly().current_use_case) {
940 case UseCase::TOUCHSTART: 967 case UseCase::TOUCHSTART:
941 case UseCase::COMPOSITOR_GESTURE: 968 case UseCase::COMPOSITOR_GESTURE:
942 case UseCase::LOADING: 969 case UseCase::LOADING:
943 case UseCase::NONE: 970 case UseCase::NONE:
944 return base::TimeDelta::FromMilliseconds(kRailsResponseTimeMillis); 971 return base::TimeDelta::FromMilliseconds(kRailsResponseTimeMillis);
945 972
973 case UseCase::MAIN_THREAD_CUSTOM_INPUT_HANDLING:
946 case UseCase::MAIN_THREAD_GESTURE: 974 case UseCase::MAIN_THREAD_GESTURE:
947 case UseCase::SYNCHRONIZED_GESTURE: 975 case UseCase::SYNCHRONIZED_GESTURE:
948 return MainThreadOnly().idle_time_estimator.GetExpectedIdleDuration( 976 return MainThreadOnly().idle_time_estimator.GetExpectedIdleDuration(
949 MainThreadOnly().compositor_frame_interval); 977 MainThreadOnly().compositor_frame_interval);
950 978
951 default: 979 default:
952 NOTREACHED(); 980 NOTREACHED();
953 return base::TimeDelta::FromMilliseconds(kRailsResponseTimeMillis); 981 return base::TimeDelta::FromMilliseconds(kRailsResponseTimeMillis);
954 } 982 }
955 } 983 }
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
1089 MainThreadOnly().navigation_task_expected_count); 1117 MainThreadOnly().navigation_task_expected_count);
1090 state->SetDouble("last_idle_period_end_time", 1118 state->SetDouble("last_idle_period_end_time",
1091 (AnyThread().last_idle_period_end_time - base::TimeTicks()) 1119 (AnyThread().last_idle_period_end_time - base::TimeTicks())
1092 .InMillisecondsF()); 1120 .InMillisecondsF());
1093 state->SetBoolean("awaiting_touch_start_response", 1121 state->SetBoolean("awaiting_touch_start_response",
1094 AnyThread().awaiting_touch_start_response); 1122 AnyThread().awaiting_touch_start_response);
1095 state->SetBoolean("begin_main_frame_on_critical_path", 1123 state->SetBoolean("begin_main_frame_on_critical_path",
1096 AnyThread().begin_main_frame_on_critical_path); 1124 AnyThread().begin_main_frame_on_critical_path);
1097 state->SetBoolean("last_gesture_was_compositor_driven", 1125 state->SetBoolean("last_gesture_was_compositor_driven",
1098 AnyThread().last_gesture_was_compositor_driven); 1126 AnyThread().last_gesture_was_compositor_driven);
1127 state->SetBoolean("default_gesture_prevented",
1128 AnyThread().default_gesture_prevented);
1099 state->SetDouble("expected_loading_task_duration", 1129 state->SetDouble("expected_loading_task_duration",
1100 MainThreadOnly() 1130 MainThreadOnly()
1101 .loading_task_cost_estimator.expected_task_duration() 1131 .loading_task_cost_estimator.expected_task_duration()
1102 .InMillisecondsF()); 1132 .InMillisecondsF());
1103 state->SetDouble("expected_timer_task_duration", 1133 state->SetDouble("expected_timer_task_duration",
1104 MainThreadOnly() 1134 MainThreadOnly()
1105 .timer_task_cost_estimator.expected_task_duration() 1135 .timer_task_cost_estimator.expected_task_duration()
1106 .InMillisecondsF()); 1136 .InMillisecondsF());
1107 // TODO(skyostil): Can we somehow trace how accurate these estimates were? 1137 // TODO(skyostil): Can we somehow trace how accurate these estimates were?
1108 state->SetDouble( 1138 state->SetDouble(
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
1284 } 1314 }
1285 MainThreadOnly().have_reported_blocking_intervention_since_navigation = 1315 MainThreadOnly().have_reported_blocking_intervention_since_navigation =
1286 true; 1316 true;
1287 BroadcastConsoleWarning( 1317 BroadcastConsoleWarning(
1288 "Deferred long-running timer task(s) to improve scrolling smoothness. " 1318 "Deferred long-running timer task(s) to improve scrolling smoothness. "
1289 "See crbug.com/574343."); 1319 "See crbug.com/574343.");
1290 } 1320 }
1291 } 1321 }
1292 1322
1293 } // namespace scheduler 1323 } // namespace scheduler
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698