| 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 19 matching lines...) Expand all Loading... |
| 30 task_queue_manager_->TaskRunnerForQueue(DEFAULT_TASK_QUEUE)), | 30 task_queue_manager_->TaskRunnerForQueue(DEFAULT_TASK_QUEUE)), |
| 31 compositor_task_runner_( | 31 compositor_task_runner_( |
| 32 task_queue_manager_->TaskRunnerForQueue(COMPOSITOR_TASK_QUEUE)), | 32 task_queue_manager_->TaskRunnerForQueue(COMPOSITOR_TASK_QUEUE)), |
| 33 loading_task_runner_( | 33 loading_task_runner_( |
| 34 task_queue_manager_->TaskRunnerForQueue(LOADING_TASK_QUEUE)), | 34 task_queue_manager_->TaskRunnerForQueue(LOADING_TASK_QUEUE)), |
| 35 delayed_update_policy_runner_( | 35 delayed_update_policy_runner_( |
| 36 base::Bind(&RendererSchedulerImpl::UpdatePolicy, | 36 base::Bind(&RendererSchedulerImpl::UpdatePolicy, |
| 37 base::Unretained(this)), | 37 base::Unretained(this)), |
| 38 control_task_runner_), | 38 control_task_runner_), |
| 39 current_policy_(Policy::NORMAL), | 39 current_policy_(Policy::NORMAL), |
| 40 idle_period_state_(IdlePeriodState::NOT_IN_IDLE_PERIOD), |
| 41 long_idle_periods_enabled_(false), |
| 40 last_input_type_(blink::WebInputEvent::Undefined), | 42 last_input_type_(blink::WebInputEvent::Undefined), |
| 41 input_stream_state_(InputStreamState::INACTIVE), | 43 input_stream_state_(InputStreamState::INACTIVE), |
| 42 policy_may_need_update_(&incoming_signals_lock_), | 44 policy_may_need_update_(&incoming_signals_lock_), |
| 43 weak_factory_(this) { | 45 weak_factory_(this) { |
| 44 weak_renderer_scheduler_ptr_ = weak_factory_.GetWeakPtr(); | 46 weak_renderer_scheduler_ptr_ = weak_factory_.GetWeakPtr(); |
| 45 update_policy_closure_ = base::Bind(&RendererSchedulerImpl::UpdatePolicy, | 47 update_policy_closure_ = base::Bind(&RendererSchedulerImpl::UpdatePolicy, |
| 46 weak_renderer_scheduler_ptr_); | 48 weak_renderer_scheduler_ptr_); |
| 47 end_idle_period_closure_.Reset(base::Bind( | 49 end_idle_period_closure_.Reset(base::Bind( |
| 48 &RendererSchedulerImpl::EndIdlePeriod, weak_renderer_scheduler_ptr_)); | 50 &RendererSchedulerImpl::EndIdlePeriod, weak_renderer_scheduler_ptr_)); |
| 51 initiate_next_long_idle_period_closure_.Reset(base::Bind( |
| 52 &RendererSchedulerImpl::InitiateLongIdlePeriod, |
| 53 weak_renderer_scheduler_ptr_)); |
| 54 initiate_next_long_idle_period_after_wakeup_closure_.Reset(base::Bind( |
| 55 &RendererSchedulerImpl::InitiateLongIdlePeriodAfterWakeup, |
| 56 weak_renderer_scheduler_ptr_)); |
| 57 |
| 49 idle_task_runner_ = make_scoped_refptr(new SingleThreadIdleTaskRunner( | 58 idle_task_runner_ = make_scoped_refptr(new SingleThreadIdleTaskRunner( |
| 50 task_queue_manager_->TaskRunnerForQueue(IDLE_TASK_QUEUE), | 59 task_queue_manager_->TaskRunnerForQueue(IDLE_TASK_QUEUE), |
| 51 control_task_after_wakeup_runner_, | 60 control_task_after_wakeup_runner_, |
| 52 base::Bind(&RendererSchedulerImpl::CurrentIdleTaskDeadlineCallback, | 61 base::Bind(&RendererSchedulerImpl::CurrentIdleTaskDeadlineCallback, |
| 53 weak_renderer_scheduler_ptr_))); | 62 weak_renderer_scheduler_ptr_))); |
| 54 | 63 |
| 55 renderer_task_queue_selector_->SetQueuePriority( | 64 renderer_task_queue_selector_->SetQueuePriority( |
| 56 CONTROL_TASK_QUEUE, RendererTaskQueueSelector::CONTROL_PRIORITY); | 65 CONTROL_TASK_QUEUE, RendererTaskQueueSelector::CONTROL_PRIORITY); |
| 57 | 66 |
| 58 renderer_task_queue_selector_->SetQueuePriority( | 67 renderer_task_queue_selector_->SetQueuePriority( |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 129 | 138 |
| 130 void RendererSchedulerImpl::DidCommitFrameToCompositor() { | 139 void RendererSchedulerImpl::DidCommitFrameToCompositor() { |
| 131 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), | 140 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), |
| 132 "RendererSchedulerImpl::DidCommitFrameToCompositor"); | 141 "RendererSchedulerImpl::DidCommitFrameToCompositor"); |
| 133 DCHECK(main_thread_checker_.CalledOnValidThread()); | 142 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 134 if (!task_queue_manager_) | 143 if (!task_queue_manager_) |
| 135 return; | 144 return; |
| 136 | 145 |
| 137 base::TimeTicks now(Now()); | 146 base::TimeTicks now(Now()); |
| 138 if (now < estimated_next_frame_begin_) { | 147 if (now < estimated_next_frame_begin_) { |
| 139 StartIdlePeriod(); | 148 // TODO(rmcilroy): Consider reducing the idle period based on the runtime of |
| 149 // the next pending delayed tasks (as currently done in for long idle times) |
| 150 StartIdlePeriod(IdlePeriodState::IN_SHORT_IDLE_PERIOD); |
| 140 control_task_runner_->PostDelayedTask(FROM_HERE, | 151 control_task_runner_->PostDelayedTask(FROM_HERE, |
| 141 end_idle_period_closure_.callback(), | 152 end_idle_period_closure_.callback(), |
| 142 estimated_next_frame_begin_ - now); | 153 estimated_next_frame_begin_ - now); |
| 143 } | 154 } |
| 144 } | 155 } |
| 145 | 156 |
| 146 void RendererSchedulerImpl::BeginFrameNotExpectedSoon() { | 157 void RendererSchedulerImpl::BeginFrameNotExpectedSoon() { |
| 147 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), | 158 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), |
| 148 "RendererSchedulerImpl::BeginFrameNotExpectedSoon"); | 159 "RendererSchedulerImpl::BeginFrameNotExpectedSoon"); |
| 149 DCHECK(main_thread_checker_.CalledOnValidThread()); | 160 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 161 if (!task_queue_manager_) |
| 162 return; |
| 163 |
| 150 // TODO(skyostil): Wire up real notification of input events processing | 164 // TODO(skyostil): Wire up real notification of input events processing |
| 151 // instead of this approximation. | 165 // instead of this approximation. |
| 152 DidProcessInputEvent(base::TimeTicks()); | 166 DidProcessInputEvent(base::TimeTicks()); |
| 153 // TODO(rmcilroy): Implement long idle times. | 167 |
| 168 InitiateLongIdlePeriod(); |
| 154 } | 169 } |
| 155 | 170 |
| 156 void RendererSchedulerImpl::DidReceiveInputEventOnCompositorThread( | 171 void RendererSchedulerImpl::DidReceiveInputEventOnCompositorThread( |
| 157 const blink::WebInputEvent& web_input_event) { | 172 const blink::WebInputEvent& web_input_event) { |
| 158 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), | 173 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), |
| 159 "RendererSchedulerImpl::DidReceiveInputEventOnCompositorThread"); | 174 "RendererSchedulerImpl::DidReceiveInputEventOnCompositorThread"); |
| 160 // We regard MouseMove events with the left mouse button down as a signal | 175 // We regard MouseMove events with the left mouse button down as a signal |
| 161 // that the user is doing something requiring a smooth frame rate. | 176 // that the user is doing something requiring a smooth frame rate. |
| 162 if (web_input_event.type == blink::WebInputEvent::MouseMove && | 177 if (web_input_event.type == blink::WebInputEvent::MouseMove && |
| 163 (web_input_event.modifiers & blink::WebInputEvent::LeftButtonDown)) { | 178 (web_input_event.modifiers & blink::WebInputEvent::LeftButtonDown)) { |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 294 incoming_signals_lock_.AssertAcquired(); | 309 incoming_signals_lock_.AssertAcquired(); |
| 295 if (!task_queue_manager_) | 310 if (!task_queue_manager_) |
| 296 return; | 311 return; |
| 297 | 312 |
| 298 base::TimeTicks now = Now(); | 313 base::TimeTicks now = Now(); |
| 299 policy_may_need_update_.SetWhileLocked(false); | 314 policy_may_need_update_.SetWhileLocked(false); |
| 300 | 315 |
| 301 base::TimeDelta new_policy_duration; | 316 base::TimeDelta new_policy_duration; |
| 302 Policy new_policy = ComputeNewPolicy(now, &new_policy_duration); | 317 Policy new_policy = ComputeNewPolicy(now, &new_policy_duration); |
| 303 if (new_policy_duration > base::TimeDelta()) { | 318 if (new_policy_duration > base::TimeDelta()) { |
| 319 current_policy_expiration_time_ = now + new_policy_duration; |
| 304 delayed_update_policy_runner_.SetDeadline(FROM_HERE, new_policy_duration, | 320 delayed_update_policy_runner_.SetDeadline(FROM_HERE, new_policy_duration, |
| 305 now); | 321 now); |
| 322 } else { |
| 323 current_policy_expiration_time_ = base::TimeTicks(); |
| 306 } | 324 } |
| 307 | 325 |
| 308 if (new_policy == current_policy_) | 326 if (new_policy == current_policy_) |
| 309 return; | 327 return; |
| 310 | 328 |
| 311 switch (new_policy) { | 329 switch (new_policy) { |
| 312 case Policy::COMPOSITOR_PRIORITY: | 330 case Policy::COMPOSITOR_PRIORITY: |
| 313 renderer_task_queue_selector_->SetQueuePriority( | 331 renderer_task_queue_selector_->SetQueuePriority( |
| 314 COMPOSITOR_TASK_QUEUE, RendererTaskQueueSelector::HIGH_PRIORITY); | 332 COMPOSITOR_TASK_QUEUE, RendererTaskQueueSelector::HIGH_PRIORITY); |
| 315 // TODO(scheduler-dev): Add a task priority between HIGH and BEST_EFFORT | 333 // TODO(scheduler-dev): Add a task priority between HIGH and BEST_EFFORT |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 347 base::TimeDelta* new_policy_duration) { | 365 base::TimeDelta* new_policy_duration) { |
| 348 DCHECK(main_thread_checker_.CalledOnValidThread()); | 366 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 349 incoming_signals_lock_.AssertAcquired(); | 367 incoming_signals_lock_.AssertAcquired(); |
| 350 | 368 |
| 351 Policy new_policy = Policy::NORMAL; | 369 Policy new_policy = Policy::NORMAL; |
| 352 *new_policy_duration = base::TimeDelta(); | 370 *new_policy_duration = base::TimeDelta(); |
| 353 | 371 |
| 354 if (input_stream_state_ == InputStreamState::INACTIVE) | 372 if (input_stream_state_ == InputStreamState::INACTIVE) |
| 355 return new_policy; | 373 return new_policy; |
| 356 | 374 |
| 357 base::TimeDelta new_priority_duration = | |
| 358 base::TimeDelta::FromMilliseconds(kPriorityEscalationAfterInputMillis); | |
| 359 Policy input_priority_policy = | 375 Policy input_priority_policy = |
| 360 input_stream_state_ == | 376 input_stream_state_ == |
| 361 InputStreamState::ACTIVE_AND_AWAITING_TOUCHSTART_RESPONSE | 377 InputStreamState::ACTIVE_AND_AWAITING_TOUCHSTART_RESPONSE |
| 362 ? Policy::TOUCHSTART_PRIORITY | 378 ? Policy::TOUCHSTART_PRIORITY |
| 363 : Policy::COMPOSITOR_PRIORITY; | 379 : Policy::COMPOSITOR_PRIORITY; |
| 380 base::TimeDelta time_left_in_policy = TimeLeftInInputEscalatedPolicy(now); |
| 381 if (time_left_in_policy > base::TimeDelta()) { |
| 382 new_policy = input_priority_policy; |
| 383 *new_policy_duration = time_left_in_policy; |
| 384 } else { |
| 385 // Reset |input_stream_state_| to ensure |
| 386 // DidReceiveInputEventOnCompositorThread will post an UpdatePolicy task |
| 387 // when it's next called. |
| 388 input_stream_state_ = InputStreamState::INACTIVE; |
| 389 } |
| 390 return new_policy; |
| 391 } |
| 364 | 392 |
| 365 // If the input event is still pending, go into input prioritized policy | 393 base::TimeDelta RendererSchedulerImpl::TimeLeftInInputEscalatedPolicy( |
| 366 // and check again later. | 394 base::TimeTicks now) const { |
| 395 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 396 // TODO(rmcilroy): Change this to DCHECK_EQ when crbug.com/463869 is fixed. |
| 397 DCHECK(input_stream_state_ != InputStreamState::INACTIVE); |
| 398 incoming_signals_lock_.AssertAcquired(); |
| 399 |
| 400 base::TimeDelta escalated_priority_duration = |
| 401 base::TimeDelta::FromMilliseconds(kPriorityEscalationAfterInputMillis); |
| 402 base::TimeDelta time_left_in_policy; |
| 367 if (last_input_process_time_on_main_.is_null() && | 403 if (last_input_process_time_on_main_.is_null() && |
| 368 !task_queue_manager_->IsQueueEmpty(COMPOSITOR_TASK_QUEUE)) { | 404 !task_queue_manager_->IsQueueEmpty(COMPOSITOR_TASK_QUEUE)) { |
| 369 new_policy = input_priority_policy; | 405 // If the input event is still pending, go into input prioritized policy |
| 370 *new_policy_duration = new_priority_duration; | 406 // and check again later. |
| 407 time_left_in_policy = escalated_priority_duration; |
| 371 } else { | 408 } else { |
| 372 // Otherwise make sure the input prioritization policy ends on time. | 409 // Otherwise make sure the input prioritization policy ends on time. |
| 373 base::TimeTicks new_priority_end( | 410 base::TimeTicks new_priority_end( |
| 374 std::max(last_input_receipt_time_on_compositor_, | 411 std::max(last_input_receipt_time_on_compositor_, |
| 375 last_input_process_time_on_main_) + | 412 last_input_process_time_on_main_) + |
| 376 new_priority_duration); | 413 escalated_priority_duration); |
| 377 base::TimeDelta time_left_in_policy = new_priority_end - now; | 414 time_left_in_policy = new_priority_end - now; |
| 378 | |
| 379 if (time_left_in_policy > base::TimeDelta()) { | |
| 380 new_policy = input_priority_policy; | |
| 381 *new_policy_duration = time_left_in_policy; | |
| 382 } else { | |
| 383 // Reset |input_stream_state_| to ensure | |
| 384 // DidReceiveInputEventOnCompositorThread will post an UpdatePolicy task | |
| 385 // when it's next called. | |
| 386 input_stream_state_ = InputStreamState::INACTIVE; | |
| 387 } | |
| 388 } | 415 } |
| 389 return new_policy; | 416 return time_left_in_policy; |
| 390 } | 417 } |
| 391 | 418 |
| 392 void RendererSchedulerImpl::StartIdlePeriod() { | 419 RendererSchedulerImpl::IdlePeriodState |
| 420 RendererSchedulerImpl::ComputeNewLongIdlePeriodState( |
| 421 const base::TimeTicks now, |
| 422 base::TimeDelta* next_long_idle_period_delay_out) { |
| 423 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 424 |
| 425 MaybeUpdatePolicy(); |
| 426 if (SchedulerPolicy() == Policy::TOUCHSTART_PRIORITY) { |
| 427 // Don't start a long idle task in touch start priority, try again when |
| 428 // the policy is scheduled to end. |
| 429 *next_long_idle_period_delay_out = current_policy_expiration_time_ - now; |
| 430 return IdlePeriodState::NOT_IN_IDLE_PERIOD; |
| 431 } |
| 432 |
| 433 base::TimeTicks next_pending_delayed_task = |
| 434 task_queue_manager_->NextPendingDelayedTaskRunTime(); |
| 435 base::TimeDelta max_long_idle_period_duration = |
| 436 base::TimeDelta::FromMilliseconds(kMaximumIdlePeriodMillis); |
| 437 base::TimeDelta long_idle_period_duration; |
| 438 if (next_pending_delayed_task.is_null()) { |
| 439 long_idle_period_duration = max_long_idle_period_duration; |
| 440 } else { |
| 441 // Limit the idle period duration to be before the next pending task. |
| 442 long_idle_period_duration = std::min(next_pending_delayed_task - now, |
| 443 max_long_idle_period_duration); |
| 444 } |
| 445 |
| 446 if (long_idle_period_duration > base::TimeDelta()) { |
| 447 *next_long_idle_period_delay_out = long_idle_period_duration; |
| 448 return long_idle_period_duration == max_long_idle_period_duration |
| 449 ? IdlePeriodState::IN_LONG_IDLE_PERIOD_WITH_MAX_DEADLINE |
| 450 : IdlePeriodState::IN_LONG_IDLE_PERIOD; |
| 451 } else { |
| 452 // If we can't start the idle period yet then try again after wakeup. |
| 453 *next_long_idle_period_delay_out = base::TimeDelta::FromMilliseconds( |
| 454 kRetryInitiateLongIdlePeriodDelayMillis); |
| 455 return IdlePeriodState::NOT_IN_IDLE_PERIOD; |
| 456 } |
| 457 } |
| 458 |
| 459 void RendererSchedulerImpl::InitiateLongIdlePeriod() { |
| 460 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), |
| 461 "InitiateLongIdlePeriod"); |
| 462 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 463 |
| 464 // End any previous idle period. |
| 465 EndIdlePeriod(); |
| 466 |
| 467 base::TimeTicks now(Now()); |
| 468 base::TimeDelta next_long_idle_period_delay; |
| 469 IdlePeriodState new_idle_period_state = |
| 470 ComputeNewLongIdlePeriodState(now, &next_long_idle_period_delay); |
| 471 if (long_idle_periods_enabled_ && IsInIdlePeriod(new_idle_period_state)) { |
| 472 estimated_next_frame_begin_ = now + next_long_idle_period_delay; |
| 473 StartIdlePeriod(new_idle_period_state); |
| 474 } |
| 475 |
| 476 if (task_queue_manager_->IsQueueEmpty(IDLE_TASK_QUEUE)) { |
| 477 // If there are no current idle tasks then post the call to initiate the |
| 478 // next idle for execution after wakeup (at which point after-wakeup idle |
| 479 // tasks might be eligible to run or more idle tasks posted). |
| 480 control_task_after_wakeup_runner_->PostDelayedTask( |
| 481 FROM_HERE, |
| 482 initiate_next_long_idle_period_after_wakeup_closure_.callback(), |
| 483 next_long_idle_period_delay); |
| 484 } else { |
| 485 // Otherwise post on the normal control task queue. |
| 486 control_task_runner_->PostDelayedTask( |
| 487 FROM_HERE, |
| 488 initiate_next_long_idle_period_closure_.callback(), |
| 489 next_long_idle_period_delay); |
| 490 } |
| 491 } |
| 492 |
| 493 void RendererSchedulerImpl::InitiateLongIdlePeriodAfterWakeup() { |
| 494 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), |
| 495 "InitiateLongIdlePeriodAfterWakeup"); |
| 496 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 497 |
| 498 if (IsInIdlePeriod(idle_period_state_)) { |
| 499 // Since we were asleep until now, end the async idle period trace event at |
| 500 // the time when it would have ended were we awake. |
| 501 TRACE_EVENT_ASYNC_END_WITH_TIMESTAMP0( |
| 502 "renderer.scheduler", "RendererSchedulerIdlePeriod", this, |
| 503 std::min(estimated_next_frame_begin_, Now()).ToInternalValue()); |
| 504 idle_period_state_ = IdlePeriodState::ENDING_LONG_IDLE_PERIOD; |
| 505 EndIdlePeriod(); |
| 506 } |
| 507 |
| 508 // Post a task to initiate the next long idle period rather than calling it |
| 509 // directly to allow all pending PostIdleTaskAfterWakeup tasks to get enqueued |
| 510 // on the idle task queue before the next idle period starts so they are |
| 511 // eligible to be run during the new idle period. |
| 512 control_task_runner_->PostTask( |
| 513 FROM_HERE, |
| 514 initiate_next_long_idle_period_closure_.callback()); |
| 515 } |
| 516 |
| 517 void RendererSchedulerImpl::StartIdlePeriod(IdlePeriodState new_state) { |
| 393 TRACE_EVENT_ASYNC_BEGIN0("renderer.scheduler", | 518 TRACE_EVENT_ASYNC_BEGIN0("renderer.scheduler", |
| 394 "RendererSchedulerIdlePeriod", this); | 519 "RendererSchedulerIdlePeriod", this); |
| 395 DCHECK(main_thread_checker_.CalledOnValidThread()); | 520 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 521 DCHECK(IsInIdlePeriod(new_state)); |
| 396 renderer_task_queue_selector_->EnableQueue( | 522 renderer_task_queue_selector_->EnableQueue( |
| 397 IDLE_TASK_QUEUE, RendererTaskQueueSelector::BEST_EFFORT_PRIORITY); | 523 IDLE_TASK_QUEUE, RendererTaskQueueSelector::BEST_EFFORT_PRIORITY); |
| 398 task_queue_manager_->PumpQueue(IDLE_TASK_QUEUE); | 524 task_queue_manager_->PumpQueue(IDLE_TASK_QUEUE); |
| 525 idle_period_state_ = new_state; |
| 399 } | 526 } |
| 400 | 527 |
| 401 void RendererSchedulerImpl::EndIdlePeriod() { | 528 void RendererSchedulerImpl::EndIdlePeriod() { |
| 402 bool is_tracing; | 529 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 403 TRACE_EVENT_CATEGORY_GROUP_ENABLED("renderer.scheduler", &is_tracing); | 530 |
| 404 if (is_tracing && !estimated_next_frame_begin_.is_null() && | 531 end_idle_period_closure_.Cancel(); |
| 405 base::TimeTicks::Now() > estimated_next_frame_begin_) { | 532 initiate_next_long_idle_period_closure_.Cancel(); |
| 406 TRACE_EVENT_ASYNC_STEP_INTO_WITH_TIMESTAMP0( | 533 initiate_next_long_idle_period_after_wakeup_closure_.Cancel(); |
| 407 "renderer.scheduler", | 534 |
| 408 "RendererSchedulerIdlePeriod", | 535 // If we weren't already within an idle period then early-out. |
| 409 this, | 536 if (!IsInIdlePeriod(idle_period_state_)) |
| 410 "DeadlineOverrun", | 537 return; |
| 411 estimated_next_frame_begin_.ToInternalValue()); | 538 |
| 539 // If we are in the ENDING_LONG_IDLE_PERIOD state we have already logged the |
| 540 // trace event. |
| 541 if (idle_period_state_ != IdlePeriodState::ENDING_LONG_IDLE_PERIOD) { |
| 542 bool is_tracing; |
| 543 TRACE_EVENT_CATEGORY_GROUP_ENABLED("renderer.scheduler", &is_tracing); |
| 544 if (is_tracing && !estimated_next_frame_begin_.is_null() && |
| 545 base::TimeTicks::Now() > estimated_next_frame_begin_) { |
| 546 TRACE_EVENT_ASYNC_STEP_INTO_WITH_TIMESTAMP0( |
| 547 "renderer.scheduler", |
| 548 "RendererSchedulerIdlePeriod", |
| 549 this, |
| 550 "DeadlineOverrun", |
| 551 estimated_next_frame_begin_.ToInternalValue()); |
| 552 } |
| 553 TRACE_EVENT_ASYNC_END0("renderer.scheduler", |
| 554 "RendererSchedulerIdlePeriod", this); |
| 412 } | 555 } |
| 413 TRACE_EVENT_ASYNC_END0("renderer.scheduler", | 556 |
| 414 "RendererSchedulerIdlePeriod", this); | |
| 415 DCHECK(main_thread_checker_.CalledOnValidThread()); | |
| 416 end_idle_period_closure_.Cancel(); | |
| 417 renderer_task_queue_selector_->DisableQueue(IDLE_TASK_QUEUE); | 557 renderer_task_queue_selector_->DisableQueue(IDLE_TASK_QUEUE); |
| 558 idle_period_state_ = IdlePeriodState::NOT_IN_IDLE_PERIOD; |
| 559 } |
| 560 |
| 561 // static |
| 562 bool RendererSchedulerImpl::IsInIdlePeriod(IdlePeriodState state) { |
| 563 return state != IdlePeriodState::NOT_IN_IDLE_PERIOD; |
| 418 } | 564 } |
| 419 | 565 |
| 420 void RendererSchedulerImpl::SetTimeSourceForTesting( | 566 void RendererSchedulerImpl::SetTimeSourceForTesting( |
| 421 scoped_refptr<cc::TestNowSource> time_source) { | 567 scoped_refptr<cc::TestNowSource> time_source) { |
| 422 DCHECK(main_thread_checker_.CalledOnValidThread()); | 568 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 423 time_source_ = time_source; | 569 time_source_ = time_source; |
| 424 task_queue_manager_->SetTimeSourceForTesting(time_source); | 570 task_queue_manager_->SetTimeSourceForTesting(time_source); |
| 425 } | 571 } |
| 426 | 572 |
| 427 void RendererSchedulerImpl::SetWorkBatchSizeForTesting(size_t work_batch_size) { | 573 void RendererSchedulerImpl::SetWorkBatchSizeForTesting(size_t work_batch_size) { |
| 428 DCHECK(main_thread_checker_.CalledOnValidThread()); | 574 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 429 task_queue_manager_->SetWorkBatchSize(work_batch_size); | 575 task_queue_manager_->SetWorkBatchSize(work_batch_size); |
| 430 } | 576 } |
| 431 | 577 |
| 578 void RendererSchedulerImpl::SetLongIdlePeriodsEnabledForTesting( |
| 579 bool long_idle_periods_enabled) { |
| 580 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 581 long_idle_periods_enabled_ = long_idle_periods_enabled; |
| 582 } |
| 583 |
| 432 base::TimeTicks RendererSchedulerImpl::Now() const { | 584 base::TimeTicks RendererSchedulerImpl::Now() const { |
| 433 return UNLIKELY(time_source_) ? time_source_->Now() : base::TimeTicks::Now(); | 585 return UNLIKELY(time_source_) ? time_source_->Now() : base::TimeTicks::Now(); |
| 434 } | 586 } |
| 435 | 587 |
| 436 RendererSchedulerImpl::PollableNeedsUpdateFlag::PollableNeedsUpdateFlag( | 588 RendererSchedulerImpl::PollableNeedsUpdateFlag::PollableNeedsUpdateFlag( |
| 437 base::Lock* write_lock_) | 589 base::Lock* write_lock_) |
| 438 : flag_(false), write_lock_(write_lock_) { | 590 : flag_(false), write_lock_(write_lock_) { |
| 439 } | 591 } |
| 440 | 592 |
| 441 RendererSchedulerImpl::PollableNeedsUpdateFlag::~PollableNeedsUpdateFlag() { | 593 RendererSchedulerImpl::PollableNeedsUpdateFlag::~PollableNeedsUpdateFlag() { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 495 case InputStreamState::ACTIVE: | 647 case InputStreamState::ACTIVE: |
| 496 return "active"; | 648 return "active"; |
| 497 case InputStreamState::ACTIVE_AND_AWAITING_TOUCHSTART_RESPONSE: | 649 case InputStreamState::ACTIVE_AND_AWAITING_TOUCHSTART_RESPONSE: |
| 498 return "active_and_awaiting_touchstart_response"; | 650 return "active_and_awaiting_touchstart_response"; |
| 499 default: | 651 default: |
| 500 NOTREACHED(); | 652 NOTREACHED(); |
| 501 return nullptr; | 653 return nullptr; |
| 502 } | 654 } |
| 503 } | 655 } |
| 504 | 656 |
| 657 const char* RendererSchedulerImpl::IdlePeriodStateToString( |
| 658 IdlePeriodState idle_period_state) { |
| 659 switch (idle_period_state) { |
| 660 case IdlePeriodState::NOT_IN_IDLE_PERIOD: |
| 661 return "not_in_idle_period"; |
| 662 case IdlePeriodState::IN_SHORT_IDLE_PERIOD: |
| 663 return "in_short_idle_period"; |
| 664 case IdlePeriodState::IN_LONG_IDLE_PERIOD: |
| 665 return "in_long_idle_period"; |
| 666 case IdlePeriodState::IN_LONG_IDLE_PERIOD_WITH_MAX_DEADLINE: |
| 667 return "in_long_idle_period_with_max_deadline"; |
| 668 case IdlePeriodState::ENDING_LONG_IDLE_PERIOD: |
| 669 return "ending_long_idle_period"; |
| 670 default: |
| 671 NOTREACHED(); |
| 672 return nullptr; |
| 673 } |
| 674 } |
| 675 |
| 505 scoped_refptr<base::trace_event::ConvertableToTraceFormat> | 676 scoped_refptr<base::trace_event::ConvertableToTraceFormat> |
| 506 RendererSchedulerImpl::AsValueLocked(base::TimeTicks optional_now) const { | 677 RendererSchedulerImpl::AsValueLocked(base::TimeTicks optional_now) const { |
| 507 DCHECK(main_thread_checker_.CalledOnValidThread()); | 678 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 508 incoming_signals_lock_.AssertAcquired(); | 679 incoming_signals_lock_.AssertAcquired(); |
| 509 | 680 |
| 510 if (optional_now.is_null()) | 681 if (optional_now.is_null()) |
| 511 optional_now = Now(); | 682 optional_now = Now(); |
| 512 scoped_refptr<base::trace_event::TracedValue> state = | 683 scoped_refptr<base::trace_event::TracedValue> state = |
| 513 new base::trace_event::TracedValue(); | 684 new base::trace_event::TracedValue(); |
| 514 | 685 |
| 515 state->SetString("current_policy", PolicyToString(current_policy_)); | 686 state->SetString("current_policy", PolicyToString(current_policy_)); |
| 687 state->SetString("idle_period_state", |
| 688 IdlePeriodStateToString(idle_period_state_)); |
| 516 state->SetString("input_stream_state", | 689 state->SetString("input_stream_state", |
| 517 InputStreamStateToString(input_stream_state_)); | 690 InputStreamStateToString(input_stream_state_)); |
| 518 state->SetDouble("now", (optional_now - base::TimeTicks()).InMillisecondsF()); | 691 state->SetDouble("now", (optional_now - base::TimeTicks()).InMillisecondsF()); |
| 519 state->SetDouble("last_input_receipt_time_on_compositor_", | 692 state->SetDouble("last_input_receipt_time_on_compositor_", |
| 520 (last_input_receipt_time_on_compositor_ - base::TimeTicks()) | 693 (last_input_receipt_time_on_compositor_ - base::TimeTicks()) |
| 521 .InMillisecondsF()); | 694 .InMillisecondsF()); |
| 522 state->SetDouble( | 695 state->SetDouble( |
| 523 "last_input_process_time_on_main_", | 696 "last_input_process_time_on_main_", |
| 524 (last_input_process_time_on_main_ - base::TimeTicks()).InMillisecondsF()); | 697 (last_input_process_time_on_main_ - base::TimeTicks()).InMillisecondsF()); |
| 525 state->SetDouble( | 698 state->SetDouble( |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 573 } | 746 } |
| 574 | 747 |
| 575 void RendererSchedulerImpl::RemoveTaskObserver( | 748 void RendererSchedulerImpl::RemoveTaskObserver( |
| 576 base::MessageLoop::TaskObserver* task_observer) { | 749 base::MessageLoop::TaskObserver* task_observer) { |
| 577 DCHECK(main_thread_checker_.CalledOnValidThread()); | 750 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 578 if (task_queue_manager_) | 751 if (task_queue_manager_) |
| 579 task_queue_manager_->RemoveTaskObserver(task_observer); | 752 task_queue_manager_->RemoveTaskObserver(task_observer); |
| 580 } | 753 } |
| 581 | 754 |
| 582 } // namespace content | 755 } // namespace content |
| OLD | NEW |