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/trace_event/trace_event.h" | 9 #include "base/trace_event/trace_event.h" |
10 #include "base/trace_event/trace_event_argument.h" | 10 #include "base/trace_event/trace_event_argument.h" |
11 #include "cc/output/begin_frame_args.h" | 11 #include "cc/output/begin_frame_args.h" |
12 #include "components/scheduler/child/scheduler_task_runner_delegate.h" | 12 #include "components/scheduler/child/scheduler_task_runner_delegate.h" |
13 #include "components/scheduler/child/task_queue_impl.h" | 13 #include "components/scheduler/child/task_queue_impl.h" |
14 #include "components/scheduler/child/task_queue_selector.h" | 14 #include "components/scheduler/child/task_queue_selector.h" |
15 | 15 |
16 namespace scheduler { | 16 namespace scheduler { |
17 namespace { | 17 namespace { |
18 const int kTimerTaskEstimationSampleCount = 4 * 60; | 18 const int kLoadingTaskEstimationSampleCount = 200; |
19 const double kTimerTaskEstimationPercentile = 80; | 19 const double kLoadingTaskEstimationPercentile = 90; |
20 const int kTimerTaskEstimationSampleCount = 200; | |
21 const double kTimerTaskEstimationPercentile = 90; | |
Sami
2015/08/26 13:38:01
Any reason for tweaking these in this way?
alex clarke (OOO till 29th)
2015/08/27 12:02:51
Yes, I was hoping for a more pessimistic result th
| |
20 const int kShortIdlePeriodDurationSampleCount = 10; | 22 const int kShortIdlePeriodDurationSampleCount = 10; |
21 const double kShortIdlePeriodDurationPercentile = 20; | 23 const double kShortIdlePeriodDurationPercentile = 20; |
22 } | 24 } |
23 | 25 |
24 RendererSchedulerImpl::RendererSchedulerImpl( | 26 RendererSchedulerImpl::RendererSchedulerImpl( |
25 scoped_refptr<SchedulerTaskRunnerDelegate> main_task_runner) | 27 scoped_refptr<SchedulerTaskRunnerDelegate> main_task_runner) |
26 : helper_(main_task_runner, | 28 : helper_(main_task_runner, |
27 "renderer.scheduler", | 29 "renderer.scheduler", |
28 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), | 30 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), |
29 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler.debug")), | 31 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler.debug")), |
(...skipping 17 matching lines...) Expand all Loading... | |
47 base::Bind(&RendererSchedulerImpl::UpdatePolicy, | 49 base::Bind(&RendererSchedulerImpl::UpdatePolicy, |
48 base::Unretained(this)), | 50 base::Unretained(this)), |
49 helper_.ControlTaskRunner()), | 51 helper_.ControlTaskRunner()), |
50 policy_may_need_update_(&any_thread_lock_), | 52 policy_may_need_update_(&any_thread_lock_), |
51 weak_factory_(this) { | 53 weak_factory_(this) { |
52 update_policy_closure_ = base::Bind(&RendererSchedulerImpl::UpdatePolicy, | 54 update_policy_closure_ = base::Bind(&RendererSchedulerImpl::UpdatePolicy, |
53 weak_factory_.GetWeakPtr()); | 55 weak_factory_.GetWeakPtr()); |
54 end_renderer_hidden_idle_period_closure_.Reset(base::Bind( | 56 end_renderer_hidden_idle_period_closure_.Reset(base::Bind( |
55 &RendererSchedulerImpl::EndIdlePeriod, weak_factory_.GetWeakPtr())); | 57 &RendererSchedulerImpl::EndIdlePeriod, weak_factory_.GetWeakPtr())); |
56 | 58 |
59 loading_task_runner_->AddTaskObserver( | |
60 &MainThreadOnly().loading_task_cost_estimator_); | |
61 | |
57 timer_task_runner_->AddTaskObserver( | 62 timer_task_runner_->AddTaskObserver( |
58 &MainThreadOnly().timer_task_cost_estimator_); | 63 &MainThreadOnly().timer_task_cost_estimator_); |
59 | 64 |
60 TRACE_EVENT_OBJECT_CREATED_WITH_ID( | 65 TRACE_EVENT_OBJECT_CREATED_WITH_ID( |
61 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler", | 66 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler", |
62 this); | 67 this); |
68 | |
69 // Make sure that we don't initially assume there is no idle time. | |
70 MainThreadOnly().short_idle_period_duration_.InsertSample( | |
71 base::TimeDelta::FromMilliseconds(16)); | |
Sami
2015/08/26 13:38:01
BeginFrameArgs::DefaultInterval()?
alex clarke (OOO till 29th)
2015/08/27 12:02:51
Done.
| |
63 } | 72 } |
64 | 73 |
65 RendererSchedulerImpl::~RendererSchedulerImpl() { | 74 RendererSchedulerImpl::~RendererSchedulerImpl() { |
66 TRACE_EVENT_OBJECT_DELETED_WITH_ID( | 75 TRACE_EVENT_OBJECT_DELETED_WITH_ID( |
67 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler", | 76 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler", |
68 this); | 77 this); |
69 timer_task_runner_->RemoveTaskObserver( | 78 timer_task_runner_->RemoveTaskObserver( |
70 &MainThreadOnly().timer_task_cost_estimator_); | 79 &MainThreadOnly().timer_task_cost_estimator_); |
71 // Ensure the renderer scheduler was shut down explicitly, because otherwise | 80 // Ensure the renderer scheduler was shut down explicitly, because otherwise |
72 // we could end up having stale pointers to the Blink heap which has been | 81 // we could end up having stale pointers to the Blink heap which has been |
73 // terminated by this point. | 82 // terminated by this point. |
74 DCHECK(MainThreadOnly().was_shutdown_); | 83 DCHECK(MainThreadOnly().was_shutdown_); |
75 } | 84 } |
76 | 85 |
86 RendererSchedulerImpl::Policy::Policy() | |
87 : compositor_queue_priority_(TaskQueue::NORMAL_PRIORITY), | |
88 loading_queue_priority_(TaskQueue::NORMAL_PRIORITY), | |
89 timer_queue_priority_(TaskQueue::NORMAL_PRIORITY) {} | |
90 | |
77 RendererSchedulerImpl::MainThreadOnly::MainThreadOnly() | 91 RendererSchedulerImpl::MainThreadOnly::MainThreadOnly() |
78 : timer_task_cost_estimator_(kTimerTaskEstimationSampleCount, | 92 : loading_task_cost_estimator_(kLoadingTaskEstimationSampleCount, |
93 kLoadingTaskEstimationPercentile), | |
94 timer_task_cost_estimator_(kTimerTaskEstimationSampleCount, | |
79 kTimerTaskEstimationPercentile), | 95 kTimerTaskEstimationPercentile), |
80 short_idle_period_duration_(kShortIdlePeriodDurationSampleCount), | 96 short_idle_period_duration_(kShortIdlePeriodDurationSampleCount), |
81 current_policy_(Policy::NORMAL), | 97 current_use_case_(UseCase::NOT_SCROLLING), |
82 timer_queue_suspend_count_(0), | 98 timer_queue_suspend_count_(0), |
83 renderer_hidden_(false), | 99 renderer_hidden_(false), |
84 was_shutdown_(false) {} | 100 was_shutdown_(false), |
101 loading_tasks_seem_expensive_(false), | |
102 timer_tasks_seem_expensive_(false) {} | |
85 | 103 |
86 RendererSchedulerImpl::MainThreadOnly::~MainThreadOnly() {} | 104 RendererSchedulerImpl::MainThreadOnly::~MainThreadOnly() {} |
87 | 105 |
88 RendererSchedulerImpl::AnyThread::AnyThread() | 106 RendererSchedulerImpl::AnyThread::AnyThread() |
89 : pending_main_thread_input_event_count_(0), | 107 : pending_main_thread_input_event_count_(0), |
90 awaiting_touch_start_response_(false), | 108 awaiting_touch_start_response_(false), |
91 in_idle_period_(false), | 109 in_idle_period_(false), |
92 begin_main_frame_on_critical_path_(false), | 110 begin_main_frame_on_critical_path_(false) {} |
93 timer_tasks_seem_expensive_(false) {} | |
94 | 111 |
95 RendererSchedulerImpl::CompositorThreadOnly::CompositorThreadOnly() | 112 RendererSchedulerImpl::CompositorThreadOnly::CompositorThreadOnly() |
96 : last_input_type_(blink::WebInputEvent::Undefined) { | 113 : last_input_type_(blink::WebInputEvent::Undefined) { |
97 } | 114 } |
98 | 115 |
99 RendererSchedulerImpl::CompositorThreadOnly::~CompositorThreadOnly() { | 116 RendererSchedulerImpl::CompositorThreadOnly::~CompositorThreadOnly() { |
100 } | 117 } |
101 | 118 |
102 void RendererSchedulerImpl::Shutdown() { | 119 void RendererSchedulerImpl::Shutdown() { |
103 helper_.Shutdown(); | 120 helper_.Shutdown(); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
169 | 186 |
170 base::TimeTicks now(helper_.Now()); | 187 base::TimeTicks now(helper_.Now()); |
171 if (now < MainThreadOnly().estimated_next_frame_begin_) { | 188 if (now < MainThreadOnly().estimated_next_frame_begin_) { |
172 // TODO(rmcilroy): Consider reducing the idle period based on the runtime of | 189 // TODO(rmcilroy): Consider reducing the idle period based on the runtime of |
173 // the next pending delayed tasks (as currently done in for long idle times) | 190 // the next pending delayed tasks (as currently done in for long idle times) |
174 idle_helper_.StartIdlePeriod( | 191 idle_helper_.StartIdlePeriod( |
175 IdleHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD, now, | 192 IdleHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD, now, |
176 MainThreadOnly().estimated_next_frame_begin_); | 193 MainThreadOnly().estimated_next_frame_begin_); |
177 MainThreadOnly().short_idle_period_duration_.InsertSample( | 194 MainThreadOnly().short_idle_period_duration_.InsertSample( |
178 MainThreadOnly().estimated_next_frame_begin_ - now); | 195 MainThreadOnly().estimated_next_frame_begin_ - now); |
179 MainThreadOnly().expected_short_idle_period_duration_ = | 196 } else { |
180 MainThreadOnly().short_idle_period_duration_.Percentile( | 197 // There was no idle time :( |
181 kShortIdlePeriodDurationPercentile); | 198 MainThreadOnly().short_idle_period_duration_.InsertSample( |
199 base::TimeDelta()); | |
182 } | 200 } |
201 | |
202 MainThreadOnly().expected_short_idle_period_duration_ = | |
203 MainThreadOnly().short_idle_period_duration_.Percentile( | |
204 kShortIdlePeriodDurationPercentile); | |
183 } | 205 } |
184 | 206 |
185 void RendererSchedulerImpl::BeginFrameNotExpectedSoon() { | 207 void RendererSchedulerImpl::BeginFrameNotExpectedSoon() { |
186 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), | 208 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), |
187 "RendererSchedulerImpl::BeginFrameNotExpectedSoon"); | 209 "RendererSchedulerImpl::BeginFrameNotExpectedSoon"); |
188 helper_.CheckOnValidThread(); | 210 helper_.CheckOnValidThread(); |
189 if (helper_.IsShutdown()) | 211 if (helper_.IsShutdown()) |
190 return; | 212 return; |
191 | 213 |
192 idle_helper_.EnableLongIdlePeriod(); | 214 idle_helper_.EnableLongIdlePeriod(); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
271 } | 293 } |
272 | 294 |
273 void RendererSchedulerImpl::DidAnimateForInputOnCompositorThread() { | 295 void RendererSchedulerImpl::DidAnimateForInputOnCompositorThread() { |
274 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), | 296 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), |
275 "RendererSchedulerImpl::DidAnimateForInputOnCompositorThread"); | 297 "RendererSchedulerImpl::DidAnimateForInputOnCompositorThread"); |
276 UpdateForInputEventOnCompositorThread( | 298 UpdateForInputEventOnCompositorThread( |
277 blink::WebInputEvent::Undefined, | 299 blink::WebInputEvent::Undefined, |
278 InputEventState::EVENT_CONSUMED_BY_COMPOSITOR); | 300 InputEventState::EVENT_CONSUMED_BY_COMPOSITOR); |
279 } | 301 } |
280 | 302 |
303 const char* WebInputEventToString(blink::WebInputEvent::Type type) { | |
304 #define CASE_TYPE(t) \ | |
305 case blink::WebInputEvent::t: \ | |
306 return #t | |
307 switch (type) { | |
308 CASE_TYPE(Undefined); | |
Sami
2015/08/26 13:38:01
Instead of duplicating this from RenderWidget, cou
alex clarke (OOO till 29th)
2015/08/27 12:02:51
Acknowledged.
| |
309 CASE_TYPE(MouseDown); | |
310 CASE_TYPE(MouseUp); | |
311 CASE_TYPE(MouseMove); | |
312 CASE_TYPE(MouseEnter); | |
313 CASE_TYPE(MouseLeave); | |
314 CASE_TYPE(ContextMenu); | |
315 CASE_TYPE(MouseWheel); | |
316 CASE_TYPE(RawKeyDown); | |
317 CASE_TYPE(KeyDown); | |
318 CASE_TYPE(KeyUp); | |
319 CASE_TYPE(Char); | |
320 CASE_TYPE(GestureScrollBegin); | |
321 CASE_TYPE(GestureScrollEnd); | |
322 CASE_TYPE(GestureScrollUpdate); | |
323 CASE_TYPE(GestureFlingStart); | |
324 CASE_TYPE(GestureFlingCancel); | |
325 CASE_TYPE(GestureShowPress); | |
326 CASE_TYPE(GestureTap); | |
327 CASE_TYPE(GestureTapUnconfirmed); | |
328 CASE_TYPE(GestureTapDown); | |
329 CASE_TYPE(GestureTapCancel); | |
330 CASE_TYPE(GestureDoubleTap); | |
331 CASE_TYPE(GestureTwoFingerTap); | |
332 CASE_TYPE(GestureLongPress); | |
333 CASE_TYPE(GestureLongTap); | |
334 CASE_TYPE(GesturePinchBegin); | |
335 CASE_TYPE(GesturePinchEnd); | |
336 CASE_TYPE(GesturePinchUpdate); | |
337 CASE_TYPE(TouchStart); | |
338 CASE_TYPE(TouchMove); | |
339 CASE_TYPE(TouchEnd); | |
340 CASE_TYPE(TouchCancel); | |
341 } | |
342 return ""; | |
343 } | |
344 | |
281 void RendererSchedulerImpl::UpdateForInputEventOnCompositorThread( | 345 void RendererSchedulerImpl::UpdateForInputEventOnCompositorThread( |
282 blink::WebInputEvent::Type type, | 346 blink::WebInputEvent::Type type, |
283 InputEventState input_event_state) { | 347 InputEventState input_event_state) { |
284 base::AutoLock lock(any_thread_lock_); | 348 base::AutoLock lock(any_thread_lock_); |
285 base::TimeTicks now = helper_.Now(); | 349 base::TimeTicks now = helper_.Now(); |
286 bool was_in_compositor_priority = InputSignalsSuggestCompositorPriority(now); | 350 bool already_scrolling = InputSignalsSuggestScrolling(now); |
287 bool was_awaiting_touch_start_response = | 351 bool was_awaiting_touch_start_response = |
288 AnyThread().awaiting_touch_start_response_; | 352 AnyThread().awaiting_touch_start_response_; |
289 | 353 |
290 if (type) { | 354 if (type) { |
291 switch (type) { | 355 switch (type) { |
292 case blink::WebInputEvent::TouchStart: | 356 case blink::WebInputEvent::TouchStart: |
293 AnyThread().awaiting_touch_start_response_ = true; | 357 AnyThread().awaiting_touch_start_response_ = true; |
358 AnyThread().last_touchstart_time_ = now; | |
294 break; | 359 break; |
295 | 360 |
296 case blink::WebInputEvent::TouchMove: | 361 case blink::WebInputEvent::TouchMove: |
297 // Observation of consecutive touchmoves is a strong signal that the | 362 // Observation of consecutive touchmoves is a strong signal that the |
298 // page is consuming the touch sequence, in which case touchstart | 363 // page is consuming the touch sequence, in which case touchstart |
299 // response prioritization is no longer necessary. Otherwise, the | 364 // response prioritization is no longer necessary. Otherwise, the |
300 // initial touchmove should preserve the touchstart response pending | 365 // initial touchmove should preserve the touchstart response pending |
301 // state. | 366 // state. |
302 if (AnyThread().awaiting_touch_start_response_ && | 367 if (AnyThread().awaiting_touch_start_response_ && |
303 CompositorThreadOnly().last_input_type_ == | 368 CompositorThreadOnly().last_input_type_ == |
(...skipping 11 matching lines...) Expand all Loading... | |
315 // meaningful touchstart response and should not impact task priority. | 380 // meaningful touchstart response and should not impact task priority. |
316 break; | 381 break; |
317 | 382 |
318 default: | 383 default: |
319 AnyThread().awaiting_touch_start_response_ = false; | 384 AnyThread().awaiting_touch_start_response_ = false; |
320 break; | 385 break; |
321 } | 386 } |
322 } | 387 } |
323 | 388 |
324 // Avoid unnecessary policy updates, while in compositor priority. | 389 // Avoid unnecessary policy updates, while in compositor priority. |
325 if (!was_in_compositor_priority || | 390 if (!already_scrolling || |
326 was_awaiting_touch_start_response != | 391 was_awaiting_touch_start_response != |
327 AnyThread().awaiting_touch_start_response_) { | 392 AnyThread().awaiting_touch_start_response_) { |
328 EnsureUrgentPolicyUpdatePostedOnMainThread(FROM_HERE); | 393 EnsureUrgentPolicyUpdatePostedOnMainThread(FROM_HERE); |
329 } | 394 } |
330 AnyThread().last_input_signal_time_ = now; | 395 AnyThread().last_input_signal_time_ = now; |
331 CompositorThreadOnly().last_input_type_ = type; | 396 CompositorThreadOnly().last_input_type_ = type; |
332 | 397 |
333 if (input_event_state == InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD) | 398 if (input_event_state == InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD) { |
399 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), | |
400 "InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD", "type", | |
401 WebInputEventToString(type)); | |
334 AnyThread().pending_main_thread_input_event_count_++; | 402 AnyThread().pending_main_thread_input_event_count_++; |
403 } | |
335 } | 404 } |
336 | 405 |
337 void RendererSchedulerImpl::DidHandleInputEventOnMainThread( | 406 void RendererSchedulerImpl::DidHandleInputEventOnMainThread( |
338 const blink::WebInputEvent& web_input_event) { | 407 const blink::WebInputEvent& web_input_event) { |
339 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), | 408 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), |
340 "RendererSchedulerImpl::DidHandleInputEventOnMainThread"); | 409 "RendererSchedulerImpl::DidHandleInputEventOnMainThread"); |
341 helper_.CheckOnValidThread(); | 410 helper_.CheckOnValidThread(); |
342 if (ShouldPrioritizeInputEvent(web_input_event)) { | 411 if (ShouldPrioritizeInputEvent(web_input_event)) { |
343 base::AutoLock lock(any_thread_lock_); | 412 base::AutoLock lock(any_thread_lock_); |
344 AnyThread().last_input_signal_time_ = helper_.Now(); | 413 AnyThread().last_input_signal_time_ = helper_.Now(); |
345 if (AnyThread().pending_main_thread_input_event_count_ > 0) | 414 if (AnyThread().pending_main_thread_input_event_count_ > 0) |
346 AnyThread().pending_main_thread_input_event_count_--; | 415 AnyThread().pending_main_thread_input_event_count_--; |
347 } | 416 } |
348 } | 417 } |
349 | 418 |
350 bool RendererSchedulerImpl::IsHighPriorityWorkAnticipated() { | 419 bool RendererSchedulerImpl::IsHighPriorityWorkAnticipated() { |
351 helper_.CheckOnValidThread(); | 420 helper_.CheckOnValidThread(); |
352 if (helper_.IsShutdown()) | 421 if (helper_.IsShutdown()) |
353 return false; | 422 return false; |
354 | 423 |
355 MaybeUpdatePolicy(); | 424 MaybeUpdatePolicy(); |
356 // The touchstart and compositor policies indicate a strong likelihood of | 425 // The touchstart and main-thread scrolling states indicate a strong |
357 // high-priority work in the near future. | 426 // likelihood of high-priority work in the near future. |
358 return MainThreadOnly().current_policy_ == Policy::COMPOSITOR_PRIORITY || | 427 UseCase use_case = MainThreadOnly().current_use_case_; |
359 MainThreadOnly().current_policy_ == | 428 return MainThreadOnly().scroll_expected_soon_ || |
360 Policy::COMPOSITOR_CRITICAL_PATH_PRIORITY || | 429 use_case == UseCase::MAINTHREAD_SCROLLING || |
361 MainThreadOnly().current_policy_ == Policy::TOUCHSTART_PRIORITY; | 430 use_case == UseCase::TOUCHSTART; |
362 } | 431 } |
363 | 432 |
364 bool RendererSchedulerImpl::ShouldYieldForHighPriorityWork() { | 433 bool RendererSchedulerImpl::ShouldYieldForHighPriorityWork() { |
365 helper_.CheckOnValidThread(); | 434 helper_.CheckOnValidThread(); |
366 if (helper_.IsShutdown()) | 435 if (helper_.IsShutdown()) |
367 return false; | 436 return false; |
368 | 437 |
369 MaybeUpdatePolicy(); | 438 MaybeUpdatePolicy(); |
370 // We only yield if we are in the compositor priority and there is compositor | 439 // We only yield if there's a urgent task to be run now, or we are expecting |
371 // work outstanding, or if we are in the touchstart response priority. | 440 // one soon (touch start). |
372 // Note: even though the control queue is higher priority we don't yield for | 441 // Note: even though the control queue has the highest priority we don't yield |
373 // it since these tasks are not user-provided work and they are only intended | 442 // for it since these tasks are not user-provided work and they are only |
374 // to run before the next task, not interrupt the tasks. | 443 // intended to run before the next task, not interrupt the tasks. |
375 switch (MainThreadOnly().current_policy_) { | 444 switch (MainThreadOnly().current_use_case_) { |
376 case Policy::NORMAL: | 445 case UseCase::NOT_SCROLLING: |
Sami
2015/08/26 13:38:01
Could we not be expecting a scroll in this state?
alex clarke (OOO till 29th)
2015/08/27 12:02:51
Yeah we could. Maybe we should yeild in that situ
| |
377 return false; | 446 return false; |
378 | 447 |
379 case Policy::COMPOSITOR_PRIORITY: | 448 case UseCase::COMPOSITOR_SCROLLING: |
449 return MainThreadOnly().scroll_expected_soon_; | |
450 | |
451 case UseCase::MAINTHREAD_SCROLLING: | |
380 return !compositor_task_runner_->IsQueueEmpty(); | 452 return !compositor_task_runner_->IsQueueEmpty(); |
381 | 453 |
382 case Policy::COMPOSITOR_CRITICAL_PATH_PRIORITY: | 454 case UseCase::TOUCHSTART: |
383 return !compositor_task_runner_->IsQueueEmpty(); | |
384 | |
385 case Policy::TOUCHSTART_PRIORITY: | |
386 return true; | 455 return true; |
387 | 456 |
388 case Policy::LOADING_PRIORITY: | 457 case UseCase::LOADING: |
389 return false; | 458 return false; |
390 | 459 |
391 default: | 460 default: |
392 NOTREACHED(); | 461 NOTREACHED(); |
393 return false; | 462 return false; |
394 } | 463 } |
395 } | 464 } |
396 | 465 |
397 base::TimeTicks RendererSchedulerImpl::CurrentIdleTaskDeadlineForTesting() | 466 base::TimeTicks RendererSchedulerImpl::CurrentIdleTaskDeadlineForTesting() |
398 const { | 467 const { |
(...skipping 21 matching lines...) Expand all Loading... | |
420 void RendererSchedulerImpl::UpdatePolicy() { | 489 void RendererSchedulerImpl::UpdatePolicy() { |
421 base::AutoLock lock(any_thread_lock_); | 490 base::AutoLock lock(any_thread_lock_); |
422 UpdatePolicyLocked(UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED); | 491 UpdatePolicyLocked(UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED); |
423 } | 492 } |
424 | 493 |
425 void RendererSchedulerImpl::ForceUpdatePolicy() { | 494 void RendererSchedulerImpl::ForceUpdatePolicy() { |
426 base::AutoLock lock(any_thread_lock_); | 495 base::AutoLock lock(any_thread_lock_); |
427 UpdatePolicyLocked(UpdateType::FORCE_UPDATE); | 496 UpdatePolicyLocked(UpdateType::FORCE_UPDATE); |
428 } | 497 } |
429 | 498 |
499 bool RendererSchedulerImpl::ScrollExpectedSoon( | |
500 UseCase use_case, | |
501 const base::TimeTicks now, | |
502 base::TimeDelta* new_policy_duration) const { | |
503 if (use_case == UseCase::NOT_SCROLLING) { | |
504 // If we've scrolled recently then future scrolling is likely. | |
505 base::TimeDelta expect_subsequent_input_for = | |
506 base::TimeDelta::FromMilliseconds(kExpectSubsequentInputMillis); | |
507 if (AnyThread().last_input_signal_time_.is_null() || | |
508 AnyThread().last_input_signal_time_ + expect_subsequent_input_for <= | |
509 now) { | |
510 return false; | |
511 } | |
512 *new_policy_duration = | |
513 AnyThread().last_input_signal_time_ + expect_subsequent_input_for - now; | |
514 return true; | |
515 } | |
516 | |
517 if (use_case == UseCase::COMPOSITOR_SCROLLING) { | |
518 // If we've only just started scrolling then, then future scrolling is | |
519 // unlikely. | |
520 base::TimeDelta minimum_typical_scroll_duration = | |
521 base::TimeDelta::FromMilliseconds(kMinimumTypicalScrollDurationMillis); | |
522 if (AnyThread().last_touchstart_time_.is_null() || | |
Sami
2015/08/26 13:38:01
Touchstart doesn't get sent if there are no touch
alex clarke (OOO till 29th)
2015/08/27 12:02:51
Maybe this function is badly named then (see comme
| |
523 AnyThread().last_touchstart_time_ + minimum_typical_scroll_duration <= | |
524 now) { | |
525 return true; | |
526 } | |
527 *new_policy_duration = AnyThread().last_touchstart_time_ + | |
528 minimum_typical_scroll_duration - now; | |
529 return false; | |
530 } | |
531 return false; | |
Sami
2015/08/26 13:38:01
Should we always return true for main thread scrol
alex clarke (OOO till 29th)
2015/08/27 12:02:51
Good question. I think that depends on what we wa
| |
532 } | |
533 | |
430 void RendererSchedulerImpl::UpdatePolicyLocked(UpdateType update_type) { | 534 void RendererSchedulerImpl::UpdatePolicyLocked(UpdateType update_type) { |
431 helper_.CheckOnValidThread(); | 535 helper_.CheckOnValidThread(); |
432 any_thread_lock_.AssertAcquired(); | 536 any_thread_lock_.AssertAcquired(); |
433 if (helper_.IsShutdown()) | 537 if (helper_.IsShutdown()) |
434 return; | 538 return; |
435 | 539 |
436 base::TimeTicks now = helper_.Now(); | 540 base::TimeTicks now = helper_.Now(); |
437 policy_may_need_update_.SetWhileLocked(false); | 541 policy_may_need_update_.SetWhileLocked(false); |
438 | 542 |
439 AnyThread().timer_tasks_seem_expensive_ = | 543 base::TimeDelta new_policy_duration; |
440 MainThreadOnly().expected_short_idle_period_duration_ > | 544 UseCase use_case = ComputeCurrentUseCase(now, &new_policy_duration); |
441 base::TimeDelta() && | 545 |
546 // Adjust the policy duration if |scroll_expected_soon| is likely to change. | |
547 bool scroll_expected_soon = ScrollExpectedSoon(use_case, | |
548 now, | |
549 &new_policy_duration); | |
550 bool loading_tasks_seem_expensive = | |
551 MainThreadOnly().loading_task_cost_estimator_.expected_task_duration() > | |
552 MainThreadOnly().expected_short_idle_period_duration_; | |
553 bool timer_tasks_seem_expensive = | |
442 MainThreadOnly().timer_task_cost_estimator_.expected_task_duration() > | 554 MainThreadOnly().timer_task_cost_estimator_.expected_task_duration() > |
443 MainThreadOnly().expected_short_idle_period_duration_; | 555 MainThreadOnly().expected_short_idle_period_duration_; |
556 MainThreadOnly().scroll_expected_soon_ = scroll_expected_soon; | |
557 MainThreadOnly().loading_tasks_seem_expensive_ = loading_tasks_seem_expensive; | |
558 MainThreadOnly().timer_tasks_seem_expensive_ = timer_tasks_seem_expensive; | |
444 | 559 |
445 base::TimeDelta new_policy_duration; | |
446 Policy new_policy = ComputeNewPolicy(now, &new_policy_duration); | |
447 if (new_policy_duration > base::TimeDelta()) { | 560 if (new_policy_duration > base::TimeDelta()) { |
448 MainThreadOnly().current_policy_expiration_time_ = | 561 MainThreadOnly().current_policy_expiration_time_ = |
449 now + new_policy_duration; | 562 now + new_policy_duration; |
450 delayed_update_policy_runner_.SetDeadline(FROM_HERE, new_policy_duration, | 563 delayed_update_policy_runner_.SetDeadline(FROM_HERE, new_policy_duration, |
451 now); | 564 now); |
452 } else { | 565 } else { |
453 MainThreadOnly().current_policy_expiration_time_ = base::TimeTicks(); | 566 MainThreadOnly().current_policy_expiration_time_ = base::TimeTicks(); |
454 } | 567 } |
455 | 568 |
456 if (update_type == UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED && | 569 Policy new_policy; |
457 new_policy == MainThreadOnly().current_policy_) | 570 bool block_expensive_tasks = false; |
458 return; | 571 switch (use_case) { |
572 case UseCase::COMPOSITOR_SCROLLING: | |
573 if (scroll_expected_soon) | |
574 block_expensive_tasks = true; | |
575 else | |
576 new_policy.loading_queue_priority_ = TaskQueue::HIGH_PRIORITY; | |
577 break; | |
459 | 578 |
460 TaskQueue::QueuePriority compositor_queue_priority = | 579 case UseCase::MAINTHREAD_SCROLLING: |
461 TaskQueue::NORMAL_PRIORITY; | 580 new_policy.compositor_queue_priority_ = TaskQueue::HIGH_PRIORITY; |
462 TaskQueue::QueuePriority loading_queue_priority = TaskQueue::NORMAL_PRIORITY; | 581 block_expensive_tasks = true; |
463 TaskQueue::QueuePriority timer_queue_priority = | 582 break; |
464 MainThreadOnly().timer_queue_suspend_count_ != 0 | |
465 ? TaskQueue::DISABLED_PRIORITY | |
466 : TaskQueue::NORMAL_PRIORITY; | |
467 | 583 |
468 switch (new_policy) { | 584 case UseCase::TOUCHSTART: |
469 case Policy::COMPOSITOR_PRIORITY: | 585 new_policy.compositor_queue_priority_ = TaskQueue::HIGH_PRIORITY; |
470 compositor_queue_priority = TaskQueue::HIGH_PRIORITY; | 586 new_policy.loading_queue_priority_ = TaskQueue::DISABLED_PRIORITY; |
587 new_policy.timer_queue_priority_ = TaskQueue::DISABLED_PRIORITY; | |
Sami
2015/08/26 13:38:01
block_expensive_tasks = true?
alex clarke (OOO till 29th)
2015/08/27 12:02:51
We could do that, but it would be a nop. Do you st
Sami
2015/08/27 15:15:58
Yeah, I was thinking it would be better to have it
alex clarke (OOO till 29th)
2015/09/03 10:34:25
Done.
| |
471 break; | 588 break; |
472 case Policy::COMPOSITOR_CRITICAL_PATH_PRIORITY: | 589 |
473 compositor_queue_priority = TaskQueue::HIGH_PRIORITY; | 590 case UseCase::NOT_SCROLLING: |
474 loading_queue_priority = TaskQueue::DISABLED_PRIORITY; | 591 if (scroll_expected_soon) |
475 timer_queue_priority = TaskQueue::DISABLED_PRIORITY; | 592 block_expensive_tasks = true; |
593 else | |
594 new_policy.loading_queue_priority_ = TaskQueue::HIGH_PRIORITY; | |
476 break; | 595 break; |
477 case Policy::TOUCHSTART_PRIORITY: | 596 |
478 compositor_queue_priority = TaskQueue::HIGH_PRIORITY; | 597 case UseCase::LOADING: |
479 loading_queue_priority = TaskQueue::DISABLED_PRIORITY; | 598 new_policy.loading_queue_priority_ = TaskQueue::HIGH_PRIORITY; |
480 timer_queue_priority = TaskQueue::DISABLED_PRIORITY; | 599 new_policy.timer_queue_priority_ = TaskQueue::HIGH_PRIORITY; |
Sami
2015/08/26 13:38:01
Why are timers now high priority? They used to be
alex clarke (OOO till 29th)
2015/08/27 12:02:51
They don't need to be :)
| |
481 break; | |
482 case Policy::NORMAL: | |
483 break; | |
484 case Policy::LOADING_PRIORITY: | |
485 // We prioritize loading tasks by deprioritizing compositing and timers. | |
486 compositor_queue_priority = TaskQueue::BEST_EFFORT_PRIORITY; | |
487 timer_queue_priority = TaskQueue::BEST_EFFORT_PRIORITY; | |
488 // TODO(alexclarke): See if we can safely mark the loading task queue as | |
489 // high priority. | |
490 break; | 600 break; |
491 default: | 601 default: |
492 NOTREACHED(); | 602 NOTREACHED(); |
493 } | 603 } |
494 | 604 |
495 compositor_task_runner_->SetQueuePriority(compositor_queue_priority); | 605 if (block_expensive_tasks && loading_tasks_seem_expensive) |
496 loading_task_runner_->SetQueuePriority(loading_queue_priority); | 606 new_policy.loading_queue_priority_ = TaskQueue::DISABLED_PRIORITY; |
497 timer_task_runner_->SetQueuePriority(timer_queue_priority); | |
498 | 607 |
499 DCHECK(compositor_task_runner_->IsQueueEnabled()); | 608 if ((block_expensive_tasks && timer_tasks_seem_expensive) || |
500 if (new_policy != Policy::TOUCHSTART_PRIORITY && | 609 MainThreadOnly().timer_queue_suspend_count_ != 0) |
501 new_policy != Policy::COMPOSITOR_CRITICAL_PATH_PRIORITY) { | 610 new_policy.timer_queue_priority_ = TaskQueue::DISABLED_PRIORITY; |
502 DCHECK(loading_task_runner_->IsQueueEnabled()); | |
503 } | |
504 MainThreadOnly().current_policy_ = new_policy; | |
505 | 611 |
612 // Tracing is done before the early out check, because it's quite possible we | |
613 // will otherwise miss this information in traces. | |
506 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( | 614 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( |
507 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler", | 615 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler", |
508 this, AsValueLocked(now)); | 616 this, AsValueLocked(now)); |
617 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "use_case", | |
618 use_case); | |
509 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), | 619 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), |
510 "RendererScheduler.policy", MainThreadOnly().current_policy_); | 620 "RendererScheduler.loading_tasks_seem_expensive", |
621 MainThreadOnly().loading_tasks_seem_expensive_); | |
511 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), | 622 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), |
512 "RendererScheduler.timer_tasks_seem_expensive", | 623 "RendererScheduler.timer_tasks_seem_expensive", |
513 AnyThread().timer_tasks_seem_expensive_); | 624 MainThreadOnly().timer_tasks_seem_expensive_); |
625 | |
626 if (update_type == UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED && | |
627 use_case == MainThreadOnly().current_use_case_ && | |
Sami
2015/08/26 13:38:01
Do we need to check if the use case changed? Could
alex clarke (OOO till 29th)
2015/08/27 12:02:51
Yeah I think we could do that.
| |
628 new_policy == MainThreadOnly().current_policy_) { | |
629 return; | |
630 } | |
631 | |
632 compositor_task_runner_->SetQueuePriority( | |
633 new_policy.compositor_queue_priority_); | |
634 loading_task_runner_->SetQueuePriority(new_policy.loading_queue_priority_); | |
635 timer_task_runner_->SetQueuePriority(new_policy.timer_queue_priority_); | |
636 | |
637 DCHECK(compositor_task_runner_->IsQueueEnabled()); | |
638 MainThreadOnly().current_use_case_ = use_case; | |
639 MainThreadOnly().current_policy_ = new_policy; | |
514 } | 640 } |
515 | 641 |
516 bool RendererSchedulerImpl::InputSignalsSuggestCompositorPriority( | 642 bool RendererSchedulerImpl::InputSignalsSuggestScrolling( |
517 base::TimeTicks now) const { | 643 base::TimeTicks now) const { |
518 base::TimeDelta unused_policy_duration; | 644 base::TimeDelta unused_policy_duration; |
519 switch (ComputeNewPolicy(now, &unused_policy_duration)) { | 645 switch (ComputeCurrentUseCase(now, &unused_policy_duration)) { |
520 case Policy::TOUCHSTART_PRIORITY: | 646 case UseCase::COMPOSITOR_SCROLLING: |
521 case Policy::COMPOSITOR_PRIORITY: | 647 case UseCase::MAINTHREAD_SCROLLING: |
522 case Policy::COMPOSITOR_CRITICAL_PATH_PRIORITY: | 648 case UseCase::TOUCHSTART: |
523 return true; | 649 return true; |
524 | 650 |
525 default: | 651 default: |
526 break; | 652 break; |
527 } | 653 } |
528 return false; | 654 return false; |
529 } | 655 } |
530 | 656 |
531 RendererSchedulerImpl::Policy RendererSchedulerImpl::ComputeNewPolicy( | 657 RendererSchedulerImpl::UseCase RendererSchedulerImpl::ComputeCurrentUseCase( |
532 base::TimeTicks now, | 658 base::TimeTicks now, |
533 base::TimeDelta* new_policy_duration) const { | 659 base::TimeDelta* new_policy_duration) const { |
534 any_thread_lock_.AssertAcquired(); | 660 any_thread_lock_.AssertAcquired(); |
535 // Above all else we want to be responsive to user input. | 661 // Above all else we want to be responsive to user input. |
536 *new_policy_duration = TimeLeftInInputEscalatedPolicy(now); | 662 *new_policy_duration = TimeLeftInInputEscalatedPolicy(now); |
537 if (*new_policy_duration > base::TimeDelta()) { | 663 if (*new_policy_duration > base::TimeDelta()) { |
538 if (AnyThread().awaiting_touch_start_response_) | 664 // Has scrolling been fully established? |
539 return Policy::TOUCHSTART_PRIORITY; | 665 if (AnyThread().awaiting_touch_start_response_) { |
540 // If BeginMainFrame is on the critical path, we want to try and prevent | 666 // No., so arrange for compositor tasks to be run at the highest priority. |
Sami
2015/08/26 13:38:01
typo: .
alex clarke (OOO till 29th)
2015/08/27 12:02:51
Done.
| |
541 // timers and loading tasks from running if we think they might be | 667 return UseCase::TOUCHSTART; |
542 // expensive. | |
543 // TODO(skyostil): Consider removing in_idle_period_ and | |
Sami
2015/08/26 13:38:01
Wanna keep this todo since the code is still here?
alex clarke (OOO till 29th)
2015/08/27 12:02:51
Done.
| |
544 // HadAnIdlePeriodRecently() unless we need them here. | |
545 if (AnyThread().timer_tasks_seem_expensive_ && | |
546 AnyThread().begin_main_frame_on_critical_path_) { | |
547 return Policy::COMPOSITOR_CRITICAL_PATH_PRIORITY; | |
548 } | 668 } |
549 return Policy::COMPOSITOR_PRIORITY; | 669 // Yes scrolling has been established. If BeginMainFrame is on the critical |
670 // path, compositor tasks need to be prioritized, otherwise now might be a | |
671 // good time to run potentially expensive work. | |
672 if (AnyThread().begin_main_frame_on_critical_path_) { | |
673 return UseCase::MAINTHREAD_SCROLLING; | |
674 } else { | |
675 return UseCase::COMPOSITOR_SCROLLING; | |
676 } | |
550 } | 677 } |
551 | 678 |
552 if (AnyThread().rails_loading_priority_deadline_ > now) { | 679 if (AnyThread().rails_loading_priority_deadline_ > now) { |
553 *new_policy_duration = AnyThread().rails_loading_priority_deadline_ - now; | 680 *new_policy_duration = AnyThread().rails_loading_priority_deadline_ - now; |
554 return Policy::LOADING_PRIORITY; | 681 return UseCase::LOADING; |
555 } | 682 } |
556 | 683 |
557 return Policy::NORMAL; | 684 return UseCase::NOT_SCROLLING; |
558 } | 685 } |
559 | 686 |
560 base::TimeDelta RendererSchedulerImpl::TimeLeftInInputEscalatedPolicy( | 687 base::TimeDelta RendererSchedulerImpl::TimeLeftInInputEscalatedPolicy( |
561 base::TimeTicks now) const { | 688 base::TimeTicks now) const { |
562 any_thread_lock_.AssertAcquired(); | 689 any_thread_lock_.AssertAcquired(); |
563 | 690 |
564 base::TimeDelta escalated_priority_duration = | 691 base::TimeDelta escalated_priority_duration = |
565 base::TimeDelta::FromMilliseconds(kPriorityEscalationAfterInputMillis); | 692 base::TimeDelta::FromMilliseconds(kPriorityEscalationAfterInputMillis); |
566 | 693 |
567 // If the input event is still pending, go into input prioritized policy | 694 // If the input event is still pending, go into input prioritized policy |
568 // and check again later. | 695 // and check again later. |
569 if (AnyThread().pending_main_thread_input_event_count_ > 0) | 696 if (AnyThread().pending_main_thread_input_event_count_ > 0) |
570 return escalated_priority_duration; | 697 return escalated_priority_duration; |
571 if (AnyThread().last_input_signal_time_.is_null() || | 698 if (AnyThread().last_input_signal_time_.is_null() || |
572 AnyThread().last_input_signal_time_ + escalated_priority_duration < now) { | 699 AnyThread().last_input_signal_time_ + escalated_priority_duration < now) { |
573 return base::TimeDelta(); | 700 return base::TimeDelta(); |
574 } | 701 } |
575 return AnyThread().last_input_signal_time_ + escalated_priority_duration - | 702 return AnyThread().last_input_signal_time_ + escalated_priority_duration - |
576 now; | 703 now; |
577 } | 704 } |
578 | 705 |
579 bool RendererSchedulerImpl::CanEnterLongIdlePeriod( | 706 bool RendererSchedulerImpl::CanEnterLongIdlePeriod( |
580 base::TimeTicks now, | 707 base::TimeTicks now, |
581 base::TimeDelta* next_long_idle_period_delay_out) { | 708 base::TimeDelta* next_long_idle_period_delay_out) { |
582 helper_.CheckOnValidThread(); | 709 helper_.CheckOnValidThread(); |
583 | 710 |
584 MaybeUpdatePolicy(); | 711 MaybeUpdatePolicy(); |
585 if (MainThreadOnly().current_policy_ == Policy::TOUCHSTART_PRIORITY) { | 712 if (MainThreadOnly().current_use_case_ == UseCase::TOUCHSTART) { |
586 // Don't start a long idle task in touch start priority, try again when | 713 // Don't start a long idle task in touch start priority, try again when |
587 // the policy is scheduled to end. | 714 // the policy is scheduled to end. |
588 *next_long_idle_period_delay_out = | 715 *next_long_idle_period_delay_out = |
589 MainThreadOnly().current_policy_expiration_time_ - now; | 716 MainThreadOnly().current_policy_expiration_time_ - now; |
590 return false; | 717 return false; |
591 } | 718 } |
592 return true; | 719 return true; |
593 } | 720 } |
594 | 721 |
595 SchedulerHelper* RendererSchedulerImpl::GetSchedulerHelperForTesting() { | 722 SchedulerHelper* RendererSchedulerImpl::GetSchedulerHelperForTesting() { |
596 return &helper_; | 723 return &helper_; |
597 } | 724 } |
598 | 725 |
599 void RendererSchedulerImpl::SuspendTimerQueue() { | 726 void RendererSchedulerImpl::SuspendTimerQueue() { |
600 MainThreadOnly().timer_queue_suspend_count_++; | 727 MainThreadOnly().timer_queue_suspend_count_++; |
601 ForceUpdatePolicy(); | 728 ForceUpdatePolicy(); |
602 DCHECK(!timer_task_runner_->IsQueueEnabled()); | 729 DCHECK(!timer_task_runner_->IsQueueEnabled()); |
603 } | 730 } |
604 | 731 |
605 void RendererSchedulerImpl::ResumeTimerQueue() { | 732 void RendererSchedulerImpl::ResumeTimerQueue() { |
606 MainThreadOnly().timer_queue_suspend_count_--; | 733 MainThreadOnly().timer_queue_suspend_count_--; |
607 DCHECK_GE(MainThreadOnly().timer_queue_suspend_count_, 0); | 734 DCHECK_GE(MainThreadOnly().timer_queue_suspend_count_, 0); |
608 ForceUpdatePolicy(); | 735 ForceUpdatePolicy(); |
609 } | 736 } |
610 | 737 |
611 // static | 738 // static |
612 const char* RendererSchedulerImpl::PolicyToString(Policy policy) { | 739 const char* RendererSchedulerImpl::UseCaseToString(UseCase use_case) { |
613 switch (policy) { | 740 switch (use_case) { |
614 case Policy::NORMAL: | 741 case UseCase::NOT_SCROLLING: |
615 return "normal"; | 742 return "not_scrolling"; |
616 case Policy::COMPOSITOR_PRIORITY: | 743 case UseCase::COMPOSITOR_SCROLLING: |
617 return "compositor"; | 744 return "compositor_scrolling"; |
618 case Policy::COMPOSITOR_CRITICAL_PATH_PRIORITY: | 745 case UseCase::MAINTHREAD_SCROLLING: |
619 return "compositor_critical_path"; | 746 return "mainthread_scrolling"; |
620 case Policy::TOUCHSTART_PRIORITY: | 747 case UseCase::TOUCHSTART: |
621 return "touchstart"; | 748 return "touchstart"; |
622 case Policy::LOADING_PRIORITY: | 749 case UseCase::LOADING: |
623 return "loading"; | 750 return "loading"; |
624 default: | 751 default: |
625 NOTREACHED(); | 752 NOTREACHED(); |
626 return nullptr; | 753 return nullptr; |
627 } | 754 } |
628 } | 755 } |
629 | 756 |
630 scoped_refptr<base::trace_event::ConvertableToTraceFormat> | 757 scoped_refptr<base::trace_event::ConvertableToTraceFormat> |
631 RendererSchedulerImpl::AsValue(base::TimeTicks optional_now) const { | 758 RendererSchedulerImpl::AsValue(base::TimeTicks optional_now) const { |
632 base::AutoLock lock(any_thread_lock_); | 759 base::AutoLock lock(any_thread_lock_); |
633 return AsValueLocked(optional_now); | 760 return AsValueLocked(optional_now); |
634 } | 761 } |
635 | 762 |
636 scoped_refptr<base::trace_event::ConvertableToTraceFormat> | 763 scoped_refptr<base::trace_event::ConvertableToTraceFormat> |
637 RendererSchedulerImpl::AsValueLocked(base::TimeTicks optional_now) const { | 764 RendererSchedulerImpl::AsValueLocked(base::TimeTicks optional_now) const { |
638 helper_.CheckOnValidThread(); | 765 helper_.CheckOnValidThread(); |
639 any_thread_lock_.AssertAcquired(); | 766 any_thread_lock_.AssertAcquired(); |
640 | 767 |
641 if (optional_now.is_null()) | 768 if (optional_now.is_null()) |
642 optional_now = helper_.Now(); | 769 optional_now = helper_.Now(); |
643 scoped_refptr<base::trace_event::TracedValue> state = | 770 scoped_refptr<base::trace_event::TracedValue> state = |
644 new base::trace_event::TracedValue(); | 771 new base::trace_event::TracedValue(); |
645 | 772 |
646 state->SetString("current_policy", | 773 state->SetString("current_use_case", |
Sami
2015/08/26 13:38:01
Do we want to trace the policy too? One way would
alex clarke (OOO till 29th)
2015/08/27 12:02:51
We could do that, mind you it's already logged in
Sami
2015/08/27 15:15:58
Right, let's add it once it actually adds new info
alex clarke (OOO till 29th)
2015/09/03 10:34:25
Acknowledged.
| |
647 PolicyToString(MainThreadOnly().current_policy_)); | 774 UseCaseToString(MainThreadOnly().current_use_case_)); |
775 state->SetBoolean("loading_tasks_seem_expensive", | |
776 MainThreadOnly().loading_tasks_seem_expensive_); | |
777 state->SetBoolean("timer_tasks_seem_expensive", | |
778 MainThreadOnly().timer_tasks_seem_expensive_); | |
779 state->SetBoolean("scroll_expected_soon", | |
780 MainThreadOnly().scroll_expected_soon_); | |
648 state->SetString("idle_period_state", | 781 state->SetString("idle_period_state", |
649 IdleHelper::IdlePeriodStateToString( | 782 IdleHelper::IdlePeriodStateToString( |
650 idle_helper_.SchedulerIdlePeriodState())); | 783 idle_helper_.SchedulerIdlePeriodState())); |
651 state->SetBoolean("renderer_hidden", MainThreadOnly().renderer_hidden_); | 784 state->SetBoolean("renderer_hidden", MainThreadOnly().renderer_hidden_); |
652 state->SetDouble("now", (optional_now - base::TimeTicks()).InMillisecondsF()); | 785 state->SetDouble("now", (optional_now - base::TimeTicks()).InMillisecondsF()); |
653 state->SetDouble("last_input_signal_time", | 786 state->SetDouble("last_input_signal_time", |
654 (AnyThread().last_input_signal_time_ - base::TimeTicks()) | 787 (AnyThread().last_input_signal_time_ - base::TimeTicks()) |
655 .InMillisecondsF()); | 788 .InMillisecondsF()); |
656 state->SetDouble("rails_loading_priority_deadline", | 789 state->SetDouble("rails_loading_priority_deadline", |
657 (AnyThread().rails_loading_priority_deadline_ - | 790 (AnyThread().rails_loading_priority_deadline_ - |
658 base::TimeTicks()).InMillisecondsF()); | 791 base::TimeTicks()).InMillisecondsF()); |
659 state->SetDouble("last_idle_period_end_time", | 792 state->SetDouble("last_idle_period_end_time", |
660 (AnyThread().last_idle_period_end_time_ - base::TimeTicks()) | 793 (AnyThread().last_idle_period_end_time_ - base::TimeTicks()) |
661 .InMillisecondsF()); | 794 .InMillisecondsF()); |
662 state->SetInteger("pending_main_thread_input_event_count", | 795 state->SetInteger("pending_main_thread_input_event_count", |
663 AnyThread().pending_main_thread_input_event_count_); | 796 AnyThread().pending_main_thread_input_event_count_); |
664 state->SetBoolean("awaiting_touch_start_response", | 797 state->SetBoolean("awaiting_touch_start_response", |
665 AnyThread().awaiting_touch_start_response_); | 798 AnyThread().awaiting_touch_start_response_); |
666 state->SetBoolean("begin_main_frame_on_critical_path", | 799 state->SetBoolean("begin_main_frame_on_critical_path", |
667 AnyThread().begin_main_frame_on_critical_path_); | 800 AnyThread().begin_main_frame_on_critical_path_); |
801 state->SetDouble("expected_loading_task_duration", | |
802 MainThreadOnly() | |
803 .loading_task_cost_estimator_.expected_task_duration() | |
804 .InMillisecondsF()); | |
668 state->SetDouble("expected_timer_task_duration", | 805 state->SetDouble("expected_timer_task_duration", |
669 MainThreadOnly() | 806 MainThreadOnly() |
670 .timer_task_cost_estimator_.expected_task_duration() | 807 .timer_task_cost_estimator_.expected_task_duration() |
671 .InMillisecondsF()); | 808 .InMillisecondsF()); |
672 // TODO(skyostil): Can we somehow trace how accurate these estimates were? | 809 // TODO(skyostil): Can we somehow trace how accurate these estimates were? |
673 state->SetDouble( | 810 state->SetDouble( |
674 "expected_short_idle_period_duration", | 811 "expected_short_idle_period_duration", |
675 MainThreadOnly().expected_short_idle_period_duration_.InMillisecondsF()); | 812 MainThreadOnly().expected_short_idle_period_duration_.InMillisecondsF()); |
676 state->SetBoolean("timer_tasks_seem_expensive", | |
677 AnyThread().timer_tasks_seem_expensive_); | |
678 state->SetDouble("estimated_next_frame_begin", | 813 state->SetDouble("estimated_next_frame_begin", |
679 (MainThreadOnly().estimated_next_frame_begin_ - | 814 (MainThreadOnly().estimated_next_frame_begin_ - |
680 base::TimeTicks()).InMillisecondsF()); | 815 base::TimeTicks()).InMillisecondsF()); |
681 state->SetBoolean("in_idle_period", AnyThread().in_idle_period_); | 816 state->SetBoolean("in_idle_period", AnyThread().in_idle_period_); |
682 | 817 |
683 return state; | 818 return state; |
684 } | 819 } |
685 | 820 |
686 void RendererSchedulerImpl::OnIdlePeriodStarted() { | 821 void RendererSchedulerImpl::OnIdlePeriodStarted() { |
687 base::AutoLock lock(any_thread_lock_); | 822 base::AutoLock lock(any_thread_lock_); |
(...skipping 16 matching lines...) Expand all Loading... | |
704 UpdatePolicyLocked(UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED); | 839 UpdatePolicyLocked(UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED); |
705 } | 840 } |
706 | 841 |
707 bool RendererSchedulerImpl::HadAnIdlePeriodRecently(base::TimeTicks now) const { | 842 bool RendererSchedulerImpl::HadAnIdlePeriodRecently(base::TimeTicks now) const { |
708 return (now - AnyThread().last_idle_period_end_time_) <= | 843 return (now - AnyThread().last_idle_period_end_time_) <= |
709 base::TimeDelta::FromMilliseconds( | 844 base::TimeDelta::FromMilliseconds( |
710 kIdlePeriodStarvationThresholdMillis); | 845 kIdlePeriodStarvationThresholdMillis); |
711 } | 846 } |
712 | 847 |
713 } // namespace scheduler | 848 } // namespace scheduler |
OLD | NEW |