| OLD | NEW |
| 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 12 matching lines...) Expand all Loading... |
| 23 // The run time of loading tasks is strongly bimodal. The vast majority are | 23 // The run time of loading tasks is strongly bimodal. The vast majority are |
| 24 // very cheap, but there are usually a handful of very expensive tasks (e.g ~1 | 24 // very cheap, but there are usually a handful of very expensive tasks (e.g ~1 |
| 25 // second on a mobile device) so we take a very pesimistic view when estimating | 25 // second on a mobile device) so we take a very pesimistic view when estimating |
| 26 // the cost of loading tasks. | 26 // the cost of loading tasks. |
| 27 const int kLoadingTaskEstimationSampleCount = 1000; | 27 const int kLoadingTaskEstimationSampleCount = 1000; |
| 28 const double kLoadingTaskEstimationPercentile = 99; | 28 const double kLoadingTaskEstimationPercentile = 99; |
| 29 const int kTimerTaskEstimationSampleCount = 1000; | 29 const int kTimerTaskEstimationSampleCount = 1000; |
| 30 const double kTimerTaskEstimationPercentile = 99; | 30 const double kTimerTaskEstimationPercentile = 99; |
| 31 const int kShortIdlePeriodDurationSampleCount = 10; | 31 const int kShortIdlePeriodDurationSampleCount = 10; |
| 32 const double kShortIdlePeriodDurationPercentile = 50; | 32 const double kShortIdlePeriodDurationPercentile = 50; |
| 33 // Amount of idle time left in a frame (as a ratio of the vsync interval) above |
| 34 // which main thread compositing can be considered fast. |
| 35 const double kFastCompositingIdleTimeThreshold = .2; |
| 33 } // namespace | 36 } // namespace |
| 34 | 37 |
| 35 RendererSchedulerImpl::RendererSchedulerImpl( | 38 RendererSchedulerImpl::RendererSchedulerImpl( |
| 36 scoped_refptr<SchedulerTqmDelegate> main_task_runner) | 39 scoped_refptr<SchedulerTqmDelegate> main_task_runner) |
| 37 : helper_(main_task_runner, | 40 : helper_(main_task_runner, |
| 38 "renderer.scheduler", | 41 "renderer.scheduler", |
| 39 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), | 42 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), |
| 40 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler.debug")), | 43 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler.debug")), |
| 41 idle_helper_(&helper_, | 44 idle_helper_(&helper_, |
| 42 this, | 45 this, |
| (...skipping 629 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 672 } | 675 } |
| 673 | 676 |
| 674 if (new_policy_duration > base::TimeDelta()) { | 677 if (new_policy_duration > base::TimeDelta()) { |
| 675 MainThreadOnly().current_policy_expiration_time = now + new_policy_duration; | 678 MainThreadOnly().current_policy_expiration_time = now + new_policy_duration; |
| 676 delayed_update_policy_runner_.SetDeadline(FROM_HERE, new_policy_duration, | 679 delayed_update_policy_runner_.SetDeadline(FROM_HERE, new_policy_duration, |
| 677 now); | 680 now); |
| 678 } else { | 681 } else { |
| 679 MainThreadOnly().current_policy_expiration_time = base::TimeTicks(); | 682 MainThreadOnly().current_policy_expiration_time = base::TimeTicks(); |
| 680 } | 683 } |
| 681 | 684 |
| 685 // Avoid prioritizing main thread compositing (e.g., rAF) if it is extremely |
| 686 // slow, because that can cause starvation in other task sources. |
| 687 bool main_thread_compositing_is_fast = |
| 688 MainThreadOnly().idle_time_estimator.GetExpectedIdleDuration( |
| 689 MainThreadOnly().compositor_frame_interval) > |
| 690 MainThreadOnly().compositor_frame_interval * |
| 691 kFastCompositingIdleTimeThreshold; |
| 692 |
| 682 Policy new_policy; | 693 Policy new_policy; |
| 683 ExpensiveTaskPolicy expensive_task_policy = ExpensiveTaskPolicy::RUN; | 694 ExpensiveTaskPolicy expensive_task_policy = ExpensiveTaskPolicy::RUN; |
| 684 switch (use_case) { | 695 switch (use_case) { |
| 685 case UseCase::COMPOSITOR_GESTURE: | 696 case UseCase::COMPOSITOR_GESTURE: |
| 686 if (touchstart_expected_soon) { | 697 if (touchstart_expected_soon) { |
| 687 expensive_task_policy = ExpensiveTaskPolicy::BLOCK; | 698 expensive_task_policy = ExpensiveTaskPolicy::BLOCK; |
| 688 new_policy.compositor_queue_policy.priority = TaskQueue::HIGH_PRIORITY; | 699 new_policy.compositor_queue_policy.priority = TaskQueue::HIGH_PRIORITY; |
| 689 } else { | 700 } else { |
| 690 // What we really want to do is priorize loading tasks, but that doesn't | 701 // What we really want to do is priorize loading tasks, but that doesn't |
| 691 // seem to be safe. Instead we do that by proxy by deprioritizing | 702 // seem to be safe. Instead we do that by proxy by deprioritizing |
| 692 // compositor tasks. This should be safe since we've already gone to the | 703 // compositor tasks. This should be safe since we've already gone to the |
| 693 // pain of fixing ordering issues with them. | 704 // pain of fixing ordering issues with them. |
| 694 new_policy.compositor_queue_policy.priority = | 705 new_policy.compositor_queue_policy.priority = |
| 695 TaskQueue::BEST_EFFORT_PRIORITY; | 706 TaskQueue::BEST_EFFORT_PRIORITY; |
| 696 } | 707 } |
| 697 break; | 708 break; |
| 698 | 709 |
| 699 case UseCase::SYNCHRONIZED_GESTURE: | 710 case UseCase::SYNCHRONIZED_GESTURE: |
| 700 new_policy.compositor_queue_policy.priority = TaskQueue::HIGH_PRIORITY; | 711 new_policy.compositor_queue_policy.priority = |
| 712 main_thread_compositing_is_fast ? TaskQueue::HIGH_PRIORITY |
| 713 : TaskQueue::NORMAL_PRIORITY; |
| 701 if (touchstart_expected_soon) { | 714 if (touchstart_expected_soon) { |
| 702 expensive_task_policy = ExpensiveTaskPolicy::BLOCK; | 715 expensive_task_policy = ExpensiveTaskPolicy::BLOCK; |
| 703 } else { | 716 } else { |
| 704 expensive_task_policy = ExpensiveTaskPolicy::THROTTLE; | 717 expensive_task_policy = ExpensiveTaskPolicy::THROTTLE; |
| 705 } | 718 } |
| 706 break; | 719 break; |
| 707 | 720 |
| 708 case UseCase::MAIN_THREAD_GESTURE: | 721 case UseCase::MAIN_THREAD_GESTURE: |
| 709 // In main thread gestures we don't have perfect knowledge about which | 722 // In main thread gestures we don't have perfect knowledge about which |
| 710 // things we should be prioritizing, so we don't attempt to block | 723 // things we should be prioritizing, so we don't attempt to block |
| 711 // expensive tasks because we don't know whether they were integral to the | 724 // expensive tasks because we don't know whether they were integral to the |
| 712 // page's functionality or not. | 725 // page's functionality or not. |
| 713 new_policy.compositor_queue_policy.priority = TaskQueue::HIGH_PRIORITY; | 726 new_policy.compositor_queue_policy.priority = |
| 727 main_thread_compositing_is_fast ? TaskQueue::HIGH_PRIORITY |
| 728 : TaskQueue::NORMAL_PRIORITY; |
| 714 break; | 729 break; |
| 715 | 730 |
| 716 case UseCase::TOUCHSTART: | 731 case UseCase::TOUCHSTART: |
| 717 new_policy.compositor_queue_policy.priority = TaskQueue::HIGH_PRIORITY; | 732 new_policy.compositor_queue_policy.priority = TaskQueue::HIGH_PRIORITY; |
| 718 new_policy.loading_queue_policy.is_enabled = false; | 733 new_policy.loading_queue_policy.is_enabled = false; |
| 719 new_policy.timer_queue_policy.is_enabled = false; | 734 new_policy.timer_queue_policy.is_enabled = false; |
| 720 // NOTE this is a nop due to the above. | 735 // NOTE this is a nop due to the above. |
| 721 expensive_task_policy = ExpensiveTaskPolicy::BLOCK; | 736 expensive_task_policy = ExpensiveTaskPolicy::BLOCK; |
| 722 break; | 737 break; |
| 723 | 738 |
| (...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1245 } | 1260 } |
| 1246 MainThreadOnly().have_reported_blocking_intervention_since_navigation = | 1261 MainThreadOnly().have_reported_blocking_intervention_since_navigation = |
| 1247 true; | 1262 true; |
| 1248 BroadcastConsoleWarning( | 1263 BroadcastConsoleWarning( |
| 1249 "Deferred long-running timer task(s) to improve scrolling smoothness. " | 1264 "Deferred long-running timer task(s) to improve scrolling smoothness. " |
| 1250 "See crbug.com/574343."); | 1265 "See crbug.com/574343."); |
| 1251 } | 1266 } |
| 1252 } | 1267 } |
| 1253 | 1268 |
| 1254 } // namespace scheduler | 1269 } // namespace scheduler |
| OLD | NEW |