| Index: components/scheduler/renderer/renderer_scheduler_impl.cc
|
| diff --git a/components/scheduler/renderer/renderer_scheduler_impl.cc b/components/scheduler/renderer/renderer_scheduler_impl.cc
|
| index 0e0c705df594bf93c799c81b54aae1f386152e14..1d49c3f5c2a035d39e4961a5cefa230ff6f9e5f6 100644
|
| --- a/components/scheduler/renderer/renderer_scheduler_impl.cc
|
| +++ b/components/scheduler/renderer/renderer_scheduler_impl.cc
|
| @@ -36,16 +36,7 @@ RendererSchedulerImpl::RendererSchedulerImpl(
|
| base::Bind(&RendererSchedulerImpl::UpdatePolicy,
|
| base::Unretained(this)),
|
| helper_.ControlTaskRunner()),
|
| - current_policy_(Policy::NORMAL),
|
| - renderer_hidden_(false),
|
| - was_shutdown_(false),
|
| - pending_main_thread_input_event_count_(0),
|
| - awaiting_touch_start_response_(false),
|
| - begin_main_frame_on_critical_path_(false),
|
| - last_input_type_(blink::WebInputEvent::Undefined),
|
| - policy_may_need_update_(&incoming_signals_lock_),
|
| - timer_queue_suspend_count_(0),
|
| - in_idle_period_(false),
|
| + policy_may_need_update_(&any_thread_lock_),
|
| weak_factory_(this) {
|
| update_policy_closure_ = base::Bind(&RendererSchedulerImpl::UpdatePolicy,
|
| weak_factory_.GetWeakPtr());
|
| @@ -68,12 +59,33 @@ RendererSchedulerImpl::~RendererSchedulerImpl() {
|
| // Ensure the renderer scheduler was shut down explicitly, because otherwise
|
| // we could end up having stale pointers to the Blink heap which has been
|
| // terminated by this point.
|
| - DCHECK(was_shutdown_);
|
| + DCHECK(MainThreadOnly().was_shutdown_);
|
| +}
|
| +
|
| +RendererSchedulerImpl::MainThreadOnly::MainThreadOnly()
|
| + : current_policy_(Policy::NORMAL),
|
| + timer_queue_suspend_count_(0),
|
| + renderer_hidden_(false),
|
| + was_shutdown_(false),
|
| + in_idle_period_(false),
|
| + begin_main_frame_on_critical_path_(false) {
|
| +}
|
| +
|
| +RendererSchedulerImpl::AnyThread::AnyThread()
|
| + : pending_main_thread_input_event_count_(0),
|
| + awaiting_touch_start_response_(false) {
|
| +}
|
| +
|
| +RendererSchedulerImpl::CompositorThreadOnly::CompositorThreadOnly()
|
| + : last_input_type_(blink::WebInputEvent::Undefined) {
|
| +}
|
| +
|
| +RendererSchedulerImpl::CompositorThreadOnly::~CompositorThreadOnly() {
|
| }
|
|
|
| void RendererSchedulerImpl::Shutdown() {
|
| helper_.Shutdown();
|
| - was_shutdown_ = true;
|
| + MainThreadOnly().was_shutdown_ = true;
|
| }
|
|
|
| scoped_refptr<base::SingleThreadTaskRunner>
|
| @@ -126,8 +138,9 @@ void RendererSchedulerImpl::WillBeginFrame(const cc::BeginFrameArgs& args) {
|
| return;
|
|
|
| EndIdlePeriod();
|
| - estimated_next_frame_begin_ = args.frame_time + args.interval;
|
| - begin_main_frame_on_critical_path_ = args.on_critical_path;
|
| + MainThreadOnly().estimated_next_frame_begin_ =
|
| + args.frame_time + args.interval;
|
| + MainThreadOnly().begin_main_frame_on_critical_path_ = args.on_critical_path;
|
| }
|
|
|
| void RendererSchedulerImpl::DidCommitFrameToCompositor() {
|
| @@ -138,12 +151,12 @@ void RendererSchedulerImpl::DidCommitFrameToCompositor() {
|
| return;
|
|
|
| base::TimeTicks now(helper_.Now());
|
| - if (now < estimated_next_frame_begin_) {
|
| + if (now < MainThreadOnly().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)
|
| idle_helper_.StartIdlePeriod(
|
| IdleHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD, now,
|
| - estimated_next_frame_begin_);
|
| + MainThreadOnly().estimated_next_frame_begin_);
|
| }
|
| }
|
|
|
| @@ -161,7 +174,7 @@ void RendererSchedulerImpl::OnRendererHidden() {
|
| TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
|
| "RendererSchedulerImpl::OnRendererHidden");
|
| helper_.CheckOnValidThread();
|
| - if (helper_.IsShutdown() || renderer_hidden_)
|
| + if (helper_.IsShutdown() || MainThreadOnly().renderer_hidden_)
|
| return;
|
|
|
| idle_helper_.EnableLongIdlePeriod();
|
| @@ -173,7 +186,7 @@ void RendererSchedulerImpl::OnRendererHidden() {
|
| control_task_runner_->PostDelayedTask(
|
| FROM_HERE, end_renderer_hidden_idle_period_closure_.callback(),
|
| end_idle_when_hidden_delay);
|
| - renderer_hidden_ = true;
|
| + MainThreadOnly().renderer_hidden_ = true;
|
|
|
| TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(
|
| TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler",
|
| @@ -184,11 +197,11 @@ void RendererSchedulerImpl::OnRendererVisible() {
|
| TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
|
| "RendererSchedulerImpl::OnRendererVisible");
|
| helper_.CheckOnValidThread();
|
| - if (helper_.IsShutdown() || !renderer_hidden_)
|
| + if (helper_.IsShutdown() || !MainThreadOnly().renderer_hidden_)
|
| return;
|
|
|
| end_renderer_hidden_idle_period_closure_.Cancel();
|
| - renderer_hidden_ = false;
|
| + MainThreadOnly().renderer_hidden_ = false;
|
| EndIdlePeriod();
|
|
|
| TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(
|
| @@ -246,15 +259,16 @@ void RendererSchedulerImpl::DidAnimateForInputOnCompositorThread() {
|
| void RendererSchedulerImpl::UpdateForInputEventOnCompositorThread(
|
| blink::WebInputEvent::Type type,
|
| InputEventState input_event_state) {
|
| - base::AutoLock lock(incoming_signals_lock_);
|
| + base::AutoLock lock(any_thread_lock_);
|
| base::TimeTicks now = helper_.Now();
|
| bool was_in_compositor_priority = InputSignalsSuggestCompositorPriority(now);
|
| - bool was_awaiting_touch_start_response_ = awaiting_touch_start_response_;
|
| + bool was_awaiting_touch_start_response =
|
| + AnyThread().awaiting_touch_start_response_;
|
|
|
| if (type) {
|
| switch (type) {
|
| case blink::WebInputEvent::TouchStart:
|
| - awaiting_touch_start_response_ = true;
|
| + AnyThread().awaiting_touch_start_response_ = true;
|
| break;
|
|
|
| case blink::WebInputEvent::TouchMove:
|
| @@ -263,9 +277,10 @@ void RendererSchedulerImpl::UpdateForInputEventOnCompositorThread(
|
| // response prioritization is no longer necessary. Otherwise, the
|
| // initial touchmove should preserve the touchstart response pending
|
| // state.
|
| - if (awaiting_touch_start_response_ &&
|
| - last_input_type_ == blink::WebInputEvent::TouchMove) {
|
| - awaiting_touch_start_response_ = false;
|
| + if (AnyThread().awaiting_touch_start_response_ &&
|
| + CompositorThreadOnly().last_input_type_ ==
|
| + blink::WebInputEvent::TouchMove) {
|
| + AnyThread().awaiting_touch_start_response_ = false;
|
| }
|
| break;
|
|
|
| @@ -278,21 +293,22 @@ void RendererSchedulerImpl::UpdateForInputEventOnCompositorThread(
|
| break;
|
|
|
| default:
|
| - awaiting_touch_start_response_ = false;
|
| + AnyThread().awaiting_touch_start_response_ = false;
|
| break;
|
| }
|
| }
|
|
|
| // Avoid unnecessary policy updates, while in compositor priority.
|
| if (!was_in_compositor_priority ||
|
| - was_awaiting_touch_start_response_ != awaiting_touch_start_response_) {
|
| + was_awaiting_touch_start_response !=
|
| + AnyThread().awaiting_touch_start_response_) {
|
| EnsureUrgentPolicyUpdatePostedOnMainThread(FROM_HERE);
|
| }
|
| - last_input_signal_time_ = now;
|
| - last_input_type_ = type;
|
| + AnyThread().last_input_signal_time_ = now;
|
| + CompositorThreadOnly().last_input_type_ = type;
|
|
|
| if (input_event_state == InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD)
|
| - pending_main_thread_input_event_count_++;
|
| + AnyThread().pending_main_thread_input_event_count_++;
|
| }
|
|
|
| void RendererSchedulerImpl::DidHandleInputEventOnMainThread(
|
| @@ -301,10 +317,10 @@ void RendererSchedulerImpl::DidHandleInputEventOnMainThread(
|
| "RendererSchedulerImpl::DidHandleInputEventOnMainThread");
|
| helper_.CheckOnValidThread();
|
| if (ShouldPrioritizeInputEvent(web_input_event)) {
|
| - base::AutoLock lock(incoming_signals_lock_);
|
| - last_input_signal_time_ = helper_.Now();
|
| - if (pending_main_thread_input_event_count_ > 0)
|
| - pending_main_thread_input_event_count_--;
|
| + base::AutoLock lock(any_thread_lock_);
|
| + AnyThread().last_input_signal_time_ = helper_.Now();
|
| + if (AnyThread().pending_main_thread_input_event_count_ > 0)
|
| + AnyThread().pending_main_thread_input_event_count_--;
|
| }
|
| }
|
|
|
| @@ -316,8 +332,8 @@ bool RendererSchedulerImpl::IsHighPriorityWorkAnticipated() {
|
| MaybeUpdatePolicy();
|
| // The touchstart and compositor policies indicate a strong likelihood of
|
| // high-priority work in the near future.
|
| - return SchedulerPolicy() == Policy::COMPOSITOR_PRIORITY ||
|
| - SchedulerPolicy() == Policy::TOUCHSTART_PRIORITY;
|
| + return MainThreadOnly().current_policy_ == Policy::COMPOSITOR_PRIORITY ||
|
| + MainThreadOnly().current_policy_ == Policy::TOUCHSTART_PRIORITY;
|
| }
|
|
|
| bool RendererSchedulerImpl::ShouldYieldForHighPriorityWork() {
|
| @@ -331,7 +347,7 @@ bool RendererSchedulerImpl::ShouldYieldForHighPriorityWork() {
|
| // Note: even though the control queue is higher priority we don't yield for
|
| // it since these tasks are not user-provided work and they are only intended
|
| // to run before the next task, not interrupt the tasks.
|
| - switch (SchedulerPolicy()) {
|
| + switch (MainThreadOnly().current_policy_) {
|
| case Policy::NORMAL:
|
| return false;
|
|
|
| @@ -352,11 +368,6 @@ base::TimeTicks RendererSchedulerImpl::CurrentIdleTaskDeadlineForTesting()
|
| return idle_helper_.CurrentIdleTaskDeadline();
|
| }
|
|
|
| -RendererSchedulerImpl::Policy RendererSchedulerImpl::SchedulerPolicy() const {
|
| - helper_.CheckOnValidThread();
|
| - return current_policy_;
|
| -}
|
| -
|
| void RendererSchedulerImpl::MaybeUpdatePolicy() {
|
| helper_.CheckOnValidThread();
|
| if (policy_may_need_update_.IsSet()) {
|
| @@ -368,7 +379,7 @@ void RendererSchedulerImpl::EnsureUrgentPolicyUpdatePostedOnMainThread(
|
| const tracked_objects::Location& from_here) {
|
| // TODO(scheduler-dev): Check that this method isn't called from the main
|
| // thread.
|
| - incoming_signals_lock_.AssertAcquired();
|
| + any_thread_lock_.AssertAcquired();
|
| if (!policy_may_need_update_.IsSet()) {
|
| policy_may_need_update_.SetWhileLocked(true);
|
| control_task_runner_->PostTask(from_here, update_policy_closure_);
|
| @@ -376,18 +387,18 @@ void RendererSchedulerImpl::EnsureUrgentPolicyUpdatePostedOnMainThread(
|
| }
|
|
|
| void RendererSchedulerImpl::UpdatePolicy() {
|
| - base::AutoLock lock(incoming_signals_lock_);
|
| + base::AutoLock lock(any_thread_lock_);
|
| UpdatePolicyLocked(UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED);
|
| }
|
|
|
| void RendererSchedulerImpl::ForceUpdatePolicy() {
|
| - base::AutoLock lock(incoming_signals_lock_);
|
| + base::AutoLock lock(any_thread_lock_);
|
| UpdatePolicyLocked(UpdateType::FORCE_UPDATE);
|
| }
|
|
|
| void RendererSchedulerImpl::UpdatePolicyLocked(UpdateType update_type) {
|
| helper_.CheckOnValidThread();
|
| - incoming_signals_lock_.AssertAcquired();
|
| + any_thread_lock_.AssertAcquired();
|
| if (helper_.IsShutdown())
|
| return;
|
|
|
| @@ -397,15 +408,16 @@ void RendererSchedulerImpl::UpdatePolicyLocked(UpdateType update_type) {
|
| base::TimeDelta new_policy_duration;
|
| Policy new_policy = ComputeNewPolicy(now, &new_policy_duration);
|
| if (new_policy_duration > base::TimeDelta()) {
|
| - current_policy_expiration_time_ = now + new_policy_duration;
|
| + MainThreadOnly().current_policy_expiration_time_ =
|
| + now + new_policy_duration;
|
| delayed_update_policy_runner_.SetDeadline(FROM_HERE, new_policy_duration,
|
| now);
|
| } else {
|
| - current_policy_expiration_time_ = base::TimeTicks();
|
| + MainThreadOnly().current_policy_expiration_time_ = base::TimeTicks();
|
| }
|
|
|
| if (update_type == UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED &&
|
| - new_policy == current_policy_)
|
| + new_policy == MainThreadOnly().current_policy_)
|
| return;
|
|
|
| bool policy_disables_timers = false;
|
| @@ -435,7 +447,8 @@ void RendererSchedulerImpl::UpdatePolicyLocked(UpdateType update_type) {
|
| default:
|
| NOTREACHED();
|
| }
|
| - if (timer_queue_suspend_count_ != 0 || policy_disables_timers) {
|
| + if (MainThreadOnly().timer_queue_suspend_count_ != 0 ||
|
| + policy_disables_timers) {
|
| helper_.DisableQueue(TIMER_TASK_QUEUE);
|
| } else {
|
| helper_.SetQueuePriority(TIMER_TASK_QUEUE,
|
| @@ -445,13 +458,13 @@ void RendererSchedulerImpl::UpdatePolicyLocked(UpdateType update_type) {
|
| if (new_policy != Policy::TOUCHSTART_PRIORITY)
|
| DCHECK(helper_.IsQueueEnabled(LOADING_TASK_QUEUE));
|
|
|
| - current_policy_ = new_policy;
|
| + MainThreadOnly().current_policy_ = new_policy;
|
|
|
| TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(
|
| TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler",
|
| this, AsValueLocked(now));
|
| TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
|
| - "RendererScheduler.policy", current_policy_);
|
| + "RendererScheduler.policy", MainThreadOnly().current_policy_);
|
| }
|
|
|
| bool RendererSchedulerImpl::InputSignalsSuggestCompositorPriority(
|
| @@ -471,32 +484,34 @@ bool RendererSchedulerImpl::InputSignalsSuggestCompositorPriority(
|
| RendererSchedulerImpl::Policy RendererSchedulerImpl::ComputeNewPolicy(
|
| base::TimeTicks now,
|
| base::TimeDelta* new_policy_duration) const {
|
| - incoming_signals_lock_.AssertAcquired();
|
| + any_thread_lock_.AssertAcquired();
|
| *new_policy_duration = TimeLeftInInputEscalatedPolicy(now);
|
|
|
| if (*new_policy_duration == base::TimeDelta())
|
| return Policy::NORMAL;
|
|
|
| - return awaiting_touch_start_response_ ? Policy::TOUCHSTART_PRIORITY
|
| - : Policy::COMPOSITOR_PRIORITY;
|
| + return AnyThread().awaiting_touch_start_response_
|
| + ? Policy::TOUCHSTART_PRIORITY
|
| + : Policy::COMPOSITOR_PRIORITY;
|
| }
|
|
|
| base::TimeDelta RendererSchedulerImpl::TimeLeftInInputEscalatedPolicy(
|
| base::TimeTicks now) const {
|
| - incoming_signals_lock_.AssertAcquired();
|
| + any_thread_lock_.AssertAcquired();
|
|
|
| base::TimeDelta escalated_priority_duration =
|
| base::TimeDelta::FromMilliseconds(kPriorityEscalationAfterInputMillis);
|
|
|
| // If the input event is still pending, go into input prioritized policy
|
| // and check again later.
|
| - if (pending_main_thread_input_event_count_ > 0)
|
| + if (AnyThread().pending_main_thread_input_event_count_ > 0)
|
| return escalated_priority_duration;
|
| - if (last_input_signal_time_.is_null() ||
|
| - last_input_signal_time_ + escalated_priority_duration < now) {
|
| + if (AnyThread().last_input_signal_time_.is_null() ||
|
| + AnyThread().last_input_signal_time_ + escalated_priority_duration < now) {
|
| return base::TimeDelta();
|
| }
|
| - return last_input_signal_time_ + escalated_priority_duration - now;
|
| + return AnyThread().last_input_signal_time_ + escalated_priority_duration -
|
| + now;
|
| }
|
|
|
| bool RendererSchedulerImpl::CanEnterLongIdlePeriod(
|
| @@ -505,10 +520,11 @@ bool RendererSchedulerImpl::CanEnterLongIdlePeriod(
|
| helper_.CheckOnValidThread();
|
|
|
| MaybeUpdatePolicy();
|
| - if (SchedulerPolicy() == Policy::TOUCHSTART_PRIORITY) {
|
| + if (MainThreadOnly().current_policy_ == 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;
|
| + *next_long_idle_period_delay_out =
|
| + MainThreadOnly().current_policy_expiration_time_ - now;
|
| return false;
|
| }
|
| return true;
|
| @@ -519,16 +535,14 @@ SchedulerHelper* RendererSchedulerImpl::GetSchedulerHelperForTesting() {
|
| }
|
|
|
| void RendererSchedulerImpl::SuspendTimerQueue() {
|
| - helper_.CheckOnValidThread();
|
| - timer_queue_suspend_count_++;
|
| + MainThreadOnly().timer_queue_suspend_count_++;
|
| ForceUpdatePolicy();
|
| DCHECK(!helper_.IsQueueEnabled(TIMER_TASK_QUEUE));
|
| }
|
|
|
| void RendererSchedulerImpl::ResumeTimerQueue() {
|
| - helper_.CheckOnValidThread();
|
| - timer_queue_suspend_count_--;
|
| - DCHECK_GE(timer_queue_suspend_count_, 0);
|
| + MainThreadOnly().timer_queue_suspend_count_--;
|
| + DCHECK_GE(MainThreadOnly().timer_queue_suspend_count_, 0);
|
| ForceUpdatePolicy();
|
| }
|
|
|
| @@ -566,50 +580,51 @@ const char* RendererSchedulerImpl::PolicyToString(Policy policy) {
|
|
|
| scoped_refptr<base::trace_event::ConvertableToTraceFormat>
|
| RendererSchedulerImpl::AsValue(base::TimeTicks optional_now) const {
|
| - base::AutoLock lock(incoming_signals_lock_);
|
| + base::AutoLock lock(any_thread_lock_);
|
| return AsValueLocked(optional_now);
|
| }
|
|
|
| scoped_refptr<base::trace_event::ConvertableToTraceFormat>
|
| RendererSchedulerImpl::AsValueLocked(base::TimeTicks optional_now) const {
|
| helper_.CheckOnValidThread();
|
| - incoming_signals_lock_.AssertAcquired();
|
| + any_thread_lock_.AssertAcquired();
|
|
|
| if (optional_now.is_null())
|
| 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("current_policy",
|
| + PolicyToString(MainThreadOnly().current_policy_));
|
| state->SetString("idle_period_state",
|
| IdleHelper::IdlePeriodStateToString(
|
| idle_helper_.SchedulerIdlePeriodState()));
|
| - state->SetBoolean("renderer_hidden", renderer_hidden_);
|
| + state->SetBoolean("renderer_hidden", MainThreadOnly().renderer_hidden_);
|
| state->SetDouble("now", (optional_now - base::TimeTicks()).InMillisecondsF());
|
| - state->SetDouble(
|
| - "last_input_signal_time",
|
| - (last_input_signal_time_ - base::TimeTicks()).InMillisecondsF());
|
| + state->SetDouble("last_input_signal_time",
|
| + (AnyThread().last_input_signal_time_ - base::TimeTicks())
|
| + .InMillisecondsF());
|
| state->SetInteger("pending_main_thread_input_event_count",
|
| - pending_main_thread_input_event_count_);
|
| + AnyThread().pending_main_thread_input_event_count_);
|
| state->SetBoolean("awaiting_touch_start_response",
|
| - awaiting_touch_start_response_);
|
| + AnyThread().awaiting_touch_start_response_);
|
| state->SetBoolean("begin_main_frame_on_critical_path",
|
| - begin_main_frame_on_critical_path_);
|
| - state->SetDouble(
|
| - "estimated_next_frame_begin",
|
| - (estimated_next_frame_begin_ - base::TimeTicks()).InMillisecondsF());
|
| - state->SetBoolean("in_idle_period", in_idle_period_);
|
| + MainThreadOnly().begin_main_frame_on_critical_path_);
|
| + state->SetDouble("estimated_next_frame_begin",
|
| + (MainThreadOnly().estimated_next_frame_begin_ -
|
| + base::TimeTicks()).InMillisecondsF());
|
| + state->SetBoolean("in_idle_period", MainThreadOnly().in_idle_period_);
|
|
|
| return state;
|
| }
|
|
|
| void RendererSchedulerImpl::OnIdlePeriodStarted() {
|
| - in_idle_period_ = true;
|
| + MainThreadOnly().in_idle_period_ = true;
|
| // TODO(alexclarke): Force update the policy
|
| }
|
|
|
| void RendererSchedulerImpl::OnIdlePeriodEnded() {
|
| - in_idle_period_ = false;
|
| + MainThreadOnly().in_idle_period_ = false;
|
| // TODO(alexclarke): Force update the policy
|
| }
|
|
|
|
|