Chromium Code Reviews| 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 "content/renderer/scheduler/renderer_scheduler_impl.h" | 5 #include "content/renderer/scheduler/renderer_scheduler_impl.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/message_loop/message_loop_proxy.h" | 8 #include "base/message_loop/message_loop_proxy.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" |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 25 task_queue_manager_->TaskRunnerForQueue(CONTROL_TASK_QUEUE)), | 25 task_queue_manager_->TaskRunnerForQueue(CONTROL_TASK_QUEUE)), |
| 26 control_task_after_wakeup_runner_(task_queue_manager_->TaskRunnerForQueue( | 26 control_task_after_wakeup_runner_(task_queue_manager_->TaskRunnerForQueue( |
| 27 CONTROL_TASK_AFTER_WAKEUP_QUEUE)), | 27 CONTROL_TASK_AFTER_WAKEUP_QUEUE)), |
| 28 default_task_runner_( | 28 default_task_runner_( |
| 29 task_queue_manager_->TaskRunnerForQueue(DEFAULT_TASK_QUEUE)), | 29 task_queue_manager_->TaskRunnerForQueue(DEFAULT_TASK_QUEUE)), |
| 30 compositor_task_runner_( | 30 compositor_task_runner_( |
| 31 task_queue_manager_->TaskRunnerForQueue(COMPOSITOR_TASK_QUEUE)), | 31 task_queue_manager_->TaskRunnerForQueue(COMPOSITOR_TASK_QUEUE)), |
| 32 loading_task_runner_( | 32 loading_task_runner_( |
| 33 task_queue_manager_->TaskRunnerForQueue(LOADING_TASK_QUEUE)), | 33 task_queue_manager_->TaskRunnerForQueue(LOADING_TASK_QUEUE)), |
| 34 current_policy_(Policy::NORMAL), | 34 current_policy_(Policy::NORMAL), |
| 35 idle_period_state_(IdlePeriodState::NOT_IN_IDLE_PERIOD), | |
| 35 last_input_type_(blink::WebInputEvent::Undefined), | 36 last_input_type_(blink::WebInputEvent::Undefined), |
| 36 input_stream_state_(InputStreamState::INACTIVE), | 37 input_stream_state_(InputStreamState::INACTIVE), |
| 37 policy_may_need_update_(&incoming_signals_lock_), | 38 policy_may_need_update_(&incoming_signals_lock_), |
| 38 weak_factory_(this) { | 39 weak_factory_(this) { |
| 39 weak_renderer_scheduler_ptr_ = weak_factory_.GetWeakPtr(); | 40 weak_renderer_scheduler_ptr_ = weak_factory_.GetWeakPtr(); |
| 40 update_policy_closure_ = base::Bind(&RendererSchedulerImpl::UpdatePolicy, | 41 update_policy_closure_ = base::Bind(&RendererSchedulerImpl::UpdatePolicy, |
| 41 weak_renderer_scheduler_ptr_); | 42 weak_renderer_scheduler_ptr_); |
| 42 end_idle_period_closure_.Reset(base::Bind( | 43 end_idle_period_closure_.Reset(base::Bind( |
| 43 &RendererSchedulerImpl::EndIdlePeriod, weak_renderer_scheduler_ptr_)); | 44 &RendererSchedulerImpl::EndIdlePeriod, weak_renderer_scheduler_ptr_)); |
| 45 initiate_next_long_idle_period_closure_.Reset(base::Bind( | |
| 46 &RendererSchedulerImpl::InitiateLongIdlePeriod, | |
| 47 weak_renderer_scheduler_ptr_)); | |
| 48 initiate_next_long_idle_period_after_wakeup_closure_.Reset(base::Bind( | |
| 49 &RendererSchedulerImpl::InitiateLongIdlePeriodAfterWakeup, | |
| 50 weak_renderer_scheduler_ptr_)); | |
| 51 | |
| 44 idle_task_runner_ = make_scoped_refptr(new SingleThreadIdleTaskRunner( | 52 idle_task_runner_ = make_scoped_refptr(new SingleThreadIdleTaskRunner( |
| 45 task_queue_manager_->TaskRunnerForQueue(IDLE_TASK_QUEUE), | 53 task_queue_manager_->TaskRunnerForQueue(IDLE_TASK_QUEUE), |
| 46 control_task_after_wakeup_runner_, | 54 control_task_after_wakeup_runner_, |
| 47 base::Bind(&RendererSchedulerImpl::CurrentIdleTaskDeadlineCallback, | 55 base::Bind(&RendererSchedulerImpl::CurrentIdleTaskDeadlineCallback, |
| 48 weak_renderer_scheduler_ptr_))); | 56 weak_renderer_scheduler_ptr_))); |
| 49 | 57 |
| 50 renderer_task_queue_selector_->SetQueuePriority( | 58 renderer_task_queue_selector_->SetQueuePriority( |
| 51 CONTROL_TASK_QUEUE, RendererTaskQueueSelector::CONTROL_PRIORITY); | 59 CONTROL_TASK_QUEUE, RendererTaskQueueSelector::CONTROL_PRIORITY); |
| 52 | 60 |
| 53 renderer_task_queue_selector_->SetQueuePriority( | 61 renderer_task_queue_selector_->SetQueuePriority( |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 124 | 132 |
| 125 void RendererSchedulerImpl::DidCommitFrameToCompositor() { | 133 void RendererSchedulerImpl::DidCommitFrameToCompositor() { |
| 126 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), | 134 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), |
| 127 "RendererSchedulerImpl::DidCommitFrameToCompositor"); | 135 "RendererSchedulerImpl::DidCommitFrameToCompositor"); |
| 128 DCHECK(main_thread_checker_.CalledOnValidThread()); | 136 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 129 if (!task_queue_manager_) | 137 if (!task_queue_manager_) |
| 130 return; | 138 return; |
| 131 | 139 |
| 132 base::TimeTicks now(Now()); | 140 base::TimeTicks now(Now()); |
| 133 if (now < estimated_next_frame_begin_) { | 141 if (now < estimated_next_frame_begin_) { |
| 134 StartIdlePeriod(); | 142 // TODO(rmcilroy): Consider reducing the idle period based on the runtime of |
| 143 // the next pending delayed tasks (as currently done in for long idle times) | |
| 144 StartIdlePeriod(IdlePeriodState::IN_SHORT_IDLE_PERIOD); | |
| 135 control_task_runner_->PostDelayedTask(FROM_HERE, | 145 control_task_runner_->PostDelayedTask(FROM_HERE, |
| 136 end_idle_period_closure_.callback(), | 146 end_idle_period_closure_.callback(), |
| 137 estimated_next_frame_begin_ - now); | 147 estimated_next_frame_begin_ - now); |
| 138 } | 148 } |
| 139 } | 149 } |
| 140 | 150 |
| 141 void RendererSchedulerImpl::BeginFrameNotExpectedSoon() { | 151 void RendererSchedulerImpl::BeginFrameNotExpectedSoon() { |
| 142 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), | 152 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), |
| 143 "RendererSchedulerImpl::BeginFrameNotExpectedSoon"); | 153 "RendererSchedulerImpl::BeginFrameNotExpectedSoon"); |
| 144 DCHECK(main_thread_checker_.CalledOnValidThread()); | 154 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 155 if (!task_queue_manager_) | |
| 156 return; | |
| 157 | |
| 145 // TODO(skyostil): Wire up real notification of input events processing | 158 // TODO(skyostil): Wire up real notification of input events processing |
| 146 // instead of this approximation. | 159 // instead of this approximation. |
| 147 DidProcessInputEvent(base::TimeTicks()); | 160 DidProcessInputEvent(base::TimeTicks()); |
| 148 // TODO(rmcilroy): Implement long idle times. | 161 |
| 162 InitiateLongIdlePeriod(); | |
| 149 } | 163 } |
| 150 | 164 |
| 151 void RendererSchedulerImpl::DidReceiveInputEventOnCompositorThread( | 165 void RendererSchedulerImpl::DidReceiveInputEventOnCompositorThread( |
| 152 const blink::WebInputEvent& web_input_event) { | 166 const blink::WebInputEvent& web_input_event) { |
| 153 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), | 167 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), |
| 154 "RendererSchedulerImpl::DidReceiveInputEventOnCompositorThread"); | 168 "RendererSchedulerImpl::DidReceiveInputEventOnCompositorThread"); |
| 155 // We regard MouseMove events with the left mouse button down as a signal | 169 // We regard MouseMove events with the left mouse button down as a signal |
| 156 // that the user is doing something requiring a smooth frame rate. | 170 // that the user is doing something requiring a smooth frame rate. |
| 157 if (web_input_event.type == blink::WebInputEvent::MouseMove && | 171 if (web_input_event.type == blink::WebInputEvent::MouseMove && |
| 158 (web_input_event.modifiers & blink::WebInputEvent::LeftButtonDown)) { | 172 (web_input_event.modifiers & blink::WebInputEvent::LeftButtonDown)) { |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 278 DCHECK(main_thread_checker_.CalledOnValidThread()); | 292 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 279 if (!task_queue_manager_) | 293 if (!task_queue_manager_) |
| 280 return; | 294 return; |
| 281 | 295 |
| 282 base::AutoLock lock(incoming_signals_lock_); | 296 base::AutoLock lock(incoming_signals_lock_); |
| 283 base::TimeTicks now; | 297 base::TimeTicks now; |
| 284 policy_may_need_update_.SetWhileLocked(false); | 298 policy_may_need_update_.SetWhileLocked(false); |
| 285 | 299 |
| 286 base::TimeDelta new_policy_duration; | 300 base::TimeDelta new_policy_duration; |
| 287 Policy new_policy = ComputeNewPolicy(&new_policy_duration); | 301 Policy new_policy = ComputeNewPolicy(&new_policy_duration); |
| 288 if (new_policy_duration > base::TimeDelta()) | 302 if (new_policy_duration > base::TimeDelta()) { |
| 303 current_policy_expiration_time_ = now + new_policy_duration; | |
| 289 PostUpdatePolicyOnControlRunner(new_policy_duration); | 304 PostUpdatePolicyOnControlRunner(new_policy_duration); |
| 305 } else { | |
| 306 current_policy_expiration_time_ = base::TimeTicks(); | |
| 307 } | |
| 290 | 308 |
| 291 if (new_policy == current_policy_) | 309 if (new_policy == current_policy_) |
| 292 return; | 310 return; |
| 293 | 311 |
| 294 switch (new_policy) { | 312 switch (new_policy) { |
| 295 case Policy::COMPOSITOR_PRIORITY: | 313 case Policy::COMPOSITOR_PRIORITY: |
| 296 renderer_task_queue_selector_->SetQueuePriority( | 314 renderer_task_queue_selector_->SetQueuePriority( |
| 297 COMPOSITOR_TASK_QUEUE, RendererTaskQueueSelector::HIGH_PRIORITY); | 315 COMPOSITOR_TASK_QUEUE, RendererTaskQueueSelector::HIGH_PRIORITY); |
| 298 // TODO(scheduler-dev): Add a task priority between HIGH and BEST_EFFORT | 316 // TODO(scheduler-dev): Add a task priority between HIGH and BEST_EFFORT |
| 299 // that still has some guarantee of running. | 317 // that still has some guarantee of running. |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 329 base::TimeDelta* new_policy_duration) { | 347 base::TimeDelta* new_policy_duration) { |
| 330 DCHECK(main_thread_checker_.CalledOnValidThread()); | 348 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 331 incoming_signals_lock_.AssertAcquired(); | 349 incoming_signals_lock_.AssertAcquired(); |
| 332 | 350 |
| 333 Policy new_policy = Policy::NORMAL; | 351 Policy new_policy = Policy::NORMAL; |
| 334 *new_policy_duration = base::TimeDelta(); | 352 *new_policy_duration = base::TimeDelta(); |
| 335 | 353 |
| 336 if (input_stream_state_ == InputStreamState::INACTIVE) | 354 if (input_stream_state_ == InputStreamState::INACTIVE) |
| 337 return new_policy; | 355 return new_policy; |
| 338 | 356 |
| 339 base::TimeDelta new_priority_duration = | |
| 340 base::TimeDelta::FromMilliseconds(kPriorityEscalationAfterInputMillis); | |
| 341 Policy input_priority_policy = | 357 Policy input_priority_policy = |
| 342 input_stream_state_ == | 358 input_stream_state_ == |
| 343 InputStreamState::ACTIVE_AND_AWAITING_TOUCHSTART_RESPONSE | 359 InputStreamState::ACTIVE_AND_AWAITING_TOUCHSTART_RESPONSE |
| 344 ? Policy::TOUCHSTART_PRIORITY | 360 ? Policy::TOUCHSTART_PRIORITY |
| 345 : Policy::COMPOSITOR_PRIORITY; | 361 : Policy::COMPOSITOR_PRIORITY; |
| 362 base::TimeDelta time_left_in_policy = TimeLeftInInputEscalatedPolicy(); | |
| 363 if (time_left_in_policy > base::TimeDelta()) { | |
| 364 new_policy = input_priority_policy; | |
| 365 *new_policy_duration = time_left_in_policy; | |
| 366 } else { | |
| 367 // Reset |input_stream_state_| to ensure | |
| 368 // DidReceiveInputEventOnCompositorThread will post an UpdatePolicy task | |
| 369 // when it's next called. | |
| 370 input_stream_state_ = InputStreamState::INACTIVE; | |
| 371 } | |
| 372 return new_policy; | |
| 373 } | |
| 346 | 374 |
| 347 // If the input event is still pending, go into input prioritized policy | 375 base::TimeDelta RendererSchedulerImpl::TimeLeftInInputEscalatedPolicy() const { |
| 348 // and check again later. | 376 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 377 // TODO(rmcilroy): Change this to DCHECK_EQ when crbug.com/463869 is fixed. | |
| 378 DCHECK(input_stream_state_ != InputStreamState::INACTIVE); | |
|
Sami
2015/03/05 16:22:32
nit: could remove this TODO in favor of IsInIdlePe
rmcilroy
2015/03/05 16:42:38
This is checking InputStreamState not IsInIdlePeri
| |
| 379 incoming_signals_lock_.AssertAcquired(); | |
| 380 | |
| 381 base::TimeDelta escalated_priority_duration = | |
| 382 base::TimeDelta::FromMilliseconds(kPriorityEscalationAfterInputMillis); | |
| 383 base::TimeDelta time_left_in_policy; | |
| 349 if (last_input_process_time_on_main_.is_null() && | 384 if (last_input_process_time_on_main_.is_null() && |
| 350 !task_queue_manager_->IsQueueEmpty(COMPOSITOR_TASK_QUEUE)) { | 385 !task_queue_manager_->IsQueueEmpty(COMPOSITOR_TASK_QUEUE)) { |
| 351 new_policy = input_priority_policy; | 386 // If the input event is still pending, go into input prioritized policy |
| 352 *new_policy_duration = new_priority_duration; | 387 // and check again later. |
| 388 time_left_in_policy = escalated_priority_duration; | |
| 353 } else { | 389 } else { |
| 354 // Otherwise make sure the input prioritization policy ends on time. | 390 // Otherwise make sure the input prioritization policy ends on time. |
| 355 base::TimeTicks new_priority_end( | 391 base::TimeTicks new_priority_end( |
| 356 std::max(last_input_receipt_time_on_compositor_, | 392 std::max(last_input_receipt_time_on_compositor_, |
| 357 last_input_process_time_on_main_) + | 393 last_input_process_time_on_main_) + |
| 358 new_priority_duration); | 394 escalated_priority_duration); |
| 359 base::TimeDelta time_left_in_policy = new_priority_end - Now(); | 395 time_left_in_policy = new_priority_end - Now(); |
| 360 | |
| 361 if (time_left_in_policy > base::TimeDelta()) { | |
| 362 new_policy = input_priority_policy; | |
| 363 *new_policy_duration = time_left_in_policy; | |
| 364 } else { | |
| 365 // Reset |input_stream_state_| to ensure | |
| 366 // DidReceiveInputEventOnCompositorThread will post an UpdatePolicy task | |
| 367 // when it's next called. | |
| 368 input_stream_state_ = InputStreamState::INACTIVE; | |
| 369 } | |
| 370 } | 396 } |
| 371 return new_policy; | 397 return time_left_in_policy; |
| 372 } | 398 } |
| 373 | 399 |
| 374 void RendererSchedulerImpl::StartIdlePeriod() { | 400 RendererSchedulerImpl::IdlePeriodState |
| 401 RendererSchedulerImpl::ComputeNewLongIdlePeriodState( | |
| 402 const base::TimeTicks now, | |
| 403 base::TimeDelta* next_long_idle_period_delay_out) { | |
| 404 DCHECK(main_thread_checker_.CalledOnValidThread()); | |
| 405 | |
| 406 MaybeUpdatePolicy(); | |
| 407 if (SchedulerPolicy() == Policy::TOUCHSTART_PRIORITY) { | |
| 408 // Don't start a long idle task in touch start priority, try again when | |
| 409 // the policy is scheduled to end. | |
| 410 *next_long_idle_period_delay_out = current_policy_expiration_time_ - now; | |
| 411 return IdlePeriodState::NOT_IN_IDLE_PERIOD; | |
| 412 } | |
| 413 | |
| 414 base::TimeTicks next_pending_delayed_task = | |
| 415 task_queue_manager_->NextPendingDelayedTaskRunTime(); | |
| 416 base::TimeDelta max_long_idle_period_duration = | |
| 417 base::TimeDelta::FromMilliseconds(kMaximumIdlePeriodMillis); | |
| 418 base::TimeDelta long_idle_period_duration; | |
| 419 if (next_pending_delayed_task.is_null()) { | |
| 420 long_idle_period_duration = max_long_idle_period_duration; | |
| 421 } else { | |
| 422 // Limit the idle period duration to be before the next pending task. | |
| 423 long_idle_period_duration = std::min(next_pending_delayed_task - now, | |
| 424 max_long_idle_period_duration); | |
| 425 } | |
| 426 | |
| 427 if (long_idle_period_duration > base::TimeDelta()) { | |
| 428 *next_long_idle_period_delay_out = long_idle_period_duration; | |
| 429 return long_idle_period_duration == max_long_idle_period_duration | |
| 430 ? IdlePeriodState::IN_LONG_IDLE_WITH_MAX_DEADLINE_PERIOD | |
| 431 : IdlePeriodState::IN_LONG_IDLE_PERIOD; | |
| 432 } else { | |
| 433 // If we can't start the idle period yet then try again after wakeup. | |
| 434 *next_long_idle_period_delay_out = base::TimeDelta::FromMilliseconds( | |
| 435 kRetryInitiateLongIdlePeriodDelayMillis); | |
| 436 return IdlePeriodState::NOT_IN_IDLE_PERIOD; | |
| 437 } | |
| 438 } | |
| 439 | |
| 440 void RendererSchedulerImpl::InitiateLongIdlePeriod() { | |
| 441 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), | |
| 442 "InitiateLongIdlePeriod"); | |
| 443 DCHECK(main_thread_checker_.CalledOnValidThread()); | |
| 444 | |
| 445 // End any previous idle period. | |
| 446 EndIdlePeriod(); | |
| 447 | |
| 448 base::TimeTicks now(Now()); | |
| 449 base::TimeDelta next_long_idle_period_delay; | |
| 450 IdlePeriodState new_idle_period_state = | |
| 451 ComputeNewLongIdlePeriodState(now, &next_long_idle_period_delay); | |
| 452 if (IsInIdlePeriod(new_idle_period_state)) { | |
| 453 estimated_next_frame_begin_ = now + next_long_idle_period_delay; | |
| 454 StartIdlePeriod(new_idle_period_state); | |
| 455 } | |
| 456 | |
| 457 if (task_queue_manager_->IsQueueEmpty(IDLE_TASK_QUEUE)) { | |
| 458 // If there are no current idle tasks then post the call to initiate the | |
| 459 // next idle for execution after wakeup (at which point after-wakeup idle | |
| 460 // tasks might be eligible to run or more idle tasks posted). | |
| 461 control_task_after_wakeup_runner_->PostDelayedTask( | |
| 462 FROM_HERE, | |
| 463 initiate_next_long_idle_period_after_wakeup_closure_.callback(), | |
| 464 next_long_idle_period_delay); | |
| 465 } else { | |
| 466 // Otherwise post on the normal control task queue. | |
| 467 control_task_runner_->PostDelayedTask( | |
| 468 FROM_HERE, | |
| 469 initiate_next_long_idle_period_closure_.callback(), | |
| 470 next_long_idle_period_delay); | |
| 471 } | |
| 472 } | |
| 473 | |
| 474 void RendererSchedulerImpl::InitiateLongIdlePeriodAfterWakeup() { | |
| 475 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), | |
| 476 "AfterWakeupInitiateLongIdlePeriod"); | |
|
Sami
2015/03/05 16:22:32
nit: Trace event doesn't match function name.
rmcilroy
2015/03/05 16:42:38
Argh again - sorry, done (we should really make a
| |
| 477 DCHECK(main_thread_checker_.CalledOnValidThread()); | |
| 478 | |
| 479 if (IsInIdlePeriod(idle_period_state_)) { | |
| 480 // Since we were asleep until now, end the async idle period trace event at | |
| 481 // the time when it would have ended were we awake. | |
| 482 TRACE_EVENT_ASYNC_END_WITH_TIMESTAMP0( | |
| 483 "renderer.scheduler", "RendererSchedulerIdlePeriod", this, | |
| 484 std::min(estimated_next_frame_begin_, Now()).ToInternalValue()); | |
| 485 idle_period_state_ = IdlePeriodState::ENDING_LONG_IDLE_PERIOD; | |
| 486 EndIdlePeriod(); | |
| 487 } | |
| 488 | |
| 489 // Post a task to initiate the next long idle period rather than calling it | |
| 490 // directly to allow all pending PostIdleTaskAfterWakeup tasks to get enqueued | |
| 491 // on the idle task queue before the next idle period starts so they are | |
| 492 // eligible to be run during the new idle period. | |
| 493 control_task_runner_->PostTask( | |
| 494 FROM_HERE, | |
| 495 initiate_next_long_idle_period_closure_.callback()); | |
| 496 } | |
| 497 | |
| 498 void RendererSchedulerImpl::StartIdlePeriod(IdlePeriodState new_state) { | |
| 375 TRACE_EVENT_ASYNC_BEGIN0("renderer.scheduler", | 499 TRACE_EVENT_ASYNC_BEGIN0("renderer.scheduler", |
| 376 "RendererSchedulerIdlePeriod", this); | 500 "RendererSchedulerIdlePeriod", this); |
| 377 DCHECK(main_thread_checker_.CalledOnValidThread()); | 501 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 502 DCHECK(IsInIdlePeriod(new_state)); | |
| 378 renderer_task_queue_selector_->EnableQueue( | 503 renderer_task_queue_selector_->EnableQueue( |
| 379 IDLE_TASK_QUEUE, RendererTaskQueueSelector::BEST_EFFORT_PRIORITY); | 504 IDLE_TASK_QUEUE, RendererTaskQueueSelector::BEST_EFFORT_PRIORITY); |
| 380 task_queue_manager_->PumpQueue(IDLE_TASK_QUEUE); | 505 task_queue_manager_->PumpQueue(IDLE_TASK_QUEUE); |
| 506 idle_period_state_ = new_state; | |
| 381 } | 507 } |
| 382 | 508 |
| 383 void RendererSchedulerImpl::EndIdlePeriod() { | 509 void RendererSchedulerImpl::EndIdlePeriod() { |
| 384 bool is_tracing; | 510 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 385 TRACE_EVENT_CATEGORY_GROUP_ENABLED("renderer.scheduler", &is_tracing); | 511 |
| 386 if (is_tracing && !estimated_next_frame_begin_.is_null() && | 512 end_idle_period_closure_.Cancel(); |
| 387 base::TimeTicks::Now() > estimated_next_frame_begin_) { | 513 initiate_next_long_idle_period_closure_.Cancel(); |
| 388 TRACE_EVENT_ASYNC_STEP_INTO_WITH_TIMESTAMP0( | 514 initiate_next_long_idle_period_after_wakeup_closure_.Cancel(); |
| 389 "renderer.scheduler", | 515 |
| 390 "RendererSchedulerIdlePeriod", | 516 // If we weren't already within an idle period then early-out. |
| 391 this, | 517 if (!IsInIdlePeriod(idle_period_state_)) |
| 392 "DeadlineOverrun", | 518 return; |
| 393 estimated_next_frame_begin_.ToInternalValue()); | 519 |
| 520 // If we are in the ENDING_LONG_IDLE_PERIOD state we have already logged the | |
| 521 // trace event. | |
| 522 if (idle_period_state_ != IdlePeriodState::ENDING_LONG_IDLE_PERIOD) { | |
| 523 bool is_tracing; | |
| 524 TRACE_EVENT_CATEGORY_GROUP_ENABLED("renderer.scheduler", &is_tracing); | |
| 525 if (is_tracing && !estimated_next_frame_begin_.is_null() && | |
| 526 base::TimeTicks::Now() > estimated_next_frame_begin_) { | |
| 527 TRACE_EVENT_ASYNC_STEP_INTO_WITH_TIMESTAMP0( | |
| 528 "renderer.scheduler", | |
| 529 "RendererSchedulerIdlePeriod", | |
| 530 this, | |
| 531 "DeadlineOverrun", | |
| 532 estimated_next_frame_begin_.ToInternalValue()); | |
| 533 } | |
| 534 TRACE_EVENT_ASYNC_END0("renderer.scheduler", | |
| 535 "RendererSchedulerIdlePeriod", this); | |
| 394 } | 536 } |
| 395 TRACE_EVENT_ASYNC_END0("renderer.scheduler", | 537 |
| 396 "RendererSchedulerIdlePeriod", this); | |
| 397 DCHECK(main_thread_checker_.CalledOnValidThread()); | |
| 398 end_idle_period_closure_.Cancel(); | |
| 399 renderer_task_queue_selector_->DisableQueue(IDLE_TASK_QUEUE); | 538 renderer_task_queue_selector_->DisableQueue(IDLE_TASK_QUEUE); |
| 539 idle_period_state_ = IdlePeriodState::NOT_IN_IDLE_PERIOD; | |
| 540 } | |
| 541 | |
| 542 // static | |
| 543 bool RendererSchedulerImpl::IsInIdlePeriod(IdlePeriodState state) { | |
| 544 return state != IdlePeriodState::NOT_IN_IDLE_PERIOD; | |
| 400 } | 545 } |
| 401 | 546 |
| 402 void RendererSchedulerImpl::SetTimeSourceForTesting( | 547 void RendererSchedulerImpl::SetTimeSourceForTesting( |
| 403 scoped_refptr<cc::TestNowSource> time_source) { | 548 scoped_refptr<cc::TestNowSource> time_source) { |
| 404 DCHECK(main_thread_checker_.CalledOnValidThread()); | 549 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 405 time_source_ = time_source; | 550 time_source_ = time_source; |
| 406 task_queue_manager_->SetTimeSourceForTesting(time_source); | 551 task_queue_manager_->SetTimeSourceForTesting(time_source); |
| 407 } | 552 } |
| 408 | 553 |
| 409 void RendererSchedulerImpl::SetWorkBatchSizeForTesting(size_t work_batch_size) { | 554 void RendererSchedulerImpl::SetWorkBatchSizeForTesting(size_t work_batch_size) { |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 477 case InputStreamState::ACTIVE: | 622 case InputStreamState::ACTIVE: |
| 478 return "active"; | 623 return "active"; |
| 479 case InputStreamState::ACTIVE_AND_AWAITING_TOUCHSTART_RESPONSE: | 624 case InputStreamState::ACTIVE_AND_AWAITING_TOUCHSTART_RESPONSE: |
| 480 return "active_and_awaiting_touchstart_response"; | 625 return "active_and_awaiting_touchstart_response"; |
| 481 default: | 626 default: |
| 482 NOTREACHED(); | 627 NOTREACHED(); |
| 483 return nullptr; | 628 return nullptr; |
| 484 } | 629 } |
| 485 } | 630 } |
| 486 | 631 |
| 632 const char* RendererSchedulerImpl::IdlePeriodStateToString( | |
| 633 IdlePeriodState idle_period_state) { | |
| 634 switch (idle_period_state) { | |
| 635 case IdlePeriodState::NOT_IN_IDLE_PERIOD: | |
| 636 return "not_in_idle_period"; | |
| 637 case IdlePeriodState::IN_SHORT_IDLE_PERIOD: | |
| 638 return "in_short_idle_period"; | |
| 639 case IdlePeriodState::IN_LONG_IDLE_PERIOD: | |
| 640 return "in_long_idle_period"; | |
| 641 case IdlePeriodState::IN_LONG_IDLE_WITH_MAX_DEADLINE_PERIOD: | |
| 642 return "in_long_idle_with_max_deadline_period"; | |
| 643 case IdlePeriodState::ENDING_LONG_IDLE_PERIOD: | |
| 644 return "ending_long_idle_period"; | |
| 645 default: | |
| 646 NOTREACHED(); | |
| 647 return nullptr; | |
| 648 } | |
| 649 } | |
| 650 | |
| 487 scoped_refptr<base::trace_event::ConvertableToTraceFormat> | 651 scoped_refptr<base::trace_event::ConvertableToTraceFormat> |
| 488 RendererSchedulerImpl::AsValueLocked(base::TimeTicks optional_now) const { | 652 RendererSchedulerImpl::AsValueLocked(base::TimeTicks optional_now) const { |
| 489 DCHECK(main_thread_checker_.CalledOnValidThread()); | 653 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 490 incoming_signals_lock_.AssertAcquired(); | 654 incoming_signals_lock_.AssertAcquired(); |
| 491 | 655 |
| 492 if (optional_now.is_null()) | 656 if (optional_now.is_null()) |
| 493 optional_now = Now(); | 657 optional_now = Now(); |
| 494 scoped_refptr<base::trace_event::TracedValue> state = | 658 scoped_refptr<base::trace_event::TracedValue> state = |
| 495 new base::trace_event::TracedValue(); | 659 new base::trace_event::TracedValue(); |
| 496 | 660 |
| 497 state->SetString("current_policy", PolicyToString(current_policy_)); | 661 state->SetString("current_policy", PolicyToString(current_policy_)); |
| 662 state->SetString("idle_period_state", | |
| 663 IdlePeriodStateToString(idle_period_state_)); | |
| 498 state->SetString("input_stream_state", | 664 state->SetString("input_stream_state", |
| 499 InputStreamStateToString(input_stream_state_)); | 665 InputStreamStateToString(input_stream_state_)); |
| 500 state->SetDouble("now", (optional_now - base::TimeTicks()).InMillisecondsF()); | 666 state->SetDouble("now", (optional_now - base::TimeTicks()).InMillisecondsF()); |
| 501 state->SetDouble("last_input_receipt_time_on_compositor_", | 667 state->SetDouble("last_input_receipt_time_on_compositor_", |
| 502 (last_input_receipt_time_on_compositor_ - base::TimeTicks()) | 668 (last_input_receipt_time_on_compositor_ - base::TimeTicks()) |
| 503 .InMillisecondsF()); | 669 .InMillisecondsF()); |
| 504 state->SetDouble( | 670 state->SetDouble( |
| 505 "last_input_process_time_on_main_", | 671 "last_input_process_time_on_main_", |
| 506 (last_input_process_time_on_main_ - base::TimeTicks()).InMillisecondsF()); | 672 (last_input_process_time_on_main_ - base::TimeTicks()).InMillisecondsF()); |
| 507 state->SetDouble( | 673 state->SetDouble( |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 555 } | 721 } |
| 556 | 722 |
| 557 void RendererSchedulerImpl::RemoveTaskObserver( | 723 void RendererSchedulerImpl::RemoveTaskObserver( |
| 558 base::MessageLoop::TaskObserver* task_observer) { | 724 base::MessageLoop::TaskObserver* task_observer) { |
| 559 DCHECK(main_thread_checker_.CalledOnValidThread()); | 725 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 560 if (task_queue_manager_) | 726 if (task_queue_manager_) |
| 561 task_queue_manager_->RemoveTaskObserver(task_observer); | 727 task_queue_manager_->RemoveTaskObserver(task_observer); |
| 562 } | 728 } |
| 563 | 729 |
| 564 } // namespace content | 730 } // namespace content |
| OLD | NEW |