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 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
196 rail_mode_observer(nullptr) {} | 196 rail_mode_observer(nullptr) {} |
197 | 197 |
198 RendererSchedulerImpl::MainThreadOnly::~MainThreadOnly() {} | 198 RendererSchedulerImpl::MainThreadOnly::~MainThreadOnly() {} |
199 | 199 |
200 RendererSchedulerImpl::AnyThread::AnyThread() | 200 RendererSchedulerImpl::AnyThread::AnyThread() |
201 : awaiting_touch_start_response(false), | 201 : awaiting_touch_start_response(false), |
202 in_idle_period(false), | 202 in_idle_period(false), |
203 begin_main_frame_on_critical_path(false), | 203 begin_main_frame_on_critical_path(false), |
204 last_gesture_was_compositor_driven(false), | 204 last_gesture_was_compositor_driven(false), |
205 default_gesture_prevented(true), | 205 default_gesture_prevented(true), |
206 have_seen_touchstart(false) {} | 206 have_seen_touchstart(false), |
207 waiting_for_meaningful_paint(false), | |
208 have_seen_input_since_navigation(false) {} | |
207 | 209 |
208 RendererSchedulerImpl::AnyThread::~AnyThread() {} | 210 RendererSchedulerImpl::AnyThread::~AnyThread() {} |
209 | 211 |
210 RendererSchedulerImpl::CompositorThreadOnly::CompositorThreadOnly() | 212 RendererSchedulerImpl::CompositorThreadOnly::CompositorThreadOnly() |
211 : last_input_type(blink::WebInputEvent::Undefined) {} | 213 : last_input_type(blink::WebInputEvent::Undefined) {} |
212 | 214 |
213 RendererSchedulerImpl::CompositorThreadOnly::~CompositorThreadOnly() {} | 215 RendererSchedulerImpl::CompositorThreadOnly::~CompositorThreadOnly() {} |
214 | 216 |
215 void RendererSchedulerImpl::Shutdown() { | 217 void RendererSchedulerImpl::Shutdown() { |
216 base::TimeTicks now = tick_clock()->NowTicks(); | 218 base::TimeTicks now = tick_clock()->NowTicks(); |
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
616 "type", static_cast<int>(type), "input_event_state", | 618 "type", static_cast<int>(type), "input_event_state", |
617 InputEventStateToString(input_event_state)); | 619 InputEventStateToString(input_event_state)); |
618 | 620 |
619 base::TimeDelta unused_policy_duration; | 621 base::TimeDelta unused_policy_duration; |
620 UseCase previous_use_case = | 622 UseCase previous_use_case = |
621 ComputeCurrentUseCase(now, &unused_policy_duration); | 623 ComputeCurrentUseCase(now, &unused_policy_duration); |
622 bool was_awaiting_touch_start_response = | 624 bool was_awaiting_touch_start_response = |
623 AnyThread().awaiting_touch_start_response; | 625 AnyThread().awaiting_touch_start_response; |
624 | 626 |
625 AnyThread().user_model.DidStartProcessingInputEvent(type, now); | 627 AnyThread().user_model.DidStartProcessingInputEvent(type, now); |
628 AnyThread().have_seen_input_since_navigation = true; | |
626 | 629 |
627 if (input_event_state == InputEventState::EVENT_CONSUMED_BY_COMPOSITOR) | 630 if (input_event_state == InputEventState::EVENT_CONSUMED_BY_COMPOSITOR) |
628 AnyThread().user_model.DidFinishProcessingInputEvent(now); | 631 AnyThread().user_model.DidFinishProcessingInputEvent(now); |
629 | 632 |
630 switch (type) { | 633 switch (type) { |
631 case blink::WebInputEvent::TouchStart: | 634 case blink::WebInputEvent::TouchStart: |
632 AnyThread().awaiting_touch_start_response = true; | 635 AnyThread().awaiting_touch_start_response = true; |
633 // This is just a fail-safe to reset the state of | 636 // This is just a fail-safe to reset the state of |
634 // |last_gesture_was_compositor_driven| to the default. We don't know | 637 // |last_gesture_was_compositor_driven| to the default. We don't know |
635 // yet where the gesture will run. | 638 // yet where the gesture will run. |
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
975 // driven gesture. | 978 // driven gesture. |
976 if (touchstart_expected_soon && | 979 if (touchstart_expected_soon && |
977 AnyThread().last_gesture_was_compositor_driven) { | 980 AnyThread().last_gesture_was_compositor_driven) { |
978 new_policy.rail_mode = v8::PERFORMANCE_RESPONSE; | 981 new_policy.rail_mode = v8::PERFORMANCE_RESPONSE; |
979 expensive_task_policy = ExpensiveTaskPolicy::BLOCK; | 982 expensive_task_policy = ExpensiveTaskPolicy::BLOCK; |
980 } | 983 } |
981 break; | 984 break; |
982 | 985 |
983 case UseCase::LOADING: | 986 case UseCase::LOADING: |
984 new_policy.rail_mode = v8::PERFORMANCE_LOAD; | 987 new_policy.rail_mode = v8::PERFORMANCE_LOAD; |
985 new_policy.loading_queue_policy.priority = TaskQueue::HIGH_PRIORITY; | 988 // TODO(skyostil): Experiment with increasing loading and default queue |
986 new_policy.default_queue_policy.priority = TaskQueue::HIGH_PRIORITY; | 989 // priorities and throttling rendering frame rate. |
987 break; | 990 break; |
988 | 991 |
989 default: | 992 default: |
990 NOTREACHED(); | 993 NOTREACHED(); |
991 } | 994 } |
992 | 995 |
993 // TODO(skyostil): Add an idle state for foreground tabs too. | 996 // TODO(skyostil): Add an idle state for foreground tabs too. |
994 if (MainThreadOnly().renderer_hidden) | 997 if (MainThreadOnly().renderer_hidden) |
995 new_policy.rail_mode = v8::PERFORMANCE_IDLE; | 998 new_policy.rail_mode = v8::PERFORMANCE_IDLE; |
996 | 999 |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1182 return UseCase::COMPOSITOR_GESTURE; | 1185 return UseCase::COMPOSITOR_GESTURE; |
1183 } | 1186 } |
1184 } | 1187 } |
1185 if (AnyThread().default_gesture_prevented) { | 1188 if (AnyThread().default_gesture_prevented) { |
1186 return UseCase::MAIN_THREAD_CUSTOM_INPUT_HANDLING; | 1189 return UseCase::MAIN_THREAD_CUSTOM_INPUT_HANDLING; |
1187 } else { | 1190 } else { |
1188 return UseCase::MAIN_THREAD_GESTURE; | 1191 return UseCase::MAIN_THREAD_GESTURE; |
1189 } | 1192 } |
1190 } | 1193 } |
1191 | 1194 |
1192 // TODO(alexclarke): return UseCase::LOADING if signals suggest the system is | 1195 // Occasionally the meaningful paint fails to be detected, so as a fallback we |
1193 // in the initial 1s of RAIL loading. | 1196 // treat the presence of input as an indirect signal that there is meaningful |
1197 // content on the page. | |
1198 if (AnyThread().waiting_for_meaningful_paint && | |
1199 !AnyThread().have_seen_input_since_navigation) { | |
1200 return UseCase::LOADING; | |
1201 } | |
1194 return UseCase::NONE; | 1202 return UseCase::NONE; |
1195 } | 1203 } |
1196 | 1204 |
1197 base::TimeDelta RendererSchedulerImpl::EstimateLongestJankFreeTaskDuration() | 1205 base::TimeDelta RendererSchedulerImpl::EstimateLongestJankFreeTaskDuration() |
1198 const { | 1206 const { |
1199 switch (MainThreadOnly().current_use_case) { | 1207 switch (MainThreadOnly().current_use_case) { |
1200 case UseCase::TOUCHSTART: | 1208 case UseCase::TOUCHSTART: |
1201 case UseCase::COMPOSITOR_GESTURE: | 1209 case UseCase::COMPOSITOR_GESTURE: |
1202 case UseCase::LOADING: | 1210 case UseCase::LOADING: |
1203 case UseCase::NONE: | 1211 case UseCase::NONE: |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1328 state->SetBoolean("begin_frame_not_expected_soon", | 1336 state->SetBoolean("begin_frame_not_expected_soon", |
1329 MainThreadOnly().begin_frame_not_expected_soon); | 1337 MainThreadOnly().begin_frame_not_expected_soon); |
1330 state->SetBoolean("touchstart_expected_soon", | 1338 state->SetBoolean("touchstart_expected_soon", |
1331 MainThreadOnly().touchstart_expected_soon); | 1339 MainThreadOnly().touchstart_expected_soon); |
1332 state->SetString("idle_period_state", | 1340 state->SetString("idle_period_state", |
1333 IdleHelper::IdlePeriodStateToString( | 1341 IdleHelper::IdlePeriodStateToString( |
1334 idle_helper_.SchedulerIdlePeriodState())); | 1342 idle_helper_.SchedulerIdlePeriodState())); |
1335 state->SetBoolean("renderer_hidden", MainThreadOnly().renderer_hidden); | 1343 state->SetBoolean("renderer_hidden", MainThreadOnly().renderer_hidden); |
1336 state->SetBoolean("have_seen_a_begin_main_frame", | 1344 state->SetBoolean("have_seen_a_begin_main_frame", |
1337 MainThreadOnly().have_seen_a_begin_main_frame); | 1345 MainThreadOnly().have_seen_a_begin_main_frame); |
1346 state->SetBoolean("waiting_for_meaningful_paint", | |
1347 AnyThread().waiting_for_meaningful_paint); | |
1348 state->SetBoolean("have_seen_input_since_navigation", | |
1349 AnyThread().have_seen_input_since_navigation); | |
1338 state->SetBoolean( | 1350 state->SetBoolean( |
1339 "have_reported_blocking_intervention_in_current_policy", | 1351 "have_reported_blocking_intervention_in_current_policy", |
1340 MainThreadOnly().have_reported_blocking_intervention_in_current_policy); | 1352 MainThreadOnly().have_reported_blocking_intervention_in_current_policy); |
1341 state->SetBoolean( | 1353 state->SetBoolean( |
1342 "have_reported_blocking_intervention_since_navigation", | 1354 "have_reported_blocking_intervention_since_navigation", |
1343 MainThreadOnly().have_reported_blocking_intervention_since_navigation); | 1355 MainThreadOnly().have_reported_blocking_intervention_since_navigation); |
1344 state->SetBoolean("renderer_backgrounded", | 1356 state->SetBoolean("renderer_backgrounded", |
1345 MainThreadOnly().renderer_backgrounded); | 1357 MainThreadOnly().renderer_backgrounded); |
1346 state->SetBoolean("timer_queue_suspended_when_backgrounded", | 1358 state->SetBoolean("timer_queue_suspended_when_backgrounded", |
1347 MainThreadOnly().timer_queue_suspended_when_backgrounded); | 1359 MainThreadOnly().timer_queue_suspended_when_backgrounded); |
1348 state->SetInteger("timer_queue_suspend_count", | 1360 state->SetInteger("timer_queue_suspend_count", |
1349 MainThreadOnly().timer_queue_suspend_count); | 1361 MainThreadOnly().timer_queue_suspend_count); |
1350 state->SetDouble("now", (optional_now - base::TimeTicks()).InMillisecondsF()); | 1362 state->SetDouble("now", (optional_now - base::TimeTicks()).InMillisecondsF()); |
1351 state->SetDouble( | 1363 state->SetDouble( |
1352 "rails_loading_priority_deadline", | |
1353 (AnyThread().rails_loading_priority_deadline - base::TimeTicks()) | |
1354 .InMillisecondsF()); | |
1355 state->SetDouble( | |
1356 "fling_compositor_escalation_deadline", | 1364 "fling_compositor_escalation_deadline", |
1357 (AnyThread().fling_compositor_escalation_deadline - base::TimeTicks()) | 1365 (AnyThread().fling_compositor_escalation_deadline - base::TimeTicks()) |
1358 .InMillisecondsF()); | 1366 .InMillisecondsF()); |
1359 state->SetInteger("navigation_task_expected_count", | 1367 state->SetInteger("navigation_task_expected_count", |
1360 MainThreadOnly().navigation_task_expected_count); | 1368 MainThreadOnly().navigation_task_expected_count); |
1361 state->SetDouble("last_idle_period_end_time", | 1369 state->SetDouble("last_idle_period_end_time", |
1362 (AnyThread().last_idle_period_end_time - base::TimeTicks()) | 1370 (AnyThread().last_idle_period_end_time - base::TimeTicks()) |
1363 .InMillisecondsF()); | 1371 .InMillisecondsF()); |
1364 state->SetBoolean("awaiting_touch_start_response", | 1372 state->SetBoolean("awaiting_touch_start_response", |
1365 AnyThread().awaiting_touch_start_response); | 1373 AnyThread().awaiting_touch_start_response); |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1471 MainThreadOnly().navigation_task_expected_count > 0) { | 1479 MainThreadOnly().navigation_task_expected_count > 0) { |
1472 MainThreadOnly().navigation_task_expected_count--; | 1480 MainThreadOnly().navigation_task_expected_count--; |
1473 UpdatePolicy(); | 1481 UpdatePolicy(); |
1474 } | 1482 } |
1475 } | 1483 } |
1476 | 1484 |
1477 void RendererSchedulerImpl::OnNavigationStarted() { | 1485 void RendererSchedulerImpl::OnNavigationStarted() { |
1478 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), | 1486 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), |
1479 "RendererSchedulerImpl::OnNavigationStarted"); | 1487 "RendererSchedulerImpl::OnNavigationStarted"); |
1480 base::AutoLock lock(any_thread_lock_); | 1488 base::AutoLock lock(any_thread_lock_); |
1481 AnyThread().rails_loading_priority_deadline = | |
1482 helper_.scheduler_tqm_delegate()->NowTicks() + | |
1483 base::TimeDelta::FromMilliseconds( | |
1484 kRailsInitialLoadingPrioritizationMillis); | |
1485 ResetForNavigationLocked(); | 1489 ResetForNavigationLocked(); |
1486 } | 1490 } |
1487 | 1491 |
1492 void RendererSchedulerImpl::OnFirstMeaningfulPaint() { | |
1493 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), | |
1494 "RendererSchedulerImpl::OnFirstMeaningfulPaint"); | |
1495 { | |
1496 base::AutoLock lock(any_thread_lock_); | |
1497 AnyThread().waiting_for_meaningful_paint = false; | |
1498 } | |
1499 UpdatePolicy(); | |
alex clarke (OOO till 29th)
2016/11/24 17:54:23
Can we call
UpdatePolicyLocked(UpdateType::MAY_
Sami
2016/11/24 18:41:37
Oh, well spotted, thanks!
| |
1500 } | |
1501 | |
1488 void RendererSchedulerImpl::SuspendTimerQueueWhenBackgrounded() { | 1502 void RendererSchedulerImpl::SuspendTimerQueueWhenBackgrounded() { |
1489 DCHECK(MainThreadOnly().renderer_backgrounded); | 1503 DCHECK(MainThreadOnly().renderer_backgrounded); |
1490 if (MainThreadOnly().timer_queue_suspended_when_backgrounded) | 1504 if (MainThreadOnly().timer_queue_suspended_when_backgrounded) |
1491 return; | 1505 return; |
1492 | 1506 |
1493 MainThreadOnly().timer_queue_suspended_when_backgrounded = true; | 1507 MainThreadOnly().timer_queue_suspended_when_backgrounded = true; |
1494 ForceUpdatePolicy(); | 1508 ForceUpdatePolicy(); |
1495 } | 1509 } |
1496 | 1510 |
1497 void RendererSchedulerImpl::ResumeTimerQueueWhenForegroundedOrResumed() { | 1511 void RendererSchedulerImpl::ResumeTimerQueueWhenForegroundedOrResumed() { |
1498 DCHECK(!MainThreadOnly().renderer_backgrounded || | 1512 DCHECK(!MainThreadOnly().renderer_backgrounded || |
1499 (MainThreadOnly().renderer_backgrounded && | 1513 (MainThreadOnly().renderer_backgrounded && |
1500 !MainThreadOnly().renderer_suspended)); | 1514 !MainThreadOnly().renderer_suspended)); |
1501 if (!MainThreadOnly().timer_queue_suspended_when_backgrounded) | 1515 if (!MainThreadOnly().timer_queue_suspended_when_backgrounded) |
1502 return; | 1516 return; |
1503 | 1517 |
1504 MainThreadOnly().timer_queue_suspended_when_backgrounded = false; | 1518 MainThreadOnly().timer_queue_suspended_when_backgrounded = false; |
1505 ForceUpdatePolicy(); | 1519 ForceUpdatePolicy(); |
1506 } | 1520 } |
1507 | 1521 |
1508 void RendererSchedulerImpl::ResetForNavigationLocked() { | 1522 void RendererSchedulerImpl::ResetForNavigationLocked() { |
1509 helper_.CheckOnValidThread(); | 1523 helper_.CheckOnValidThread(); |
1510 any_thread_lock_.AssertAcquired(); | 1524 any_thread_lock_.AssertAcquired(); |
1511 AnyThread().user_model.Reset(helper_.scheduler_tqm_delegate()->NowTicks()); | 1525 AnyThread().user_model.Reset(helper_.scheduler_tqm_delegate()->NowTicks()); |
1512 AnyThread().have_seen_touchstart = false; | 1526 AnyThread().have_seen_touchstart = false; |
1527 AnyThread().waiting_for_meaningful_paint = true; | |
1528 AnyThread().have_seen_input_since_navigation = false; | |
1513 MainThreadOnly().loading_task_cost_estimator.Clear(); | 1529 MainThreadOnly().loading_task_cost_estimator.Clear(); |
1514 MainThreadOnly().timer_task_cost_estimator.Clear(); | 1530 MainThreadOnly().timer_task_cost_estimator.Clear(); |
1515 MainThreadOnly().idle_time_estimator.Clear(); | 1531 MainThreadOnly().idle_time_estimator.Clear(); |
1516 MainThreadOnly().have_seen_a_begin_main_frame = false; | 1532 MainThreadOnly().have_seen_a_begin_main_frame = false; |
1517 MainThreadOnly().have_reported_blocking_intervention_since_navigation = false; | 1533 MainThreadOnly().have_reported_blocking_intervention_since_navigation = false; |
1518 for (WebViewSchedulerImpl* web_view_scheduler : | 1534 for (WebViewSchedulerImpl* web_view_scheduler : |
1519 MainThreadOnly().web_view_schedulers) { | 1535 MainThreadOnly().web_view_schedulers) { |
1520 web_view_scheduler->OnNavigation(); | 1536 web_view_scheduler->OnNavigation(); |
1521 } | 1537 } |
1522 UpdatePolicyLocked(UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED); | 1538 UpdatePolicyLocked(UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED); |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1752 case TimeDomainType::VIRTUAL: | 1768 case TimeDomainType::VIRTUAL: |
1753 return "virtual"; | 1769 return "virtual"; |
1754 default: | 1770 default: |
1755 NOTREACHED(); | 1771 NOTREACHED(); |
1756 return nullptr; | 1772 return nullptr; |
1757 } | 1773 } |
1758 } | 1774 } |
1759 | 1775 |
1760 } // namespace scheduler | 1776 } // namespace scheduler |
1761 } // namespace blink | 1777 } // namespace blink |
OLD | NEW |