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

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

Issue 1411843008: Make blink platform time consistent with the timer virtual time (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix CachingCorrectnessTest Created 5 years, 1 month 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/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
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_.scheduler_tqm_delegate().get()),
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 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 } 246 }
246 } 247 }
247 248
248 void RendererSchedulerImpl::DidCommitFrameToCompositor() { 249 void RendererSchedulerImpl::DidCommitFrameToCompositor() {
249 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), 250 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
250 "RendererSchedulerImpl::DidCommitFrameToCompositor"); 251 "RendererSchedulerImpl::DidCommitFrameToCompositor");
251 helper_.CheckOnValidThread(); 252 helper_.CheckOnValidThread();
252 if (helper_.IsShutdown()) 253 if (helper_.IsShutdown())
253 return; 254 return;
254 255
255 base::TimeTicks now(helper_.tick_clock()->NowTicks()); 256 base::TimeTicks now(helper_.scheduler_tqm_delegate()->NowTicks());
256 if (now < MainThreadOnly().estimated_next_frame_begin) { 257 if (now < MainThreadOnly().estimated_next_frame_begin) {
257 // TODO(rmcilroy): Consider reducing the idle period based on the runtime of 258 // TODO(rmcilroy): Consider reducing the idle period based on the runtime of
258 // the next pending delayed tasks (as currently done in for long idle times) 259 // the next pending delayed tasks (as currently done in for long idle times)
259 idle_helper_.StartIdlePeriod( 260 idle_helper_.StartIdlePeriod(
260 IdleHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD, now, 261 IdleHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD, now,
261 MainThreadOnly().estimated_next_frame_begin); 262 MainThreadOnly().estimated_next_frame_begin);
262 } 263 }
263 264
264 MainThreadOnly().idle_time_estimator.DidCommitFrameToCompositor(); 265 MainThreadOnly().idle_time_estimator.DidCommitFrameToCompositor();
265 } 266 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 end_idle_when_hidden_delay); 303 end_idle_when_hidden_delay);
303 MainThreadOnly().renderer_hidden = true; 304 MainThreadOnly().renderer_hidden = true;
304 } else { 305 } else {
305 MainThreadOnly().renderer_hidden = false; 306 MainThreadOnly().renderer_hidden = false;
306 EndIdlePeriod(); 307 EndIdlePeriod();
307 } 308 }
308 309
309 // TODO(alexclarke): Should we update policy here? 310 // TODO(alexclarke): Should we update policy here?
310 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( 311 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(
311 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler", 312 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler",
312 this, AsValue(helper_.tick_clock()->NowTicks())); 313 this, AsValue(helper_.scheduler_tqm_delegate()->NowTicks()));
313 } 314 }
314 315
315 void RendererSchedulerImpl::SetHasVisibleRenderWidgetWithTouchHandler( 316 void RendererSchedulerImpl::SetHasVisibleRenderWidgetWithTouchHandler(
316 bool has_visible_render_widget_with_touch_handler) { 317 bool has_visible_render_widget_with_touch_handler) {
317 helper_.CheckOnValidThread(); 318 helper_.CheckOnValidThread();
318 if (has_visible_render_widget_with_touch_handler == 319 if (has_visible_render_widget_with_touch_handler ==
319 MainThreadOnly().has_visible_render_widget_with_touch_handler) 320 MainThreadOnly().has_visible_render_widget_with_touch_handler)
320 return; 321 return;
321 322
322 MainThreadOnly().has_visible_render_widget_with_touch_handler = 323 MainThreadOnly().has_visible_render_widget_with_touch_handler =
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 return; 396 return;
396 397
397 UpdateForInputEventOnCompositorThread(web_input_event.type, event_state); 398 UpdateForInputEventOnCompositorThread(web_input_event.type, event_state);
398 } 399 }
399 400
400 void RendererSchedulerImpl::DidAnimateForInputOnCompositorThread() { 401 void RendererSchedulerImpl::DidAnimateForInputOnCompositorThread() {
401 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), 402 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
402 "RendererSchedulerImpl::DidAnimateForInputOnCompositorThread"); 403 "RendererSchedulerImpl::DidAnimateForInputOnCompositorThread");
403 base::AutoLock lock(any_thread_lock_); 404 base::AutoLock lock(any_thread_lock_);
404 AnyThread().fling_compositor_escalation_deadline = 405 AnyThread().fling_compositor_escalation_deadline =
405 helper_.tick_clock()->NowTicks() + 406 helper_.scheduler_tqm_delegate()->NowTicks() +
406 base::TimeDelta::FromMilliseconds(kFlingEscalationLimitMillis); 407 base::TimeDelta::FromMilliseconds(kFlingEscalationLimitMillis);
407 } 408 }
408 409
409 void RendererSchedulerImpl::UpdateForInputEventOnCompositorThread( 410 void RendererSchedulerImpl::UpdateForInputEventOnCompositorThread(
410 blink::WebInputEvent::Type type, 411 blink::WebInputEvent::Type type,
411 InputEventState input_event_state) { 412 InputEventState input_event_state) {
412 base::AutoLock lock(any_thread_lock_); 413 base::AutoLock lock(any_thread_lock_);
413 base::TimeTicks now = helper_.tick_clock()->NowTicks(); 414 base::TimeTicks now = helper_.scheduler_tqm_delegate()->NowTicks();
414 415
415 // TODO(alexclarke): Move WebInputEventTraits where we can access it from here 416 // TODO(alexclarke): Move WebInputEventTraits where we can access it from here
416 // and record the name rather than the integer representation. 417 // and record the name rather than the integer representation.
417 TRACE_EVENT2(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), 418 TRACE_EVENT2(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
418 "RendererSchedulerImpl::UpdateForInputEventOnCompositorThread", 419 "RendererSchedulerImpl::UpdateForInputEventOnCompositorThread",
419 "type", static_cast<int>(type), "input_event_state", 420 "type", static_cast<int>(type), "input_event_state",
420 InputEventStateToString(input_event_state)); 421 InputEventStateToString(input_event_state));
421 422
422 bool gesture_already_in_progress = InputSignalsSuggestGestureInProgress(now); 423 bool gesture_already_in_progress = InputSignalsSuggestGestureInProgress(now);
423 bool was_awaiting_touch_start_response = 424 bool was_awaiting_touch_start_response =
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
485 } 486 }
486 487
487 void RendererSchedulerImpl::DidHandleInputEventOnMainThread( 488 void RendererSchedulerImpl::DidHandleInputEventOnMainThread(
488 const blink::WebInputEvent& web_input_event) { 489 const blink::WebInputEvent& web_input_event) {
489 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), 490 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
490 "RendererSchedulerImpl::DidHandleInputEventOnMainThread"); 491 "RendererSchedulerImpl::DidHandleInputEventOnMainThread");
491 helper_.CheckOnValidThread(); 492 helper_.CheckOnValidThread();
492 if (ShouldPrioritizeInputEvent(web_input_event)) { 493 if (ShouldPrioritizeInputEvent(web_input_event)) {
493 base::AutoLock lock(any_thread_lock_); 494 base::AutoLock lock(any_thread_lock_);
494 AnyThread().user_model.DidFinishProcessingInputEvent( 495 AnyThread().user_model.DidFinishProcessingInputEvent(
495 helper_.tick_clock()->NowTicks()); 496 helper_.scheduler_tqm_delegate()->NowTicks());
496 } 497 }
497 } 498 }
498 499
499 bool RendererSchedulerImpl::IsHighPriorityWorkAnticipated() { 500 bool RendererSchedulerImpl::IsHighPriorityWorkAnticipated() {
500 helper_.CheckOnValidThread(); 501 helper_.CheckOnValidThread();
501 if (helper_.IsShutdown()) 502 if (helper_.IsShutdown())
502 return false; 503 return false;
503 504
504 MaybeUpdatePolicy(); 505 MaybeUpdatePolicy();
505 // The touchstart, synchronized gesture and main-thread gesture use cases 506 // The touchstart, synchronized gesture and main-thread gesture use cases
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
576 base::AutoLock lock(any_thread_lock_); 577 base::AutoLock lock(any_thread_lock_);
577 UpdatePolicyLocked(UpdateType::FORCE_UPDATE); 578 UpdatePolicyLocked(UpdateType::FORCE_UPDATE);
578 } 579 }
579 580
580 void RendererSchedulerImpl::UpdatePolicyLocked(UpdateType update_type) { 581 void RendererSchedulerImpl::UpdatePolicyLocked(UpdateType update_type) {
581 helper_.CheckOnValidThread(); 582 helper_.CheckOnValidThread();
582 any_thread_lock_.AssertAcquired(); 583 any_thread_lock_.AssertAcquired();
583 if (helper_.IsShutdown()) 584 if (helper_.IsShutdown())
584 return; 585 return;
585 586
586 base::TimeTicks now = helper_.tick_clock()->NowTicks(); 587 base::TimeTicks now = helper_.scheduler_tqm_delegate()->NowTicks();
587 policy_may_need_update_.SetWhileLocked(false); 588 policy_may_need_update_.SetWhileLocked(false);
588 589
589 base::TimeDelta expected_use_case_duration; 590 base::TimeDelta expected_use_case_duration;
590 UseCase use_case = ComputeCurrentUseCase(now, &expected_use_case_duration); 591 UseCase use_case = ComputeCurrentUseCase(now, &expected_use_case_duration);
591 MainThreadOnly().current_use_case = use_case; 592 MainThreadOnly().current_use_case = use_case;
592 593
593 base::TimeDelta touchstart_expected_flag_valid_for_duration; 594 base::TimeDelta touchstart_expected_flag_valid_for_duration;
594 bool touchstart_expected_soon = false; 595 bool touchstart_expected_soon = false;
595 if (MainThreadOnly().has_visible_render_widget_with_touch_handler) { 596 if (MainThreadOnly().has_visible_render_widget_with_touch_handler) {
596 touchstart_expected_soon = AnyThread().user_model.IsGestureExpectedSoon( 597 touchstart_expected_soon = AnyThread().user_model.IsGestureExpectedSoon(
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
878 base::AutoLock lock(any_thread_lock_); 879 base::AutoLock lock(any_thread_lock_);
879 return AsValueLocked(optional_now); 880 return AsValueLocked(optional_now);
880 } 881 }
881 882
882 scoped_refptr<base::trace_event::ConvertableToTraceFormat> 883 scoped_refptr<base::trace_event::ConvertableToTraceFormat>
883 RendererSchedulerImpl::AsValueLocked(base::TimeTicks optional_now) const { 884 RendererSchedulerImpl::AsValueLocked(base::TimeTicks optional_now) const {
884 helper_.CheckOnValidThread(); 885 helper_.CheckOnValidThread();
885 any_thread_lock_.AssertAcquired(); 886 any_thread_lock_.AssertAcquired();
886 887
887 if (optional_now.is_null()) 888 if (optional_now.is_null())
888 optional_now = helper_.tick_clock()->NowTicks(); 889 optional_now = helper_.scheduler_tqm_delegate()->NowTicks();
889 scoped_refptr<base::trace_event::TracedValue> state = 890 scoped_refptr<base::trace_event::TracedValue> state =
890 new base::trace_event::TracedValue(); 891 new base::trace_event::TracedValue();
891 892
892 state->SetBoolean( 893 state->SetBoolean(
893 "has_visible_render_widget_with_touch_handler", 894 "has_visible_render_widget_with_touch_handler",
894 MainThreadOnly().has_visible_render_widget_with_touch_handler); 895 MainThreadOnly().has_visible_render_widget_with_touch_handler);
895 state->SetString("current_use_case", 896 state->SetString("current_use_case",
896 UseCaseToString(MainThreadOnly().current_use_case)); 897 UseCaseToString(MainThreadOnly().current_use_case));
897 state->SetBoolean("loading_tasks_seem_expensive", 898 state->SetBoolean("loading_tasks_seem_expensive",
898 MainThreadOnly().loading_tasks_seem_expensive); 899 MainThreadOnly().loading_tasks_seem_expensive);
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
956 } 957 }
957 958
958 void RendererSchedulerImpl::OnIdlePeriodStarted() { 959 void RendererSchedulerImpl::OnIdlePeriodStarted() {
959 base::AutoLock lock(any_thread_lock_); 960 base::AutoLock lock(any_thread_lock_);
960 AnyThread().in_idle_period = true; 961 AnyThread().in_idle_period = true;
961 UpdatePolicyLocked(UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED); 962 UpdatePolicyLocked(UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED);
962 } 963 }
963 964
964 void RendererSchedulerImpl::OnIdlePeriodEnded() { 965 void RendererSchedulerImpl::OnIdlePeriodEnded() {
965 base::AutoLock lock(any_thread_lock_); 966 base::AutoLock lock(any_thread_lock_);
966 AnyThread().last_idle_period_end_time = helper_.tick_clock()->NowTicks(); 967 AnyThread().last_idle_period_end_time =
968 helper_.scheduler_tqm_delegate()->NowTicks();
967 AnyThread().in_idle_period = false; 969 AnyThread().in_idle_period = false;
968 UpdatePolicyLocked(UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED); 970 UpdatePolicyLocked(UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED);
969 } 971 }
970 972
971 void RendererSchedulerImpl::AddPendingNavigation() { 973 void RendererSchedulerImpl::AddPendingNavigation() {
972 helper_.CheckOnValidThread(); 974 helper_.CheckOnValidThread();
973 MainThreadOnly().navigation_task_expected_count++; 975 MainThreadOnly().navigation_task_expected_count++;
974 UpdatePolicy(); 976 UpdatePolicy();
975 } 977 }
976 978
977 void RendererSchedulerImpl::RemovePendingNavigation() { 979 void RendererSchedulerImpl::RemovePendingNavigation() {
978 helper_.CheckOnValidThread(); 980 helper_.CheckOnValidThread();
979 DCHECK_GT(MainThreadOnly().navigation_task_expected_count, 0); 981 DCHECK_GT(MainThreadOnly().navigation_task_expected_count, 0);
980 if (MainThreadOnly().navigation_task_expected_count > 0) 982 if (MainThreadOnly().navigation_task_expected_count > 0)
981 MainThreadOnly().navigation_task_expected_count--; 983 MainThreadOnly().navigation_task_expected_count--;
982 UpdatePolicy(); 984 UpdatePolicy();
983 } 985 }
984 986
985 void RendererSchedulerImpl::OnNavigationStarted() { 987 void RendererSchedulerImpl::OnNavigationStarted() {
986 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), 988 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
987 "RendererSchedulerImpl::OnNavigationStarted"); 989 "RendererSchedulerImpl::OnNavigationStarted");
988 base::AutoLock lock(any_thread_lock_); 990 base::AutoLock lock(any_thread_lock_);
989 AnyThread().rails_loading_priority_deadline = 991 AnyThread().rails_loading_priority_deadline =
990 helper_.tick_clock()->NowTicks() + 992 helper_.scheduler_tqm_delegate()->NowTicks() +
991 base::TimeDelta::FromMilliseconds( 993 base::TimeDelta::FromMilliseconds(
992 kRailsInitialLoadingPrioritizationMillis); 994 kRailsInitialLoadingPrioritizationMillis);
993 ResetForNavigationLocked(); 995 ResetForNavigationLocked();
994 } 996 }
995 997
996 bool RendererSchedulerImpl::HadAnIdlePeriodRecently(base::TimeTicks now) const { 998 bool RendererSchedulerImpl::HadAnIdlePeriodRecently(base::TimeTicks now) const {
997 return (now - AnyThread().last_idle_period_end_time) <= 999 return (now - AnyThread().last_idle_period_end_time) <=
998 base::TimeDelta::FromMilliseconds( 1000 base::TimeDelta::FromMilliseconds(
999 kIdlePeriodStarvationThresholdMillis); 1001 kIdlePeriodStarvationThresholdMillis);
1000 } 1002 }
(...skipping 15 matching lines...) Expand all
1016 MainThreadOnly().timer_queue_suspended_when_backgrounded = false; 1018 MainThreadOnly().timer_queue_suspended_when_backgrounded = false;
1017 ForceUpdatePolicy(); 1019 ForceUpdatePolicy();
1018 } 1020 }
1019 1021
1020 void RendererSchedulerImpl::ResetForNavigationLocked() { 1022 void RendererSchedulerImpl::ResetForNavigationLocked() {
1021 helper_.CheckOnValidThread(); 1023 helper_.CheckOnValidThread();
1022 any_thread_lock_.AssertAcquired(); 1024 any_thread_lock_.AssertAcquired();
1023 MainThreadOnly().loading_task_cost_estimator.Clear(); 1025 MainThreadOnly().loading_task_cost_estimator.Clear();
1024 MainThreadOnly().timer_task_cost_estimator.Clear(); 1026 MainThreadOnly().timer_task_cost_estimator.Clear();
1025 MainThreadOnly().idle_time_estimator.Clear(); 1027 MainThreadOnly().idle_time_estimator.Clear();
1026 AnyThread().user_model.Reset(helper_.tick_clock()->NowTicks()); 1028 AnyThread().user_model.Reset(helper_.scheduler_tqm_delegate()->NowTicks());
1027 MainThreadOnly().have_seen_a_begin_main_frame = false; 1029 MainThreadOnly().have_seen_a_begin_main_frame = false;
1028 UpdatePolicyLocked(UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED); 1030 UpdatePolicyLocked(UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED);
1029 } 1031 }
1030 1032
1033 double RendererSchedulerImpl::CurrentTimeSeconds() const {
1034 return helper_.scheduler_tqm_delegate()->CurrentTimeSeconds();
1035 }
1036
1037 double RendererSchedulerImpl::MonotonicallyIncreasingTimeSeconds() const {
1038 return helper_.scheduler_tqm_delegate()->NowTicks().ToInternalValue() /
1039 static_cast<double>(base::Time::kMicrosecondsPerSecond);
1040 }
1041
1031 } // namespace scheduler 1042 } // namespace scheduler
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698