| Index: content/renderer/scheduler/renderer_scheduler_impl.cc
|
| diff --git a/content/renderer/scheduler/renderer_scheduler_impl.cc b/content/renderer/scheduler/renderer_scheduler_impl.cc
|
| index 53281b81a807a7389d7e3917b86ef822d5c3bcc4..94067bda9d7e6a13b4baab9991f3f84b225812c5 100644
|
| --- a/content/renderer/scheduler/renderer_scheduler_impl.cc
|
| +++ b/content/renderer/scheduler/renderer_scheduler_impl.cc
|
| @@ -9,76 +9,41 @@
|
| #include "base/trace_event/trace_event.h"
|
| #include "base/trace_event/trace_event_argument.h"
|
| #include "cc/output/begin_frame_args.h"
|
| -#include "content/renderer/scheduler/nestable_single_thread_task_runner.h"
|
| -#include "content/renderer/scheduler/renderer_task_queue_selector.h"
|
| +#include "content/child/scheduler/nestable_single_thread_task_runner.h"
|
| +#include "content/child/scheduler/prioritizing_task_queue_selector.h"
|
| #include "ui/gfx/frame_time.h"
|
|
|
| namespace content {
|
|
|
| RendererSchedulerImpl::RendererSchedulerImpl(
|
| scoped_refptr<NestableSingleThreadTaskRunner> main_task_runner)
|
| - : renderer_task_queue_selector_(new RendererTaskQueueSelector()),
|
| - task_queue_manager_(
|
| - new TaskQueueManager(TASK_QUEUE_COUNT,
|
| - main_task_runner,
|
| - renderer_task_queue_selector_.get())),
|
| - control_task_runner_(
|
| - task_queue_manager_->TaskRunnerForQueue(CONTROL_TASK_QUEUE)),
|
| - control_task_after_wakeup_runner_(task_queue_manager_->TaskRunnerForQueue(
|
| - CONTROL_TASK_AFTER_WAKEUP_QUEUE)),
|
| - default_task_runner_(
|
| - task_queue_manager_->TaskRunnerForQueue(DEFAULT_TASK_QUEUE)),
|
| + : helper_(main_task_runner,
|
| + this,
|
| + "renderer.scheduler",
|
| + TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
|
| + TASK_QUEUE_COUNT),
|
| + control_task_runner_(helper_.ControlTaskRunner()),
|
| compositor_task_runner_(
|
| - task_queue_manager_->TaskRunnerForQueue(COMPOSITOR_TASK_QUEUE)),
|
| + helper_.SchedulerTaskQueueManager()->TaskRunnerForQueue(
|
| + COMPOSITOR_TASK_QUEUE)),
|
| loading_task_runner_(
|
| - task_queue_manager_->TaskRunnerForQueue(LOADING_TASK_QUEUE)),
|
| + helper_.SchedulerTaskQueueManager()->TaskRunnerForQueue(
|
| + LOADING_TASK_QUEUE)),
|
| delayed_update_policy_runner_(
|
| base::Bind(&RendererSchedulerImpl::UpdatePolicy,
|
| base::Unretained(this)),
|
| - control_task_runner_),
|
| + helper_.ControlTaskRunner()),
|
| current_policy_(Policy::NORMAL),
|
| - idle_period_state_(IdlePeriodState::NOT_IN_IDLE_PERIOD),
|
| last_input_type_(blink::WebInputEvent::Undefined),
|
| input_stream_state_(InputStreamState::INACTIVE),
|
| policy_may_need_update_(&incoming_signals_lock_),
|
| weak_factory_(this) {
|
| - weak_renderer_scheduler_ptr_ = weak_factory_.GetWeakPtr();
|
| update_policy_closure_ = base::Bind(&RendererSchedulerImpl::UpdatePolicy,
|
| - weak_renderer_scheduler_ptr_);
|
| - end_idle_period_closure_.Reset(base::Bind(
|
| - &RendererSchedulerImpl::EndIdlePeriod, weak_renderer_scheduler_ptr_));
|
| - initiate_next_long_idle_period_closure_.Reset(base::Bind(
|
| - &RendererSchedulerImpl::InitiateLongIdlePeriod,
|
| - weak_renderer_scheduler_ptr_));
|
| - initiate_next_long_idle_period_after_wakeup_closure_.Reset(base::Bind(
|
| - &RendererSchedulerImpl::InitiateLongIdlePeriodAfterWakeup,
|
| - weak_renderer_scheduler_ptr_));
|
| -
|
| - idle_task_runner_ = make_scoped_refptr(new SingleThreadIdleTaskRunner(
|
| - task_queue_manager_->TaskRunnerForQueue(IDLE_TASK_QUEUE),
|
| - control_task_after_wakeup_runner_,
|
| - base::Bind(&RendererSchedulerImpl::CurrentIdleTaskDeadlineCallback,
|
| - weak_renderer_scheduler_ptr_)));
|
| -
|
| - renderer_task_queue_selector_->SetQueuePriority(
|
| - CONTROL_TASK_QUEUE, RendererTaskQueueSelector::CONTROL_PRIORITY);
|
| -
|
| - renderer_task_queue_selector_->SetQueuePriority(
|
| - CONTROL_TASK_AFTER_WAKEUP_QUEUE,
|
| - RendererTaskQueueSelector::CONTROL_PRIORITY);
|
| - task_queue_manager_->SetPumpPolicy(
|
| - CONTROL_TASK_AFTER_WAKEUP_QUEUE,
|
| - TaskQueueManager::PumpPolicy::AFTER_WAKEUP);
|
| -
|
| - renderer_task_queue_selector_->DisableQueue(IDLE_TASK_QUEUE);
|
| - task_queue_manager_->SetPumpPolicy(IDLE_TASK_QUEUE,
|
| - TaskQueueManager::PumpPolicy::MANUAL);
|
| -
|
| - // TODO(skyostil): Increase this to 4 (crbug.com/444764).
|
| - task_queue_manager_->SetWorkBatchSize(1);
|
| -
|
| - for (size_t i = 0; i < TASK_QUEUE_COUNT; i++) {
|
| - task_queue_manager_->SetQueueName(
|
| + weak_factory_.GetWeakPtr());
|
| + for (size_t i = SchedulerHelper::TASK_QUEUE_COUNT;
|
| + i < TASK_QUEUE_COUNT;
|
| + i++) {
|
| + helper_.SchedulerTaskQueueManager()->SetQueueName(
|
| i, TaskQueueIdToString(static_cast<QueueId>(i)));
|
| }
|
| TRACE_EVENT_OBJECT_CREATED_WITH_ID(
|
| @@ -93,42 +58,53 @@ RendererSchedulerImpl::~RendererSchedulerImpl() {
|
| }
|
|
|
| void RendererSchedulerImpl::Shutdown() {
|
| - DCHECK(main_thread_checker_.CalledOnValidThread());
|
| - task_queue_manager_.reset();
|
| + helper_.Shutdown();
|
| }
|
|
|
| scoped_refptr<base::SingleThreadTaskRunner>
|
| RendererSchedulerImpl::DefaultTaskRunner() {
|
| - DCHECK(main_thread_checker_.CalledOnValidThread());
|
| - return default_task_runner_;
|
| + return helper_.DefaultTaskRunner();
|
| }
|
|
|
| scoped_refptr<base::SingleThreadTaskRunner>
|
| RendererSchedulerImpl::CompositorTaskRunner() {
|
| - DCHECK(main_thread_checker_.CalledOnValidThread());
|
| + helper_.CheckOnValidThread();
|
| return compositor_task_runner_;
|
| }
|
|
|
| scoped_refptr<SingleThreadIdleTaskRunner>
|
| RendererSchedulerImpl::IdleTaskRunner() {
|
| - DCHECK(main_thread_checker_.CalledOnValidThread());
|
| - return idle_task_runner_;
|
| + return helper_.IdleTaskRunner();
|
| }
|
|
|
| scoped_refptr<base::SingleThreadTaskRunner>
|
| RendererSchedulerImpl::LoadingTaskRunner() {
|
| - DCHECK(main_thread_checker_.CalledOnValidThread());
|
| + helper_.CheckOnValidThread();
|
| return loading_task_runner_;
|
| }
|
|
|
| +bool RendererSchedulerImpl::CanExceedIdleDeadlineIfRequired() const {
|
| + return helper_.CanExceedIdleDeadlineIfRequired();
|
| +}
|
| +
|
| +void RendererSchedulerImpl::AddTaskObserver(
|
| + base::MessageLoop::TaskObserver* task_observer) {
|
| + helper_.AddTaskObserver(task_observer);
|
| +}
|
| +
|
| +void RendererSchedulerImpl::RemoveTaskObserver(
|
| + base::MessageLoop::TaskObserver* task_observer) {
|
| + helper_.RemoveTaskObserver(task_observer);
|
| +}
|
| +
|
| void RendererSchedulerImpl::WillBeginFrame(const cc::BeginFrameArgs& args) {
|
| TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
|
| "RendererSchedulerImpl::WillBeginFrame", "args", args.AsValue());
|
| - DCHECK(main_thread_checker_.CalledOnValidThread());
|
| - if (!task_queue_manager_)
|
| + helper_.CheckOnValidThread();
|
| + if (helper_.IsShutdown())
|
| return;
|
|
|
| - EndIdlePeriod();
|
| + helper_.EndIdlePeriod();
|
| estimated_next_frame_begin_ = args.frame_time + args.interval;
|
| // TODO(skyostil): Wire up real notification of input events processing
|
| // instead of this approximation.
|
| @@ -138,33 +114,34 @@ void RendererSchedulerImpl::WillBeginFrame(const cc::BeginFrameArgs& args) {
|
| void RendererSchedulerImpl::DidCommitFrameToCompositor() {
|
| TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
|
| "RendererSchedulerImpl::DidCommitFrameToCompositor");
|
| - DCHECK(main_thread_checker_.CalledOnValidThread());
|
| - if (!task_queue_manager_)
|
| + helper_.CheckOnValidThread();
|
| + if (helper_.IsShutdown())
|
| return;
|
|
|
| - base::TimeTicks now(Now());
|
| + base::TimeTicks now(helper_.Now());
|
| if (now < estimated_next_frame_begin_) {
|
| // TODO(rmcilroy): Consider reducing the idle period based on the runtime of
|
| // the next pending delayed tasks (as currently done in for long idle times)
|
| - StartIdlePeriod(IdlePeriodState::IN_SHORT_IDLE_PERIOD);
|
| - control_task_runner_->PostDelayedTask(FROM_HERE,
|
| - end_idle_period_closure_.callback(),
|
| - estimated_next_frame_begin_ - now);
|
| + helper_.StartIdlePeriod(
|
| + SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD,
|
| + now,
|
| + estimated_next_frame_begin_,
|
| + true);
|
| }
|
| }
|
|
|
| void RendererSchedulerImpl::BeginFrameNotExpectedSoon() {
|
| TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
|
| "RendererSchedulerImpl::BeginFrameNotExpectedSoon");
|
| - DCHECK(main_thread_checker_.CalledOnValidThread());
|
| - if (!task_queue_manager_)
|
| + helper_.CheckOnValidThread();
|
| + if (helper_.IsShutdown())
|
| return;
|
|
|
| // TODO(skyostil): Wire up real notification of input events processing
|
| // instead of this approximation.
|
| DidProcessInputEvent(base::TimeTicks());
|
|
|
| - InitiateLongIdlePeriod();
|
| + helper_.InitiateLongIdlePeriod();
|
| }
|
|
|
| void RendererSchedulerImpl::DidReceiveInputEventOnCompositorThread(
|
| @@ -206,7 +183,7 @@ void RendererSchedulerImpl::UpdateForInputEvent(
|
| input_stream_state_ = new_input_stream_state;
|
| EnsureUrgentPolicyUpdatePostedOnMainThread(FROM_HERE);
|
| }
|
| - last_input_receipt_time_on_compositor_ = Now();
|
| + last_input_receipt_time_on_compositor_ = helper_.Now();
|
| // Clear the last known input processing time so that we know an input event
|
| // is still queued up. This timestamp will be updated the next time the
|
| // compositor commits or becomes quiescent. Note that this function is always
|
| @@ -218,7 +195,7 @@ void RendererSchedulerImpl::UpdateForInputEvent(
|
|
|
| void RendererSchedulerImpl::DidProcessInputEvent(
|
| base::TimeTicks begin_frame_time) {
|
| - DCHECK(main_thread_checker_.CalledOnValidThread());
|
| + helper_.CheckOnValidThread();
|
| base::AutoLock lock(incoming_signals_lock_);
|
| if (input_stream_state_ == InputStreamState::INACTIVE)
|
| return;
|
| @@ -226,13 +203,13 @@ void RendererSchedulerImpl::DidProcessInputEvent(
|
| if (!begin_frame_time.is_null() &&
|
| begin_frame_time < last_input_receipt_time_on_compositor_)
|
| return;
|
| - last_input_process_time_on_main_ = Now();
|
| + last_input_process_time_on_main_ = helper_.Now();
|
| UpdatePolicyLocked();
|
| }
|
|
|
| bool RendererSchedulerImpl::IsHighPriorityWorkAnticipated() {
|
| - DCHECK(main_thread_checker_.CalledOnValidThread());
|
| - if (!task_queue_manager_)
|
| + helper_.CheckOnValidThread();
|
| + if (helper_.IsShutdown())
|
| return false;
|
|
|
| MaybeUpdatePolicy();
|
| @@ -243,8 +220,8 @@ bool RendererSchedulerImpl::IsHighPriorityWorkAnticipated() {
|
| }
|
|
|
| bool RendererSchedulerImpl::ShouldYieldForHighPriorityWork() {
|
| - DCHECK(main_thread_checker_.CalledOnValidThread());
|
| - if (!task_queue_manager_)
|
| + helper_.CheckOnValidThread();
|
| + if (helper_.IsShutdown())
|
| return false;
|
|
|
| MaybeUpdatePolicy();
|
| @@ -258,7 +235,8 @@ bool RendererSchedulerImpl::ShouldYieldForHighPriorityWork() {
|
| return false;
|
|
|
| case Policy::COMPOSITOR_PRIORITY:
|
| - return !task_queue_manager_->IsQueueEmpty(COMPOSITOR_TASK_QUEUE);
|
| + return !helper_.SchedulerTaskQueueManager()->IsQueueEmpty(
|
| + COMPOSITOR_TASK_QUEUE);
|
|
|
| case Policy::TOUCHSTART_PRIORITY:
|
| return true;
|
| @@ -269,19 +247,20 @@ bool RendererSchedulerImpl::ShouldYieldForHighPriorityWork() {
|
| }
|
| }
|
|
|
| -void RendererSchedulerImpl::CurrentIdleTaskDeadlineCallback(
|
| - base::TimeTicks* deadline_out) const {
|
| - DCHECK(main_thread_checker_.CalledOnValidThread());
|
| - *deadline_out = estimated_next_frame_begin_;
|
| +base::TimeTicks
|
| +RendererSchedulerImpl::CurrentIdleTaskDeadlineForTesting() const {
|
| + base::TimeTicks deadline;
|
| + helper_.CurrentIdleTaskDeadlineCallback(&deadline);
|
| + return deadline;
|
| }
|
|
|
| RendererSchedulerImpl::Policy RendererSchedulerImpl::SchedulerPolicy() const {
|
| - DCHECK(main_thread_checker_.CalledOnValidThread());
|
| + helper_.CheckOnValidThread();
|
| return current_policy_;
|
| }
|
|
|
| void RendererSchedulerImpl::MaybeUpdatePolicy() {
|
| - DCHECK(main_thread_checker_.CalledOnValidThread());
|
| + helper_.CheckOnValidThread();
|
| if (policy_may_need_update_.IsSet()) {
|
| UpdatePolicy();
|
| }
|
| @@ -304,12 +283,12 @@ void RendererSchedulerImpl::UpdatePolicy() {
|
| }
|
|
|
| void RendererSchedulerImpl::UpdatePolicyLocked() {
|
| - DCHECK(main_thread_checker_.CalledOnValidThread());
|
| + helper_.CheckOnValidThread();
|
| incoming_signals_lock_.AssertAcquired();
|
| - if (!task_queue_manager_)
|
| + if (helper_.IsShutdown())
|
| return;
|
|
|
| - base::TimeTicks now = Now();
|
| + base::TimeTicks now = helper_.Now();
|
| policy_may_need_update_.SetWhileLocked(false);
|
|
|
| base::TimeDelta new_policy_duration;
|
| @@ -325,30 +304,35 @@ void RendererSchedulerImpl::UpdatePolicyLocked() {
|
| if (new_policy == current_policy_)
|
| return;
|
|
|
| + PrioritizingTaskQueueSelector* task_queue_selector =
|
| + helper_.SchedulerTaskQueueSelector();
|
| +
|
| switch (new_policy) {
|
| case Policy::COMPOSITOR_PRIORITY:
|
| - renderer_task_queue_selector_->SetQueuePriority(
|
| - COMPOSITOR_TASK_QUEUE, RendererTaskQueueSelector::HIGH_PRIORITY);
|
| + task_queue_selector->SetQueuePriority(
|
| + COMPOSITOR_TASK_QUEUE, PrioritizingTaskQueueSelector::HIGH_PRIORITY);
|
| // TODO(scheduler-dev): Add a task priority between HIGH and BEST_EFFORT
|
| // that still has some guarantee of running.
|
| - renderer_task_queue_selector_->SetQueuePriority(
|
| - LOADING_TASK_QUEUE, RendererTaskQueueSelector::BEST_EFFORT_PRIORITY);
|
| + task_queue_selector->SetQueuePriority(
|
| + LOADING_TASK_QUEUE,
|
| + PrioritizingTaskQueueSelector::BEST_EFFORT_PRIORITY);
|
| break;
|
| case Policy::TOUCHSTART_PRIORITY:
|
| - renderer_task_queue_selector_->SetQueuePriority(
|
| - COMPOSITOR_TASK_QUEUE, RendererTaskQueueSelector::HIGH_PRIORITY);
|
| - renderer_task_queue_selector_->DisableQueue(LOADING_TASK_QUEUE);
|
| + task_queue_selector->SetQueuePriority(
|
| + COMPOSITOR_TASK_QUEUE, PrioritizingTaskQueueSelector::HIGH_PRIORITY);
|
| + task_queue_selector->DisableQueue(LOADING_TASK_QUEUE);
|
| break;
|
| case Policy::NORMAL:
|
| - renderer_task_queue_selector_->SetQueuePriority(
|
| - COMPOSITOR_TASK_QUEUE, RendererTaskQueueSelector::NORMAL_PRIORITY);
|
| - renderer_task_queue_selector_->SetQueuePriority(
|
| - LOADING_TASK_QUEUE, RendererTaskQueueSelector::NORMAL_PRIORITY);
|
| + task_queue_selector->SetQueuePriority(
|
| + COMPOSITOR_TASK_QUEUE,
|
| + PrioritizingTaskQueueSelector::NORMAL_PRIORITY);
|
| + task_queue_selector->SetQueuePriority(
|
| + LOADING_TASK_QUEUE, PrioritizingTaskQueueSelector::NORMAL_PRIORITY);
|
| break;
|
| }
|
| - DCHECK(renderer_task_queue_selector_->IsQueueEnabled(COMPOSITOR_TASK_QUEUE));
|
| + DCHECK(task_queue_selector->IsQueueEnabled(COMPOSITOR_TASK_QUEUE));
|
| if (new_policy != Policy::TOUCHSTART_PRIORITY)
|
| - DCHECK(renderer_task_queue_selector_->IsQueueEnabled(LOADING_TASK_QUEUE));
|
| + DCHECK(task_queue_selector->IsQueueEnabled(LOADING_TASK_QUEUE));
|
|
|
| current_policy_ = new_policy;
|
|
|
| @@ -362,7 +346,7 @@ void RendererSchedulerImpl::UpdatePolicyLocked() {
|
| RendererSchedulerImpl::Policy RendererSchedulerImpl::ComputeNewPolicy(
|
| base::TimeTicks now,
|
| base::TimeDelta* new_policy_duration) {
|
| - DCHECK(main_thread_checker_.CalledOnValidThread());
|
| + helper_.CheckOnValidThread();
|
| incoming_signals_lock_.AssertAcquired();
|
|
|
| Policy new_policy = Policy::NORMAL;
|
| @@ -391,7 +375,7 @@ RendererSchedulerImpl::Policy RendererSchedulerImpl::ComputeNewPolicy(
|
|
|
| base::TimeDelta RendererSchedulerImpl::TimeLeftInInputEscalatedPolicy(
|
| base::TimeTicks now) const {
|
| - DCHECK(main_thread_checker_.CalledOnValidThread());
|
| + helper_.CheckOnValidThread();
|
| // TODO(rmcilroy): Change this to DCHECK_EQ when crbug.com/463869 is fixed.
|
| DCHECK(input_stream_state_ != InputStreamState::INACTIVE);
|
| incoming_signals_lock_.AssertAcquired();
|
| @@ -400,7 +384,8 @@ base::TimeDelta RendererSchedulerImpl::TimeLeftInInputEscalatedPolicy(
|
| base::TimeDelta::FromMilliseconds(kPriorityEscalationAfterInputMillis);
|
| base::TimeDelta time_left_in_policy;
|
| if (last_input_process_time_on_main_.is_null() &&
|
| - !task_queue_manager_->IsQueueEmpty(COMPOSITOR_TASK_QUEUE)) {
|
| + !helper_.SchedulerTaskQueueManager()->IsQueueEmpty(
|
| + COMPOSITOR_TASK_QUEUE)) {
|
| // If the input event is still pending, go into input prioritized policy
|
| // and check again later.
|
| time_left_in_policy = escalated_priority_duration;
|
| @@ -415,175 +400,28 @@ base::TimeDelta RendererSchedulerImpl::TimeLeftInInputEscalatedPolicy(
|
| return time_left_in_policy;
|
| }
|
|
|
| -RendererSchedulerImpl::IdlePeriodState
|
| -RendererSchedulerImpl::ComputeNewLongIdlePeriodState(
|
| - const base::TimeTicks now,
|
| +bool RendererSchedulerImpl::CanEnterLongIdlePeriod(
|
| + base::TimeTicks now,
|
| base::TimeDelta* next_long_idle_period_delay_out) {
|
| - DCHECK(main_thread_checker_.CalledOnValidThread());
|
| + helper_.CheckOnValidThread();
|
|
|
| MaybeUpdatePolicy();
|
| if (SchedulerPolicy() == Policy::TOUCHSTART_PRIORITY) {
|
| // Don't start a long idle task in touch start priority, try again when
|
| // the policy is scheduled to end.
|
| *next_long_idle_period_delay_out = current_policy_expiration_time_ - now;
|
| - return IdlePeriodState::NOT_IN_IDLE_PERIOD;
|
| - }
|
| -
|
| - base::TimeTicks next_pending_delayed_task =
|
| - task_queue_manager_->NextPendingDelayedTaskRunTime();
|
| - base::TimeDelta max_long_idle_period_duration =
|
| - base::TimeDelta::FromMilliseconds(kMaximumIdlePeriodMillis);
|
| - base::TimeDelta long_idle_period_duration;
|
| - if (next_pending_delayed_task.is_null()) {
|
| - long_idle_period_duration = max_long_idle_period_duration;
|
| - } else {
|
| - // Limit the idle period duration to be before the next pending task.
|
| - long_idle_period_duration = std::min(next_pending_delayed_task - now,
|
| - max_long_idle_period_duration);
|
| - }
|
| -
|
| - if (long_idle_period_duration > base::TimeDelta()) {
|
| - *next_long_idle_period_delay_out = long_idle_period_duration;
|
| - return long_idle_period_duration == max_long_idle_period_duration
|
| - ? IdlePeriodState::IN_LONG_IDLE_PERIOD_WITH_MAX_DEADLINE
|
| - : IdlePeriodState::IN_LONG_IDLE_PERIOD;
|
| - } else {
|
| - // If we can't start the idle period yet then try again after wakeup.
|
| - *next_long_idle_period_delay_out = base::TimeDelta::FromMilliseconds(
|
| - kRetryInitiateLongIdlePeriodDelayMillis);
|
| - return IdlePeriodState::NOT_IN_IDLE_PERIOD;
|
| - }
|
| -}
|
| -
|
| -void RendererSchedulerImpl::InitiateLongIdlePeriod() {
|
| - TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
|
| - "InitiateLongIdlePeriod");
|
| - DCHECK(main_thread_checker_.CalledOnValidThread());
|
| -
|
| - // End any previous idle period.
|
| - EndIdlePeriod();
|
| -
|
| - base::TimeTicks now(Now());
|
| - base::TimeDelta next_long_idle_period_delay;
|
| - IdlePeriodState new_idle_period_state =
|
| - ComputeNewLongIdlePeriodState(now, &next_long_idle_period_delay);
|
| - if (IsInIdlePeriod(new_idle_period_state)) {
|
| - estimated_next_frame_begin_ = now + next_long_idle_period_delay;
|
| - StartIdlePeriod(new_idle_period_state);
|
| - }
|
| -
|
| - if (task_queue_manager_->IsQueueEmpty(IDLE_TASK_QUEUE)) {
|
| - // If there are no current idle tasks then post the call to initiate the
|
| - // next idle for execution after wakeup (at which point after-wakeup idle
|
| - // tasks might be eligible to run or more idle tasks posted).
|
| - control_task_after_wakeup_runner_->PostDelayedTask(
|
| - FROM_HERE,
|
| - initiate_next_long_idle_period_after_wakeup_closure_.callback(),
|
| - next_long_idle_period_delay);
|
| - } else {
|
| - // Otherwise post on the normal control task queue.
|
| - control_task_runner_->PostDelayedTask(
|
| - FROM_HERE,
|
| - initiate_next_long_idle_period_closure_.callback(),
|
| - next_long_idle_period_delay);
|
| - }
|
| -}
|
| -
|
| -void RendererSchedulerImpl::InitiateLongIdlePeriodAfterWakeup() {
|
| - TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
|
| - "InitiateLongIdlePeriodAfterWakeup");
|
| - DCHECK(main_thread_checker_.CalledOnValidThread());
|
| -
|
| - if (IsInIdlePeriod(idle_period_state_)) {
|
| - // Since we were asleep until now, end the async idle period trace event at
|
| - // the time when it would have ended were we awake.
|
| - TRACE_EVENT_ASYNC_END_WITH_TIMESTAMP0(
|
| - "renderer.scheduler", "RendererSchedulerIdlePeriod", this,
|
| - std::min(estimated_next_frame_begin_, Now()).ToInternalValue());
|
| - idle_period_state_ = IdlePeriodState::ENDING_LONG_IDLE_PERIOD;
|
| - EndIdlePeriod();
|
| - }
|
| -
|
| - // Post a task to initiate the next long idle period rather than calling it
|
| - // directly to allow all pending PostIdleTaskAfterWakeup tasks to get enqueued
|
| - // on the idle task queue before the next idle period starts so they are
|
| - // eligible to be run during the new idle period.
|
| - control_task_runner_->PostTask(
|
| - FROM_HERE,
|
| - initiate_next_long_idle_period_closure_.callback());
|
| -}
|
| -
|
| -void RendererSchedulerImpl::StartIdlePeriod(IdlePeriodState new_state) {
|
| - TRACE_EVENT_ASYNC_BEGIN0("renderer.scheduler",
|
| - "RendererSchedulerIdlePeriod", this);
|
| - DCHECK(main_thread_checker_.CalledOnValidThread());
|
| - DCHECK(IsInIdlePeriod(new_state));
|
| -
|
| - renderer_task_queue_selector_->EnableQueue(
|
| - IDLE_TASK_QUEUE, RendererTaskQueueSelector::BEST_EFFORT_PRIORITY);
|
| - task_queue_manager_->PumpQueue(IDLE_TASK_QUEUE);
|
| - idle_period_state_ = new_state;
|
| -}
|
| -
|
| -void RendererSchedulerImpl::EndIdlePeriod() {
|
| - DCHECK(main_thread_checker_.CalledOnValidThread());
|
| -
|
| - end_idle_period_closure_.Cancel();
|
| - initiate_next_long_idle_period_closure_.Cancel();
|
| - initiate_next_long_idle_period_after_wakeup_closure_.Cancel();
|
| -
|
| - // If we weren't already within an idle period then early-out.
|
| - if (!IsInIdlePeriod(idle_period_state_))
|
| - return;
|
| -
|
| - // If we are in the ENDING_LONG_IDLE_PERIOD state we have already logged the
|
| - // trace event.
|
| - if (idle_period_state_ != IdlePeriodState::ENDING_LONG_IDLE_PERIOD) {
|
| - bool is_tracing;
|
| - TRACE_EVENT_CATEGORY_GROUP_ENABLED("renderer.scheduler", &is_tracing);
|
| - if (is_tracing && !estimated_next_frame_begin_.is_null() &&
|
| - base::TimeTicks::Now() > estimated_next_frame_begin_) {
|
| - TRACE_EVENT_ASYNC_STEP_INTO_WITH_TIMESTAMP0(
|
| - "renderer.scheduler",
|
| - "RendererSchedulerIdlePeriod",
|
| - this,
|
| - "DeadlineOverrun",
|
| - estimated_next_frame_begin_.ToInternalValue());
|
| - }
|
| - TRACE_EVENT_ASYNC_END0("renderer.scheduler",
|
| - "RendererSchedulerIdlePeriod", this);
|
| + return false;
|
| }
|
| -
|
| - renderer_task_queue_selector_->DisableQueue(IDLE_TASK_QUEUE);
|
| - idle_period_state_ = IdlePeriodState::NOT_IN_IDLE_PERIOD;
|
| -}
|
| -
|
| -// static
|
| -bool RendererSchedulerImpl::IsInIdlePeriod(IdlePeriodState state) {
|
| - return state != IdlePeriodState::NOT_IN_IDLE_PERIOD;
|
| -}
|
| -
|
| -bool RendererSchedulerImpl::CanExceedIdleDeadlineIfRequired() const {
|
| - TRACE_EVENT_BEGIN0("renderer.scheduler", "CanExceedIdleDeadlineIfRequired");
|
| - DCHECK(main_thread_checker_.CalledOnValidThread());
|
| - return idle_period_state_ ==
|
| - IdlePeriodState::IN_LONG_IDLE_PERIOD_WITH_MAX_DEADLINE;
|
| + return true;
|
| }
|
|
|
| void RendererSchedulerImpl::SetTimeSourceForTesting(
|
| scoped_refptr<cc::TestNowSource> time_source) {
|
| - DCHECK(main_thread_checker_.CalledOnValidThread());
|
| - time_source_ = time_source;
|
| - task_queue_manager_->SetTimeSourceForTesting(time_source);
|
| + helper_.SetTimeSourceForTesting(time_source);
|
| }
|
|
|
| void RendererSchedulerImpl::SetWorkBatchSizeForTesting(size_t work_batch_size) {
|
| - DCHECK(main_thread_checker_.CalledOnValidThread());
|
| - task_queue_manager_->SetWorkBatchSize(work_batch_size);
|
| -}
|
| -
|
| -base::TimeTicks RendererSchedulerImpl::Now() const {
|
| - return UNLIKELY(time_source_) ? time_source_->Now() : base::TimeTicks::Now();
|
| + helper_.SetWorkBatchSizeForTesting(work_batch_size);
|
| }
|
|
|
| RendererSchedulerImpl::PollableNeedsUpdateFlag::PollableNeedsUpdateFlag(
|
| @@ -607,21 +445,13 @@ bool RendererSchedulerImpl::PollableNeedsUpdateFlag::IsSet() const {
|
| // static
|
| const char* RendererSchedulerImpl::TaskQueueIdToString(QueueId queue_id) {
|
| switch (queue_id) {
|
| - case DEFAULT_TASK_QUEUE:
|
| - return "default_tq";
|
| case COMPOSITOR_TASK_QUEUE:
|
| return "compositor_tq";
|
| case LOADING_TASK_QUEUE:
|
| return "loading_tq";
|
| - case IDLE_TASK_QUEUE:
|
| - return "idle_tq";
|
| - case CONTROL_TASK_QUEUE:
|
| - return "control_tq";
|
| - case CONTROL_TASK_AFTER_WAKEUP_QUEUE:
|
| - return "control_after_wakeup_tq";
|
| default:
|
| - NOTREACHED();
|
| - return nullptr;
|
| + return SchedulerHelper::TaskQueueIdToString(
|
| + static_cast<SchedulerHelper::QueueId>(queue_id));
|
| }
|
| }
|
|
|
| @@ -655,38 +485,20 @@ const char* RendererSchedulerImpl::InputStreamStateToString(
|
| }
|
| }
|
|
|
| -const char* RendererSchedulerImpl::IdlePeriodStateToString(
|
| - IdlePeriodState idle_period_state) {
|
| - switch (idle_period_state) {
|
| - case IdlePeriodState::NOT_IN_IDLE_PERIOD:
|
| - return "not_in_idle_period";
|
| - case IdlePeriodState::IN_SHORT_IDLE_PERIOD:
|
| - return "in_short_idle_period";
|
| - case IdlePeriodState::IN_LONG_IDLE_PERIOD:
|
| - return "in_long_idle_period";
|
| - case IdlePeriodState::IN_LONG_IDLE_PERIOD_WITH_MAX_DEADLINE:
|
| - return "in_long_idle_period_with_max_deadline";
|
| - case IdlePeriodState::ENDING_LONG_IDLE_PERIOD:
|
| - return "ending_long_idle_period";
|
| - default:
|
| - NOTREACHED();
|
| - return nullptr;
|
| - }
|
| -}
|
| -
|
| scoped_refptr<base::trace_event::ConvertableToTraceFormat>
|
| RendererSchedulerImpl::AsValueLocked(base::TimeTicks optional_now) const {
|
| - DCHECK(main_thread_checker_.CalledOnValidThread());
|
| + helper_.CheckOnValidThread();
|
| incoming_signals_lock_.AssertAcquired();
|
|
|
| if (optional_now.is_null())
|
| - optional_now = Now();
|
| + optional_now = helper_.Now();
|
| scoped_refptr<base::trace_event::TracedValue> state =
|
| new base::trace_event::TracedValue();
|
|
|
| state->SetString("current_policy", PolicyToString(current_policy_));
|
| state->SetString("idle_period_state",
|
| - IdlePeriodStateToString(idle_period_state_));
|
| + SchedulerHelper::IdlePeriodStateToString(
|
| + helper_.SchedulerIdlePeriodState()));
|
| state->SetString("input_stream_state",
|
| InputStreamStateToString(input_stream_state_));
|
| state->SetDouble("now", (optional_now - base::TimeTicks()).InMillisecondsF());
|
| @@ -739,18 +551,4 @@ RendererSchedulerImpl::ComputeNewInputStreamState(
|
| return InputStreamState::ACTIVE;
|
| }
|
|
|
| -void RendererSchedulerImpl::AddTaskObserver(
|
| - base::MessageLoop::TaskObserver* task_observer) {
|
| - DCHECK(main_thread_checker_.CalledOnValidThread());
|
| - if (task_queue_manager_)
|
| - task_queue_manager_->AddTaskObserver(task_observer);
|
| -}
|
| -
|
| -void RendererSchedulerImpl::RemoveTaskObserver(
|
| - base::MessageLoop::TaskObserver* task_observer) {
|
| - DCHECK(main_thread_checker_.CalledOnValidThread());
|
| - if (task_queue_manager_)
|
| - task_queue_manager_->RemoveTaskObserver(task_observer);
|
| -}
|
| -
|
| } // namespace content
|
|
|