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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
42 base::TimeDelta()), | 42 base::TimeDelta()), |
43 render_widget_scheduler_signals_(this), | 43 render_widget_scheduler_signals_(this), |
44 control_task_runner_(helper_.ControlTaskRunner()), | 44 control_task_runner_(helper_.ControlTaskRunner()), |
45 compositor_task_runner_( | 45 compositor_task_runner_( |
46 helper_.NewTaskQueue(TaskQueue::Spec("compositor_tq") | 46 helper_.NewTaskQueue(TaskQueue::Spec("compositor_tq") |
47 .SetShouldMonitorQuiescence(true))), | 47 .SetShouldMonitorQuiescence(true))), |
48 delayed_update_policy_runner_( | 48 delayed_update_policy_runner_( |
49 base::Bind(&RendererSchedulerImpl::UpdatePolicy, | 49 base::Bind(&RendererSchedulerImpl::UpdatePolicy, |
50 base::Unretained(this)), | 50 base::Unretained(this)), |
51 helper_.ControlTaskRunner()), | 51 helper_.ControlTaskRunner()), |
52 main_thread_only_(compositor_task_runner_, helper_.tick_clock()), | 52 main_thread_only_(compositor_task_runner_, |
| 53 helper_.task_queue_manager_delegate()), |
53 policy_may_need_update_(&any_thread_lock_), | 54 policy_may_need_update_(&any_thread_lock_), |
54 weak_factory_(this) { | 55 weak_factory_(this) { |
55 update_policy_closure_ = base::Bind(&RendererSchedulerImpl::UpdatePolicy, | 56 update_policy_closure_ = base::Bind(&RendererSchedulerImpl::UpdatePolicy, |
56 weak_factory_.GetWeakPtr()); | 57 weak_factory_.GetWeakPtr()); |
57 end_renderer_hidden_idle_period_closure_.Reset(base::Bind( | 58 end_renderer_hidden_idle_period_closure_.Reset(base::Bind( |
58 &RendererSchedulerImpl::EndIdlePeriod, weak_factory_.GetWeakPtr())); | 59 &RendererSchedulerImpl::EndIdlePeriod, weak_factory_.GetWeakPtr())); |
59 | 60 |
60 suspend_timers_when_backgrounded_closure_.Reset( | 61 suspend_timers_when_backgrounded_closure_.Reset( |
61 base::Bind(&RendererSchedulerImpl::SuspendTimerQueueWhenBackgrounded, | 62 base::Bind(&RendererSchedulerImpl::SuspendTimerQueueWhenBackgrounded, |
62 weak_factory_.GetWeakPtr())); | 63 weak_factory_.GetWeakPtr())); |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
243 } | 244 } |
244 } | 245 } |
245 | 246 |
246 void RendererSchedulerImpl::DidCommitFrameToCompositor() { | 247 void RendererSchedulerImpl::DidCommitFrameToCompositor() { |
247 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), | 248 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), |
248 "RendererSchedulerImpl::DidCommitFrameToCompositor"); | 249 "RendererSchedulerImpl::DidCommitFrameToCompositor"); |
249 helper_.CheckOnValidThread(); | 250 helper_.CheckOnValidThread(); |
250 if (helper_.IsShutdown()) | 251 if (helper_.IsShutdown()) |
251 return; | 252 return; |
252 | 253 |
253 base::TimeTicks now(helper_.tick_clock()->NowTicks()); | 254 base::TimeTicks now(helper_.task_queue_manager_delegate()->NowTicks()); |
254 if (now < MainThreadOnly().estimated_next_frame_begin) { | 255 if (now < MainThreadOnly().estimated_next_frame_begin) { |
255 // TODO(rmcilroy): Consider reducing the idle period based on the runtime of | 256 // TODO(rmcilroy): Consider reducing the idle period based on the runtime of |
256 // the next pending delayed tasks (as currently done in for long idle times) | 257 // the next pending delayed tasks (as currently done in for long idle times) |
257 idle_helper_.StartIdlePeriod( | 258 idle_helper_.StartIdlePeriod( |
258 IdleHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD, now, | 259 IdleHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD, now, |
259 MainThreadOnly().estimated_next_frame_begin); | 260 MainThreadOnly().estimated_next_frame_begin); |
260 } | 261 } |
261 | 262 |
262 MainThreadOnly().idle_time_estimator.DidCommitFrameToCompositor(); | 263 MainThreadOnly().idle_time_estimator.DidCommitFrameToCompositor(); |
263 } | 264 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
300 end_idle_when_hidden_delay); | 301 end_idle_when_hidden_delay); |
301 MainThreadOnly().renderer_hidden = true; | 302 MainThreadOnly().renderer_hidden = true; |
302 } else { | 303 } else { |
303 MainThreadOnly().renderer_hidden = false; | 304 MainThreadOnly().renderer_hidden = false; |
304 EndIdlePeriod(); | 305 EndIdlePeriod(); |
305 } | 306 } |
306 | 307 |
307 // TODO(alexclarke): Should we update policy here? | 308 // TODO(alexclarke): Should we update policy here? |
308 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( | 309 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( |
309 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler", | 310 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler", |
310 this, AsValue(helper_.tick_clock()->NowTicks())); | 311 this, AsValue(helper_.task_queue_manager_delegate()->NowTicks())); |
311 } | 312 } |
312 | 313 |
313 void RendererSchedulerImpl::SetHasVisibleRenderWidgetWithTouchHandler( | 314 void RendererSchedulerImpl::SetHasVisibleRenderWidgetWithTouchHandler( |
314 bool has_visible_render_widget_with_touch_handler) { | 315 bool has_visible_render_widget_with_touch_handler) { |
315 helper_.CheckOnValidThread(); | 316 helper_.CheckOnValidThread(); |
316 if (has_visible_render_widget_with_touch_handler == | 317 if (has_visible_render_widget_with_touch_handler == |
317 MainThreadOnly().has_visible_render_widget_with_touch_handler) | 318 MainThreadOnly().has_visible_render_widget_with_touch_handler) |
318 return; | 319 return; |
319 | 320 |
320 MainThreadOnly().has_visible_render_widget_with_touch_handler = | 321 MainThreadOnly().has_visible_render_widget_with_touch_handler = |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
400 "RendererSchedulerImpl::DidAnimateForInputOnCompositorThread"); | 401 "RendererSchedulerImpl::DidAnimateForInputOnCompositorThread"); |
401 UpdateForInputEventOnCompositorThread( | 402 UpdateForInputEventOnCompositorThread( |
402 blink::WebInputEvent::Undefined, | 403 blink::WebInputEvent::Undefined, |
403 InputEventState::EVENT_CONSUMED_BY_COMPOSITOR); | 404 InputEventState::EVENT_CONSUMED_BY_COMPOSITOR); |
404 } | 405 } |
405 | 406 |
406 void RendererSchedulerImpl::UpdateForInputEventOnCompositorThread( | 407 void RendererSchedulerImpl::UpdateForInputEventOnCompositorThread( |
407 blink::WebInputEvent::Type type, | 408 blink::WebInputEvent::Type type, |
408 InputEventState input_event_state) { | 409 InputEventState input_event_state) { |
409 base::AutoLock lock(any_thread_lock_); | 410 base::AutoLock lock(any_thread_lock_); |
410 base::TimeTicks now = helper_.tick_clock()->NowTicks(); | 411 base::TimeTicks now = helper_.task_queue_manager_delegate()->NowTicks(); |
411 | 412 |
412 // TODO(alexclarke): Move WebInputEventTraits where we can access it from here | 413 // TODO(alexclarke): Move WebInputEventTraits where we can access it from here |
413 // and record the name rather than the integer representation. | 414 // and record the name rather than the integer representation. |
414 TRACE_EVENT2(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), | 415 TRACE_EVENT2(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), |
415 "RendererSchedulerImpl::UpdateForInputEventOnCompositorThread", | 416 "RendererSchedulerImpl::UpdateForInputEventOnCompositorThread", |
416 "type", static_cast<int>(type), "input_event_state", | 417 "type", static_cast<int>(type), "input_event_state", |
417 InputEventStateToString(input_event_state)); | 418 InputEventStateToString(input_event_state)); |
418 | 419 |
419 bool gesture_already_in_progress = InputSignalsSuggestGestureInProgress(now); | 420 bool gesture_already_in_progress = InputSignalsSuggestGestureInProgress(now); |
420 bool was_awaiting_touch_start_response = | 421 bool was_awaiting_touch_start_response = |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
469 } | 470 } |
470 | 471 |
471 void RendererSchedulerImpl::DidHandleInputEventOnMainThread( | 472 void RendererSchedulerImpl::DidHandleInputEventOnMainThread( |
472 const blink::WebInputEvent& web_input_event) { | 473 const blink::WebInputEvent& web_input_event) { |
473 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), | 474 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), |
474 "RendererSchedulerImpl::DidHandleInputEventOnMainThread"); | 475 "RendererSchedulerImpl::DidHandleInputEventOnMainThread"); |
475 helper_.CheckOnValidThread(); | 476 helper_.CheckOnValidThread(); |
476 if (ShouldPrioritizeInputEvent(web_input_event)) { | 477 if (ShouldPrioritizeInputEvent(web_input_event)) { |
477 base::AutoLock lock(any_thread_lock_); | 478 base::AutoLock lock(any_thread_lock_); |
478 AnyThread().user_model.DidFinishProcessingInputEvent( | 479 AnyThread().user_model.DidFinishProcessingInputEvent( |
479 helper_.tick_clock()->NowTicks()); | 480 helper_.task_queue_manager_delegate()->NowTicks()); |
480 } | 481 } |
481 } | 482 } |
482 | 483 |
483 bool RendererSchedulerImpl::IsHighPriorityWorkAnticipated() { | 484 bool RendererSchedulerImpl::IsHighPriorityWorkAnticipated() { |
484 helper_.CheckOnValidThread(); | 485 helper_.CheckOnValidThread(); |
485 if (helper_.IsShutdown()) | 486 if (helper_.IsShutdown()) |
486 return false; | 487 return false; |
487 | 488 |
488 MaybeUpdatePolicy(); | 489 MaybeUpdatePolicy(); |
489 // The touchstart and main-thread gesture use cases indicate a strong | 490 // The touchstart and main-thread gesture use cases indicate a strong |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
560 base::AutoLock lock(any_thread_lock_); | 561 base::AutoLock lock(any_thread_lock_); |
561 UpdatePolicyLocked(UpdateType::FORCE_UPDATE); | 562 UpdatePolicyLocked(UpdateType::FORCE_UPDATE); |
562 } | 563 } |
563 | 564 |
564 void RendererSchedulerImpl::UpdatePolicyLocked(UpdateType update_type) { | 565 void RendererSchedulerImpl::UpdatePolicyLocked(UpdateType update_type) { |
565 helper_.CheckOnValidThread(); | 566 helper_.CheckOnValidThread(); |
566 any_thread_lock_.AssertAcquired(); | 567 any_thread_lock_.AssertAcquired(); |
567 if (helper_.IsShutdown()) | 568 if (helper_.IsShutdown()) |
568 return; | 569 return; |
569 | 570 |
570 base::TimeTicks now = helper_.tick_clock()->NowTicks(); | 571 base::TimeTicks now = helper_.task_queue_manager_delegate()->NowTicks(); |
571 policy_may_need_update_.SetWhileLocked(false); | 572 policy_may_need_update_.SetWhileLocked(false); |
572 | 573 |
573 base::TimeDelta expected_use_case_duration; | 574 base::TimeDelta expected_use_case_duration; |
574 UseCase use_case = ComputeCurrentUseCase(now, &expected_use_case_duration); | 575 UseCase use_case = ComputeCurrentUseCase(now, &expected_use_case_duration); |
575 MainThreadOnly().current_use_case = use_case; | 576 MainThreadOnly().current_use_case = use_case; |
576 | 577 |
577 base::TimeDelta touchstart_expected_flag_valid_for_duration; | 578 base::TimeDelta touchstart_expected_flag_valid_for_duration; |
578 bool touchstart_expected_soon = false; | 579 bool touchstart_expected_soon = false; |
579 if (MainThreadOnly().has_visible_render_widget_with_touch_handler) { | 580 if (MainThreadOnly().has_visible_render_widget_with_touch_handler) { |
580 touchstart_expected_soon = AnyThread().user_model.IsGestureExpectedSoon( | 581 touchstart_expected_soon = AnyThread().user_model.IsGestureExpectedSoon( |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
819 base::AutoLock lock(any_thread_lock_); | 820 base::AutoLock lock(any_thread_lock_); |
820 return AsValueLocked(optional_now); | 821 return AsValueLocked(optional_now); |
821 } | 822 } |
822 | 823 |
823 scoped_refptr<base::trace_event::ConvertableToTraceFormat> | 824 scoped_refptr<base::trace_event::ConvertableToTraceFormat> |
824 RendererSchedulerImpl::AsValueLocked(base::TimeTicks optional_now) const { | 825 RendererSchedulerImpl::AsValueLocked(base::TimeTicks optional_now) const { |
825 helper_.CheckOnValidThread(); | 826 helper_.CheckOnValidThread(); |
826 any_thread_lock_.AssertAcquired(); | 827 any_thread_lock_.AssertAcquired(); |
827 | 828 |
828 if (optional_now.is_null()) | 829 if (optional_now.is_null()) |
829 optional_now = helper_.tick_clock()->NowTicks(); | 830 optional_now = helper_.task_queue_manager_delegate()->NowTicks(); |
830 scoped_refptr<base::trace_event::TracedValue> state = | 831 scoped_refptr<base::trace_event::TracedValue> state = |
831 new base::trace_event::TracedValue(); | 832 new base::trace_event::TracedValue(); |
832 | 833 |
833 state->SetBoolean( | 834 state->SetBoolean( |
834 "has_visible_render_widget_with_touch_handler", | 835 "has_visible_render_widget_with_touch_handler", |
835 MainThreadOnly().has_visible_render_widget_with_touch_handler); | 836 MainThreadOnly().has_visible_render_widget_with_touch_handler); |
836 state->SetString("current_use_case", | 837 state->SetString("current_use_case", |
837 UseCaseToString(MainThreadOnly().current_use_case)); | 838 UseCaseToString(MainThreadOnly().current_use_case)); |
838 state->SetBoolean("loading_tasks_seem_expensive", | 839 state->SetBoolean("loading_tasks_seem_expensive", |
839 MainThreadOnly().loading_tasks_seem_expensive); | 840 MainThreadOnly().loading_tasks_seem_expensive); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
891 } | 892 } |
892 | 893 |
893 void RendererSchedulerImpl::OnIdlePeriodStarted() { | 894 void RendererSchedulerImpl::OnIdlePeriodStarted() { |
894 base::AutoLock lock(any_thread_lock_); | 895 base::AutoLock lock(any_thread_lock_); |
895 AnyThread().in_idle_period = true; | 896 AnyThread().in_idle_period = true; |
896 UpdatePolicyLocked(UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED); | 897 UpdatePolicyLocked(UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED); |
897 } | 898 } |
898 | 899 |
899 void RendererSchedulerImpl::OnIdlePeriodEnded() { | 900 void RendererSchedulerImpl::OnIdlePeriodEnded() { |
900 base::AutoLock lock(any_thread_lock_); | 901 base::AutoLock lock(any_thread_lock_); |
901 AnyThread().last_idle_period_end_time = helper_.tick_clock()->NowTicks(); | 902 AnyThread().last_idle_period_end_time = |
| 903 helper_.task_queue_manager_delegate()->NowTicks(); |
902 AnyThread().in_idle_period = false; | 904 AnyThread().in_idle_period = false; |
903 UpdatePolicyLocked(UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED); | 905 UpdatePolicyLocked(UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED); |
904 } | 906 } |
905 | 907 |
906 void RendererSchedulerImpl::AddPendingNavigation() { | 908 void RendererSchedulerImpl::AddPendingNavigation() { |
907 helper_.CheckOnValidThread(); | 909 helper_.CheckOnValidThread(); |
908 MainThreadOnly().navigation_task_expected_count++; | 910 MainThreadOnly().navigation_task_expected_count++; |
909 UpdatePolicy(); | 911 UpdatePolicy(); |
910 } | 912 } |
911 | 913 |
912 void RendererSchedulerImpl::RemovePendingNavigation() { | 914 void RendererSchedulerImpl::RemovePendingNavigation() { |
913 helper_.CheckOnValidThread(); | 915 helper_.CheckOnValidThread(); |
914 DCHECK_GT(MainThreadOnly().navigation_task_expected_count, 0); | 916 DCHECK_GT(MainThreadOnly().navigation_task_expected_count, 0); |
915 if (MainThreadOnly().navigation_task_expected_count > 0) | 917 if (MainThreadOnly().navigation_task_expected_count > 0) |
916 MainThreadOnly().navigation_task_expected_count--; | 918 MainThreadOnly().navigation_task_expected_count--; |
917 UpdatePolicy(); | 919 UpdatePolicy(); |
918 } | 920 } |
919 | 921 |
920 void RendererSchedulerImpl::OnNavigationStarted() { | 922 void RendererSchedulerImpl::OnNavigationStarted() { |
921 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), | 923 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), |
922 "RendererSchedulerImpl::OnNavigationStarted"); | 924 "RendererSchedulerImpl::OnNavigationStarted"); |
923 base::AutoLock lock(any_thread_lock_); | 925 base::AutoLock lock(any_thread_lock_); |
924 AnyThread().rails_loading_priority_deadline = | 926 AnyThread().rails_loading_priority_deadline = |
925 helper_.tick_clock()->NowTicks() + | 927 helper_.task_queue_manager_delegate()->NowTicks() + |
926 base::TimeDelta::FromMilliseconds( | 928 base::TimeDelta::FromMilliseconds( |
927 kRailsInitialLoadingPrioritizationMillis); | 929 kRailsInitialLoadingPrioritizationMillis); |
928 ResetForNavigationLocked(); | 930 ResetForNavigationLocked(); |
929 } | 931 } |
930 | 932 |
931 bool RendererSchedulerImpl::HadAnIdlePeriodRecently(base::TimeTicks now) const { | 933 bool RendererSchedulerImpl::HadAnIdlePeriodRecently(base::TimeTicks now) const { |
932 return (now - AnyThread().last_idle_period_end_time) <= | 934 return (now - AnyThread().last_idle_period_end_time) <= |
933 base::TimeDelta::FromMilliseconds( | 935 base::TimeDelta::FromMilliseconds( |
934 kIdlePeriodStarvationThresholdMillis); | 936 kIdlePeriodStarvationThresholdMillis); |
935 } | 937 } |
(...skipping 15 matching lines...) Expand all Loading... |
951 MainThreadOnly().timer_queue_suspended_when_backgrounded = false; | 953 MainThreadOnly().timer_queue_suspended_when_backgrounded = false; |
952 ForceUpdatePolicy(); | 954 ForceUpdatePolicy(); |
953 } | 955 } |
954 | 956 |
955 void RendererSchedulerImpl::ResetForNavigationLocked() { | 957 void RendererSchedulerImpl::ResetForNavigationLocked() { |
956 helper_.CheckOnValidThread(); | 958 helper_.CheckOnValidThread(); |
957 any_thread_lock_.AssertAcquired(); | 959 any_thread_lock_.AssertAcquired(); |
958 MainThreadOnly().loading_task_cost_estimator.Clear(); | 960 MainThreadOnly().loading_task_cost_estimator.Clear(); |
959 MainThreadOnly().timer_task_cost_estimator.Clear(); | 961 MainThreadOnly().timer_task_cost_estimator.Clear(); |
960 MainThreadOnly().idle_time_estimator.Clear(); | 962 MainThreadOnly().idle_time_estimator.Clear(); |
961 AnyThread().user_model.Reset(helper_.tick_clock()->NowTicks()); | 963 AnyThread().user_model.Reset( |
| 964 helper_.task_queue_manager_delegate()->NowTicks()); |
962 MainThreadOnly().have_seen_a_begin_main_frame = false; | 965 MainThreadOnly().have_seen_a_begin_main_frame = false; |
963 UpdatePolicyLocked(UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED); | 966 UpdatePolicyLocked(UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED); |
964 } | 967 } |
965 | 968 |
| 969 double RendererSchedulerImpl::currentTime() const { |
| 970 return helper_.task_queue_manager_delegate()->currentTime(); |
| 971 } |
| 972 |
| 973 double RendererSchedulerImpl::monotonicallyIncreasingTime() const { |
| 974 return helper_.task_queue_manager_delegate()->NowTicks().ToInternalValue() / |
| 975 static_cast<double>(base::Time::kMicrosecondsPerSecond); |
| 976 } |
| 977 |
966 } // namespace scheduler | 978 } // namespace scheduler |
OLD | NEW |