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

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

Issue 1971763003: scheduler: Detect when a main thread touch stream turns into a compositor gesture (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Review comments 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 386 matching lines...) Expand 10 before | Expand all | Expand 10 after
397 } 397 }
398 398
399 void RendererSchedulerImpl::EndIdlePeriodForTesting( 399 void RendererSchedulerImpl::EndIdlePeriodForTesting(
400 const base::Closure& callback, 400 const base::Closure& callback,
401 base::TimeTicks time_remaining) { 401 base::TimeTicks time_remaining) {
402 MainThreadOnly().in_idle_period_for_testing = false; 402 MainThreadOnly().in_idle_period_for_testing = false;
403 EndIdlePeriod(); 403 EndIdlePeriod();
404 callback.Run(); 404 callback.Run();
405 } 405 }
406 406
407 bool RendererSchedulerImpl::PolicyNeedsUpdateForTesting() {
408 return policy_may_need_update_.IsSet();
409 }
410
407 // static 411 // static
408 bool RendererSchedulerImpl::ShouldPrioritizeInputEvent( 412 bool RendererSchedulerImpl::ShouldPrioritizeInputEvent(
409 const blink::WebInputEvent& web_input_event) { 413 const blink::WebInputEvent& web_input_event) {
410 // We regard MouseMove events with the left mouse button down as a signal 414 // We regard MouseMove events with the left mouse button down as a signal
411 // that the user is doing something requiring a smooth frame rate. 415 // that the user is doing something requiring a smooth frame rate.
412 if (web_input_event.type == blink::WebInputEvent::MouseMove && 416 if (web_input_event.type == blink::WebInputEvent::MouseMove &&
413 (web_input_event.modifiers & blink::WebInputEvent::LeftButtonDown)) { 417 (web_input_event.modifiers & blink::WebInputEvent::LeftButtonDown)) {
414 return true; 418 return true;
415 } 419 }
416 // Ignore all other mouse events because they probably don't signal user 420 // Ignore all other mouse events because they probably don't signal user
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
451 base::AutoLock lock(any_thread_lock_); 455 base::AutoLock lock(any_thread_lock_);
452 base::TimeTicks now = helper_.scheduler_tqm_delegate()->NowTicks(); 456 base::TimeTicks now = helper_.scheduler_tqm_delegate()->NowTicks();
453 457
454 // TODO(alexclarke): Move WebInputEventTraits where we can access it from here 458 // TODO(alexclarke): Move WebInputEventTraits where we can access it from here
455 // and record the name rather than the integer representation. 459 // and record the name rather than the integer representation.
456 TRACE_EVENT2(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), 460 TRACE_EVENT2(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
457 "RendererSchedulerImpl::UpdateForInputEventOnCompositorThread", 461 "RendererSchedulerImpl::UpdateForInputEventOnCompositorThread",
458 "type", static_cast<int>(type), "input_event_state", 462 "type", static_cast<int>(type), "input_event_state",
459 InputEventStateToString(input_event_state)); 463 InputEventStateToString(input_event_state));
460 464
461 bool gesture_already_in_progress = InputSignalsSuggestGestureInProgress(now); 465 base::TimeDelta unused_policy_duration;
466 UseCase previous_use_case =
467 ComputeCurrentUseCase(now, &unused_policy_duration);
462 bool was_awaiting_touch_start_response = 468 bool was_awaiting_touch_start_response =
463 AnyThread().awaiting_touch_start_response; 469 AnyThread().awaiting_touch_start_response;
464 470
465 AnyThread().user_model.DidStartProcessingInputEvent(type, now); 471 AnyThread().user_model.DidStartProcessingInputEvent(type, now);
466 472
467 if (input_event_state == InputEventState::EVENT_CONSUMED_BY_COMPOSITOR) 473 if (input_event_state == InputEventState::EVENT_CONSUMED_BY_COMPOSITOR)
468 AnyThread().user_model.DidFinishProcessingInputEvent(now); 474 AnyThread().user_model.DidFinishProcessingInputEvent(now);
469 475
470 if (type) { 476 if (type) {
471 switch (type) { 477 switch (type) {
(...skipping 14 matching lines...) Expand all
486 // state. 492 // state.
487 if (AnyThread().awaiting_touch_start_response && 493 if (AnyThread().awaiting_touch_start_response &&
488 CompositorThreadOnly().last_input_type == 494 CompositorThreadOnly().last_input_type ==
489 blink::WebInputEvent::TouchMove) { 495 blink::WebInputEvent::TouchMove) {
490 AnyThread().awaiting_touch_start_response = false; 496 AnyThread().awaiting_touch_start_response = false;
491 } 497 }
492 break; 498 break;
493 499
494 case blink::WebInputEvent::GesturePinchUpdate: 500 case blink::WebInputEvent::GesturePinchUpdate:
495 case blink::WebInputEvent::GestureScrollUpdate: 501 case blink::WebInputEvent::GestureScrollUpdate:
502 // If we see events for an established gesture, we can lock it to the
503 // appropriate thread as the gesture can no longer be cancelled.
496 AnyThread().last_gesture_was_compositor_driven = 504 AnyThread().last_gesture_was_compositor_driven =
497 input_event_state == InputEventState::EVENT_CONSUMED_BY_COMPOSITOR; 505 input_event_state == InputEventState::EVENT_CONSUMED_BY_COMPOSITOR;
498 AnyThread().awaiting_touch_start_response = false; 506 AnyThread().awaiting_touch_start_response = false;
499 break; 507 break;
500 508
501 case blink::WebInputEvent::GestureFlingCancel: 509 case blink::WebInputEvent::GestureFlingCancel:
502 AnyThread().fling_compositor_escalation_deadline = base::TimeTicks(); 510 AnyThread().fling_compositor_escalation_deadline = base::TimeTicks();
503 break; 511 break;
504 512
505 case blink::WebInputEvent::GestureTapDown: 513 case blink::WebInputEvent::GestureTapDown:
506 case blink::WebInputEvent::GestureShowPress: 514 case blink::WebInputEvent::GestureShowPress:
507 case blink::WebInputEvent::GestureScrollEnd: 515 case blink::WebInputEvent::GestureScrollEnd:
508 // With no observable effect, these meta events do not indicate a 516 // With no observable effect, these meta events do not indicate a
509 // meaningful touchstart response and should not impact task priority. 517 // meaningful touchstart response and should not impact task priority.
510 break; 518 break;
511 519
512 default: 520 default:
513 AnyThread().awaiting_touch_start_response = false; 521 AnyThread().awaiting_touch_start_response = false;
514 break; 522 break;
515 } 523 }
516 } 524 }
517 525
518 // Avoid unnecessary policy updates, while a gesture is already in progress. 526 // Avoid unnecessary policy updates if the use case did not change.
519 if (!gesture_already_in_progress || 527 UseCase use_case = ComputeCurrentUseCase(now, &unused_policy_duration);
528
529 if (use_case != previous_use_case ||
520 was_awaiting_touch_start_response != 530 was_awaiting_touch_start_response !=
521 AnyThread().awaiting_touch_start_response) { 531 AnyThread().awaiting_touch_start_response) {
522 EnsureUrgentPolicyUpdatePostedOnMainThread(FROM_HERE); 532 EnsureUrgentPolicyUpdatePostedOnMainThread(FROM_HERE);
523 } 533 }
524 CompositorThreadOnly().last_input_type = type; 534 CompositorThreadOnly().last_input_type = type;
525 } 535 }
526 536
527 void RendererSchedulerImpl::DidHandleInputEventOnMainThread( 537 void RendererSchedulerImpl::DidHandleInputEventOnMainThread(
528 const blink::WebInputEvent& web_input_event) { 538 const blink::WebInputEvent& web_input_event) {
529 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), 539 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
792 } 802 }
793 803
794 // Tracing is done before the early out check, because it's quite possible we 804 // Tracing is done before the early out check, because it's quite possible we
795 // will otherwise miss this information in traces. 805 // will otherwise miss this information in traces.
796 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( 806 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(
797 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler", 807 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler",
798 this, AsValueLocked(now)); 808 this, AsValueLocked(now));
799 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "use_case", 809 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "use_case",
800 use_case); 810 use_case);
801 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), 811 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
812 "touchstart_expected_soon",
813 MainThreadOnly().touchstart_expected_soon);
814 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
815 "expensive_task_policy", expensive_task_policy);
816 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
802 "RendererScheduler.loading_tasks_seem_expensive", 817 "RendererScheduler.loading_tasks_seem_expensive",
803 MainThreadOnly().loading_tasks_seem_expensive); 818 MainThreadOnly().loading_tasks_seem_expensive);
804 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), 819 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
805 "RendererScheduler.timer_tasks_seem_expensive", 820 "RendererScheduler.timer_tasks_seem_expensive",
806 MainThreadOnly().timer_tasks_seem_expensive); 821 MainThreadOnly().timer_tasks_seem_expensive);
807 822
808 // TODO(alexclarke): Can we get rid of force update now? 823 // TODO(alexclarke): Can we get rid of force update now?
809 if (update_type == UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED && 824 if (update_type == UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED &&
810 new_policy == MainThreadOnly().current_policy) { 825 new_policy == MainThreadOnly().current_policy) {
811 return; 826 return;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
855 new_task_queue_policy.time_domain_type) { 870 new_task_queue_policy.time_domain_type) {
856 if (new_task_queue_policy.time_domain_type == TimeDomainType::THROTTLED) { 871 if (new_task_queue_policy.time_domain_type == TimeDomainType::THROTTLED) {
857 throttling_helper_->IncreaseThrottleRefCount(task_queue); 872 throttling_helper_->IncreaseThrottleRefCount(task_queue);
858 } else if (old_task_queue_policy.time_domain_type == 873 } else if (old_task_queue_policy.time_domain_type ==
859 TimeDomainType::THROTTLED) { 874 TimeDomainType::THROTTLED) {
860 throttling_helper_->DecreaseThrottleRefCount(task_queue); 875 throttling_helper_->DecreaseThrottleRefCount(task_queue);
861 } 876 }
862 } 877 }
863 } 878 }
864 879
865 bool RendererSchedulerImpl::InputSignalsSuggestGestureInProgress(
866 base::TimeTicks now) const {
867 base::TimeDelta unused_policy_duration;
868 switch (ComputeCurrentUseCase(now, &unused_policy_duration)) {
869 case UseCase::COMPOSITOR_GESTURE:
870 case UseCase::MAIN_THREAD_GESTURE:
871 case UseCase::SYNCHRONIZED_GESTURE:
872 case UseCase::TOUCHSTART:
873 return true;
874
875 default:
876 break;
877 }
878 return false;
879 }
880
881 RendererSchedulerImpl::UseCase RendererSchedulerImpl::ComputeCurrentUseCase( 880 RendererSchedulerImpl::UseCase RendererSchedulerImpl::ComputeCurrentUseCase(
882 base::TimeTicks now, 881 base::TimeTicks now,
883 base::TimeDelta* expected_use_case_duration) const { 882 base::TimeDelta* expected_use_case_duration) const {
884 any_thread_lock_.AssertAcquired(); 883 any_thread_lock_.AssertAcquired();
885 // Special case for flings. This is needed because we don't get notification 884 // Special case for flings. This is needed because we don't get notification
886 // of a fling ending (although we do for cancellation). 885 // of a fling ending (although we do for cancellation).
887 if (AnyThread().fling_compositor_escalation_deadline > now && 886 if (AnyThread().fling_compositor_escalation_deadline > now &&
888 !AnyThread().awaiting_touch_start_response) { 887 !AnyThread().awaiting_touch_start_response) {
889 *expected_use_case_duration = 888 *expected_use_case_duration =
890 AnyThread().fling_compositor_escalation_deadline - now; 889 AnyThread().fling_compositor_escalation_deadline - now;
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after
1269 } 1268 }
1270 MainThreadOnly().have_reported_blocking_intervention_since_navigation = 1269 MainThreadOnly().have_reported_blocking_intervention_since_navigation =
1271 true; 1270 true;
1272 BroadcastConsoleWarning( 1271 BroadcastConsoleWarning(
1273 "Deferred long-running timer task(s) to improve scrolling smoothness. " 1272 "Deferred long-running timer task(s) to improve scrolling smoothness. "
1274 "See crbug.com/574343."); 1273 "See crbug.com/574343.");
1275 } 1274 }
1276 } 1275 }
1277 1276
1278 } // namespace scheduler 1277 } // namespace scheduler
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698