| 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/trace_event/trace_event.h" | 10 #include "base/trace_event/trace_event.h" |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 // The run time of loading tasks is strongly bimodal. The vast majority are | 22 // The run time of loading tasks is strongly bimodal. The vast majority are |
| 23 // very cheap, but there are usually a handful of very expensive tasks (e.g ~1 | 23 // very cheap, but there are usually a handful of very expensive tasks (e.g ~1 |
| 24 // second on a mobile device) so we take a very pesimistic view when estimating | 24 // second on a mobile device) so we take a very pesimistic view when estimating |
| 25 // the cost of loading tasks. | 25 // the cost of loading tasks. |
| 26 const int kLoadingTaskEstimationSampleCount = 1000; | 26 const int kLoadingTaskEstimationSampleCount = 1000; |
| 27 const double kLoadingTaskEstimationPercentile = 99; | 27 const double kLoadingTaskEstimationPercentile = 99; |
| 28 const int kTimerTaskEstimationSampleCount = 1000; | 28 const int kTimerTaskEstimationSampleCount = 1000; |
| 29 const double kTimerTaskEstimationPercentile = 99; | 29 const double kTimerTaskEstimationPercentile = 99; |
| 30 const int kShortIdlePeriodDurationSampleCount = 10; | 30 const int kShortIdlePeriodDurationSampleCount = 10; |
| 31 const double kShortIdlePeriodDurationPercentile = 50; | 31 const double kShortIdlePeriodDurationPercentile = 50; |
| 32 } | 32 // Amount of idle time left in a frame (as a ratio of the vsync interval) above |
| 33 // which main thread compositing can be considered fast. |
| 34 const double kFastCompositingIdleTimeThreshold = .2; |
| 35 } // namespace |
| 33 | 36 |
| 34 RendererSchedulerImpl::RendererSchedulerImpl( | 37 RendererSchedulerImpl::RendererSchedulerImpl( |
| 35 scoped_refptr<SchedulerTqmDelegate> main_task_runner) | 38 scoped_refptr<SchedulerTqmDelegate> main_task_runner) |
| 36 : helper_(main_task_runner, | 39 : helper_(main_task_runner, |
| 37 "renderer.scheduler", | 40 "renderer.scheduler", |
| 38 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), | 41 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), |
| 39 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler.debug")), | 42 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler.debug")), |
| 40 idle_helper_(&helper_, | 43 idle_helper_(&helper_, |
| 41 this, | 44 this, |
| 42 "renderer.scheduler", | 45 "renderer.scheduler", |
| (...skipping 607 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 650 } | 653 } |
| 651 | 654 |
| 652 if (new_policy_duration > base::TimeDelta()) { | 655 if (new_policy_duration > base::TimeDelta()) { |
| 653 MainThreadOnly().current_policy_expiration_time = now + new_policy_duration; | 656 MainThreadOnly().current_policy_expiration_time = now + new_policy_duration; |
| 654 delayed_update_policy_runner_.SetDeadline(FROM_HERE, new_policy_duration, | 657 delayed_update_policy_runner_.SetDeadline(FROM_HERE, new_policy_duration, |
| 655 now); | 658 now); |
| 656 } else { | 659 } else { |
| 657 MainThreadOnly().current_policy_expiration_time = base::TimeTicks(); | 660 MainThreadOnly().current_policy_expiration_time = base::TimeTicks(); |
| 658 } | 661 } |
| 659 | 662 |
| 663 // Avoid prioritizing main thread compositing (e.g., rAF) if it is extremely |
| 664 // slow, because that can cause starvation in other task sources. |
| 665 bool main_thread_compositing_is_fast = |
| 666 MainThreadOnly().idle_time_estimator.GetExpectedIdleDuration( |
| 667 MainThreadOnly().compositor_frame_interval) > |
| 668 MainThreadOnly().compositor_frame_interval * |
| 669 kFastCompositingIdleTimeThreshold; |
| 670 |
| 660 Policy new_policy; | 671 Policy new_policy; |
| 661 ExpensiveTaskPolicy expensive_task_policy = ExpensiveTaskPolicy::RUN; | 672 ExpensiveTaskPolicy expensive_task_policy = ExpensiveTaskPolicy::RUN; |
| 662 switch (use_case) { | 673 switch (use_case) { |
| 663 case UseCase::COMPOSITOR_GESTURE: | 674 case UseCase::COMPOSITOR_GESTURE: |
| 664 if (touchstart_expected_soon) { | 675 if (touchstart_expected_soon) { |
| 665 expensive_task_policy = ExpensiveTaskPolicy::BLOCK; | 676 expensive_task_policy = ExpensiveTaskPolicy::BLOCK; |
| 666 new_policy.compositor_queue_policy.priority = TaskQueue::HIGH_PRIORITY; | 677 new_policy.compositor_queue_policy.priority = TaskQueue::HIGH_PRIORITY; |
| 667 } else { | 678 } else { |
| 668 // What we really want to do is priorize loading tasks, but that doesn't | 679 // What we really want to do is priorize loading tasks, but that doesn't |
| 669 // seem to be safe. Instead we do that by proxy by deprioritizing | 680 // seem to be safe. Instead we do that by proxy by deprioritizing |
| 670 // compositor tasks. This should be safe since we've already gone to the | 681 // compositor tasks. This should be safe since we've already gone to the |
| 671 // pain of fixing ordering issues with them. | 682 // pain of fixing ordering issues with them. |
| 672 new_policy.compositor_queue_policy.priority = | 683 new_policy.compositor_queue_policy.priority = |
| 673 TaskQueue::BEST_EFFORT_PRIORITY; | 684 TaskQueue::BEST_EFFORT_PRIORITY; |
| 674 } | 685 } |
| 675 break; | 686 break; |
| 676 | 687 |
| 677 case UseCase::SYNCHRONIZED_GESTURE: | 688 case UseCase::SYNCHRONIZED_GESTURE: |
| 678 new_policy.compositor_queue_policy.priority = TaskQueue::HIGH_PRIORITY; | 689 new_policy.compositor_queue_policy.priority = |
| 690 main_thread_compositing_is_fast ? TaskQueue::HIGH_PRIORITY |
| 691 : TaskQueue::NORMAL_PRIORITY; |
| 679 if (touchstart_expected_soon) { | 692 if (touchstart_expected_soon) { |
| 680 expensive_task_policy = ExpensiveTaskPolicy::BLOCK; | 693 expensive_task_policy = ExpensiveTaskPolicy::BLOCK; |
| 681 } else { | 694 } else { |
| 682 expensive_task_policy = ExpensiveTaskPolicy::THROTTLE; | 695 expensive_task_policy = ExpensiveTaskPolicy::THROTTLE; |
| 683 } | 696 } |
| 684 break; | 697 break; |
| 685 | 698 |
| 686 case UseCase::MAIN_THREAD_GESTURE: | 699 case UseCase::MAIN_THREAD_GESTURE: |
| 687 // In main thread gestures we don't have perfect knowledge about which | 700 // In main thread gestures we don't have perfect knowledge about which |
| 688 // things we should be prioritizing, so we don't attempt to block | 701 // things we should be prioritizing, so we don't attempt to block |
| 689 // expensive tasks because we don't know whether they were integral to the | 702 // expensive tasks because we don't know whether they were integral to the |
| 690 // page's functionality or not. | 703 // page's functionality or not. |
| 691 new_policy.compositor_queue_policy.priority = TaskQueue::HIGH_PRIORITY; | 704 new_policy.compositor_queue_policy.priority = |
| 705 main_thread_compositing_is_fast ? TaskQueue::HIGH_PRIORITY |
| 706 : TaskQueue::NORMAL_PRIORITY; |
| 692 break; | 707 break; |
| 693 | 708 |
| 694 case UseCase::TOUCHSTART: | 709 case UseCase::TOUCHSTART: |
| 695 new_policy.compositor_queue_policy.priority = TaskQueue::HIGH_PRIORITY; | 710 new_policy.compositor_queue_policy.priority = TaskQueue::HIGH_PRIORITY; |
| 696 new_policy.loading_queue_policy.is_enabled = false; | 711 new_policy.loading_queue_policy.is_enabled = false; |
| 697 new_policy.timer_queue_policy.is_enabled = false; | 712 new_policy.timer_queue_policy.is_enabled = false; |
| 698 // NOTE this is a nop due to the above. | 713 // NOTE this is a nop due to the above. |
| 699 expensive_task_policy = ExpensiveTaskPolicy::BLOCK; | 714 expensive_task_policy = ExpensiveTaskPolicy::BLOCK; |
| 700 break; | 715 break; |
| 701 | 716 |
| (...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1223 } | 1238 } |
| 1224 MainThreadOnly().have_reported_blocking_intervention_since_navigation = | 1239 MainThreadOnly().have_reported_blocking_intervention_since_navigation = |
| 1225 true; | 1240 true; |
| 1226 BroadcastConsoleWarning( | 1241 BroadcastConsoleWarning( |
| 1227 "Deferred long-running timer task(s) to improve scrolling smoothness. " | 1242 "Deferred long-running timer task(s) to improve scrolling smoothness. " |
| 1228 "See crbug.com/574343."); | 1243 "See crbug.com/574343."); |
| 1229 } | 1244 } |
| 1230 } | 1245 } |
| 1231 | 1246 |
| 1232 } // namespace scheduler | 1247 } // namespace scheduler |
| OLD | NEW |