Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(325)

Side by Side Diff: content/renderer/scheduler/renderer_scheduler_impl.cc

Issue 969373002: [content]: Add CanExceedIdleDeadlineIfRequired function to RendererScheduler. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@long_idle_5
Patch Set: Change to exposing a CanExceedIdleDeadlineIfRequired function instead. Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 131
132 void RendererSchedulerImpl::DidCommitFrameToCompositor() { 132 void RendererSchedulerImpl::DidCommitFrameToCompositor() {
133 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), 133 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
134 "RendererSchedulerImpl::DidCommitFrameToCompositor"); 134 "RendererSchedulerImpl::DidCommitFrameToCompositor");
135 DCHECK(main_thread_checker_.CalledOnValidThread()); 135 DCHECK(main_thread_checker_.CalledOnValidThread());
136 if (!task_queue_manager_) 136 if (!task_queue_manager_)
137 return; 137 return;
138 138
139 base::TimeTicks now(Now()); 139 base::TimeTicks now(Now());
140 if (now < estimated_next_frame_begin_) { 140 if (now < estimated_next_frame_begin_) {
141 StartIdlePeriod(); 141 StartIdlePeriod(IdlePeriodState::WITHIN_IDLE_PERIOD);
142 control_task_runner_->PostDelayedTask(FROM_HERE, 142 control_task_runner_->PostDelayedTask(FROM_HERE,
143 end_idle_period_closure_.callback(), 143 end_idle_period_closure_.callback(),
144 estimated_next_frame_begin_ - now); 144 estimated_next_frame_begin_ - now);
145 } 145 }
146 } 146 }
147 147
148 void RendererSchedulerImpl::BeginFrameNotExpectedSoon() { 148 void RendererSchedulerImpl::BeginFrameNotExpectedSoon() {
149 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), 149 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
150 "RendererSchedulerImpl::BeginFrameNotExpectedSoon"); 150 "RendererSchedulerImpl::BeginFrameNotExpectedSoon");
151 DCHECK(main_thread_checker_.CalledOnValidThread()); 151 DCHECK(main_thread_checker_.CalledOnValidThread());
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 // Otherwise make sure the input prioritization policy ends on time. 387 // Otherwise make sure the input prioritization policy ends on time.
388 base::TimeTicks new_priority_end( 388 base::TimeTicks new_priority_end(
389 std::max(last_input_receipt_time_on_compositor_, 389 std::max(last_input_receipt_time_on_compositor_,
390 last_input_process_time_on_main_) + 390 last_input_process_time_on_main_) +
391 escalated_priority_duration); 391 escalated_priority_duration);
392 time_left_in_policy = new_priority_end - Now(); 392 time_left_in_policy = new_priority_end - Now();
393 } 393 }
394 return time_left_in_policy; 394 return time_left_in_policy;
395 } 395 }
396 396
397 bool RendererSchedulerImpl::ShouldStartLongIdlePeriod( 397 RendererSchedulerImpl::IdlePeriodState
398 RendererSchedulerImpl::ComputeNewLongIdlePeriodState(
398 const base::TimeTicks now, 399 const base::TimeTicks now,
399 base::TimeDelta* next_long_idle_period_delay_out) { 400 base::TimeDelta* next_long_idle_period_delay_out) {
400 DCHECK(main_thread_checker_.CalledOnValidThread()); 401 DCHECK(main_thread_checker_.CalledOnValidThread());
401 402
402 MaybeUpdatePolicy(); 403 MaybeUpdatePolicy();
403 if (SchedulerPolicy() == Policy::TOUCHSTART_PRIORITY) { 404 if (SchedulerPolicy() == Policy::TOUCHSTART_PRIORITY) {
404 // Don't start a long idle task in touch start priority, try again when 405 // Don't start a long idle task in touch start priority, try again when
405 // the policy is scheduled to end. 406 // the policy is scheduled to end.
406 *next_long_idle_period_delay_out = current_policy_expiration_time_ - now; 407 *next_long_idle_period_delay_out = current_policy_expiration_time_ - now;
407 return false; 408 return IdlePeriodState::NOT_WITHIN_IDLE_PERIOD;
408 } 409 }
409 410
410 base::TimeTicks next_pending_delayed_task = 411 base::TimeTicks next_pending_delayed_task =
411 task_queue_manager_->NextPendingDelayedTaskRunTime(); 412 task_queue_manager_->NextPendingDelayedTaskRunTime();
412 413 base::TimeDelta max_long_idle_period_duration =
413 base::TimeDelta long_idle_period_duration =
414 base::TimeDelta::FromMilliseconds(kMaximumIdlePeriodMillis); 414 base::TimeDelta::FromMilliseconds(kMaximumIdlePeriodMillis);
415 base::TimeDelta long_idle_period_duration;
415 if (!next_pending_delayed_task.is_null()) { 416 if (!next_pending_delayed_task.is_null()) {
416 // Limit the idle period duration to be before the next pending task. 417 // Limit the idle period duration to be before the next pending task.
417 long_idle_period_duration = std::min( 418 long_idle_period_duration = std::min(
418 next_pending_delayed_task - now, long_idle_period_duration); 419 next_pending_delayed_task - now, max_long_idle_period_duration);
420 } else {
421 long_idle_period_duration = max_long_idle_period_duration;
419 } 422 }
420 423
421 if (long_idle_period_duration > base::TimeDelta()) { 424 if (long_idle_period_duration > base::TimeDelta()) {
422 *next_long_idle_period_delay_out = long_idle_period_duration; 425 *next_long_idle_period_delay_out = long_idle_period_duration;
423 return true; 426 return long_idle_period_duration == max_long_idle_period_duration ?
427 IdlePeriodState::WITHIN_MAX_DEADLINE_IDLE_PERIOD:
428 IdlePeriodState::WITHIN_IDLE_PERIOD;
424 } else { 429 } else {
425 // If we can't start the idle period yet then try again after wakeup. 430 // If we can't start the idle period yet then try again after wakeup.
426 *next_long_idle_period_delay_out = base::TimeDelta::FromMilliseconds( 431 *next_long_idle_period_delay_out = base::TimeDelta::FromMilliseconds(
427 kRetryInitiateLongIdlePeriodDelayMillis); 432 kRetryInitiateLongIdlePeriodDelayMillis);
428 return false; 433 return IdlePeriodState::NOT_WITHIN_IDLE_PERIOD;
429 } 434 }
430 } 435 }
431 436
432 void RendererSchedulerImpl::InitiateLongIdlePeriod() { 437 void RendererSchedulerImpl::InitiateLongIdlePeriod() {
433 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), 438 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
434 "InitiateLongIdlePeriod"); 439 "InitiateLongIdlePeriod");
435 DCHECK(main_thread_checker_.CalledOnValidThread()); 440 DCHECK(main_thread_checker_.CalledOnValidThread());
436 441
437 // End any previous idle period. 442 // End any previous idle period.
438 EndIdlePeriod(); 443 EndIdlePeriod();
439 444
440 base::TimeTicks now(Now()); 445 base::TimeTicks now(Now());
441 base::TimeDelta next_long_idle_period_delay; 446 base::TimeDelta next_long_idle_period_delay;
442 if (ShouldStartLongIdlePeriod(now, &next_long_idle_period_delay)) { 447 IdlePeriodState new_idle_period_state = ComputeNewLongIdlePeriodState(
448 now, &next_long_idle_period_delay);
449 if (new_idle_period_state != IdlePeriodState::NOT_WITHIN_IDLE_PERIOD) {
443 estimated_next_frame_begin_ = now + next_long_idle_period_delay; 450 estimated_next_frame_begin_ = now + next_long_idle_period_delay;
444 StartIdlePeriod(); 451 StartIdlePeriod(new_idle_period_state);
445 } 452 }
446 453
447 if (task_queue_manager_->IsQueueEmpty(IDLE_TASK_QUEUE)) { 454 if (task_queue_manager_->IsQueueEmpty(IDLE_TASK_QUEUE)) {
448 // If there are no current idle tasks then post the call to initiate the 455 // If there are no current idle tasks then post the call to initiate the
449 // next idle for execution after wakeup (at which point after-wakeup idle 456 // next idle for execution after wakeup (at which point after-wakeup idle
450 // tasks might be eligible to run or more idle tasks posted). 457 // tasks might be eligible to run or more idle tasks posted).
451 control_task_after_wakeup_runner_->PostDelayedTask( 458 control_task_after_wakeup_runner_->PostDelayedTask(
452 FROM_HERE, 459 FROM_HERE,
453 after_wakeup_initiate_next_long_idle_period_closure_.callback(), 460 after_wakeup_initiate_next_long_idle_period_closure_.callback(),
454 next_long_idle_period_delay); 461 next_long_idle_period_delay);
455 } else { 462 } else {
456 // Otherwise post on the normal control task queue. 463 // Otherwise post on the normal control task queue.
457 control_task_runner_->PostDelayedTask( 464 control_task_runner_->PostDelayedTask(
458 FROM_HERE, 465 FROM_HERE,
459 initiate_next_long_idle_period_closure_.callback(), 466 initiate_next_long_idle_period_closure_.callback(),
460 next_long_idle_period_delay); 467 next_long_idle_period_delay);
461 } 468 }
462 } 469 }
463 470
464 void RendererSchedulerImpl::InitiateLongIdlePeriodAfterWakeup() { 471 void RendererSchedulerImpl::InitiateLongIdlePeriodAfterWakeup() {
465 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), 472 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
466 "AfterWakeupInitiateLongIdlePeriod"); 473 "AfterWakeupInitiateLongIdlePeriod");
467 DCHECK(main_thread_checker_.CalledOnValidThread()); 474 DCHECK(main_thread_checker_.CalledOnValidThread());
468 475
469 if (in_idle_period_) { 476 if (idle_period_state_ != IdlePeriodState::NOT_WITHIN_IDLE_PERIOD) {
Sami 2015/03/05 11:59:32 Should we still mark the async event as ended here
rmcilroy 2015/03/05 13:50:19 No (for the reasons discussed on the other CL).
470 // Since we were asleep until now, end the async idle period trace event at 477 // Since we were asleep until now, end the async idle period trace event at
471 // the time when it would have ended were we awake. 478 // the time when it would have ended were we awake.
472 TRACE_EVENT_ASYNC_END_WITH_TIMESTAMP0( 479 TRACE_EVENT_ASYNC_END_WITH_TIMESTAMP0(
473 "renderer.scheduler", "RendererSchedulerIdlePeriod", this, 480 "renderer.scheduler", "RendererSchedulerIdlePeriod", this,
474 std::min(estimated_next_frame_begin_, Now()).ToInternalValue()); 481 std::min(estimated_next_frame_begin_, Now()).ToInternalValue());
475 } 482 }
476 483
477 // Post a task to initiate the next long idle period rather than calling it 484 // Post a task to initiate the next long idle period rather than calling it
478 // directly to allow all pending PostIdleTaskAfterWakeup tasks to get enqueued 485 // directly to allow all pending PostIdleTaskAfterWakeup tasks to get enqueued
479 // on the idle task queue before the next idle period starts so they are 486 // on the idle task queue before the next idle period starts so they are
480 // eligible to be run during the new idle period. 487 // eligible to be run during the new idle period.
481 control_task_runner_->PostTask( 488 control_task_runner_->PostTask(
482 FROM_HERE, 489 FROM_HERE,
483 initiate_next_long_idle_period_closure_.callback()); 490 initiate_next_long_idle_period_closure_.callback());
484 } 491 }
485 492
486 void RendererSchedulerImpl::StartIdlePeriod() { 493 void RendererSchedulerImpl::StartIdlePeriod(IdlePeriodState new_state) {
487 TRACE_EVENT_ASYNC_BEGIN0("renderer.scheduler", 494 TRACE_EVENT_ASYNC_BEGIN0("renderer.scheduler",
488 "RendererSchedulerIdlePeriod", this); 495 "RendererSchedulerIdlePeriod", this);
489 DCHECK(main_thread_checker_.CalledOnValidThread()); 496 DCHECK(main_thread_checker_.CalledOnValidThread());
497 // TODO(rmcilroy): Change this to DCHECK_EQ when crbug.com/463869 is fixed.
498 DCHECK(new_state != IdlePeriodState::NOT_WITHIN_IDLE_PERIOD);
499 idle_period_state_ = new_state;
490 renderer_task_queue_selector_->EnableQueue( 500 renderer_task_queue_selector_->EnableQueue(
491 IDLE_TASK_QUEUE, RendererTaskQueueSelector::BEST_EFFORT_PRIORITY); 501 IDLE_TASK_QUEUE, RendererTaskQueueSelector::BEST_EFFORT_PRIORITY);
492 task_queue_manager_->PumpQueue(IDLE_TASK_QUEUE); 502 task_queue_manager_->PumpQueue(IDLE_TASK_QUEUE);
493 in_idle_period_ = true;
494 } 503 }
495 504
496 void RendererSchedulerImpl::EndIdlePeriod() { 505 void RendererSchedulerImpl::EndIdlePeriod() {
497 DCHECK(main_thread_checker_.CalledOnValidThread()); 506 DCHECK(main_thread_checker_.CalledOnValidThread());
498 507
499 end_idle_period_closure_.Cancel(); 508 end_idle_period_closure_.Cancel();
500 initiate_next_long_idle_period_closure_.Cancel(); 509 initiate_next_long_idle_period_closure_.Cancel();
501 after_wakeup_initiate_next_long_idle_period_closure_.Cancel(); 510 after_wakeup_initiate_next_long_idle_period_closure_.Cancel();
502 511
503 if (!in_idle_period_) 512 if (idle_period_state_ == IdlePeriodState::NOT_WITHIN_IDLE_PERIOD)
504 return; 513 return;
505 514
515 idle_period_state_ = IdlePeriodState::NOT_WITHIN_IDLE_PERIOD;
506 renderer_task_queue_selector_->DisableQueue(IDLE_TASK_QUEUE); 516 renderer_task_queue_selector_->DisableQueue(IDLE_TASK_QUEUE);
507 bool is_tracing; 517 bool is_tracing;
508 TRACE_EVENT_CATEGORY_GROUP_ENABLED("renderer.scheduler", &is_tracing); 518 TRACE_EVENT_CATEGORY_GROUP_ENABLED("renderer.scheduler", &is_tracing);
509 if (is_tracing && !estimated_next_frame_begin_.is_null() && 519 if (is_tracing && !estimated_next_frame_begin_.is_null() &&
510 base::TimeTicks::Now() > estimated_next_frame_begin_) { 520 base::TimeTicks::Now() > estimated_next_frame_begin_) {
511 TRACE_EVENT_ASYNC_STEP_INTO_WITH_TIMESTAMP0( 521 TRACE_EVENT_ASYNC_STEP_INTO_WITH_TIMESTAMP0(
512 "renderer.scheduler", 522 "renderer.scheduler",
513 "RendererSchedulerIdlePeriod", 523 "RendererSchedulerIdlePeriod",
514 this, 524 this,
515 "DeadlineOverrun", 525 "DeadlineOverrun",
516 estimated_next_frame_begin_.ToInternalValue()); 526 estimated_next_frame_begin_.ToInternalValue());
517 } 527 }
518 TRACE_EVENT_ASYNC_END0("renderer.scheduler", 528 TRACE_EVENT_ASYNC_END0("renderer.scheduler",
519 "RendererSchedulerIdlePeriod", this); 529 "RendererSchedulerIdlePeriod", this);
520 } 530 }
521 531
532 bool RendererSchedulerImpl::CanExceedIdleDeadlineIfRequired() const {
533 return idle_period_state_ == IdlePeriodState::WITHIN_MAX_DEADLINE_IDLE_PERIOD;
Sami 2015/03/05 11:59:32 DCHECK(main_thread_checker_.CalledOnValidThread())
rmcilroy 2015/03/05 13:50:19 Done.
534 }
535
522 void RendererSchedulerImpl::SetTimeSourceForTesting( 536 void RendererSchedulerImpl::SetTimeSourceForTesting(
523 scoped_refptr<cc::TestNowSource> time_source) { 537 scoped_refptr<cc::TestNowSource> time_source) {
524 DCHECK(main_thread_checker_.CalledOnValidThread()); 538 DCHECK(main_thread_checker_.CalledOnValidThread());
525 time_source_ = time_source; 539 time_source_ = time_source;
526 task_queue_manager_->SetTimeSourceForTesting(time_source); 540 task_queue_manager_->SetTimeSourceForTesting(time_source);
527 } 541 }
528 542
529 void RendererSchedulerImpl::SetWorkBatchSizeForTesting(size_t work_batch_size) { 543 void RendererSchedulerImpl::SetWorkBatchSizeForTesting(size_t work_batch_size) {
530 DCHECK(main_thread_checker_.CalledOnValidThread()); 544 DCHECK(main_thread_checker_.CalledOnValidThread());
531 task_queue_manager_->SetWorkBatchSize(work_batch_size); 545 task_queue_manager_->SetWorkBatchSize(work_batch_size);
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
675 } 689 }
676 690
677 void RendererSchedulerImpl::RemoveTaskObserver( 691 void RendererSchedulerImpl::RemoveTaskObserver(
678 base::MessageLoop::TaskObserver* task_observer) { 692 base::MessageLoop::TaskObserver* task_observer) {
679 DCHECK(main_thread_checker_.CalledOnValidThread()); 693 DCHECK(main_thread_checker_.CalledOnValidThread());
680 if (task_queue_manager_) 694 if (task_queue_manager_)
681 task_queue_manager_->RemoveTaskObserver(task_observer); 695 task_queue_manager_->RemoveTaskObserver(task_observer);
682 } 696 }
683 697
684 } // namespace content 698 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698