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

Unified Diff: components/scheduler/renderer/renderer_scheduler_impl.cc

Issue 1320633002: Optimize for TouchStart responsiveness (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase + remove some unwanted changes Created 5 years, 4 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 side-by-side diff with in-line comments
Download patch
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 4b565314a7996816887d0a71aaca51161fe5515c..4a2aa633fee93523ccd378844d5ec6c45d94a6a9 100644
--- a/components/scheduler/renderer/renderer_scheduler_impl.cc
+++ b/components/scheduler/renderer/renderer_scheduler_impl.cc
@@ -15,8 +15,10 @@
namespace scheduler {
namespace {
-const int kTimerTaskEstimationSampleCount = 4 * 60;
-const double kTimerTaskEstimationPercentile = 80;
+const int kLoadingTaskEstimationSampleCount = 200;
+const double kLoadingTaskEstimationPercentile = 90;
+const int kTimerTaskEstimationSampleCount = 200;
+const double kTimerTaskEstimationPercentile = 90;
Sami 2015/08/26 13:38:01 Any reason for tweaking these in this way?
alex clarke (OOO till 29th) 2015/08/27 12:02:51 Yes, I was hoping for a more pessimistic result th
const int kShortIdlePeriodDurationSampleCount = 10;
const double kShortIdlePeriodDurationPercentile = 20;
}
@@ -54,12 +56,19 @@ RendererSchedulerImpl::RendererSchedulerImpl(
end_renderer_hidden_idle_period_closure_.Reset(base::Bind(
&RendererSchedulerImpl::EndIdlePeriod, weak_factory_.GetWeakPtr()));
+ loading_task_runner_->AddTaskObserver(
+ &MainThreadOnly().loading_task_cost_estimator_);
+
timer_task_runner_->AddTaskObserver(
&MainThreadOnly().timer_task_cost_estimator_);
TRACE_EVENT_OBJECT_CREATED_WITH_ID(
TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler",
this);
+
+ // Make sure that we don't initially assume there is no idle time.
+ MainThreadOnly().short_idle_period_duration_.InsertSample(
+ base::TimeDelta::FromMilliseconds(16));
Sami 2015/08/26 13:38:01 BeginFrameArgs::DefaultInterval()?
alex clarke (OOO till 29th) 2015/08/27 12:02:51 Done.
}
RendererSchedulerImpl::~RendererSchedulerImpl() {
@@ -74,14 +83,23 @@ RendererSchedulerImpl::~RendererSchedulerImpl() {
DCHECK(MainThreadOnly().was_shutdown_);
}
+RendererSchedulerImpl::Policy::Policy()
+ : compositor_queue_priority_(TaskQueue::NORMAL_PRIORITY),
+ loading_queue_priority_(TaskQueue::NORMAL_PRIORITY),
+ timer_queue_priority_(TaskQueue::NORMAL_PRIORITY) {}
+
RendererSchedulerImpl::MainThreadOnly::MainThreadOnly()
- : timer_task_cost_estimator_(kTimerTaskEstimationSampleCount,
+ : loading_task_cost_estimator_(kLoadingTaskEstimationSampleCount,
+ kLoadingTaskEstimationPercentile),
+ timer_task_cost_estimator_(kTimerTaskEstimationSampleCount,
kTimerTaskEstimationPercentile),
short_idle_period_duration_(kShortIdlePeriodDurationSampleCount),
- current_policy_(Policy::NORMAL),
+ current_use_case_(UseCase::NOT_SCROLLING),
timer_queue_suspend_count_(0),
renderer_hidden_(false),
- was_shutdown_(false) {}
+ was_shutdown_(false),
+ loading_tasks_seem_expensive_(false),
+ timer_tasks_seem_expensive_(false) {}
RendererSchedulerImpl::MainThreadOnly::~MainThreadOnly() {}
@@ -89,8 +107,7 @@ RendererSchedulerImpl::AnyThread::AnyThread()
: pending_main_thread_input_event_count_(0),
awaiting_touch_start_response_(false),
in_idle_period_(false),
- begin_main_frame_on_critical_path_(false),
- timer_tasks_seem_expensive_(false) {}
+ begin_main_frame_on_critical_path_(false) {}
RendererSchedulerImpl::CompositorThreadOnly::CompositorThreadOnly()
: last_input_type_(blink::WebInputEvent::Undefined) {
@@ -176,10 +193,15 @@ void RendererSchedulerImpl::DidCommitFrameToCompositor() {
MainThreadOnly().estimated_next_frame_begin_);
MainThreadOnly().short_idle_period_duration_.InsertSample(
MainThreadOnly().estimated_next_frame_begin_ - now);
- MainThreadOnly().expected_short_idle_period_duration_ =
- MainThreadOnly().short_idle_period_duration_.Percentile(
- kShortIdlePeriodDurationPercentile);
+ } else {
+ // There was no idle time :(
+ MainThreadOnly().short_idle_period_duration_.InsertSample(
+ base::TimeDelta());
}
+
+ MainThreadOnly().expected_short_idle_period_duration_ =
+ MainThreadOnly().short_idle_period_duration_.Percentile(
+ kShortIdlePeriodDurationPercentile);
}
void RendererSchedulerImpl::BeginFrameNotExpectedSoon() {
@@ -278,12 +300,54 @@ void RendererSchedulerImpl::DidAnimateForInputOnCompositorThread() {
InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
}
+const char* WebInputEventToString(blink::WebInputEvent::Type type) {
+#define CASE_TYPE(t) \
+ case blink::WebInputEvent::t: \
+ return #t
+ switch (type) {
+ CASE_TYPE(Undefined);
Sami 2015/08/26 13:38:01 Instead of duplicating this from RenderWidget, cou
alex clarke (OOO till 29th) 2015/08/27 12:02:51 Acknowledged.
+ CASE_TYPE(MouseDown);
+ CASE_TYPE(MouseUp);
+ CASE_TYPE(MouseMove);
+ CASE_TYPE(MouseEnter);
+ CASE_TYPE(MouseLeave);
+ CASE_TYPE(ContextMenu);
+ CASE_TYPE(MouseWheel);
+ CASE_TYPE(RawKeyDown);
+ CASE_TYPE(KeyDown);
+ CASE_TYPE(KeyUp);
+ CASE_TYPE(Char);
+ CASE_TYPE(GestureScrollBegin);
+ CASE_TYPE(GestureScrollEnd);
+ CASE_TYPE(GestureScrollUpdate);
+ CASE_TYPE(GestureFlingStart);
+ CASE_TYPE(GestureFlingCancel);
+ CASE_TYPE(GestureShowPress);
+ CASE_TYPE(GestureTap);
+ CASE_TYPE(GestureTapUnconfirmed);
+ CASE_TYPE(GestureTapDown);
+ CASE_TYPE(GestureTapCancel);
+ CASE_TYPE(GestureDoubleTap);
+ CASE_TYPE(GestureTwoFingerTap);
+ CASE_TYPE(GestureLongPress);
+ CASE_TYPE(GestureLongTap);
+ CASE_TYPE(GesturePinchBegin);
+ CASE_TYPE(GesturePinchEnd);
+ CASE_TYPE(GesturePinchUpdate);
+ CASE_TYPE(TouchStart);
+ CASE_TYPE(TouchMove);
+ CASE_TYPE(TouchEnd);
+ CASE_TYPE(TouchCancel);
+ }
+ return "";
+}
+
void RendererSchedulerImpl::UpdateForInputEventOnCompositorThread(
blink::WebInputEvent::Type type,
InputEventState input_event_state) {
base::AutoLock lock(any_thread_lock_);
base::TimeTicks now = helper_.Now();
- bool was_in_compositor_priority = InputSignalsSuggestCompositorPriority(now);
+ bool already_scrolling = InputSignalsSuggestScrolling(now);
bool was_awaiting_touch_start_response =
AnyThread().awaiting_touch_start_response_;
@@ -291,6 +355,7 @@ void RendererSchedulerImpl::UpdateForInputEventOnCompositorThread(
switch (type) {
case blink::WebInputEvent::TouchStart:
AnyThread().awaiting_touch_start_response_ = true;
+ AnyThread().last_touchstart_time_ = now;
break;
case blink::WebInputEvent::TouchMove:
@@ -322,7 +387,7 @@ void RendererSchedulerImpl::UpdateForInputEventOnCompositorThread(
}
// Avoid unnecessary policy updates, while in compositor priority.
- if (!was_in_compositor_priority ||
+ if (!already_scrolling ||
was_awaiting_touch_start_response !=
AnyThread().awaiting_touch_start_response_) {
EnsureUrgentPolicyUpdatePostedOnMainThread(FROM_HERE);
@@ -330,8 +395,12 @@ void RendererSchedulerImpl::UpdateForInputEventOnCompositorThread(
AnyThread().last_input_signal_time_ = now;
CompositorThreadOnly().last_input_type_ = type;
- if (input_event_state == InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD)
+ if (input_event_state == InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD) {
+ TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
+ "InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD", "type",
+ WebInputEventToString(type));
AnyThread().pending_main_thread_input_event_count_++;
+ }
}
void RendererSchedulerImpl::DidHandleInputEventOnMainThread(
@@ -353,12 +422,12 @@ bool RendererSchedulerImpl::IsHighPriorityWorkAnticipated() {
return false;
MaybeUpdatePolicy();
- // The touchstart and compositor policies indicate a strong likelihood of
- // high-priority work in the near future.
- return MainThreadOnly().current_policy_ == Policy::COMPOSITOR_PRIORITY ||
- MainThreadOnly().current_policy_ ==
- Policy::COMPOSITOR_CRITICAL_PATH_PRIORITY ||
- MainThreadOnly().current_policy_ == Policy::TOUCHSTART_PRIORITY;
+ // The touchstart and main-thread scrolling states indicate a strong
+ // likelihood of high-priority work in the near future.
+ UseCase use_case = MainThreadOnly().current_use_case_;
+ return MainThreadOnly().scroll_expected_soon_ ||
+ use_case == UseCase::MAINTHREAD_SCROLLING ||
+ use_case == UseCase::TOUCHSTART;
}
bool RendererSchedulerImpl::ShouldYieldForHighPriorityWork() {
@@ -367,25 +436,25 @@ bool RendererSchedulerImpl::ShouldYieldForHighPriorityWork() {
return false;
MaybeUpdatePolicy();
- // We only yield if we are in the compositor priority and there is compositor
- // work outstanding, or if we are in the touchstart response priority.
- // 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 (MainThreadOnly().current_policy_) {
- case Policy::NORMAL:
+ // We only yield if there's a urgent task to be run now, or we are expecting
+ // one soon (touch start).
+ // Note: even though the control queue has the highest 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 (MainThreadOnly().current_use_case_) {
+ case UseCase::NOT_SCROLLING:
Sami 2015/08/26 13:38:01 Could we not be expecting a scroll in this state?
alex clarke (OOO till 29th) 2015/08/27 12:02:51 Yeah we could. Maybe we should yeild in that situ
return false;
- case Policy::COMPOSITOR_PRIORITY:
- return !compositor_task_runner_->IsQueueEmpty();
+ case UseCase::COMPOSITOR_SCROLLING:
+ return MainThreadOnly().scroll_expected_soon_;
- case Policy::COMPOSITOR_CRITICAL_PATH_PRIORITY:
+ case UseCase::MAINTHREAD_SCROLLING:
return !compositor_task_runner_->IsQueueEmpty();
- case Policy::TOUCHSTART_PRIORITY:
+ case UseCase::TOUCHSTART:
return true;
- case Policy::LOADING_PRIORITY:
+ case UseCase::LOADING:
return false;
default:
@@ -427,6 +496,41 @@ void RendererSchedulerImpl::ForceUpdatePolicy() {
UpdatePolicyLocked(UpdateType::FORCE_UPDATE);
}
+bool RendererSchedulerImpl::ScrollExpectedSoon(
+ UseCase use_case,
+ const base::TimeTicks now,
+ base::TimeDelta* new_policy_duration) const {
+ if (use_case == UseCase::NOT_SCROLLING) {
+ // If we've scrolled recently then future scrolling is likely.
+ base::TimeDelta expect_subsequent_input_for =
+ base::TimeDelta::FromMilliseconds(kExpectSubsequentInputMillis);
+ if (AnyThread().last_input_signal_time_.is_null() ||
+ AnyThread().last_input_signal_time_ + expect_subsequent_input_for <=
+ now) {
+ return false;
+ }
+ *new_policy_duration =
+ AnyThread().last_input_signal_time_ + expect_subsequent_input_for - now;
+ return true;
+ }
+
+ if (use_case == UseCase::COMPOSITOR_SCROLLING) {
+ // If we've only just started scrolling then, then future scrolling is
+ // unlikely.
+ base::TimeDelta minimum_typical_scroll_duration =
+ base::TimeDelta::FromMilliseconds(kMinimumTypicalScrollDurationMillis);
+ if (AnyThread().last_touchstart_time_.is_null() ||
Sami 2015/08/26 13:38:01 Touchstart doesn't get sent if there are no touch
alex clarke (OOO till 29th) 2015/08/27 12:02:51 Maybe this function is badly named then (see comme
+ AnyThread().last_touchstart_time_ + minimum_typical_scroll_duration <=
+ now) {
+ return true;
+ }
+ *new_policy_duration = AnyThread().last_touchstart_time_ +
+ minimum_typical_scroll_duration - now;
+ return false;
+ }
+ return false;
Sami 2015/08/26 13:38:01 Should we always return true for main thread scrol
alex clarke (OOO till 29th) 2015/08/27 12:02:51 Good question. I think that depends on what we wa
+}
+
void RendererSchedulerImpl::UpdatePolicyLocked(UpdateType update_type) {
helper_.CheckOnValidThread();
any_thread_lock_.AssertAcquired();
@@ -436,14 +540,23 @@ void RendererSchedulerImpl::UpdatePolicyLocked(UpdateType update_type) {
base::TimeTicks now = helper_.Now();
policy_may_need_update_.SetWhileLocked(false);
- AnyThread().timer_tasks_seem_expensive_ =
- MainThreadOnly().expected_short_idle_period_duration_ >
- base::TimeDelta() &&
+ base::TimeDelta new_policy_duration;
+ UseCase use_case = ComputeCurrentUseCase(now, &new_policy_duration);
+
+ // Adjust the policy duration if |scroll_expected_soon| is likely to change.
+ bool scroll_expected_soon = ScrollExpectedSoon(use_case,
+ now,
+ &new_policy_duration);
+ bool loading_tasks_seem_expensive =
+ MainThreadOnly().loading_task_cost_estimator_.expected_task_duration() >
+ MainThreadOnly().expected_short_idle_period_duration_;
+ bool timer_tasks_seem_expensive =
MainThreadOnly().timer_task_cost_estimator_.expected_task_duration() >
- MainThreadOnly().expected_short_idle_period_duration_;
+ MainThreadOnly().expected_short_idle_period_duration_;
+ MainThreadOnly().scroll_expected_soon_ = scroll_expected_soon;
+ MainThreadOnly().loading_tasks_seem_expensive_ = loading_tasks_seem_expensive;
+ MainThreadOnly().timer_tasks_seem_expensive_ = timer_tasks_seem_expensive;
- base::TimeDelta new_policy_duration;
- Policy new_policy = ComputeNewPolicy(now, &new_policy_duration);
if (new_policy_duration > base::TimeDelta()) {
MainThreadOnly().current_policy_expiration_time_ =
now + new_policy_duration;
@@ -453,73 +566,86 @@ void RendererSchedulerImpl::UpdatePolicyLocked(UpdateType update_type) {
MainThreadOnly().current_policy_expiration_time_ = base::TimeTicks();
}
- if (update_type == UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED &&
- new_policy == MainThreadOnly().current_policy_)
- return;
-
- TaskQueue::QueuePriority compositor_queue_priority =
- TaskQueue::NORMAL_PRIORITY;
- TaskQueue::QueuePriority loading_queue_priority = TaskQueue::NORMAL_PRIORITY;
- TaskQueue::QueuePriority timer_queue_priority =
- MainThreadOnly().timer_queue_suspend_count_ != 0
- ? TaskQueue::DISABLED_PRIORITY
- : TaskQueue::NORMAL_PRIORITY;
-
- switch (new_policy) {
- case Policy::COMPOSITOR_PRIORITY:
- compositor_queue_priority = TaskQueue::HIGH_PRIORITY;
+ Policy new_policy;
+ bool block_expensive_tasks = false;
+ switch (use_case) {
+ case UseCase::COMPOSITOR_SCROLLING:
+ if (scroll_expected_soon)
+ block_expensive_tasks = true;
+ else
+ new_policy.loading_queue_priority_ = TaskQueue::HIGH_PRIORITY;
break;
- case Policy::COMPOSITOR_CRITICAL_PATH_PRIORITY:
- compositor_queue_priority = TaskQueue::HIGH_PRIORITY;
- loading_queue_priority = TaskQueue::DISABLED_PRIORITY;
- timer_queue_priority = TaskQueue::DISABLED_PRIORITY;
+
+ case UseCase::MAINTHREAD_SCROLLING:
+ new_policy.compositor_queue_priority_ = TaskQueue::HIGH_PRIORITY;
+ block_expensive_tasks = true;
break;
- case Policy::TOUCHSTART_PRIORITY:
- compositor_queue_priority = TaskQueue::HIGH_PRIORITY;
- loading_queue_priority = TaskQueue::DISABLED_PRIORITY;
- timer_queue_priority = TaskQueue::DISABLED_PRIORITY;
+
+ case UseCase::TOUCHSTART:
+ new_policy.compositor_queue_priority_ = TaskQueue::HIGH_PRIORITY;
+ new_policy.loading_queue_priority_ = TaskQueue::DISABLED_PRIORITY;
+ new_policy.timer_queue_priority_ = TaskQueue::DISABLED_PRIORITY;
Sami 2015/08/26 13:38:01 block_expensive_tasks = true?
alex clarke (OOO till 29th) 2015/08/27 12:02:51 We could do that, but it would be a nop. Do you st
Sami 2015/08/27 15:15:58 Yeah, I was thinking it would be better to have it
alex clarke (OOO till 29th) 2015/09/03 10:34:25 Done.
break;
- case Policy::NORMAL:
+
+ case UseCase::NOT_SCROLLING:
+ if (scroll_expected_soon)
+ block_expensive_tasks = true;
+ else
+ new_policy.loading_queue_priority_ = TaskQueue::HIGH_PRIORITY;
break;
- case Policy::LOADING_PRIORITY:
- // We prioritize loading tasks by deprioritizing compositing and timers.
- compositor_queue_priority = TaskQueue::BEST_EFFORT_PRIORITY;
- timer_queue_priority = TaskQueue::BEST_EFFORT_PRIORITY;
- // TODO(alexclarke): See if we can safely mark the loading task queue as
- // high priority.
+
+ case UseCase::LOADING:
+ new_policy.loading_queue_priority_ = TaskQueue::HIGH_PRIORITY;
+ new_policy.timer_queue_priority_ = TaskQueue::HIGH_PRIORITY;
Sami 2015/08/26 13:38:01 Why are timers now high priority? They used to be
alex clarke (OOO till 29th) 2015/08/27 12:02:51 They don't need to be :)
break;
default:
NOTREACHED();
}
- compositor_task_runner_->SetQueuePriority(compositor_queue_priority);
- loading_task_runner_->SetQueuePriority(loading_queue_priority);
- timer_task_runner_->SetQueuePriority(timer_queue_priority);
+ if (block_expensive_tasks && loading_tasks_seem_expensive)
+ new_policy.loading_queue_priority_ = TaskQueue::DISABLED_PRIORITY;
- DCHECK(compositor_task_runner_->IsQueueEnabled());
- if (new_policy != Policy::TOUCHSTART_PRIORITY &&
- new_policy != Policy::COMPOSITOR_CRITICAL_PATH_PRIORITY) {
- DCHECK(loading_task_runner_->IsQueueEnabled());
- }
- MainThreadOnly().current_policy_ = new_policy;
+ if ((block_expensive_tasks && timer_tasks_seem_expensive) ||
+ MainThreadOnly().timer_queue_suspend_count_ != 0)
+ new_policy.timer_queue_priority_ = TaskQueue::DISABLED_PRIORITY;
+ // Tracing is done before the early out check, because it's quite possible we
+ // will otherwise miss this information in traces.
TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(
TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler",
this, AsValueLocked(now));
+ TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "use_case",
+ use_case);
TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
- "RendererScheduler.policy", MainThreadOnly().current_policy_);
+ "RendererScheduler.loading_tasks_seem_expensive",
+ MainThreadOnly().loading_tasks_seem_expensive_);
TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
"RendererScheduler.timer_tasks_seem_expensive",
- AnyThread().timer_tasks_seem_expensive_);
+ MainThreadOnly().timer_tasks_seem_expensive_);
+
+ if (update_type == UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED &&
+ use_case == MainThreadOnly().current_use_case_ &&
Sami 2015/08/26 13:38:01 Do we need to check if the use case changed? Could
alex clarke (OOO till 29th) 2015/08/27 12:02:51 Yeah I think we could do that.
+ new_policy == MainThreadOnly().current_policy_) {
+ return;
+ }
+
+ compositor_task_runner_->SetQueuePriority(
+ new_policy.compositor_queue_priority_);
+ loading_task_runner_->SetQueuePriority(new_policy.loading_queue_priority_);
+ timer_task_runner_->SetQueuePriority(new_policy.timer_queue_priority_);
+
+ DCHECK(compositor_task_runner_->IsQueueEnabled());
+ MainThreadOnly().current_use_case_ = use_case;
+ MainThreadOnly().current_policy_ = new_policy;
}
-bool RendererSchedulerImpl::InputSignalsSuggestCompositorPriority(
+bool RendererSchedulerImpl::InputSignalsSuggestScrolling(
base::TimeTicks now) const {
base::TimeDelta unused_policy_duration;
- switch (ComputeNewPolicy(now, &unused_policy_duration)) {
- case Policy::TOUCHSTART_PRIORITY:
- case Policy::COMPOSITOR_PRIORITY:
- case Policy::COMPOSITOR_CRITICAL_PATH_PRIORITY:
+ switch (ComputeCurrentUseCase(now, &unused_policy_duration)) {
+ case UseCase::COMPOSITOR_SCROLLING:
+ case UseCase::MAINTHREAD_SCROLLING:
+ case UseCase::TOUCHSTART:
return true;
default:
@@ -528,33 +654,34 @@ bool RendererSchedulerImpl::InputSignalsSuggestCompositorPriority(
return false;
}
-RendererSchedulerImpl::Policy RendererSchedulerImpl::ComputeNewPolicy(
+RendererSchedulerImpl::UseCase RendererSchedulerImpl::ComputeCurrentUseCase(
base::TimeTicks now,
base::TimeDelta* new_policy_duration) const {
any_thread_lock_.AssertAcquired();
// Above all else we want to be responsive to user input.
*new_policy_duration = TimeLeftInInputEscalatedPolicy(now);
if (*new_policy_duration > base::TimeDelta()) {
- if (AnyThread().awaiting_touch_start_response_)
- return Policy::TOUCHSTART_PRIORITY;
- // If BeginMainFrame is on the critical path, we want to try and prevent
- // timers and loading tasks from running if we think they might be
- // expensive.
- // TODO(skyostil): Consider removing in_idle_period_ and
Sami 2015/08/26 13:38:01 Wanna keep this todo since the code is still here?
alex clarke (OOO till 29th) 2015/08/27 12:02:51 Done.
- // HadAnIdlePeriodRecently() unless we need them here.
- if (AnyThread().timer_tasks_seem_expensive_ &&
- AnyThread().begin_main_frame_on_critical_path_) {
- return Policy::COMPOSITOR_CRITICAL_PATH_PRIORITY;
+ // Has scrolling been fully established?
+ if (AnyThread().awaiting_touch_start_response_) {
+ // No., so arrange for compositor tasks to be run at the highest priority.
Sami 2015/08/26 13:38:01 typo: .
alex clarke (OOO till 29th) 2015/08/27 12:02:51 Done.
+ return UseCase::TOUCHSTART;
+ }
+ // Yes scrolling has been established. If BeginMainFrame is on the critical
+ // path, compositor tasks need to be prioritized, otherwise now might be a
+ // good time to run potentially expensive work.
+ if (AnyThread().begin_main_frame_on_critical_path_) {
+ return UseCase::MAINTHREAD_SCROLLING;
+ } else {
+ return UseCase::COMPOSITOR_SCROLLING;
}
- return Policy::COMPOSITOR_PRIORITY;
}
if (AnyThread().rails_loading_priority_deadline_ > now) {
*new_policy_duration = AnyThread().rails_loading_priority_deadline_ - now;
- return Policy::LOADING_PRIORITY;
+ return UseCase::LOADING;
}
- return Policy::NORMAL;
+ return UseCase::NOT_SCROLLING;
}
base::TimeDelta RendererSchedulerImpl::TimeLeftInInputEscalatedPolicy(
@@ -582,7 +709,7 @@ bool RendererSchedulerImpl::CanEnterLongIdlePeriod(
helper_.CheckOnValidThread();
MaybeUpdatePolicy();
- if (MainThreadOnly().current_policy_ == Policy::TOUCHSTART_PRIORITY) {
+ if (MainThreadOnly().current_use_case_ == UseCase::TOUCHSTART) {
// 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 =
@@ -609,17 +736,17 @@ void RendererSchedulerImpl::ResumeTimerQueue() {
}
// static
-const char* RendererSchedulerImpl::PolicyToString(Policy policy) {
- switch (policy) {
- case Policy::NORMAL:
- return "normal";
- case Policy::COMPOSITOR_PRIORITY:
- return "compositor";
- case Policy::COMPOSITOR_CRITICAL_PATH_PRIORITY:
- return "compositor_critical_path";
- case Policy::TOUCHSTART_PRIORITY:
+const char* RendererSchedulerImpl::UseCaseToString(UseCase use_case) {
+ switch (use_case) {
+ case UseCase::NOT_SCROLLING:
+ return "not_scrolling";
+ case UseCase::COMPOSITOR_SCROLLING:
+ return "compositor_scrolling";
+ case UseCase::MAINTHREAD_SCROLLING:
+ return "mainthread_scrolling";
+ case UseCase::TOUCHSTART:
return "touchstart";
- case Policy::LOADING_PRIORITY:
+ case UseCase::LOADING:
return "loading";
default:
NOTREACHED();
@@ -643,8 +770,14 @@ RendererSchedulerImpl::AsValueLocked(base::TimeTicks optional_now) const {
scoped_refptr<base::trace_event::TracedValue> state =
new base::trace_event::TracedValue();
- state->SetString("current_policy",
- PolicyToString(MainThreadOnly().current_policy_));
+ state->SetString("current_use_case",
Sami 2015/08/26 13:38:01 Do we want to trace the policy too? One way would
alex clarke (OOO till 29th) 2015/08/27 12:02:51 We could do that, mind you it's already logged in
Sami 2015/08/27 15:15:58 Right, let's add it once it actually adds new info
alex clarke (OOO till 29th) 2015/09/03 10:34:25 Acknowledged.
+ UseCaseToString(MainThreadOnly().current_use_case_));
+ state->SetBoolean("loading_tasks_seem_expensive",
+ MainThreadOnly().loading_tasks_seem_expensive_);
+ state->SetBoolean("timer_tasks_seem_expensive",
+ MainThreadOnly().timer_tasks_seem_expensive_);
+ state->SetBoolean("scroll_expected_soon",
+ MainThreadOnly().scroll_expected_soon_);
state->SetString("idle_period_state",
IdleHelper::IdlePeriodStateToString(
idle_helper_.SchedulerIdlePeriodState()));
@@ -665,6 +798,10 @@ RendererSchedulerImpl::AsValueLocked(base::TimeTicks optional_now) const {
AnyThread().awaiting_touch_start_response_);
state->SetBoolean("begin_main_frame_on_critical_path",
AnyThread().begin_main_frame_on_critical_path_);
+ state->SetDouble("expected_loading_task_duration",
+ MainThreadOnly()
+ .loading_task_cost_estimator_.expected_task_duration()
+ .InMillisecondsF());
state->SetDouble("expected_timer_task_duration",
MainThreadOnly()
.timer_task_cost_estimator_.expected_task_duration()
@@ -673,8 +810,6 @@ RendererSchedulerImpl::AsValueLocked(base::TimeTicks optional_now) const {
state->SetDouble(
"expected_short_idle_period_duration",
MainThreadOnly().expected_short_idle_period_duration_.InMillisecondsF());
- state->SetBoolean("timer_tasks_seem_expensive",
- AnyThread().timer_tasks_seem_expensive_);
state->SetDouble("estimated_next_frame_begin",
(MainThreadOnly().estimated_next_frame_begin_ -
base::TimeTicks()).InMillisecondsF());

Powered by Google App Engine
This is Rietveld 408576698