| 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 "platform/scheduler/renderer/renderer_scheduler_impl.h" | 5 #include "platform/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 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 216 rail_mode_observer(nullptr) {} | 216 rail_mode_observer(nullptr) {} |
| 217 | 217 |
| 218 RendererSchedulerImpl::MainThreadOnly::~MainThreadOnly() {} | 218 RendererSchedulerImpl::MainThreadOnly::~MainThreadOnly() {} |
| 219 | 219 |
| 220 RendererSchedulerImpl::AnyThread::AnyThread() | 220 RendererSchedulerImpl::AnyThread::AnyThread() |
| 221 : awaiting_touch_start_response(false), | 221 : awaiting_touch_start_response(false), |
| 222 in_idle_period(false), | 222 in_idle_period(false), |
| 223 begin_main_frame_on_critical_path(false), | 223 begin_main_frame_on_critical_path(false), |
| 224 last_gesture_was_compositor_driven(false), | 224 last_gesture_was_compositor_driven(false), |
| 225 default_gesture_prevented(true), | 225 default_gesture_prevented(true), |
| 226 have_seen_touchstart(false) {} | 226 have_seen_touchstart(false), |
| 227 waiting_for_meaningful_paint(false), |
| 228 have_seen_input_since_navigation(false) {} |
| 227 | 229 |
| 228 RendererSchedulerImpl::AnyThread::~AnyThread() {} | 230 RendererSchedulerImpl::AnyThread::~AnyThread() {} |
| 229 | 231 |
| 230 RendererSchedulerImpl::CompositorThreadOnly::CompositorThreadOnly() | 232 RendererSchedulerImpl::CompositorThreadOnly::CompositorThreadOnly() |
| 231 : last_input_type(blink::WebInputEvent::Undefined) {} | 233 : last_input_type(blink::WebInputEvent::Undefined) {} |
| 232 | 234 |
| 233 RendererSchedulerImpl::CompositorThreadOnly::~CompositorThreadOnly() {} | 235 RendererSchedulerImpl::CompositorThreadOnly::~CompositorThreadOnly() {} |
| 234 | 236 |
| 235 void RendererSchedulerImpl::Shutdown() { | 237 void RendererSchedulerImpl::Shutdown() { |
| 236 base::TimeTicks now = tick_clock()->NowTicks(); | 238 base::TimeTicks now = tick_clock()->NowTicks(); |
| (...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 638 "type", static_cast<int>(type), "input_event_state", | 640 "type", static_cast<int>(type), "input_event_state", |
| 639 InputEventStateToString(input_event_state)); | 641 InputEventStateToString(input_event_state)); |
| 640 | 642 |
| 641 base::TimeDelta unused_policy_duration; | 643 base::TimeDelta unused_policy_duration; |
| 642 UseCase previous_use_case = | 644 UseCase previous_use_case = |
| 643 ComputeCurrentUseCase(now, &unused_policy_duration); | 645 ComputeCurrentUseCase(now, &unused_policy_duration); |
| 644 bool was_awaiting_touch_start_response = | 646 bool was_awaiting_touch_start_response = |
| 645 AnyThread().awaiting_touch_start_response; | 647 AnyThread().awaiting_touch_start_response; |
| 646 | 648 |
| 647 AnyThread().user_model.DidStartProcessingInputEvent(type, now); | 649 AnyThread().user_model.DidStartProcessingInputEvent(type, now); |
| 650 AnyThread().have_seen_input_since_navigation = true; |
| 648 | 651 |
| 649 if (input_event_state == InputEventState::EVENT_CONSUMED_BY_COMPOSITOR) | 652 if (input_event_state == InputEventState::EVENT_CONSUMED_BY_COMPOSITOR) |
| 650 AnyThread().user_model.DidFinishProcessingInputEvent(now); | 653 AnyThread().user_model.DidFinishProcessingInputEvent(now); |
| 651 | 654 |
| 652 switch (type) { | 655 switch (type) { |
| 653 case blink::WebInputEvent::TouchStart: | 656 case blink::WebInputEvent::TouchStart: |
| 654 AnyThread().awaiting_touch_start_response = true; | 657 AnyThread().awaiting_touch_start_response = true; |
| 655 // This is just a fail-safe to reset the state of | 658 // This is just a fail-safe to reset the state of |
| 656 // |last_gesture_was_compositor_driven| to the default. We don't know | 659 // |last_gesture_was_compositor_driven| to the default. We don't know |
| 657 // yet where the gesture will run. | 660 // yet where the gesture will run. |
| (...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 997 // driven gesture. | 1000 // driven gesture. |
| 998 if (touchstart_expected_soon && | 1001 if (touchstart_expected_soon && |
| 999 AnyThread().last_gesture_was_compositor_driven) { | 1002 AnyThread().last_gesture_was_compositor_driven) { |
| 1000 new_policy.rail_mode = v8::PERFORMANCE_RESPONSE; | 1003 new_policy.rail_mode = v8::PERFORMANCE_RESPONSE; |
| 1001 expensive_task_policy = ExpensiveTaskPolicy::BLOCK; | 1004 expensive_task_policy = ExpensiveTaskPolicy::BLOCK; |
| 1002 } | 1005 } |
| 1003 break; | 1006 break; |
| 1004 | 1007 |
| 1005 case UseCase::LOADING: | 1008 case UseCase::LOADING: |
| 1006 new_policy.rail_mode = v8::PERFORMANCE_LOAD; | 1009 new_policy.rail_mode = v8::PERFORMANCE_LOAD; |
| 1007 new_policy.loading_queue_policy.priority = TaskQueue::HIGH_PRIORITY; | 1010 // TODO(skyostil): Experiment with increasing loading and default queue |
| 1008 new_policy.default_queue_policy.priority = TaskQueue::HIGH_PRIORITY; | 1011 // priorities and throttling rendering frame rate. |
| 1009 break; | 1012 break; |
| 1010 | 1013 |
| 1011 default: | 1014 default: |
| 1012 NOTREACHED(); | 1015 NOTREACHED(); |
| 1013 } | 1016 } |
| 1014 | 1017 |
| 1015 // TODO(skyostil): Add an idle state for foreground tabs too. | 1018 // TODO(skyostil): Add an idle state for foreground tabs too. |
| 1016 if (MainThreadOnly().renderer_hidden) | 1019 if (MainThreadOnly().renderer_hidden) |
| 1017 new_policy.rail_mode = v8::PERFORMANCE_IDLE; | 1020 new_policy.rail_mode = v8::PERFORMANCE_IDLE; |
| 1018 | 1021 |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1209 return UseCase::COMPOSITOR_GESTURE; | 1212 return UseCase::COMPOSITOR_GESTURE; |
| 1210 } | 1213 } |
| 1211 } | 1214 } |
| 1212 if (AnyThread().default_gesture_prevented) { | 1215 if (AnyThread().default_gesture_prevented) { |
| 1213 return UseCase::MAIN_THREAD_CUSTOM_INPUT_HANDLING; | 1216 return UseCase::MAIN_THREAD_CUSTOM_INPUT_HANDLING; |
| 1214 } else { | 1217 } else { |
| 1215 return UseCase::MAIN_THREAD_GESTURE; | 1218 return UseCase::MAIN_THREAD_GESTURE; |
| 1216 } | 1219 } |
| 1217 } | 1220 } |
| 1218 | 1221 |
| 1219 // TODO(alexclarke): return UseCase::LOADING if signals suggest the system is | 1222 // Occasionally the meaningful paint fails to be detected, so as a fallback we |
| 1220 // in the initial 1s of RAIL loading. | 1223 // treat the presence of input as an indirect signal that there is meaningful |
| 1224 // content on the page. |
| 1225 if (AnyThread().waiting_for_meaningful_paint && |
| 1226 !AnyThread().have_seen_input_since_navigation) { |
| 1227 return UseCase::LOADING; |
| 1228 } |
| 1221 return UseCase::NONE; | 1229 return UseCase::NONE; |
| 1222 } | 1230 } |
| 1223 | 1231 |
| 1224 base::TimeDelta RendererSchedulerImpl::EstimateLongestJankFreeTaskDuration() | 1232 base::TimeDelta RendererSchedulerImpl::EstimateLongestJankFreeTaskDuration() |
| 1225 const { | 1233 const { |
| 1226 switch (MainThreadOnly().current_use_case) { | 1234 switch (MainThreadOnly().current_use_case) { |
| 1227 case UseCase::TOUCHSTART: | 1235 case UseCase::TOUCHSTART: |
| 1228 case UseCase::COMPOSITOR_GESTURE: | 1236 case UseCase::COMPOSITOR_GESTURE: |
| 1229 case UseCase::LOADING: | 1237 case UseCase::LOADING: |
| 1230 case UseCase::NONE: | 1238 case UseCase::NONE: |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1355 state->SetBoolean("begin_frame_not_expected_soon", | 1363 state->SetBoolean("begin_frame_not_expected_soon", |
| 1356 MainThreadOnly().begin_frame_not_expected_soon); | 1364 MainThreadOnly().begin_frame_not_expected_soon); |
| 1357 state->SetBoolean("touchstart_expected_soon", | 1365 state->SetBoolean("touchstart_expected_soon", |
| 1358 MainThreadOnly().touchstart_expected_soon); | 1366 MainThreadOnly().touchstart_expected_soon); |
| 1359 state->SetString("idle_period_state", | 1367 state->SetString("idle_period_state", |
| 1360 IdleHelper::IdlePeriodStateToString( | 1368 IdleHelper::IdlePeriodStateToString( |
| 1361 idle_helper_.SchedulerIdlePeriodState())); | 1369 idle_helper_.SchedulerIdlePeriodState())); |
| 1362 state->SetBoolean("renderer_hidden", MainThreadOnly().renderer_hidden); | 1370 state->SetBoolean("renderer_hidden", MainThreadOnly().renderer_hidden); |
| 1363 state->SetBoolean("have_seen_a_begin_main_frame", | 1371 state->SetBoolean("have_seen_a_begin_main_frame", |
| 1364 MainThreadOnly().have_seen_a_begin_main_frame); | 1372 MainThreadOnly().have_seen_a_begin_main_frame); |
| 1373 state->SetBoolean("waiting_for_meaningful_paint", |
| 1374 AnyThread().waiting_for_meaningful_paint); |
| 1375 state->SetBoolean("have_seen_input_since_navigation", |
| 1376 AnyThread().have_seen_input_since_navigation); |
| 1365 state->SetBoolean( | 1377 state->SetBoolean( |
| 1366 "have_reported_blocking_intervention_in_current_policy", | 1378 "have_reported_blocking_intervention_in_current_policy", |
| 1367 MainThreadOnly().have_reported_blocking_intervention_in_current_policy); | 1379 MainThreadOnly().have_reported_blocking_intervention_in_current_policy); |
| 1368 state->SetBoolean( | 1380 state->SetBoolean( |
| 1369 "have_reported_blocking_intervention_since_navigation", | 1381 "have_reported_blocking_intervention_since_navigation", |
| 1370 MainThreadOnly().have_reported_blocking_intervention_since_navigation); | 1382 MainThreadOnly().have_reported_blocking_intervention_since_navigation); |
| 1371 state->SetBoolean("renderer_backgrounded", | 1383 state->SetBoolean("renderer_backgrounded", |
| 1372 MainThreadOnly().renderer_backgrounded); | 1384 MainThreadOnly().renderer_backgrounded); |
| 1373 state->SetBoolean("timer_queue_suspended_when_backgrounded", | 1385 state->SetBoolean("timer_queue_suspended_when_backgrounded", |
| 1374 MainThreadOnly().timer_queue_suspended_when_backgrounded); | 1386 MainThreadOnly().timer_queue_suspended_when_backgrounded); |
| 1375 state->SetInteger("timer_queue_suspend_count", | 1387 state->SetInteger("timer_queue_suspend_count", |
| 1376 MainThreadOnly().timer_queue_suspend_count); | 1388 MainThreadOnly().timer_queue_suspend_count); |
| 1377 state->SetDouble("now", (optional_now - base::TimeTicks()).InMillisecondsF()); | 1389 state->SetDouble("now", (optional_now - base::TimeTicks()).InMillisecondsF()); |
| 1378 state->SetDouble( | 1390 state->SetDouble( |
| 1379 "rails_loading_priority_deadline", | |
| 1380 (AnyThread().rails_loading_priority_deadline - base::TimeTicks()) | |
| 1381 .InMillisecondsF()); | |
| 1382 state->SetDouble( | |
| 1383 "fling_compositor_escalation_deadline", | 1391 "fling_compositor_escalation_deadline", |
| 1384 (AnyThread().fling_compositor_escalation_deadline - base::TimeTicks()) | 1392 (AnyThread().fling_compositor_escalation_deadline - base::TimeTicks()) |
| 1385 .InMillisecondsF()); | 1393 .InMillisecondsF()); |
| 1386 state->SetInteger("navigation_task_expected_count", | 1394 state->SetInteger("navigation_task_expected_count", |
| 1387 MainThreadOnly().navigation_task_expected_count); | 1395 MainThreadOnly().navigation_task_expected_count); |
| 1388 state->SetDouble("last_idle_period_end_time", | 1396 state->SetDouble("last_idle_period_end_time", |
| 1389 (AnyThread().last_idle_period_end_time - base::TimeTicks()) | 1397 (AnyThread().last_idle_period_end_time - base::TimeTicks()) |
| 1390 .InMillisecondsF()); | 1398 .InMillisecondsF()); |
| 1391 state->SetBoolean("awaiting_touch_start_response", | 1399 state->SetBoolean("awaiting_touch_start_response", |
| 1392 AnyThread().awaiting_touch_start_response); | 1400 AnyThread().awaiting_touch_start_response); |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1507 MainThreadOnly().navigation_task_expected_count > 0) { | 1515 MainThreadOnly().navigation_task_expected_count > 0) { |
| 1508 MainThreadOnly().navigation_task_expected_count--; | 1516 MainThreadOnly().navigation_task_expected_count--; |
| 1509 UpdatePolicy(); | 1517 UpdatePolicy(); |
| 1510 } | 1518 } |
| 1511 } | 1519 } |
| 1512 | 1520 |
| 1513 void RendererSchedulerImpl::OnNavigationStarted() { | 1521 void RendererSchedulerImpl::OnNavigationStarted() { |
| 1514 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), | 1522 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), |
| 1515 "RendererSchedulerImpl::OnNavigationStarted"); | 1523 "RendererSchedulerImpl::OnNavigationStarted"); |
| 1516 base::AutoLock lock(any_thread_lock_); | 1524 base::AutoLock lock(any_thread_lock_); |
| 1517 AnyThread().rails_loading_priority_deadline = | |
| 1518 helper_.scheduler_tqm_delegate()->NowTicks() + | |
| 1519 base::TimeDelta::FromMilliseconds( | |
| 1520 kRailsInitialLoadingPrioritizationMillis); | |
| 1521 ResetForNavigationLocked(); | 1525 ResetForNavigationLocked(); |
| 1522 } | 1526 } |
| 1523 | 1527 |
| 1528 void RendererSchedulerImpl::OnFirstMeaningfulPaint() { |
| 1529 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), |
| 1530 "RendererSchedulerImpl::OnFirstMeaningfulPaint"); |
| 1531 base::AutoLock lock(any_thread_lock_); |
| 1532 AnyThread().waiting_for_meaningful_paint = false; |
| 1533 UpdatePolicyLocked(UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED); |
| 1534 } |
| 1535 |
| 1524 void RendererSchedulerImpl::SuspendTimerQueueWhenBackgrounded() { | 1536 void RendererSchedulerImpl::SuspendTimerQueueWhenBackgrounded() { |
| 1525 DCHECK(MainThreadOnly().renderer_backgrounded); | 1537 DCHECK(MainThreadOnly().renderer_backgrounded); |
| 1526 if (MainThreadOnly().timer_queue_suspended_when_backgrounded) | 1538 if (MainThreadOnly().timer_queue_suspended_when_backgrounded) |
| 1527 return; | 1539 return; |
| 1528 | 1540 |
| 1529 MainThreadOnly().timer_queue_suspended_when_backgrounded = true; | 1541 MainThreadOnly().timer_queue_suspended_when_backgrounded = true; |
| 1530 ForceUpdatePolicy(); | 1542 ForceUpdatePolicy(); |
| 1531 } | 1543 } |
| 1532 | 1544 |
| 1533 void RendererSchedulerImpl::ResumeTimerQueueWhenForegroundedOrResumed() { | 1545 void RendererSchedulerImpl::ResumeTimerQueueWhenForegroundedOrResumed() { |
| 1534 DCHECK(!MainThreadOnly().renderer_backgrounded || | 1546 DCHECK(!MainThreadOnly().renderer_backgrounded || |
| 1535 (MainThreadOnly().renderer_backgrounded && | 1547 (MainThreadOnly().renderer_backgrounded && |
| 1536 !MainThreadOnly().renderer_suspended)); | 1548 !MainThreadOnly().renderer_suspended)); |
| 1537 if (!MainThreadOnly().timer_queue_suspended_when_backgrounded) | 1549 if (!MainThreadOnly().timer_queue_suspended_when_backgrounded) |
| 1538 return; | 1550 return; |
| 1539 | 1551 |
| 1540 MainThreadOnly().timer_queue_suspended_when_backgrounded = false; | 1552 MainThreadOnly().timer_queue_suspended_when_backgrounded = false; |
| 1541 ForceUpdatePolicy(); | 1553 ForceUpdatePolicy(); |
| 1542 } | 1554 } |
| 1543 | 1555 |
| 1544 void RendererSchedulerImpl::ResetForNavigationLocked() { | 1556 void RendererSchedulerImpl::ResetForNavigationLocked() { |
| 1545 helper_.CheckOnValidThread(); | 1557 helper_.CheckOnValidThread(); |
| 1546 any_thread_lock_.AssertAcquired(); | 1558 any_thread_lock_.AssertAcquired(); |
| 1547 AnyThread().user_model.Reset(helper_.scheduler_tqm_delegate()->NowTicks()); | 1559 AnyThread().user_model.Reset(helper_.scheduler_tqm_delegate()->NowTicks()); |
| 1548 AnyThread().have_seen_touchstart = false; | 1560 AnyThread().have_seen_touchstart = false; |
| 1561 AnyThread().waiting_for_meaningful_paint = true; |
| 1562 AnyThread().have_seen_input_since_navigation = false; |
| 1549 MainThreadOnly().loading_task_cost_estimator.Clear(); | 1563 MainThreadOnly().loading_task_cost_estimator.Clear(); |
| 1550 MainThreadOnly().timer_task_cost_estimator.Clear(); | 1564 MainThreadOnly().timer_task_cost_estimator.Clear(); |
| 1551 MainThreadOnly().idle_time_estimator.Clear(); | 1565 MainThreadOnly().idle_time_estimator.Clear(); |
| 1552 MainThreadOnly().have_seen_a_begin_main_frame = false; | 1566 MainThreadOnly().have_seen_a_begin_main_frame = false; |
| 1553 MainThreadOnly().have_reported_blocking_intervention_since_navigation = false; | 1567 MainThreadOnly().have_reported_blocking_intervention_since_navigation = false; |
| 1554 for (WebViewSchedulerImpl* web_view_scheduler : | 1568 for (WebViewSchedulerImpl* web_view_scheduler : |
| 1555 MainThreadOnly().web_view_schedulers) { | 1569 MainThreadOnly().web_view_schedulers) { |
| 1556 web_view_scheduler->OnNavigation(); | 1570 web_view_scheduler->OnNavigation(); |
| 1557 } | 1571 } |
| 1558 UpdatePolicyLocked(UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED); | 1572 UpdatePolicyLocked(UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED); |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1794 case TimeDomainType::VIRTUAL: | 1808 case TimeDomainType::VIRTUAL: |
| 1795 return "virtual"; | 1809 return "virtual"; |
| 1796 default: | 1810 default: |
| 1797 NOTREACHED(); | 1811 NOTREACHED(); |
| 1798 return nullptr; | 1812 return nullptr; |
| 1799 } | 1813 } |
| 1800 } | 1814 } |
| 1801 | 1815 |
| 1802 } // namespace scheduler | 1816 } // namespace scheduler |
| 1803 } // namespace blink | 1817 } // namespace blink |
| OLD | NEW |